def to_viewport_point(self, point): with self.lock: if not isinstance(point, list) and not isinstance(point, tuple) \ and not isinstance(point, np.ndarray): raise GenericRolloutException("point must be a type of list, tuple, or numpy.ndarray") ray_origin = np.array(point) points_in_viewports = [] for cam_pose, near_plane_info in zip(self.cam_poses, self.near_plane_infos): cam_pos = cam_pose["position"] cam_quaternion = cam_pose["orientation"] near_width = near_plane_info["width"] near_height = near_plane_info["height"] near_center = near_plane_info["position"] near_normal = near_plane_info["normal"] near_offset = near_plane_info["offset"] ray_dir = normalize(cam_pos - ray_origin) point_on_plane = ray_plane_intersect(ray_origin=ray_origin, ray_dir=ray_dir, plane_normal=near_normal, plane_offset=near_offset, threshold=self.threshold) if point_on_plane is None: points_in_viewports.append((-1.0, -1.0)) else: point_in_viewport = project_to_2d(point_on_plane=point_on_plane, plane_center=near_center, plane_width=near_width, plane_height=near_height, plane_quaternion=cam_quaternion) points_in_viewports.append(point_in_viewport) return points_in_viewports
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_right, near_bottom_left, near_top_left else: p0, p1, p2 = near_top_left, near_bottom_left, near_bottom_right near_plane_normal = normalize(np.cross(p1 - p0, p2 - p1)) 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_top_left else: p0, p1, p2 = far_top_left, far_top_right, far_bottom_right far_plane_normal = normalize(np.cross(p1 - p0, p2 - p1)) 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 = near_bottom_left, far_bottom_left, far_top_left else: p0, p1, p2 = far_top_left, far_bottom_left, near_bottom_left left_plane_normal = normalize(np.cross(p1 - p0, p2-p1)) 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_top_right, far_top_right, far_bottom_right else: p0, p1, p2 = far_bottom_right, far_top_right, near_top_right right_plane_normal = normalize(np.cross(p1 - p0, p2-p1)) 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_left, far_top_left, far_top_right else: p0, p1, p2 = far_top_right, far_top_left, near_top_left top_plane_normal = normalize(np.cross(p1 - p0, p2-p1)) 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, far_bottom_left else: p0, p1, p2 = far_bottom_left, far_bottom_right, near_bottom_right bottom_plane_normal = normalize(np.cross(p1 - p0, p2 - p1)) 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