| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- //##########################################################################
- //# #
- //# CLOUDCOMPARE #
- //# #
- //# This program is free software; you can redistribute it and/or modify #
- //# it under the terms of the GNU General Public License as published by #
- //# the Free Software Foundation; version 2 or later of the License. #
- //# #
- //# This program is distributed in the hope that it will be useful, #
- //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
- //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- //# GNU General Public License for more details. #
- //# #
- //# COPYRIGHT: CloudCompare project #
- //# #
- //##########################################################################
- #ifndef CC_FRUSTUM_HEADER
- #define CC_FRUSTUM_HEADER
- //CCCoreLib
- #include <RayAndBox.h>
- //Local
- #include "ccGLMatrix.h"
- class Plane
- {
- public:
- Plane()
- : normal(0, 0, 1)
- , constCoef(0)
- {}
- virtual ~Plane() = default;
- void setCoefficients(float a, float b, float c, float d)
- {
- // set the normal vector
- normal = CCVector3f(a, b, c);
- //compute the length of the vector
- float l = normal.norm();
- if (l != 0)
- {
- // normalize the vector
- normal /= l;
- // and divide constCoef as well
- constCoef = d / l;
- }
- else
- {
- constCoef = d;
- }
- }
- float distance(const CCVector3f& p) const
- {
- return normal.dot(p) + constCoef;
- }
- public: //members
- CCVector3f normal;
- float constCoef;
- };
- class AABox : public CCCoreLib::AABB<float>
- {
- public:
- AABox(const CCVector3f& A, const CCVector3f& B) : CCCoreLib::AABB<float>(A, B)
- {
- }
- CCVector3f getVertexP(const CCVector3f& normal) const
- {
- return {
- corners[normal.x > 0 ? 1 : 0].x,
- corners[normal.y > 0 ? 1 : 0].y,
- corners[normal.z > 0 ? 1 : 0].z
- };
- }
- CCVector3f getVertexN(const CCVector3f& normal) const
- {
- return {
- corners[normal.x < 0 ? 1 : 0].x,
- corners[normal.y < 0 ? 1 : 0].y,
- corners[normal.z < 0 ? 1 : 0].z
- };
- }
- };
- class AACube
- {
- public:
- AACube()
- : O(0, 0, 0)
- , d(0)
- {}
- AACube(const CCVector3f& origin, float size)
- : O(origin)
- , d(size)
- {
- }
- virtual ~AACube() = default;
- CCVector3f getVertexP(const CCVector3f& normal) const
- {
- return {
- normal.x > 0 ? O.x + d : O.x,
- normal.y > 0 ? O.y + d : O.y,
- normal.z > 0 ? O.z + d : O.z
- };
- }
-
- CCVector3f getVertexN(const CCVector3f& normal) const
- {
- return {
- normal.x < 0 ? O.x + d : O.x,
- normal.y < 0 ? O.y + d : O.y,
- normal.z < 0 ? O.z + d : O.z
- };
- }
- public: //members
- CCVector3f O;
- float d;
- };
- class Frustum
- {
- public:
- Frustum() = default;
- Frustum(const ccGLMatrixd& modelViewMat, const ccGLMatrixd& projMat)
- {
- ccGLMatrixd MP = projMat * modelViewMat;
- initfromMPMatrix(MP);
- }
- virtual ~Frustum() = default;
- enum Intersection
- {
- OUTSIDE = 0,
- INTERSECT = 1,
- INSIDE = 2,
- };
- public: //Intersection tests
- Intersection pointInFrustum(const CCVector3f& p) const
- {
- for (const auto &plane : pl)
- {
- if (plane.distance(p) < 0)
- {
- return OUTSIDE;
- }
- }
- return INSIDE;
- }
- Intersection sphereInFrustum(const CCVector3f &c, float r) const
- {
- Intersection result = INSIDE;
- for (const auto &plane : pl)
- {
- float distance = plane.distance(c);
- if (distance < -r)
- return OUTSIDE;
- else if (distance < r)
- result = INTERSECT;
- }
- return result;
- }
- Intersection boxInFrustum(const AABox& box) const
- {
- Intersection result = INSIDE;
-
- for (const auto &plane : pl)
- {
- if (plane.distance(box.getVertexP(plane.normal)) < 0)
- return OUTSIDE;
- else if (plane.distance(box.getVertexN(plane.normal)) < 0)
- result = INTERSECT;
- }
- return result;
- }
- Intersection boxInFrustum(const AACube& cube) const
- {
- Intersection result = INSIDE;
-
- for (const auto &plane : pl)
- {
- if (plane.distance(cube.getVertexP(plane.normal)) < 0)
- return OUTSIDE;
- else if (plane.distance(cube.getVertexN(plane.normal)) < 0)
- result = INTERSECT;
- }
- return result;
- }
- protected: //protected methods
- enum PLANE
- {
- TOP = 0,
- BOTTOM = 1,
- LEFT = 2,
- RIGHT = 3,
- NEARP = 4,
- FARP = 5
- };
- template <typename T> void initfromMPMatrix(const ccGLMatrixTpl<T>& MP)
- {
- const T* m = MP.data();
- pl[NEARP].setCoefficients
- (
- m[3] + m[2],
- m[7] + m[6],
- m[11] + m[10],
- m[15] + m[14]
- );
- pl[FARP].setCoefficients
- (
- m[3] - m[2],
- m[7] - m[6],
- m[11] - m[10],
- m[15] - m[14]
- );
- pl[BOTTOM].setCoefficients
- (
- m[3] + m[1],
- m[7] + m[5],
- m[11] + m[9],
- m[15] + m[13]
- );
- pl[TOP].setCoefficients
- (
- m[3] - m[1],
- m[7] - m[5],
- m[11] - m[9],
- m[15] - m[13]
- );
- pl[LEFT].setCoefficients
- (
- m[3] + m[0],
- m[7] + m[4],
- m[11] + m[8],
- m[15] + m[12]
- );
- pl[RIGHT].setCoefficients
- (
- m[3] - m[0],
- m[7] - m[4],
- m[11] - m[8],
- m[15] - m[12]
- );
- }
- protected: //members
- Plane pl[6];
- };
- #endif // CC_FRUSTUM_HEADER
|