26 #include "BasicMath.h" 37 Plane3D LeftPlane, RightPlane, BottomPlane, TopPlane, NearPlane, FarPlane;
40 struct ViewFrustumExt :
public ViewFrustum
42 float3 FrustumCorners[8];
47 inline void ExtractViewFrustumPlanesFromMatrix(
const float4x4 &Matrix, ViewFrustum &Frustum,
bool bIsDirectX)
54 Frustum.LeftPlane.Normal.x = Matrix._14 + Matrix._11;
55 Frustum.LeftPlane.Normal.y = Matrix._24 + Matrix._21;
56 Frustum.LeftPlane.Normal.z = Matrix._34 + Matrix._31;
57 Frustum.LeftPlane.Distance = Matrix._44 + Matrix._41;
60 Frustum.RightPlane.Normal.x = Matrix._14 - Matrix._11;
61 Frustum.RightPlane.Normal.y = Matrix._24 - Matrix._21;
62 Frustum.RightPlane.Normal.z = Matrix._34 - Matrix._31;
63 Frustum.RightPlane.Distance = Matrix._44 - Matrix._41;
66 Frustum.TopPlane.Normal.x = Matrix._14 - Matrix._12;
67 Frustum.TopPlane.Normal.y = Matrix._24 - Matrix._22;
68 Frustum.TopPlane.Normal.z = Matrix._34 - Matrix._32;
69 Frustum.TopPlane.Distance = Matrix._44 - Matrix._42;
72 Frustum.BottomPlane.Normal.x = Matrix._14 + Matrix._12;
73 Frustum.BottomPlane.Normal.y = Matrix._24 + Matrix._22;
74 Frustum.BottomPlane.Normal.z = Matrix._34 + Matrix._32;
75 Frustum.BottomPlane.Distance = Matrix._44 + Matrix._42;
81 Frustum.NearPlane.Normal.x = Matrix._13;
82 Frustum.NearPlane.Normal.y = Matrix._23;
83 Frustum.NearPlane.Normal.z = Matrix._33;
84 Frustum.NearPlane.Distance = Matrix._43;
89 Frustum.NearPlane.Normal.x = Matrix._14 + Matrix._13;
90 Frustum.NearPlane.Normal.y = Matrix._24 + Matrix._23;
91 Frustum.NearPlane.Normal.z = Matrix._34 + Matrix._33;
92 Frustum.NearPlane.Distance = Matrix._44 + Matrix._43;
96 Frustum.FarPlane.Normal.x = Matrix._14 - Matrix._13;
97 Frustum.FarPlane.Normal.y = Matrix._24 - Matrix._23;
98 Frustum.FarPlane.Normal.z = Matrix._34 - Matrix._33;
99 Frustum.FarPlane.Distance = Matrix._44 - Matrix._43;
102 inline void ExtractViewFrustumPlanesFromMatrix(
const float4x4 &Matrix, ViewFrustumExt &FrustumExt,
bool bIsDirectX)
104 ExtractViewFrustumPlanesFromMatrix(Matrix, static_cast<ViewFrustum&>(FrustumExt), bIsDirectX);
107 float4x4 InvMatrix = inverseMatrix(Matrix);
109 float nearClipZ = bIsDirectX ? 0.f : -1.f;
110 static const float3 ProjSpaceCorners[] =
112 float3(-1,-1, nearClipZ),
113 float3( 1,-1, nearClipZ),
114 float3(-1, 1, nearClipZ),
115 float3( 1, 1, nearClipZ),
123 for(
int i = 0; i < 8; ++i)
124 FrustumExt.FrustumCorners[i] = ProjSpaceCorners[i] * InvMatrix;
130 float fMinX, fMaxX, fMinY, fMaxY, fMinZ, fMaxZ;
133 enum class BoxVisibility
170 template<
bool TestFullVisibility>
171 inline BoxVisibility GetBoxVisibilityAgainstPlane(
const Plane3D& Plane,
const BoundBox &Box)
173 const float3& Normal = Plane.Normal;
176 (Normal.x > 0) ? Box.fMaxX : Box.fMinX,
177 (Normal.y > 0) ? Box.fMaxY : Box.fMinY,
178 (Normal.z > 0) ? Box.fMaxZ : Box.fMinZ
181 float DMax = dot( MaxPoint, Normal ) + Plane.Distance;
184 return BoxVisibility::Invisible;
186 if (TestFullVisibility)
189 (Normal.x > 0) ? Box.fMinX : Box.fMaxX,
190 (Normal.y > 0) ? Box.fMinY : Box.fMaxY,
191 (Normal.z > 0) ? Box.fMinZ : Box.fMaxZ
194 float DMin = dot(MinPoint, Normal) + Plane.Distance;
197 return BoxVisibility::FullyVisible;
200 return BoxVisibility::Intersecting;
204 template<
bool TestFullVisibility>
205 inline BoxVisibility GetBoxVisibility(
const ViewFrustum &ViewFrustum,
const BoundBox &Box)
207 const Plane3D *pPlanes =
reinterpret_cast<const Plane3D*
>(&ViewFrustum);
209 int NumPlanesInside = 0;
210 for(
int iViewFrustumPlane = 0; iViewFrustumPlane < 6; iViewFrustumPlane++)
212 const Plane3D &CurrPlane = pPlanes[iViewFrustumPlane];
213 auto VisibilityAgainstPlane = GetBoxVisibilityAgainstPlane<TestFullVisibility>(CurrPlane, Box);
216 if (VisibilityAgainstPlane == BoxVisibility::Invisible)
217 return BoxVisibility::Invisible;
220 if (VisibilityAgainstPlane == BoxVisibility::FullyVisible)
224 return (TestFullVisibility && NumPlanesInside == 6) ? BoxVisibility::FullyVisible : BoxVisibility::Intersecting;
227 template<
bool TestFullVisibility>
228 inline BoxVisibility GetBoxVisibility(
const ViewFrustumExt &ViewFrustumExt,
const BoundBox &Box)
230 auto Visibility = GetBoxVisibility<TestFullVisibility>(
static_cast<const ViewFrustum&
>(ViewFrustumExt), Box);
231 if (Visibility == BoxVisibility::FullyVisible || Visibility == BoxVisibility::Invisible)
248 for(
int iBoundBoxPlane = 0; iBoundBoxPlane < 6; ++iBoundBoxPlane)
254 float CurrPlaneCoord =
reinterpret_cast<const float*
>(&Box)[iBoundBoxPlane];
255 int iCoordOrder = iBoundBoxPlane / 2;
256 float fSign = (iBoundBoxPlane & 0x01) ? +1.f : -1.f;
257 bool bAllCornersOutside =
true;
258 for(
int iCorner=0; iCorner < 8; iCorner++)
260 float CurrCornerCoord = ViewFrustumExt.FrustumCorners[iCorner][iCoordOrder];
261 if( fSign * (CurrPlaneCoord - CurrCornerCoord) > 0)
263 bAllCornersOutside =
false;
267 if( bAllCornersOutside )
268 return BoxVisibility::Invisible;
271 return BoxVisibility::Intersecting;
274 inline float GetPointToBoxDistance(
const BoundBox &BndBox,
const float3 &Pos)
276 VERIFY_EXPR(BndBox.fMaxX >= BndBox.fMinX &&
277 BndBox.fMaxY >= BndBox.fMinY &&
278 BndBox.fMaxZ >= BndBox.fMinZ);
279 float fdX = (Pos.x > BndBox.fMaxX) ? (Pos.x - BndBox.fMaxX) : ( (Pos.x < BndBox.fMinX) ? (BndBox.fMinX - Pos.x) : 0.f );
280 float fdY = (Pos.y > BndBox.fMaxY) ? (Pos.y - BndBox.fMaxY) : ( (Pos.y < BndBox.fMinY) ? (BndBox.fMinY - Pos.y) : 0.f );
281 float fdZ = (Pos.z > BndBox.fMaxZ) ? (Pos.z - BndBox.fMaxZ) : ( (Pos.z < BndBox.fMinZ) ? (BndBox.fMinZ - Pos.z) : 0.f );
282 VERIFY_EXPR(fdX >= 0 && fdY >= 0 && fdZ >= 0);
284 float3 RangeVec(fdX, fdY, fdZ);
285 return length( RangeVec );
288 inline bool operator == (
const Plane3D &p1,
const Plane3D &p2)
290 return p1.Normal == p2.Normal &&
291 p1.Distance == p2.Distance;
294 inline bool operator == (
const ViewFrustum &f1,
const ViewFrustum &f2)
296 return f1.LeftPlane == f2.LeftPlane &&
297 f1.RightPlane == f2.RightPlane &&
298 f1.BottomPlane == f2.BottomPlane &&
299 f1.TopPlane == f2.TopPlane &&
300 f1.NearPlane == f2.NearPlane &&
301 f1.FarPlane == f2.FarPlane;
304 inline bool operator == (
const ViewFrustumExt &f1,
const ViewFrustumExt &f2)
306 if (! (static_cast<const ViewFrustum &>(f1) == static_cast<const ViewFrustum &>(f2)) )
309 for (
int c = 0; c < _countof(f1.FrustumCorners); ++c)
310 if (f1.FrustumCorners[c] != f2.FrustumCorners[c])
321 size_t operator()(
const Plane3D &Plane )
const 323 return Diligent::ComputeHash(Plane.Normal, Plane.Distance);
328 struct hash<ViewFrustum>
330 size_t operator()(
const ViewFrustum &Frustum )
const 332 return Diligent::ComputeHash(Frustum.LeftPlane, Frustum.RightPlane, Frustum.BottomPlane, Frustum.TopPlane, Frustum.NearPlane, Frustum.FarPlane);
337 struct hash<ViewFrustumExt>
339 size_t operator()(
const ViewFrustumExt &Frustum )
const 341 auto Seed = Diligent::ComputeHash(static_cast<const ViewFrustum&>(Frustum));
342 for (
int Corner = 0; Corner < _countof(Frustum.FrustumCorners); ++Corner)
343 Diligent::HashCombine(Seed, Frustum.FrustumCorners[Corner]);
Definition: AdvancedMath.h:316