@@ -39,7 +39,8 @@ using namespace VIEWER;
3939Renderer::Renderer ()
4040 : pointCount(0 )
4141 , pointNormalCount(0 )
42- , cameraIndexCount(0 )
42+ , cameraPointIndexCount(0 )
43+ , cameraLineIndexCount(0 )
4344 , imageOverlayIndexCount(0 )
4445 , selectionPrimitiveCount(0 )
4546 , selectionOverlayVertexCount(0 )
@@ -102,7 +103,8 @@ void Renderer::Reset() {
102103 // Reset scene-dependent primitive counts
103104 pointCount = 0 ;
104105 pointNormalCount = 0 ;
105- cameraIndexCount = 0 ;
106+ cameraPointIndexCount = 0 ;
107+ cameraLineIndexCount = 0 ;
106108 imageOverlayIndexCount = 0 ;
107109 selectionPrimitiveCount = 0 ;
108110 boundsPrimitiveCount = 0 ;
@@ -725,13 +727,15 @@ static std::array<Point3f, 4> ComputeCameraFrustumCorners(const MVS::Image& imag
725727 return worldCorners;
726728}
727729
728- // Helper function to create camera frustum geometry for a single camera
729- // Returns the vertices, colors, and indices for the camera wireframe
730- static void CreateCameraFrustumGeometry (
730+ // Helper function to create camera frustum geometry for a single camera;
731+ // generate the vertices, colors, and indices for the camera wireframe and
732+ // returns the number of indices added
733+ static uint32_t CreateCameraFrustumGeometry (
731734 const MVS::Image& imageData,
732735 float depth,
733- const Eigen::Vector3f& centerColor,
734- const Eigen::Vector3f& frustumColor,
736+ bool showLookAt,
737+ const Pixel32F& centerColor,
738+ const Pixel32F& frustumColor,
735739 std::vector<float >& vertices,
736740 std::vector<float >& colors,
737741 std::vector<uint32_t >& indices,
@@ -740,31 +744,17 @@ static void CreateCameraFrustumGeometry(
740744 // Camera center (apex of the pyramid)
741745 const Point3f center = imageData.camera .C ;
742746 vertices.insert (vertices.end (), {center.x , center.y , center.z });
743- colors.insert (colors.end (), {centerColor.x () , centerColor.y () , centerColor.z () });
747+ colors.insert (colors.end (), {centerColor.c2 , centerColor.c1 , centerColor.c0 });
744748
745- // Get frustum corners using the helper function
746- std::array<Point3f, 4 > worldCorners = ComputeCameraFrustumCorners (imageData, depth);
747-
748- // Add the 4 corners to vertices and colors
749- for (int j = 0 ; j < 4 ; ++j) {
750- const Point3f& worldCorner = worldCorners[j];
749+ // Get frustum corners using the helper function,
750+ // add the 4 corners to vertices and colors
751+ for (const Point3f& worldCorner : ComputeCameraFrustumCorners (imageData, depth)) {
751752 vertices.insert (vertices.end (), {worldCorner.x , worldCorner.y , worldCorner.z });
752- colors.insert (colors.end (), {frustumColor.x () , frustumColor.y () , frustumColor.z () });
753+ colors.insert (colors.end (), {frustumColor.c2 , frustumColor.c1 , frustumColor.c0 });
753754 }
754755
755- // Add principal center point (green) - point on the image plane at the principal point
756- const Point2 pp = imageData.camera .GetPrincipalPoint ();
757- const Point3f worldPrincipalPoint = imageData.camera .TransformPointI2W (Point3 (pp.x , pp.y , depth));
758- vertices.insert (vertices.end (), {worldPrincipalPoint.x , worldPrincipalPoint.y , worldPrincipalPoint.z });
759- colors.insert (colors.end (), {0 .f , 1 .f , 0 .f }); // Green
760-
761- // Add upwards direction indicator (blue) - line showing camera's up direction
762- const Point3f worldUpPoint = imageData.camera .TransformPointI2W (Point3 (pp.x , pp.y - imageData.height * 0 .5f , depth)); // Half way up from center
763- vertices.insert (vertices.end (), {worldUpPoint.x , worldUpPoint.y , worldUpPoint.z });
764- colors.insert (colors.end (), {0 .f , 0 .f , 1 .f }); // Blue
765-
766- // Create indices for wireframe lines
767- // Lines from camera center to each corner (4 lines)
756+ // Create indices for wireframe lines,
757+ // lines from camera center to each corner (4 lines)
768758 for (int j = 0 ; j < 4 ; ++j) {
769759 indices.push_back (baseIndex); // camera center
770760 indices.push_back (baseIndex + 1 + j); // corner j
@@ -775,56 +765,102 @@ static void CreateCameraFrustumGeometry(
775765 indices.push_back (baseIndex + 1 + j); // current corner
776766 indices.push_back (baseIndex + 1 + ((j + 1 ) % 4 )); // next corner
777767 }
768+ if (!showLookAt)
769+ return 16 ; // 4 lines from center + 4 lines for rectangle = 8 lines = 16 indices
778770
779- // Line from camera center to principal point (green indicator)
771+ // Add principal center point (green) - point on the image plane at the principal point
772+ const Point2 pp = imageData.camera .GetPrincipalPoint ();
773+ const Point3f worldPrincipalPoint = imageData.camera .TransformPointI2W (Point3 (pp.x , pp.y , depth));
774+ vertices.insert (vertices.end (), {worldPrincipalPoint.x , worldPrincipalPoint.y , worldPrincipalPoint.z });
775+ colors.insert (colors.end (), {0 .f , 1 .f , 0 .f }); // Green
776+
777+ // Add upwards direction indicator (blue) - line showing camera's up direction
778+ const Point3f worldUpPoint = imageData.camera .TransformPointI2W (Point3 (pp.x , pp.y - imageData.height * 0 .25f , depth)); // Quarter way up from center
779+ vertices.insert (vertices.end (), {worldUpPoint.x , worldUpPoint.y , worldUpPoint.z });
780+ colors.insert (colors.end (), {0 .f , 0 .f , 1 .f }); // Blue
781+
782+ // Line from camera center to principal point (look-at indicator).
780783 indices.push_back (baseIndex); // camera center
781784 indices.push_back (baseIndex + 5 ); // principal point (index 5)
782785
783- // Line from principal point to up direction point (blue indicator)
784- indices.push_back (baseIndex + 5 ); // principal point
785- indices.push_back (baseIndex + 6 ); // up direction point (index 6)
786+ // Line from principal point to upwards direction indicator.
787+ indices.push_back (baseIndex + 5 ); // principal point (index 5)
788+ indices.push_back (baseIndex + 6 ); // upwards direction indicator (index 6)
789+
790+ return 20 ; // 4 lines from center + 4 lines for rectangle + 2 lines for look-at = 10 lines = 20 indices
786791}
787792
788793void Renderer::UploadCameras (const Window& window) {
794+ cameraPointIndexCount = cameraLineIndexCount = imageOverlayIndexCount = 0 ;
789795 if (window.GetScene ().GetImages ().empty ())
790796 return ;
791797 const float depth = window.GetCamera ().GetSceneDistance () * window.cameraSize ;
798+ const bool useJetColors = window.cameraDisplayColor == Window::CAMERA_COLOR_JET;
799+ const bool displayDots = window.cameraDisplayType == Window::CAMERA_DISPLAY_DOT;
800+ const bool showLookAt = window.showCameraLookAt ;
801+ const MVS::ImageArr& images = window.GetScene ().GetScene ().images ;
802+ const ImageArr& viewerImages = window.GetScene ().GetImages ();
803+ const size_t imageCount = viewerImages.size ();
792804
793805 // Generate camera frustum geometry
794- cameraIndexCount = 0 ;
795806 std::vector<float > cameraVertices;
796807 std::vector<float > cameraColors;
797- std::vector<uint32_t > cameraIndices;
798- // Use white colors for normal camera rendering
799- const Eigen::Vector3f centerColor (1 .f , 1 .f , 1 .f ); // White for center
800- const Eigen::Vector3f frustumColor (1 .f , 1 .f , 0 .f ); // Yellow for frustum
801- for (const auto & image : window.GetScene ().GetImages ()) {
802- const MVS::Image& imageData = window.GetScene ().GetScene ().images [image.idx ];
808+ std::vector<uint32_t > cameraPointIndices;
809+ std::vector<uint32_t > cameraLineIndices;
810+ for (size_t cameraIdx = 0 ; cameraIdx < imageCount; ++cameraIdx) {
811+ const MVS::Image& imageData = images[viewerImages[cameraIdx].idx ];
803812 ASSERT (imageData.IsValid ());
804- // Create frustum vertices in camera coordinate system
805- size_t baseIndex = cameraVertices.size () / 3 ;
806- // Create camera frustum geometry using the shared function
807- CreateCameraFrustumGeometry (
813+ const float colorValue = imageCount > 1 ? ((float )cameraIdx / (float )(imageCount - 1 )) : 0 .5f ;
814+ const Pixel32F cameraColor = useJetColors ? Pixel32F::gray2color (colorValue) : Pixel32F::YELLOW;
815+
816+ // Dot mode: draw only camera centers.
817+ if (displayDots) {
818+ const uint32_t baseIndex = (uint32_t )(cameraVertices.size () / 3 );
819+ const Point3f center = imageData.camera .C ;
820+ cameraVertices.insert (cameraVertices.end (), {center.x , center.y , center.z });
821+ cameraColors.insert (cameraColors.end (), {cameraColor.c2 , cameraColor.c1 , cameraColor.c0 });
822+ cameraPointIndices.push_back ((uint32_t )baseIndex);
823+ ++cameraPointIndexCount;
824+ if (showLookAt) {
825+ const Point2 pp = imageData.camera .GetPrincipalPoint ();
826+ const Point3f worldPrincipalPoint = imageData.camera .TransformPointI2W (Point3 (pp.x , pp.y , depth));
827+ cameraVertices.insert (cameraVertices.end (), {worldPrincipalPoint.x , worldPrincipalPoint.y , worldPrincipalPoint.z });
828+ cameraColors.insert (cameraColors.end (), {0 .f , 1 .f , 0 .f }); // Green look-at target
829+ cameraLineIndices.push_back (baseIndex);
830+ cameraLineIndices.push_back (baseIndex + 1 );
831+ cameraLineIndexCount += 2 ;
832+ }
833+ continue ;
834+ }
835+
836+ // Frustum mode: draw full camera wireframe.
837+ const size_t baseIndex = cameraVertices.size () / 3 ;
838+ cameraLineIndexCount += CreateCameraFrustumGeometry (
808839 imageData,
809840 depth,
810- centerColor,
811- frustumColor,
841+ showLookAt,
842+ cameraColor,
843+ cameraColor,
812844 cameraVertices,
813845 cameraColors,
814- cameraIndices ,
846+ cameraLineIndices ,
815847 baseIndex
816848 );
817- cameraIndexCount += 20 ; // 10 lines * 2 indices per line
818849 }
850+
851+ std::vector<uint32_t > cameraIndices;
852+ cameraIndices.reserve (cameraPointIndices.size () + cameraLineIndices.size ());
853+ cameraIndices.insert (cameraIndices.end (), cameraPointIndices.begin (), cameraPointIndices.end ());
854+ cameraIndices.insert (cameraIndices.end (), cameraLineIndices.begin (), cameraLineIndices.end ());
855+
819856 // Upload camera geometry to GPU buffers
820- if (cameraIndexCount ) {
857+ if (!cameraIndices. empty () ) {
821858 cameraVBO->SetData (cameraVertices);
822859 cameraColorVBO->SetData (cameraColors);
823860 cameraEBO->SetData (cameraIndices);
824861 }
825862
826863 // Collect all overlay geometry for images with valid textures
827- imageOverlayIndexCount = 0 ;
828864 std::vector<float > allVertices;
829865 std::vector<uint32_t > allIndices;
830866 for (const auto & image : window.GetScene ().GetImages ()) {
@@ -1167,15 +1203,25 @@ void Renderer::RenderMesh(const Window& window) {
11671203}
11681204
11691205void Renderer::RenderCameras (const Window& window) {
1170- if (cameraIndexCount == 0 )
1206+ if (cameraPointIndexCount == 0 && cameraLineIndexCount == 0 )
11711207 return ;
11721208
11731209 cameraShader->Use ();
11741210
11751211 cameraVAO->Bind ();
11761212 cameraEBO->Bind ();
11771213
1178- GL_CHECK (glDrawElements (GL_LINES, cameraIndexCount, GL_UNSIGNED_INT, 0 ));
1214+ if (window.cameraDisplayType == Window::CAMERA_DISPLAY_DOT) {
1215+ if (cameraPointIndexCount > 0 )
1216+ GL_CHECK (glDrawElements (GL_POINTS, static_cast <GLsizei>(cameraPointIndexCount), GL_UNSIGNED_INT, 0 ));
1217+ if (window.showCameraLookAt && cameraLineIndexCount > 0 ) {
1218+ const void * lineOffset = reinterpret_cast <const void *>(cameraPointIndexCount * sizeof (uint32_t ));
1219+ GL_CHECK (glDrawElements (GL_LINES, static_cast <GLsizei>(cameraLineIndexCount), GL_UNSIGNED_INT, lineOffset));
1220+ }
1221+ } else {
1222+ if (cameraLineIndexCount > 0 )
1223+ GL_CHECK (glDrawElements (GL_LINES, static_cast <GLsizei>(cameraLineIndexCount), GL_UNSIGNED_INT, 0 ));
1224+ }
11791225
11801226 cameraVAO->Unbind ();
11811227}
0 commit comments