Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
Frustum.cpp
Go to the documentation of this file.
1
2
3#include "Headers/Frustum.h"
4
8
9namespace Divide {
10
11FrustumCollision PlanePointIntersect(const Plane<F32>& plane, const vec3<F32>& point) noexcept {
12 switch (plane.classifyPoint(point)) {
16 }
17
19}
20
21FrustumCollision Frustum::ContainsPoint(const vec3<F32>& point, I8& lastPlaneCache) const noexcept {
23 I8 planeToSkip = -1;
24 if (lastPlaneCache != -1) {
25 res = Divide::PlanePointIntersect(_frustumPlanes[lastPlaneCache], point);
27 // reset cache if it's no longer valid
28 planeToSkip = lastPlaneCache;
29 lastPlaneCache = -1;
30 }
31 }
32
33 // Cache miss: check all planes
34 if (lastPlaneCache == -1) {
35 for (I8 i = 0; i < to_I8(FrustumPlane::COUNT); ++i) {
36 if (i != planeToSkip) {
37 res = Divide::PlanePointIntersect(_frustumPlanes[i], point);
39 lastPlaneCache = i;
40 break;
41 }
42 }
43 }
44 }
45
46 return res;
47}
48
50 return PlaneSphereIntersect(plane, bsphere.getCenter(), bsphere.getRadius());
51}
52
53FrustumCollision PlaneSphereIntersect(const Plane<F32>& plane, const vec3<F32>& center, const F32 radius) noexcept {
54 const F32 distance = plane.signedDistanceToPoint(center);
55 if (distance < -radius) {
57 }
58
59 if (std::abs(distance) < radius) {
61 }
62
64}
65
66FrustumCollision Frustum::ContainsSphere(const vec3<F32>& center, const F32 radius, I8& lastPlaneCache) const noexcept {
68 I8 planeToSkip = -1;
69 if (lastPlaneCache != -1) {
70 res = Divide::PlaneSphereIntersect(_frustumPlanes[lastPlaneCache], center, radius);
72 // reset cache if it's no longer valid
73 planeToSkip = lastPlaneCache;
74 lastPlaneCache = -1;
75 }
76 }
77
78 // Cache miss: check all planes
79 if (lastPlaneCache == -1) {
80 for (I8 i = 0; i < to_I8(FrustumPlane::COUNT); ++i) {
81 if (i != planeToSkip) {
82 res = Divide::PlaneSphereIntersect(_frustumPlanes[i], center, radius);
84 lastPlaneCache = i;
85 break;
86 }
87 }
88 }
89 }
90
91 return res;
92}
93
94FrustumCollision Frustum::PlaneBoundingBoxIntersect(const FrustumPlane frustumPlane, const BoundingBox& bbox) const noexcept {
95 return Divide::PlaneBoundingBoxIntersect(_frustumPlanes[to_base(frustumPlane)], bbox);
96}
97
99 return Divide::PlaneBoundingSphereIntersect(_frustumPlanes[to_base(frustumPlane)], bsphere);
100}
101
102FrustumCollision Frustum::PlanePointIntersect(const FrustumPlane frustumPlane, const vec3<F32>& point) const noexcept {
103 return Divide::PlanePointIntersect(_frustumPlanes[to_base(frustumPlane)], point);
104}
105
106FrustumCollision Frustum::PlaneSphereIntersect(const FrustumPlane frustumPlane, const vec3<F32>& center, const F32 radius) const noexcept {
107 return Divide::PlaneSphereIntersect(_frustumPlanes[to_base(frustumPlane)], center, radius);
108}
109
110FrustumCollision Frustum::PlaneBoundingBoxIntersect(const FrustumPlane* frustumPlanes, const U8 count, const BoundingBox& bbox) const noexcept {
112 for (U8 i = 0u; i < count; ++i) {
113 res = Divide::PlaneBoundingBoxIntersect(_frustumPlanes[to_base(frustumPlanes[i])], bbox);
114 if (res != FrustumCollision::FRUSTUM_IN) {
115 break;
116 }
117 }
118
119 return res;
120}
121
122FrustumCollision Frustum::PlaneBoundingSphereIntersect(const FrustumPlane* frustumPlanes, U8 count, const BoundingSphere& bsphere) const noexcept {
124 for (U8 i = 0u; i < count; ++i) {
125 res = Divide::PlaneBoundingSphereIntersect(_frustumPlanes[to_base(frustumPlanes[i])], bsphere);
126 if (res != FrustumCollision::FRUSTUM_IN) {
127 break;
128 }
129 }
130
131 return res;
132}
133
134FrustumCollision Frustum::PlanePointIntersect(const FrustumPlane* frustumPlanes, const U8 count, const vec3<F32>& point) const noexcept {
136 for (U8 i = 0u; i < count; ++i) {
137 res = Divide::PlanePointIntersect(_frustumPlanes[to_base(frustumPlanes[i])], point);
138 if (res != FrustumCollision::FRUSTUM_IN) {
139 break;
140 }
141 }
142
143 return res;
144}
145
146FrustumCollision Frustum::PlaneSphereIntersect(const FrustumPlane* frustumPlanes, const U8 count, const vec3<F32>& center, const F32 radius) const noexcept {
148
149 for (U8 i = 0u; i < count; ++i) {
150 res = Divide::PlaneSphereIntersect(_frustumPlanes[to_base(frustumPlanes[i])], center, radius);
151 if (res != FrustumCollision::FRUSTUM_IN) {
152 break;
153 }
154 }
155
156 return res;
157}
158
160 if (plane.signedDistanceToPoint(bbox.getPVertex(plane._normal)) < 0) {
162 }
163 if (plane.signedDistanceToPoint(bbox.getNVertex(plane._normal)) < 0) {
165 }
166
168}
169
170FrustumCollision Frustum::ContainsSphere(const BoundingSphere& bSphere, I8& lastPlaneCache) const noexcept {
171 return ContainsSphere(bSphere.getCenter(), bSphere.getRadius(), lastPlaneCache);
172}
173
174FrustumCollision Frustum::ContainsBoundingBox(const BoundingBox& bbox, I8& lastPlaneCache) const noexcept {
176 I8 planeToSkip = -1;
177 if (lastPlaneCache != -1) {
178 res = Divide::PlaneBoundingBoxIntersect(_frustumPlanes[lastPlaneCache], bbox);
179 if (res == FrustumCollision::FRUSTUM_IN) {
180 // reset cache if it's no longer valid
181 planeToSkip = lastPlaneCache;
182 lastPlaneCache = -1;
183 }
184 }
185
186 // Cache miss: check all planes
187 if (lastPlaneCache == -1) {
188 for (I8 i = 0; i < to_I8(FrustumPlane::COUNT); ++i) {
189 if (i != planeToSkip) {
190 res = Divide::PlaneBoundingBoxIntersect(_frustumPlanes[i], bbox);
191 if (res != FrustumCollision::FRUSTUM_IN) {
192 lastPlaneCache = i;
193 break;
194 }
195 }
196 }
197 }
198
199 return res;
200}
201
202void Frustum::set(const Frustum& other) noexcept
203{
204 _frustumPlanes = other._frustumPlanes;
205}
206
207// Get the frustum corners in WorldSpace.
208void Frustum::getCornersWorldSpace(std::array<vec3<F32>, to_base(FrustumPoints::COUNT)>& cornersWS) const noexcept {
209 const Plane<F32>& leftPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_LEFT)];
210 const Plane<F32>& rightPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_RIGHT)];
211 const Plane<F32>& nearPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_NEAR)];
212 const Plane<F32>& farPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_FAR)];
213 const Plane<F32>& topPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_TOP)];
214 const Plane<F32>& bottomPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_BOTTOM)];
215
216 cornersWS[to_base(FrustumPoints::NEAR_LEFT_TOP)] = GetIntersection(nearPlane, leftPlane, topPlane);
217 cornersWS[to_base(FrustumPoints::NEAR_RIGHT_TOP)] = GetIntersection(nearPlane, rightPlane, topPlane);
218 cornersWS[to_base(FrustumPoints::NEAR_LEFT_BOTTOM)] = GetIntersection(nearPlane, leftPlane, bottomPlane);
219 cornersWS[to_base(FrustumPoints::NEAR_RIGHT_BOTTOM)] = GetIntersection(nearPlane, rightPlane, bottomPlane);
220 cornersWS[to_base(FrustumPoints::FAR_LEFT_TOP)] = GetIntersection(farPlane, leftPlane, topPlane);
221 cornersWS[to_base(FrustumPoints::FAR_RIGHT_TOP)] = GetIntersection(farPlane, rightPlane, topPlane);
222 cornersWS[to_base(FrustumPoints::FAR_LEFT_BOTTOM)] = GetIntersection(farPlane, leftPlane, bottomPlane);
223 cornersWS[to_base(FrustumPoints::FAR_RIGHT_BOTTOM)] = GetIntersection(farPlane, rightPlane, bottomPlane);
224}
225
226const std::array<Plane<F32>, to_base(FrustumPlane::COUNT)>& Frustum::computePlanes(const mat4<F32>& viewProjMatrix) {
227 F32* leftPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_LEFT)]._equation._v;
228 F32* rightPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_RIGHT)]._equation._v;
229 F32* nearPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_NEAR)]._equation._v;
230 F32* farPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_FAR)]._equation._v;
231 F32* topPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_TOP)]._equation._v;
232 F32* bottomPlane = _frustumPlanes[to_base(FrustumPlane::PLANE_BOTTOM)]._equation._v;
233
234 const auto& mat = viewProjMatrix.m;
235
236 for (I8 i = 4; i--; ) { leftPlane[i] = mat[i][3] + mat[i][0]; }
237 for (I8 i = 4; i--; ) { rightPlane[i] = mat[i][3] - mat[i][0]; }
238 for (I8 i = 4; i--; ) { bottomPlane[i] = mat[i][3] + mat[i][1]; }
239 for (I8 i = 4; i--; ) { topPlane[i] = mat[i][3] - mat[i][1]; }
240 for (I8 i = 4; i--; ) { nearPlane[i] = mat[i][3] + mat[i][2]; }
241 for (I8 i = 4; i--; ) { farPlane[i] = mat[i][3] - mat[i][2]; }
242
243 for (Plane<F32>& plane : _frustumPlanes)
244 {
245 plane.normalize();
246 }
247
248 return _frustumPlanes;
249}
250
251} //namespace Divide
FrustumCollision PlaneBoundingBoxIntersect(FrustumPlane frustumPlane, const BoundingBox &bbox) const noexcept
Definition: Frustum.cpp:94
FrustumCollision ContainsPoint(const vec3< F32 > &point, I8 &lastPlaneCache) const noexcept
Definition: Frustum.cpp:21
FrustumCollision ContainsSphere(const BoundingSphere &bSphere, I8 &lastPlaneCache) const noexcept
Definition: Frustum.cpp:170
const std::array< Plane< F32 >, to_base(FrustumPlane::COUNT)> & computePlanes(const mat4< F32 > &viewProjMatrix)
Definition: Frustum.cpp:226
FrustumCollision PlanePointIntersect(FrustumPlane frustumPlane, const vec3< F32 > &point) const noexcept
Definition: Frustum.cpp:102
FrustumCollision ContainsBoundingBox(const BoundingBox &bbox, I8 &lastPlaneCache) const noexcept
Definition: Frustum.cpp:174
void set(const Frustum &other) noexcept
Definition: Frustum.cpp:202
FrustumCollision PlaneBoundingSphereIntersect(FrustumPlane frustumPlane, const BoundingSphere &bsphere) const noexcept
Definition: Frustum.cpp:98
void getCornersWorldSpace(std::array< vec3< F32 >, to_base(FrustumPoints::COUNT)> &cornersWS) const noexcept
Definition: Frustum.cpp:208
FrustumCollision PlaneSphereIntersect(FrustumPlane frustumPlane, const vec3< F32 > &center, F32 radius) const noexcept
Definition: Frustum.cpp:106
std::array< Plane< F32 >, to_base(FrustumPlane::COUNT)> _frustumPlanes
Definition: Frustum.h:87
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
FrustumCollision PlaneBoundingSphereIntersect(const Plane< F32 > &plane, const BoundingSphere &bsphere) noexcept
Definition: Frustum.cpp:49
uint8_t U8
FORCE_INLINE vec3< T > GetIntersection(const Plane< T > &a, const Plane< T > &b, const Plane< T > &c) noexcept
Definition: Plane.h:193
constexpr I8 to_I8(const T value)
FrustumCollision PlaneSphereIntersect(const Plane< F32 > &plane, const vec3< F32 > &center, const F32 radius) noexcept
Definition: Frustum.cpp:53
FrustumCollision PlaneBoundingBoxIntersect(const Plane< F32 > &plane, const BoundingBox &bbox) noexcept
Definition: Frustum.cpp:159
FrustumCollision PlanePointIntersect(const Plane< F32 > &plane, const vec3< F32 > &point) noexcept
Definition: Frustum.cpp:11
constexpr auto to_base(const Type value) -> Type