Builds a viewing frustum (image plane as two triangles, plus the frame and connecting lines to the projection center) for a perspective camera.
| 222 | // Builds a viewing frustum (image plane as two triangles, plus the frame and |
| 223 | // connecting lines to the projection center) for a perspective camera. |
| 224 | void BuildPerspectiveCameraModel( |
| 225 | const Eigen::Matrix<float, 3, 4>& world_from_cam_mat, |
| 226 | const Camera& camera, |
| 227 | const float image_width, |
| 228 | const float image_height, |
| 229 | const float image_extent, |
| 230 | const RGBAColor& plane_color, |
| 231 | const RGBAColor& frame_color, |
| 232 | const bool show_camera_orientation, |
| 233 | std::vector<TrianglePainter::Data>* triangle_data, |
| 234 | std::vector<LinePainter::Data>* line_data) { |
| 235 | const float camera_extent = std::max(camera.width, camera.height); |
| 236 | const float camera_extent_normalized = |
| 237 | static_cast<float>(camera.CamFromImgThreshold(camera_extent)); |
| 238 | const float focal_length = 2.0f * image_extent / camera_extent_normalized; |
| 239 | |
| 240 | // Projection center, top-left, top-right, bottom-right, bottom-left corners. |
| 241 | const Eigen::Vector3f pc = world_from_cam_mat.rightCols<1>(); |
| 242 | const Eigen::Vector3f tl = |
| 243 | world_from_cam_mat * |
| 244 | Eigen::Vector4f(-image_width, -image_height, focal_length, 1); |
| 245 | const Eigen::Vector3f tr = |
| 246 | world_from_cam_mat * |
| 247 | Eigen::Vector4f(image_width, -image_height, focal_length, 1); |
| 248 | const Eigen::Vector3f br = |
| 249 | world_from_cam_mat * |
| 250 | Eigen::Vector4f(image_width, image_height, focal_length, 1); |
| 251 | const Eigen::Vector3f bl = |
| 252 | world_from_cam_mat * |
| 253 | Eigen::Vector4f(-image_width, image_height, focal_length, 1); |
| 254 | |
| 255 | // Image plane as two triangles. |
| 256 | if (triangle_data != nullptr) { |
| 257 | const auto add_triangle = [&](const Eigen::Vector3f& p1, |
| 258 | const Eigen::Vector3f& p2, |
| 259 | const Eigen::Vector3f& p3, |
| 260 | const RGBAColor& color) { |
| 261 | triangle_data->emplace_back( |
| 262 | PointPainter::Data( |
| 263 | p1(0), p1(1), p1(2), color(0), color(1), color(2), color(3)), |
| 264 | PointPainter::Data( |
| 265 | p2(0), p2(1), p2(2), color(0), color(1), color(2), color(3)), |
| 266 | PointPainter::Data( |
| 267 | p3(0), p3(1), p3(2), color(0), color(1), color(2), color(3))); |
| 268 | }; |
| 269 | add_triangle(tl, tr, bl, plane_color); |
| 270 | add_triangle(bl, tr, br, plane_color); |
| 271 | |
| 272 | if (show_camera_orientation) { |
| 273 | const Eigen::Matrix3f world_from_cam_rot = |
| 274 | world_from_cam_mat.block<3, 3>(0, 0); |
| 275 | |
| 276 | const Eigen::Vector3f right_dir = world_from_cam_rot.col(0); |
| 277 | const Eigen::Vector3f up_dir = -world_from_cam_rot.col(1); |
| 278 | const Eigen::Vector3f forward_dir = world_from_cam_rot.col(2); |
| 279 | |
| 280 | // Size + offset |
| 281 | const float size = 0.5f * image_extent; |
no test coverage detected