14 #ifndef hifi_ViewFrustum_h
15 #define hifi_ViewFrustum_h
17 #include <glm/glm.hpp>
18 #include <glm/gtc/quaternion.hpp>
22 #include "CubeProjectedPolygon.h"
24 #include "RegisteredMetaTypes.h"
25 #include "Transform.h"
27 const int NUM_FRUSTUM_CORNERS = 8;
28 const int NUM_FRUSTUM_PLANES = 6;
30 const float DEFAULT_CENTER_SPHERE_RADIUS = 3.0f;
31 const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f;
32 const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f;
33 const float DEFAULT_NEAR_CLIP = 0.08f;
34 const float DEFAULT_FAR_CLIP = 16384.0f;
39 void setPosition(
const glm::vec3& position);
40 void setOrientation(
const glm::quat& orientation);
43 const glm::vec3& getPosition()
const {
return _position; }
44 const glm::quat& getOrientation()
const {
return _orientation; }
45 const glm::vec3& getDirection()
const {
return _direction; }
46 const glm::vec3& getUp()
const {
return _up; }
47 const glm::vec3& getRight()
const {
return _right; }
50 void setProjection(
const glm::mat4 & projection);
51 void setProjection(
float cameraFov,
float cameraAspectRatio,
float cameraNearClip,
float cameraFarClip);
52 void setFocalLength(
float focalLength) { _focalLength = focalLength; }
53 bool isPerspective()
const;
56 const glm::mat4& getProjection()
const {
return _projection; }
57 const glm::mat4& getView()
const {
return _view; }
58 float getWidth()
const {
return _width; }
59 float getHeight()
const {
return _height; }
60 float getFieldOfView()
const {
return _fieldOfView; }
61 float getAspectRatio()
const {
return _aspectRatio; }
62 float getNearClip()
const {
return _nearClip; }
63 float getFarClip()
const {
return _farClip; }
64 float getFocalLength()
const {
return _focalLength; }
68 Corners(glm::vec3&& topLeft, glm::vec3&& topRight, glm::vec3&& bottomLeft, glm::vec3&& bottomRight)
69 : topLeft{ topLeft }, topRight{ topRight }, bottomLeft{ bottomLeft }, bottomRight{ bottomRight } {}
73 glm::vec3 bottomRight;
76 const Corners getCorners(
const float depth)
const;
79 const glm::vec3& getFarTopLeft()
const {
return _cornersWorld[TOP_LEFT_FAR]; }
80 const glm::vec3& getFarTopRight()
const {
return _cornersWorld[TOP_RIGHT_FAR]; }
81 const glm::vec3& getFarBottomLeft()
const {
return _cornersWorld[BOTTOM_LEFT_FAR]; }
82 const glm::vec3& getFarBottomRight()
const {
return _cornersWorld[BOTTOM_RIGHT_FAR]; }
83 const glm::vec3& getNearTopLeft()
const {
return _cornersWorld[TOP_LEFT_NEAR]; }
84 const glm::vec3& getNearTopRight()
const {
return _cornersWorld[TOP_RIGHT_NEAR]; }
85 const glm::vec3& getNearBottomLeft()
const {
return _cornersWorld[BOTTOM_LEFT_NEAR]; }
86 const glm::vec3& getNearBottomRight()
const {
return _cornersWorld[BOTTOM_RIGHT_NEAR]; }
89 void setCenterRadius(
float radius) { _centerSphereRadius = radius; }
90 float getCenterRadius()
const {
return _centerSphereRadius; }
92 void tesselateSides(Triangle triangles[8])
const;
93 void tesselateSides(
const Transform& transform, Triangle triangles[8])
const;
94 void tesselateSidesAndFar(
const Transform& transform, Triangle triangles[10],
float farDistance)
const;
98 typedef enum { OUTSIDE = 0, INTERSECT, INSIDE } intersection;
101 ViewFrustum::intersection calculateCubeFrustumIntersection(
const AACube& cube)
const;
102 ViewFrustum::intersection calculateCubeKeyholeIntersection(
const AACube& cube)
const;
104 bool pointIntersectsFrustum(
const glm::vec3& point)
const;
105 bool sphereIntersectsFrustum(
const glm::vec3& center,
float radius)
const;
106 bool cubeIntersectsFrustum(
const AACube& box)
const;
107 bool boxIntersectsFrustum(
const AABox& box)
const;
108 bool boxInsideFrustum(
const AABox& box)
const;
110 bool sphereIntersectsKeyhole(
const glm::vec3& center,
float radius)
const;
111 bool cubeIntersectsKeyhole(
const AACube& cube)
const;
112 bool boxIntersectsKeyhole(
const AABox& box)
const;
114 bool isVerySimilar(
const ViewFrustum& compareTo)
const;
116 PickRay computePickRay(
float x,
float y);
117 void computePickRay(
float x,
float y, glm::vec3& origin, glm::vec3& direction)
const;
119 void computeOffAxisFrustum(
float& left,
float& right,
float& bottom,
float& top,
float& nearValue,
float& farValue,
120 glm::vec4& nearClipPlane, glm::vec4& farClipPlane)
const;
122 void printDebugDetails()
const;
124 glm::vec2 projectPoint(glm::vec3 point,
bool& pointInView)
const;
125 CubeProjectedPolygon getProjectedPolygon(
const AACube& box)
const;
126 CubeProjectedPolygon getProjectedPolygon(
const AABox& box)
const;
127 bool getProjectedRect(
const AABox& box, glm::vec2& bottomLeft, glm::vec2& topRight)
const;
128 void getFurthestPointFromCamera(
const AACube& box, glm::vec3& furthestPoint)
const;
130 float distanceToCameraSquared(
const glm::vec3& point)
const;
131 float distanceToCamera(
const glm::vec3& point)
const {
return sqrtf(distanceToCameraSquared(point)); }
133 void evalProjectionMatrix(glm::mat4& proj)
const;
135 glm::mat4 evalProjectionMatrixRange(
float rangeNear,
float rangeFar)
const;
137 void evalViewTransform(Transform& view)
const;
139 enum PlaneIndex { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE, NUM_PLANES };
141 const ::Plane* getPlanes()
const {
return _planes; }
142 void getSidePlanes(::Plane planes[4])
const;
144 void getTransformedSidePlanes(
const Transform& transform, ::Plane planes[4])
const;
147 void getUniformlyTransformedSidePlanes(
const Transform& transform, ::Plane planes[4])
const;
153 glm::mat4 _projection;
155 ::Plane _planes[NUM_FRUSTUM_PLANES];
158 glm::quat _orientation;
161 glm::vec3 _direction = IDENTITY_FORWARD;
162 glm::vec3 _up = IDENTITY_UP;
163 glm::vec3 _right = IDENTITY_RIGHT;
166 glm::vec4 _corners[NUM_FRUSTUM_CORNERS];
167 glm::vec3 _cornersWorld[NUM_FRUSTUM_CORNERS];
168 float _centerSphereRadius = DEFAULT_CENTER_SPHERE_RADIUS;
169 float _width { 1.0f };
170 float _height { 1.0f };
171 float _aspectRatio { 1.0f };
172 float _focalLength { 0.25f };
173 float _fieldOfView { DEFAULT_FIELD_OF_VIEW_DEGREES };
175 float _nearClip { DEFAULT_NEAR_CLIP };
176 float _farClip { DEFAULT_FAR_CLIP };
178 const char* debugPlaneName (
int plane)
const;
181 glm::mat4 _ourModelViewProjectionMatrix;
183 template <
typename TBOX>
184 CubeProjectedPolygon computeProjectedPolygon(
const TBOX& box)
const;
186 static void tesselateSides(
const glm::vec3 points[8], Triangle triangles[8]);
189 using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;
190 using ViewFrustums = std::vector<ViewFrustum>;