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 = 55.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,
bool isOblique =
false);
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 boxIntersectsFrustum(
const AABox& box)
const;
107 bool boxInsideFrustum(
const AABox& box)
const;
109 bool sphereIntersectsKeyhole(
const glm::vec3& center,
float radius)
const;
110 bool cubeIntersectsKeyhole(
const AACube& cube)
const;
111 bool boxIntersectsKeyhole(
const AABox& box)
const;
113 bool isVerySimilar(
const ViewFrustum& compareTo)
const;
115 PickRay computePickRay(
float x,
float y);
116 void computePickRay(
float x,
float y, glm::vec3& origin, glm::vec3& direction)
const;
118 void computeOffAxisFrustum(
float& left,
float& right,
float& bottom,
float& top,
float& nearValue,
float& farValue,
119 glm::vec4& nearClipPlane, glm::vec4& farClipPlane)
const;
121 void printDebugDetails()
const;
123 glm::vec2 projectPoint(glm::vec3 point,
bool& pointInView)
const;
124 CubeProjectedPolygon getProjectedPolygon(
const AACube& box)
const;
125 CubeProjectedPolygon getProjectedPolygon(
const AABox& box)
const;
126 bool getProjectedRect(
const AABox& box, glm::vec2& bottomLeft, glm::vec2& topRight)
const;
127 void getFurthestPointFromCamera(
const AACube& box, glm::vec3& furthestPoint)
const;
129 float distanceToCameraSquared(
const glm::vec3& point)
const;
130 float distanceToCamera(
const glm::vec3& point)
const {
return sqrtf(distanceToCameraSquared(point)); }
132 void evalProjectionMatrix(glm::mat4& proj)
const;
134 glm::mat4 evalProjectionMatrixRange(
float rangeNear,
float rangeFar)
const;
136 void evalViewTransform(Transform& view)
const;
138 enum PlaneIndex { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE, NUM_PLANES };
140 const ::Plane* getPlanes()
const {
return _planes; }
141 void getSidePlanes(::Plane planes[4])
const;
143 void getTransformedSidePlanes(
const Transform& transform, ::Plane planes[4])
const;
146 void getUniformlyTransformedSidePlanes(
const Transform& transform, ::Plane planes[4])
const;
152 glm::mat4 _projection;
154 ::Plane _planes[NUM_FRUSTUM_PLANES];
157 glm::quat _orientation;
160 glm::vec3 _direction = IDENTITY_FORWARD;
161 glm::vec3 _up = IDENTITY_UP;
162 glm::vec3 _right = IDENTITY_RIGHT;
165 glm::vec4 _corners[NUM_FRUSTUM_CORNERS];
166 glm::vec3 _cornersWorld[NUM_FRUSTUM_CORNERS];
167 float _centerSphereRadius = DEFAULT_CENTER_SPHERE_RADIUS;
168 float _width { 1.0f };
169 float _height { 1.0f };
170 float _aspectRatio { 1.0f };
171 float _focalLength { 0.25f };
172 float _fieldOfView { DEFAULT_FIELD_OF_VIEW_DEGREES };
174 float _nearClip { DEFAULT_NEAR_CLIP };
175 float _farClip { DEFAULT_FAR_CLIP };
177 bool _isOblique {
false };
179 const char* debugPlaneName (
int plane)
const;
182 glm::mat4 _ourModelViewProjectionMatrix;
184 template <
typename TBOX>
185 CubeProjectedPolygon computeProjectedPolygon(
const TBOX& box)
const;
187 static void tesselateSides(
const glm::vec3 points[8], Triangle triangles[8]);
190 using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;
191 using ViewFrustums = std::vector<ViewFrustum>;