def _calculate_frustum_planes()

in src/markov/cameras/frustum.py [0:0]


    def _calculate_frustum_planes(self, cam_pos, cam_quaternion):
        cam_pos = np.array(cam_pos)
        cam_quaternion = np.array(cam_quaternion)
        cam_forward = Frustum.get_forward_vec(cam_quaternion)
        cam_up = Frustum.get_up_vec(cam_quaternion)
        cam_right = Frustum.get_right_vec(cam_quaternion)

        near_center = cam_pos + cam_forward * self.near
        far_center = cam_pos + cam_forward * self.far

        near_width = 2.0 * math.tan(self.horizontal_fov * 0.5) * self.near
        near_height = near_width * self.view_ratio
        far_width = 2.0 * math.tan(self.horizontal_fov * 0.5) * self.far
        far_height = far_width * self.view_ratio

        far_top_left = far_center + cam_up * (far_height * 0.5) - cam_right * (far_width * 0.5)
        far_top_right = far_center + cam_up * (far_height * 0.5) + cam_right * (far_width * 0.5)
        far_bottom_left = far_center - cam_up * (far_height * 0.5) - cam_right * (far_width * 0.5)
        far_bottom_right = far_center - cam_up * (far_height * 0.5) + cam_right * (far_width * 0.5)

        near_top_left = near_center + cam_up * (near_height * 0.5) - cam_right * (near_width * 0.5)
        near_top_right = near_center + cam_up * (near_height * 0.5) + cam_right * (near_width * 0.5)
        near_bottom_left = near_center - cam_up * (near_height * 0.5) - cam_right * (near_width * 0.5)
        near_bottom_right = near_center - cam_up * (near_height * 0.5) + cam_right * (near_width * 0.5)
        planes = []

        # near plane
        if self.ccw:
            p0, p1, p2 = near_bottom_left, near_top_left, near_bottom_right
        else:
            p0, p1, p2 = near_bottom_right, near_top_right, near_bottom_left
        near_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        near_plane_offset = -np.dot(near_plane_normal, p0)
        planes.append((near_plane_normal, near_plane_offset))

        # far plane
        if self.ccw:
            p0, p1, p2 = far_bottom_right, far_top_right, far_bottom_left
        else:
            p0, p1, p2 = far_bottom_left, far_top_left, far_bottom_right
        far_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        far_plane_offset = -np.dot(far_plane_normal, p0)
        planes.append((far_plane_normal, far_plane_offset))

        # left plane
        if self.ccw:
            p0, p1, p2 = far_bottom_left, far_top_left, near_bottom_left
        else:
            p0, p1, p2 = near_bottom_left, near_top_left, far_bottom_left
        left_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        left_plane_offset = -np.dot(left_plane_normal, p0)
        planes.append((left_plane_normal, left_plane_offset))

        # right plane
        if self.ccw:
            p0, p1, p2 = near_bottom_right, near_top_right, far_bottom_right
        else:
            p0, p1, p2 = far_bottom_right, far_top_right, near_bottom_right
        right_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        right_plane_offset = -np.dot(right_plane_normal, p0)
        planes.append((right_plane_normal, right_plane_offset))

        # top plane
        if self.ccw:
            p0, p1, p2 = near_top_right, near_top_left, far_top_right
        else:
            p0, p1, p2 = near_top_left, near_top_right, far_top_left
        top_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        top_plane_offset = -np.dot(top_plane_normal, p0)
        planes.append((top_plane_normal, top_plane_offset))

        # bottom plane
        if self.ccw:
            p0, p1, p2 = near_bottom_right, far_bottom_right, near_bottom_left
        else:
            p0, p1, p2 = near_bottom_left, far_bottom_left, near_bottom_right
        bottom_plane_normal = normalize(np.cross(p1 - p0, p2 - p0))
        bottom_plane_offset = -np.dot(bottom_plane_normal, p0)
        planes.append((bottom_plane_normal, bottom_plane_offset))

        cam_pose = {
            "position": cam_pos,
            "orientation": cam_quaternion
        }

        near_plane_info = {
            "width": near_width,
            "height": near_height,
            "position": near_center,
            "bounding_box": {
                "bottom_left": near_bottom_left,
                "top_left": near_top_left,
                "top_right": near_top_right,
                "bottom_right": near_bottom_right,
            },
            "normal": near_plane_normal,
            "offset": near_plane_offset
        }

        return planes, cam_pose, near_plane_info