ccCameraSensor.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  15. //# #
  16. //##########################################################################
  17. #ifndef CC_CAMERA_SENSOR_HEADER
  18. #define CC_CAMERA_SENSOR_HEADER
  19. //local
  20. #include "ccSensor.h"
  21. #include "ccOctree.h"
  22. //system
  23. #include <unordered_set>
  24. class ccImage;
  25. class ccMesh;
  26. class ccPointCloud;
  27. class QDir;
  28. //! Camera (projective) sensor
  29. class QCC_DB_LIB_API ccCameraSensor : public ccSensor
  30. {
  31. public: //general
  32. //! Intrinsic parameters of the camera sensor
  33. struct QCC_DB_LIB_API IntrinsicParameters
  34. {
  35. //! Default initializer
  36. IntrinsicParameters();
  37. //! Helper: initializes a IntrinsicParameters structure with the default Kinect parameters
  38. static void GetKinectDefaults(IntrinsicParameters& params);
  39. float vertFocal_pix; /**< focal length (in pixels) - vertical dimension by default**/
  40. float pixelSize_mm[2]; /**< sensor pixel size (in real dimension, e.g. mm) **/
  41. float skew; /**< skew **/
  42. float vFOV_rad; /**< vertical field of view (in Radians) **/
  43. float zNear_mm; /**< Near plane position **/
  44. float zFar_mm; /**< Far plane position **/
  45. int arrayWidth; /**< Pixel array width (in pixels) **/
  46. int arrayHeight; /**< Pixel array height (in pixels) **/
  47. float principal_point[2]; /**< Principal point (in pixels) **/
  48. //! Returns the horizontal focal pix
  49. /** \warning Be sure the pixel size values are correct!
  50. **/
  51. inline float horizFocal_pix() const
  52. {
  53. assert(pixelSize_mm[1] > 0);
  54. return (vertFocal_pix * pixelSize_mm[0]) / pixelSize_mm[1];
  55. }
  56. };
  57. //! Supported distortion models
  58. enum DistortionModel { NO_DISTORTION_MODEL = 0, /**< no distortion model **/
  59. SIMPLE_RADIAL_DISTORTION = 1, /**< simple radial distortion model (k1, k2) **/
  60. BROWN_DISTORTION = 2, /**< Brown's distortion model (k1, k2, k3, etc.) **/
  61. EXTENDED_RADIAL_DISTORTION = 3 /**< extended radial distortion model (k1, k2, k3) **/
  62. };
  63. //! Lens distortion parameters (interface)
  64. struct LensDistortionParameters
  65. {
  66. //! Shared pointer type
  67. using Shared = QSharedPointer<LensDistortionParameters>;
  68. //! Virtual destructor
  69. virtual ~LensDistortionParameters() = default;
  70. //! Returns distortion model type
  71. virtual DistortionModel getModel() const = 0;
  72. };
  73. //! Simple radial distortion model
  74. struct QCC_DB_LIB_API RadialDistortionParameters : LensDistortionParameters
  75. {
  76. //! Shared pointer type
  77. using Shared = QSharedPointer<RadialDistortionParameters>;
  78. //! Default initializer
  79. RadialDistortionParameters() : k1(0), k2(0) {}
  80. //inherited from LensDistortionParameters
  81. inline DistortionModel getModel() const override { return SIMPLE_RADIAL_DISTORTION; }
  82. //! 1st radial distortion coefficient
  83. float k1;
  84. //! 2nd radial distortion coefficient
  85. float k2;
  86. };
  87. //! Extended radial distortion model
  88. struct QCC_DB_LIB_API ExtendedRadialDistortionParameters : RadialDistortionParameters
  89. {
  90. //! Shared pointer type
  91. using Shared = QSharedPointer<RadialDistortionParameters>;
  92. //! Default initializer
  93. ExtendedRadialDistortionParameters() : RadialDistortionParameters(), k3(0) {}
  94. //inherited from LensDistortionParameters
  95. inline DistortionModel getModel() const override { return EXTENDED_RADIAL_DISTORTION; }
  96. //! 3rd radial distortion coefficient
  97. float k3;
  98. };
  99. //! Brown's distortion model + Linear Disparity
  100. /** To know how to use K & P parameters, please read:
  101. "Decentering Distortion of Lenses", Duane C. Brown
  102. To know how to use the linearDisparityParams parameter (kinect attribute), please read:
  103. "Accuracy and Resolution of Kinect Depth Data for Indoor Mapping Applications", K. Khoshelham and S.O. Elberink
  104. **/
  105. struct QCC_DB_LIB_API BrownDistortionParameters : LensDistortionParameters
  106. {
  107. //! Shared pointer type
  108. using Shared = QSharedPointer<BrownDistortionParameters>;
  109. //! Default initializer
  110. BrownDistortionParameters();
  111. //inherited from LensDistortionParameters
  112. inline DistortionModel getModel() const override { return BROWN_DISTORTION; }
  113. //! Helper: initializes a IntrinsicParameters structure with the default Kinect parameters
  114. static void GetKinectDefaults(BrownDistortionParameters& params);
  115. float principalPointOffset[2]; /**< offset of the principal point (in meters) **/
  116. float linearDisparityParams[2]; /**< contains A and B where : 1/Z = A*d' + B (with Z=depth and d'=normalized disparity) **/
  117. float K_BrownParams[3]; /**< radial parameters Brown's distortion model **/
  118. float P_BrownParams[2]; /**< tangential parameters Brown's distortion model **/
  119. };
  120. //! Frustum information structure
  121. /** Used to draw the frustum associated to a camera sensor.
  122. **/
  123. struct QCC_DB_LIB_API FrustumInformation
  124. {
  125. //! Default initializer
  126. FrustumInformation();
  127. //! Destructor
  128. ~FrustumInformation();
  129. //! Reserves memory for the frustum corners cloud
  130. /** Warning: reset the cloud contents!
  131. **/
  132. bool initFrustumCorners();
  133. //! Creates the frustum hull mesh
  134. /** The frustum corners must have already been setup!
  135. \return success
  136. **/
  137. bool initFrustumHull();
  138. bool isComputed;
  139. bool drawFrustum;
  140. bool drawSidePlanes;
  141. ccPointCloud* frustumCorners;
  142. ccMesh* frustumHull;
  143. //! Center of the circumscribed sphere
  144. CCVector3 center;
  145. };
  146. //! Default constructor
  147. ccCameraSensor();
  148. //! Copy constructor
  149. ccCameraSensor(const ccCameraSensor& sensor);
  150. //! Constructor with given intrinsic parameters (and optional uncertainty parameters)
  151. ccCameraSensor(const IntrinsicParameters& iParams);
  152. //! Destructor
  153. ~ccCameraSensor() override = default;
  154. //inherited from ccHObject
  155. CC_CLASS_ENUM getClassID() const override { return CC_TYPES::CAMERA_SENSOR; }
  156. bool isSerializable() const override { return true; }
  157. ccBBox getOwnBB(bool withGLFeatures = false) override;
  158. ccBBox getOwnFitBB(ccGLMatrix& trans) override;
  159. //inherited from ccSensor
  160. bool applyViewport(ccGenericGLDisplay* win = nullptr) const override;
  161. //! Applies the sensor viewport with respect to an image (assumed to be displayed on the 'foreground' 2D layer)
  162. bool applyImageViewport(ccImage* image, ccGenericGLDisplay* win = nullptr) const;
  163. public: //getters and setters
  164. //! Sets focal (in pixels)
  165. /** \warning Vertical dimension by default
  166. **/
  167. void setVertFocal_pix(float vertFocal_pix);
  168. //! Returns vertical focal (in pixels)
  169. inline float getVertFocal_pix() const { return m_intrinsicParams.vertFocal_pix; }
  170. //! Returns horizontal focal (in pixels)
  171. inline float getHorizFocal_pix() const { return m_intrinsicParams.horizFocal_pix(); }
  172. //! Sets the (vertical) field of view in radians
  173. void setVerticalFov_rad(float fov_rad);
  174. //! Returns the (vertical) field of view in radians
  175. inline float getVerticalFov_rad() const { return m_intrinsicParams.vFOV_rad; }
  176. //! Returns intrinsic parameters
  177. const IntrinsicParameters& getIntrinsicParameters() const { return m_intrinsicParams; }
  178. //! Sets intrinsic parameters
  179. void setIntrinsicParameters(const IntrinsicParameters& params);
  180. //! Returns uncertainty parameters
  181. const LensDistortionParameters::Shared& getDistortionParameters() const { return m_distortionParams; }
  182. //! Sets uncertainty parameters
  183. void setDistortionParameters(LensDistortionParameters::Shared params) { m_distortionParams = params; }
  184. //! Returns the camera projection matrix
  185. /** \param[out] matrix projection matrix (if the method returns true)
  186. \return whether the matrix could be computed or not (probably due to wrong parameters)
  187. **/
  188. bool getProjectionMatrix(ccGLMatrix& matrix);
  189. public: //frustum display
  190. //! Returns whether the frustum should be displayed or not
  191. inline bool frustumIsDrawn() const { return m_frustumInfos.drawFrustum; }
  192. //! Sets whether the frustum should be displayed or not
  193. inline void drawFrustum(bool state) { m_frustumInfos.drawFrustum = state; }
  194. //! Returns whether the frustum planes should be displayed or not
  195. inline bool frustumPlanesAreDrawn() const { return m_frustumInfos.drawSidePlanes; }
  196. //! Sets whether the frustum planes should be displayed or not
  197. inline void drawFrustumPlanes(bool state) { m_frustumInfos.drawSidePlanes = state; }
  198. public: //coordinate systems conversion methods
  199. //! Computes the coordinates of a 3D point in the global coordinate system knowing its coordinates in the sensor coordinate system.
  200. /** \param localCoord local coordinates of the 3D point (input)
  201. \param globalCoord corresponding global coordinates of the 3D point (output)
  202. **/
  203. bool fromLocalCoordToGlobalCoord(const CCVector3& localCoord, CCVector3& globalCoord) const;
  204. //! Computes the coordinates of a 3D point in the sensor coordinate system knowing its coordinates in the global coordinate system.
  205. /** \param globalCoord global coordinates of the 3D point (input)
  206. \param localCoord corresponding local coordinates of the 3D point (output)
  207. **/
  208. bool fromGlobalCoordToLocalCoord(const CCVector3& globalCoord, CCVector3& localCoord) const;
  209. //! Computes the coordinates of a 3D point in the global coordinate system knowing its coordinates in the sensor coordinate system.
  210. /** \param localCoord local coordinates of the 3D point (input)
  211. \param imageCoord image coordinates of the projected point on the image (output) --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  212. \param withLensError to take lens distortion into account
  213. \return if operation has succeeded (typically, errors occur when the projection of the initial 3D points is not into the image boundaries, or when the 3D point is behind the camera)
  214. **/
  215. bool fromLocalCoordToImageCoord(const CCVector3& localCoord, CCVector2& imageCoord, bool withLensError = true) const;
  216. //! Computes the coordinates of a 3D point in the sensor coordinate system knowing its coordinates in the global coordinate system.
  217. /** \param imageCoord image coordinates of the pixel (input) --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  218. \param localCoord local coordinates of the corresponding 3D point (output)
  219. \param depth depth of the output pixel relatively to the camera center
  220. \param withLensCorrection if we want to correct the initial pixel coordinates with the lens correction formula
  221. \return if operation has succeeded (typically, errors occur when the initial pixel coordinates are not into the image boundaries)
  222. **/
  223. bool fromImageCoordToLocalCoord(const CCVector2& imageCoord, CCVector3& localCoord, PointCoordinateType depth, bool withLensCorrection = true) const;
  224. //! Computes the coordinates of a 3D point in the image knowing its coordinates in the global coordinate system.
  225. /** \param globalCoord global coordinates of the 3D point
  226. \param imageCoord to get back the image coordinates of the projected 3D point --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  227. \param withLensError to take lens distortion into account
  228. \return if operation has succeeded (typically, errors occur when the projection of the initial 3D points is not into the image boundaries, or when the 3D point is behind the camera)
  229. **/
  230. bool fromGlobalCoordToImageCoord(const CCVector3& globalCoord, CCVector2& imageCoord, bool withLensError = true) const;
  231. //! Computes the global coordinates of a 3D points from its 3D coordinates (pixel position in the image)
  232. /** \param imageCoord image coordinates of the pixel (input) --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  233. \param globalCoord global coordinates of the corresponding 3D point (output)
  234. \param z0 altitude of the output pixel
  235. \param withLensCorrection if we want to correct the initial pixel coordinates with the lens correction formula
  236. \return if operation has succeeded (typically, errors occur when the initial pixel coordinates are not into the image boundaries)
  237. **/
  238. bool fromImageCoordToGlobalCoord(const CCVector2& imageCoord, CCVector3& globalCoord, PointCoordinateType z0, bool withLensCorrection = true) const;
  239. //! Apply the Brown's lens correction to the real projection (through a lens) of a 3D point in the image
  240. /** \warning Only works with Brown's distortion model for now (see BrownDistortionParameters).
  241. \param real real 2D coordinates of a pixel (assuming that this pixel coordinate is obtained after projection through a lens) (input) !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  242. \param ideal after applying lens correction (output) --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  243. **/
  244. bool fromRealImCoordToIdealImCoord(const CCVector2& real, CCVector2& ideal) const;
  245. //! Knowing the ideal projection of a 3D point, computes what would be the real projection (through a lens)
  246. /** \warning The first pixel is (0,0) and the last (width-1,height-1)
  247. \param[in] ideal 2D coordinates of the ideal projection
  248. \param[out] real what would be the real 2D coordinates of the projection trough a lens
  249. **/
  250. //TODO
  251. //bool fromIdealImCoordToRealImCoord(const CCVector2& ideal, CCVector2& real) const;
  252. public: //orthorectification tools
  253. //! Key point (i.e. mapping between a point in a 3D cloud and a pixel in an image)
  254. struct KeyPoint
  255. {
  256. //! 2D 'x' coordinate (in pixels)
  257. float x;
  258. //! 2D 'y' coordinate (in pixels)
  259. float y;
  260. //! Index in associated point cloud
  261. unsigned index;
  262. //! Default constructor
  263. KeyPoint()
  264. : x(0)
  265. , y(0)
  266. , index(0)
  267. {}
  268. //! Constructor from a pixel and its index in associated cloud
  269. KeyPoint(float Px, float Py, unsigned indexInCloud)
  270. : x(Px)
  271. , y(Py)
  272. , index(indexInCloud)
  273. {}
  274. };
  275. //! Projective ortho-rectification of an image (as cloud)
  276. /** Requires at least 4 key points!
  277. \param image input image
  278. \param keypoints3D keypoints in 3D
  279. \param keypointsImage corresponding keypoints in image
  280. \return ortho-rectified image as a point cloud
  281. **/
  282. ccPointCloud* orthoRectifyAsCloud( const ccImage* image,
  283. CCCoreLib::GenericIndexedCloud* keypoints3D,
  284. std::vector<KeyPoint>& keypointsImage) const;
  285. //! Projective ortho-rectification of an image (as image)
  286. /** Requires at least 4 key points!
  287. \param image input image
  288. \param keypoints3D keypoints in 3D
  289. \param keypointsImage corresponding keypoints in image
  290. \param pixelSize pixel size (auto if -1)
  291. \param minCorner (optional) outputs 3D min corner (2 values)
  292. \param maxCorner (optional) outputs 3D max corner (2 values)
  293. \param realCorners (optional) image real 3D corners (4*2 values)
  294. \return ortho-rectified image
  295. **/
  296. ccImage* orthoRectifyAsImage( const ccImage* image,
  297. CCCoreLib::GenericIndexedCloud* keypoints3D,
  298. std::vector<KeyPoint>& keypointsImage,
  299. double& pixelSize,
  300. double* minCorner = nullptr,
  301. double* maxCorner = nullptr,
  302. double* realCorners = nullptr) const;
  303. //! Direct ortho-rectification of an image (as image)
  304. /** No keypoint is required. The user must specify however the
  305. orthorectification 'altitude'.
  306. \param image input image
  307. \param altitude orthorectification altitude
  308. \param pixelSize pixel size (auto if -1)
  309. \param undistortImages whether images should be undistorted or not
  310. \param minCorner (optional) outputs 3D min corner (2 values)
  311. \param maxCorner (optional) outputs 3D max corner (2 values)
  312. \param realCorners (optional) image real 3D corners (4*2 values)
  313. \return ortho-rectified image
  314. **/
  315. ccImage* orthoRectifyAsImageDirect( const ccImage* image,
  316. PointCoordinateType altitude,
  317. double& pixelSize,
  318. bool undistortImages = true,
  319. double* minCorner = nullptr,
  320. double* maxCorner = nullptr,
  321. double* realCorners = nullptr) const;
  322. //! Projective ortho-rectification of multiple images (as image files)
  323. /** \param images set of N calibrated images (i.e. images with their associated sensor)
  324. \param a {a0, a1, a2} triplets for all images (size: 3*N)
  325. \param b {b0, b1, b2} triplets for all images (size: 3*N)
  326. \param c {c0(=1), c1, c2} triplets for all images (size: 3*N)
  327. \param maxSize output image(s) max dimension
  328. \param outputDir output directory for resulting images (is successful)
  329. \param[out] orthoRectifiedImages resulting images (is successful)
  330. \param[out] relativePos relative positions (relatively to first image)
  331. \return true if successful
  332. **/
  333. static bool OrthoRectifyAsImages(std::vector<ccImage*> images,
  334. double a[], double b[], double c[],
  335. unsigned maxSize,
  336. QDir* outputDir = nullptr,
  337. std::vector<ccImage*>* orthoRectifiedImages = nullptr,
  338. std::vector<std::pair<double,double> >* relativePos = nullptr);
  339. //! Computes ortho-rectification parameters for a given image
  340. /** Requires at least 4 key points!
  341. Collinearity equation:
  342. * x'i = (a0+a1.xi+a2.yi)/(1+c1.xi+c2.yi)
  343. * y'i = (b0+b1.xi+b2.yi)/(1+c1.xi+c2.yi)
  344. \param image input image
  345. \param keypoints3D keypoints in 3D
  346. \param keypointsImage corresponding keypoints in image
  347. \param a a0, a1 & a2 parameters
  348. \param b b0, b1 & b2 parameters
  349. \param c c0(=1), c1 & c2 parameters
  350. \return success
  351. **/
  352. bool computeOrthoRectificationParams( const ccImage* image,
  353. CCCoreLib::GenericIndexedCloud* keypoints3D,
  354. std::vector<KeyPoint>& keypointsImage,
  355. double a[3],
  356. double b[3],
  357. double c[3]) const;
  358. public: //misc
  359. //! Computes the uncertainty of a point knowing its depth (from the sensor view point) and pixel projection coordinates
  360. /** \warning Only works with Brown's distortion model for now (see BrownDistortionParameters).
  361. \param pixel coordinates of the pixel where the 3D points is projected --> !! Note that the first index is (0,0) and the last (width-1,height-1) !!
  362. \param depth depth from sensor center to 3D point (must be positive)
  363. \param sigma uncertainty vector (along X, Y and Z)
  364. \return operation has succeeded (typically, errors occur when the initial pixel coordinates are not into the image boundaries, or when the depth of the 3D point is negative)
  365. **/
  366. bool computeUncertainty(const CCVector2& pixel, const float depth, Vector3Tpl<ScalarType>& sigma) const;
  367. //! Computes the coordinates of a 3D point in the sensor coordinate system knowing its coordinates in the global coordinate system.
  368. /** \warning Only works with Brown's distortion model for now (see BrownDistortionParameters).
  369. \param points the points we want to compute the uncertainty
  370. \param accuracy to get back the uncertainty
  371. //TODO lensDistortion if we want to take the lens distortion into consideration
  372. \return success
  373. **/
  374. bool computeUncertainty(CCCoreLib::ReferenceCloud* points, std::vector< Vector3Tpl<ScalarType> >& accuracy/*, bool lensDistortion*/);
  375. //! Undistorts an image based on the sensor distortion parameters
  376. /** \warning Only works with the simple radial distortion model for now (see RadialDistortionParameters).
  377. \param image input image
  378. \return undistorted image (or a null one if an error occurred)
  379. **/
  380. QImage undistort(const QImage& image) const;
  381. //! Undistorts an image based on the sensor distortion parameters
  382. /** \warning Only works with the simple radial distortion model for now (see RadialDistortionParameters).
  383. \param image input image
  384. \param inplace whether the undistortion should be applied in place or not
  385. \return undistorted image (maybe the same as the input image if inplace is true, or even a null pointer if an error occurred)
  386. **/
  387. ccImage* undistort(ccImage* image, bool inplace = true) const;
  388. //! Tests if a 3D point is in the field of view of the camera.
  389. /** \param globalCoord global coordinates of the 3D point
  390. //TODO withLensCorrection if we want to take the lens distortion into consideration
  391. \return if operation has succeeded
  392. **/
  393. bool isGlobalCoordInFrustum(const CCVector3& globalCoord/*, bool withLensCorrection*/) const;
  394. //! Compute the coefficients of the 6 planes frustum in the global coordinates system (normal vector are headed the frustum inside), the edges direction vectors and the frustum center
  395. /** \param planeCoefficients coefficients of the six planes
  396. \param edges direction vectors of the frustum edges (there are 12 edges but some of them are collinear)
  397. \param ptsFrustum the 8 frustum corners in the global coordinates system
  398. \param center center of the the frustum circumscribed sphere
  399. \return success
  400. **/
  401. bool computeGlobalPlaneCoefficients(float planeCoefficients[6][4], CCVector3 ptsFrustum[8], CCVector3 edges[6], CCVector3& center);
  402. public: //helpers
  403. //! Helper: converts camera focal from pixels to mm
  404. static float ConvertFocalPixToMM(float focal_pix, float ccdPixelSize_mm);
  405. //! Helper: converts camera focal from mm to pixels
  406. static float ConvertFocalMMToPix(float focal_mm, float ccdPixelSize_mm);
  407. //! Helper: deduces camera f.o.v. (in radians) from focal (in pixels)
  408. static float ComputeFovRadFromFocalPix(float focal_pix, int imageSize_pix);
  409. //! Helper: deduces camera f.o.v. (in radians) from focal (in mm)
  410. static float ComputeFovRadFromFocalMm(float focal_mm, float ccdSize_mm);
  411. protected:
  412. //! Used internally for display
  413. CCVector3 computeUpperLeftPoint() const;
  414. //! Compute the projection matrix (from intrinsic parameters)
  415. void computeProjectionMatrix();
  416. //! Computes the eight corners of the frustum
  417. /** \return success
  418. **/
  419. bool computeFrustumCorners();
  420. //Inherited from ccHObject
  421. bool toFile_MeOnly(QFile& out, short dataVersion) const override;
  422. bool fromFile_MeOnly(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;
  423. short minimumFileVersion_MeOnly() const override;
  424. void drawMeOnly(CC_DRAW_CONTEXT& context) override;
  425. //! Camera intrinsic parameters
  426. IntrinsicParameters m_intrinsicParams;
  427. //! Lens distortion parameters
  428. LensDistortionParameters::Shared m_distortionParams;
  429. //! Frustum information structure
  430. /** Used to draw it properly.
  431. **/
  432. FrustumInformation m_frustumInfos;
  433. //! Intrinsic parameters matrix
  434. ccGLMatrix m_projectionMatrix;
  435. //! Whether the intrinsic matrix is valid or not
  436. bool m_projectionMatrixIsValid;
  437. };
  438. class ccOctreeFrustumIntersector
  439. {
  440. public:
  441. //! Definition of the state of a cell compared to a frustum
  442. /** OUTSIDE : the celle is completely outside the frustum (no intersection, no inclusion)
  443. INSIDE : the cell is completely inside the frustum
  444. INTERSECT : other cases --> the frustum is completely inside the cell OR the frustum and the cell have an intersection
  445. **/
  446. enum OctreeCellVisibility
  447. {
  448. CELL_OUTSIDE_FRUSTUM = 0,
  449. CELL_INSIDE_FRUSTUM = 1,
  450. CELL_INTERSECT_FRUSTUM = 2,
  451. };
  452. //! Default constructor
  453. ccOctreeFrustumIntersector()
  454. : m_associatedOctree(nullptr)
  455. {
  456. }
  457. //! Prepares structure for frustum filtering
  458. bool build(CCCoreLib::DgmOctree* octree);
  459. //! Returns the cell visibility
  460. OctreeCellVisibility positionFromFrustum(CCCoreLib::DgmOctree::CellCode truncatedCode, unsigned char level) const
  461. {
  462. assert(m_associatedOctree);
  463. std::unordered_set<CCCoreLib::DgmOctree::CellCode>::const_iterator got = m_cellsInFrustum[level].find(truncatedCode);
  464. if (got != m_cellsInFrustum[level].end())
  465. return CELL_INSIDE_FRUSTUM;
  466. got = m_cellsIntersectFrustum[level].find(truncatedCode);
  467. if (got != m_cellsIntersectFrustum[level].end())
  468. return CELL_INTERSECT_FRUSTUM;
  469. return CELL_OUTSIDE_FRUSTUM;
  470. }
  471. //! Compute intersection between the octree and a frustum and send back the indices of 3D points inside the frustum or in cells intersecting it.
  472. /** Every cells of each level of the octree will be classified as INSIDE, OUTSIDE or INTERSECTING the frustum.
  473. Their truncated code are then stored in m_cellsInFrustum (for cells INSIDE) or m_cellsIntersectFrustum (for
  474. cells INTERSECTING).
  475. \param pointsToTest contains the indice and 3D position (global coordinates system) of every 3D points stored in an INTERSECTING cell
  476. \param inCameraFrustum contains the indice of every 3D points stored in an INSIDE cell
  477. \param planesCoefficients coefficients (a, b, c and d) of the six frustum planes (0:right, 1:bottom, 2:left, 3:top, 4:near, 5:far)
  478. \param ptsFrustum 3D coordinates of the eight corners of the frustum (global coordinates system)
  479. \param edges 3D coordinates (global coordinates system) of the six director vector of the frustum edges
  480. \param center 3D coordinates of the frustum center (global coordinates system) ; this is the center of the circumscribed sphere
  481. **/
  482. void computeFrustumIntersectionWithOctree( std::vector< std::pair<unsigned, CCVector3> >& pointsToTest,
  483. std::vector<unsigned>& inCameraFrustum,
  484. const float planesCoefficients[6][4],
  485. const CCVector3 ptsFrustum[8],
  486. const CCVector3 edges[6],
  487. const CCVector3& center);
  488. //! Compute intersection between the octree and the height children cells of a parent cell.
  489. /** \param level current level
  490. \param parentTruncatedCode truncated code of the parent cell (at level-1)
  491. \param parentResult contains in which class the parent cell has been classified (OUTSIDE, INTERSECTING, INSIDE)
  492. \param planesCoefficients coefficients (a, b, c and d) of the six frustum planes (0:right, 1:bottom, 2:left, 3:top, 4:near, 5:far)
  493. \param ptsFrustum 3D coordinates of the eight corners of the frustum (global coordinates system)
  494. \param edges 3D coordinates (global coordinates system) of the six director vector of the frustum edges
  495. \param center 3D coordinates of the frustum center (global coordinates system) ; this is the center of the circumscribed sphere
  496. **/
  497. void computeFrustumIntersectionByLevel( unsigned char level,
  498. CCCoreLib::DgmOctree::CellCode parentTruncatedCode,
  499. OctreeCellVisibility parentResult,
  500. const float planesCoefficients[6][4],
  501. const CCVector3 ptsFrustum[8],
  502. const CCVector3 edges[6],
  503. const CCVector3& center);
  504. //! Separating Axis Test
  505. /** See "Detecting intersection of a rectangular solid and a convex polyhedron" of Ned Greene
  506. See "OBBTree: A Hierarchical Structure for Rapid Interference Detection" of S. Gottschalk, M. C. Lin and D. Manocha
  507. \param bbMin minimum coordinates of the cell
  508. \param bbMax maximum coordinates of the cell
  509. \param planesCoefficients coefficients (a, b, c and d) of the six frustum planes (0:right, 1:bottom, 2:left, 3:top, 4:near, 5:far)
  510. \param frustumCorners 3D coordinates of the eight corners of the frustum (global coordinates system)
  511. \param frustumEdges 3D coordinates (global coordinates system) of the six director vector of the frustum edges
  512. \param frustumCenter 3D coordinates of the frustum center (global coordinates system) ; this is the center of the circumscribed sphere
  513. **/
  514. OctreeCellVisibility separatingAxisTest(const CCVector3& bbMin,
  515. const CCVector3& bbMax,
  516. const float planesCoefficients[6][4],
  517. const CCVector3 frustumCorners[8],
  518. const CCVector3 frustumEdges[6],
  519. const CCVector3& frustumCenter);
  520. protected:
  521. CCCoreLib::DgmOctree* m_associatedOctree;
  522. // contains the truncated code of the cells built in the octree
  523. std::unordered_set<CCCoreLib::DgmOctree::CellCode> m_cellsBuilt[CCCoreLib::DgmOctree::MAX_OCTREE_LEVEL+1];
  524. // contains the truncated code of the cells INSIDE the frustum
  525. std::unordered_set<CCCoreLib::DgmOctree::CellCode> m_cellsInFrustum[CCCoreLib::DgmOctree::MAX_OCTREE_LEVEL+1];
  526. // contains the truncated code of the cells INTERSECTING the frustum
  527. std::unordered_set<CCCoreLib::DgmOctree::CellCode> m_cellsIntersectFrustum[CCCoreLib::DgmOctree::MAX_OCTREE_LEVEL+1];
  528. };
  529. #endif //CC_CAMERA_SENSOR_HEADER