summaryrefslogtreecommitdiffstats
path: root/Common/interface
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2017-11-13 02:54:50 +0000
committerEgor Yusov <egor.yusov@gmail.com>2017-11-13 02:54:50 +0000
commit8e24a0919d30f939140e776bc5e64bd77767e99c (patch)
treebfa1c37385cafe7d6c192ed0c8eb936aa828cb5a /Common/interface
parentMerge from dev branch (diff)
downloadDiligentCore-8e24a0919d30f939140e776bc5e64bd77767e99c.tar.gz
DiligentCore-8e24a0919d30f939140e776bc5e64bd77767e99c.zip
Updated to Diligent Engine 2.1
Diffstat (limited to 'Common/interface')
-rw-r--r--Common/interface/AdvancedMath.h308
-rw-r--r--Common/interface/BasicMath.h75
-rw-r--r--Common/interface/Object.h2
3 files changed, 325 insertions, 60 deletions
diff --git a/Common/interface/AdvancedMath.h b/Common/interface/AdvancedMath.h
index d90488f7..a4287b67 100644
--- a/Common/interface/AdvancedMath.h
+++ b/Common/interface/AdvancedMath.h
@@ -37,91 +37,311 @@ struct ViewFrustum
Plane3D LeftPlane, RightPlane, BottomPlane, TopPlane, NearPlane, FarPlane;
};
+struct ViewFrustumExt : public ViewFrustum
+{
+ float3 FrustumCorners[8];
+};
+
// For OpenGL, matrix is still considered row-major. The only difference is that
// near clip plane is at -1, not 0.
-inline void ExtractViewFrustumPlanesFromMatrix(const float4x4 &Matrix, ViewFrustum &ViewFrustum, bool bIsDirectX)
+inline void ExtractViewFrustumPlanesFromMatrix(const float4x4 &Matrix, ViewFrustum &Frustum, bool bIsDirectX)
{
// For more details, see Gribb G., Hartmann K., "Fast Extraction of Viewing Frustum Planes from the
// World-View-Projection Matrix" (the paper is available at
// http://gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf)
// Left clipping plane
- ViewFrustum.LeftPlane.Normal.x = Matrix._14 + Matrix._11;
- ViewFrustum.LeftPlane.Normal.y = Matrix._24 + Matrix._21;
- ViewFrustum.LeftPlane.Normal.z = Matrix._34 + Matrix._31;
- ViewFrustum.LeftPlane.Distance = Matrix._44 + Matrix._41;
+ Frustum.LeftPlane.Normal.x = Matrix._14 + Matrix._11;
+ Frustum.LeftPlane.Normal.y = Matrix._24 + Matrix._21;
+ Frustum.LeftPlane.Normal.z = Matrix._34 + Matrix._31;
+ Frustum.LeftPlane.Distance = Matrix._44 + Matrix._41;
// Right clipping plane
- ViewFrustum.RightPlane.Normal.x = Matrix._14 - Matrix._11;
- ViewFrustum.RightPlane.Normal.y = Matrix._24 - Matrix._21;
- ViewFrustum.RightPlane.Normal.z = Matrix._34 - Matrix._31;
- ViewFrustum.RightPlane.Distance = Matrix._44 - Matrix._41;
+ Frustum.RightPlane.Normal.x = Matrix._14 - Matrix._11;
+ Frustum.RightPlane.Normal.y = Matrix._24 - Matrix._21;
+ Frustum.RightPlane.Normal.z = Matrix._34 - Matrix._31;
+ Frustum.RightPlane.Distance = Matrix._44 - Matrix._41;
// Top clipping plane
- ViewFrustum.TopPlane.Normal.x = Matrix._14 - Matrix._12;
- ViewFrustum.TopPlane.Normal.y = Matrix._24 - Matrix._22;
- ViewFrustum.TopPlane.Normal.z = Matrix._34 - Matrix._32;
- ViewFrustum.TopPlane.Distance = Matrix._44 - Matrix._42;
+ Frustum.TopPlane.Normal.x = Matrix._14 - Matrix._12;
+ Frustum.TopPlane.Normal.y = Matrix._24 - Matrix._22;
+ Frustum.TopPlane.Normal.z = Matrix._34 - Matrix._32;
+ Frustum.TopPlane.Distance = Matrix._44 - Matrix._42;
// Bottom clipping plane
- ViewFrustum.BottomPlane.Normal.x = Matrix._14 + Matrix._12;
- ViewFrustum.BottomPlane.Normal.y = Matrix._24 + Matrix._22;
- ViewFrustum.BottomPlane.Normal.z = Matrix._34 + Matrix._32;
- ViewFrustum.BottomPlane.Distance = Matrix._44 + Matrix._42;
+ Frustum.BottomPlane.Normal.x = Matrix._14 + Matrix._12;
+ Frustum.BottomPlane.Normal.y = Matrix._24 + Matrix._22;
+ Frustum.BottomPlane.Normal.z = Matrix._34 + Matrix._32;
+ Frustum.BottomPlane.Distance = Matrix._44 + Matrix._42;
// Near clipping plane
if( bIsDirectX )
{
// 0 <= z <= w
- ViewFrustum.NearPlane.Normal.x = Matrix._13;
- ViewFrustum.NearPlane.Normal.y = Matrix._23;
- ViewFrustum.NearPlane.Normal.z = Matrix._33;
- ViewFrustum.NearPlane.Distance = Matrix._43;
+ Frustum.NearPlane.Normal.x = Matrix._13;
+ Frustum.NearPlane.Normal.y = Matrix._23;
+ Frustum.NearPlane.Normal.z = Matrix._33;
+ Frustum.NearPlane.Distance = Matrix._43;
}
else
{
// -w <= z <= w
- ViewFrustum.NearPlane.Normal.x = Matrix._14 + Matrix._13;
- ViewFrustum.NearPlane.Normal.y = Matrix._24 + Matrix._23;
- ViewFrustum.NearPlane.Normal.z = Matrix._34 + Matrix._33;
- ViewFrustum.NearPlane.Distance = Matrix._44 + Matrix._43;
+ Frustum.NearPlane.Normal.x = Matrix._14 + Matrix._13;
+ Frustum.NearPlane.Normal.y = Matrix._24 + Matrix._23;
+ Frustum.NearPlane.Normal.z = Matrix._34 + Matrix._33;
+ Frustum.NearPlane.Distance = Matrix._44 + Matrix._43;
}
// Far clipping plane
- ViewFrustum.FarPlane.Normal.x = Matrix._14 - Matrix._13;
- ViewFrustum.FarPlane.Normal.y = Matrix._24 - Matrix._23;
- ViewFrustum.FarPlane.Normal.z = Matrix._34 - Matrix._33;
- ViewFrustum.FarPlane.Distance = Matrix._44 - Matrix._43;
+ Frustum.FarPlane.Normal.x = Matrix._14 - Matrix._13;
+ Frustum.FarPlane.Normal.y = Matrix._24 - Matrix._23;
+ Frustum.FarPlane.Normal.z = Matrix._34 - Matrix._33;
+ Frustum.FarPlane.Distance = Matrix._44 - Matrix._43;
}
+inline void ExtractViewFrustumPlanesFromMatrix(const float4x4 &Matrix, ViewFrustumExt &FrustumExt, bool bIsDirectX)
+{
+ ExtractViewFrustumPlanesFromMatrix(Matrix, static_cast<ViewFrustum&>(FrustumExt), bIsDirectX);
+
+ // Compute frustum corners
+ float4x4 InvMatrix = inverseMatrix(Matrix);
+
+ float nearClipZ = bIsDirectX ? 0.f : -1.f;
+ static const float3 ProjSpaceCorners[] =
+ {
+ float3(-1,-1, nearClipZ),
+ float3( 1,-1, nearClipZ),
+ float3(-1, 1, nearClipZ),
+ float3( 1, 1, nearClipZ),
+
+ float3(-1,-1, 1),
+ float3( 1,-1, 1),
+ float3(-1, 1, 1),
+ float3( 1, 1, 1),
+ };
+ for(int i = 0; i < 8; ++i)
+ FrustumExt.FrustumCorners[i] = ProjSpaceCorners[i] * InvMatrix;
+}
struct BoundBox
{
+ // Order must not be changed!
float fMinX, fMaxX, fMinY, fMaxY, fMinZ, fMaxZ;
};
+enum class BoxVisibility
+{
+ // Bounding box is guaranteed to be outside of the view frustum
+ // .
+ // . ' |
+ // . ' |
+ // | |
+ // . |
+ // ___ ' . |
+ // | | ' .
+ // |___|
+ //
+ Invisible,
+
+ // Bounding box intersects the frustum
+ // .
+ // . ' |
+ // . ' |
+ // | |
+ // _.__ |
+ // | '|. |
+ // |____| ' .
+ //
+ Intersecting,
+
+ // Bounding box is fully inside the view frustum
+ // .
+ // . ' |
+ // . '___ |
+ // | | | |
+ // . |___| |
+ // ' . |
+ // ' .
+ //
+ FullyVisible
+};
+
+template<bool TestFullVisibility>
+inline BoxVisibility GetBoxVisibilityAgainstPlane(const Plane3D& Plane, const BoundBox &Box)
+{
+ const float3& Normal = Plane.Normal;
+
+ float3 MaxPoint(
+ (Normal.x > 0) ? Box.fMaxX : Box.fMinX,
+ (Normal.y > 0) ? Box.fMaxY : Box.fMinY,
+ (Normal.z > 0) ? Box.fMaxZ : Box.fMinZ
+ );
+
+ float DMax = dot( MaxPoint, Normal ) + Plane.Distance;
+
+ if( DMax < 0 )
+ return BoxVisibility::Invisible;
+
+ if (TestFullVisibility)
+ {
+ float3 MinPoint(
+ (Normal.x > 0) ? Box.fMinX : Box.fMaxX,
+ (Normal.y > 0) ? Box.fMinY : Box.fMaxY,
+ (Normal.z > 0) ? Box.fMinZ : Box.fMaxZ
+ );
+
+ float DMin = dot(MinPoint, Normal) + Plane.Distance;
+
+ if (DMin > 0)
+ return BoxVisibility::FullyVisible;
+ }
+
+ return BoxVisibility::Intersecting;
+}
+
// Tests if bounding box is visible by the camera
-inline bool IBoxVisible(const ViewFrustum &ViewFrustum, const BoundBox &Box)
+template<bool TestFullVisibility>
+inline BoxVisibility GetBoxVisibility(const ViewFrustum &ViewFrustum, const BoundBox &Box)
{
- Plane3D *pPlanes = (Plane3D *)&ViewFrustum;
- // If bounding box is "behind" some plane, then it is invisible
- // Otherwise it is treated as visible
+ const Plane3D *pPlanes = reinterpret_cast<const Plane3D*>(&ViewFrustum);
+
+ int NumPlanesInside = 0;
for(int iViewFrustumPlane = 0; iViewFrustumPlane < 6; iViewFrustumPlane++)
{
- Plane3D *pCurrPlane = pPlanes + iViewFrustumPlane;
- float3 *pCurrNormal = &pCurrPlane->Normal;
- float3 MaxPoint;
-
- MaxPoint.x = (pCurrNormal->x > 0) ? Box.fMaxX : Box.fMinX;
- MaxPoint.y = (pCurrNormal->y > 0) ? Box.fMaxY : Box.fMinY;
- MaxPoint.z = (pCurrNormal->z > 0) ? Box.fMaxZ : Box.fMinZ;
-
- float DMax = dot( MaxPoint, *pCurrNormal ) + pCurrPlane->Distance;
+ const Plane3D &CurrPlane = pPlanes[iViewFrustumPlane];
+ auto VisibilityAgainstPlane = GetBoxVisibilityAgainstPlane<TestFullVisibility>(CurrPlane, Box);
- if( DMax < 0 )
- return false;
+ // If bounding box is "behind" one of the planes, it is definitely invisible
+ if (VisibilityAgainstPlane == BoxVisibility::Invisible)
+ return BoxVisibility::Invisible;
+
+ // Count total number of planes the bound box is inside
+ if (VisibilityAgainstPlane == BoxVisibility::FullyVisible)
+ ++NumPlanesInside;
+ }
+
+ return (TestFullVisibility && NumPlanesInside == 6) ? BoxVisibility::FullyVisible : BoxVisibility::Intersecting;
+}
+
+template<bool TestFullVisibility>
+inline BoxVisibility GetBoxVisibility(const ViewFrustumExt &ViewFrustumExt, const BoundBox &Box)
+{
+ auto Visibility = GetBoxVisibility<TestFullVisibility>(static_cast<const ViewFrustum&>(ViewFrustumExt), Box);
+ if (Visibility == BoxVisibility::FullyVisible || Visibility == BoxVisibility::Invisible)
+ return Visibility;
+
+ // Additionally test if the whole frustum is outside one of
+ // the the bounding box planes. This helps in the following situation:
+ //
+ //
+ // .
+ // / ' . .
+ // / AABB / . ' |
+ // / /. ' |
+ // ' . / | |
+ // * . | |
+ // ' . |
+ // ' . |
+ // ' .
+
+ for(int iBoundBoxPlane = 0; iBoundBoxPlane < 6; ++iBoundBoxPlane)
+ {
+ // struct BoundBox
+ // {
+ // float fMinX, fMaxX, fMinY, fMaxY, fMinZ, fMaxZ;
+ // };
+ float CurrPlaneCoord = reinterpret_cast<const float*>(&Box)[iBoundBoxPlane];
+ int iCoordOrder = iBoundBoxPlane / 2; // 0, 0, 1, 1, 2, 2
+ float fSign = (iBoundBoxPlane & 0x01) ? +1.f : -1.f;
+ bool bAllCornersOutside = true;
+ for(int iCorner=0; iCorner < 8; iCorner++)
+ {
+ float CurrCornerCoord = ViewFrustumExt.FrustumCorners[iCorner][iCoordOrder];
+ if( fSign * (CurrPlaneCoord - CurrCornerCoord) > 0)
+ {
+ bAllCornersOutside = false;
+ break;
+ }
+ }
+ if( bAllCornersOutside )
+ return BoxVisibility::Invisible;
}
+ return BoxVisibility::Intersecting;
+}
+
+inline float GetPointToBoxDistance(const BoundBox &BndBox, const float3 &Pos)
+{
+ VERIFY_EXPR(BndBox.fMaxX >= BndBox.fMinX &&
+ BndBox.fMaxY >= BndBox.fMinY &&
+ BndBox.fMaxZ >= BndBox.fMinZ);
+ float fdX = (Pos.x > BndBox.fMaxX) ? (Pos.x - BndBox.fMaxX) : ( (Pos.x < BndBox.fMinX) ? (BndBox.fMinX - Pos.x) : 0.f );
+ float fdY = (Pos.y > BndBox.fMaxY) ? (Pos.y - BndBox.fMaxY) : ( (Pos.y < BndBox.fMinY) ? (BndBox.fMinY - Pos.y) : 0.f );
+ float fdZ = (Pos.z > BndBox.fMaxZ) ? (Pos.z - BndBox.fMaxZ) : ( (Pos.z < BndBox.fMinZ) ? (BndBox.fMinZ - Pos.z) : 0.f );
+ VERIFY_EXPR(fdX >= 0 && fdY >= 0 && fdZ >= 0);
+
+ float3 RangeVec(fdX, fdY, fdZ);
+ return length( RangeVec );
+}
+
+inline bool operator == (const Plane3D &p1, const Plane3D &p2)
+{
+ return p1.Normal == p2.Normal &&
+ p1.Distance == p2.Distance;
+}
+
+inline bool operator == (const ViewFrustum &f1, const ViewFrustum &f2)
+{
+ return f1.LeftPlane == f2.LeftPlane &&
+ f1.RightPlane == f2.RightPlane &&
+ f1.BottomPlane == f2.BottomPlane &&
+ f1.TopPlane == f2.TopPlane &&
+ f1.NearPlane == f2.NearPlane &&
+ f1.FarPlane == f2.FarPlane;
+}
+
+inline bool operator == (const ViewFrustumExt &f1, const ViewFrustumExt &f2)
+{
+ if (! (static_cast<const ViewFrustum &>(f1) == static_cast<const ViewFrustum &>(f2)) )
+ return false;
+
+ for (int c = 0; c < _countof(f1.FrustumCorners); ++c)
+ if (f1.FrustumCorners[c] != f2.FrustumCorners[c])
+ return false;
+
return true;
}
+
+namespace std
+{
+ template<>
+ struct hash<Plane3D>
+ {
+ size_t operator()( const Plane3D &Plane ) const
+ {
+ return Diligent::ComputeHash(Plane.Normal, Plane.Distance);
+ }
+ };
+
+ template<>
+ struct hash<ViewFrustum>
+ {
+ size_t operator()( const ViewFrustum &Frustum ) const
+ {
+ return Diligent::ComputeHash(Frustum.LeftPlane, Frustum.RightPlane, Frustum.BottomPlane, Frustum.TopPlane, Frustum.NearPlane, Frustum.FarPlane);
+ }
+ };
+
+ template<>
+ struct hash<ViewFrustumExt>
+ {
+ size_t operator()( const ViewFrustumExt &Frustum ) const
+ {
+ auto Seed = Diligent::ComputeHash(static_cast<const ViewFrustum&>(Frustum));
+ for (int Corner = 0; Corner < _countof(Frustum.FrustumCorners); ++Corner)
+ Diligent::HashCombine(Seed, Frustum.FrustumCorners[Corner]);
+ return Seed;
+ }
+ };
+}
diff --git a/Common/interface/BasicMath.h b/Common/interface/BasicMath.h
index b1ecdf17..1e7ebc9a 100644
--- a/Common/interface/BasicMath.h
+++ b/Common/interface/BasicMath.h
@@ -35,8 +35,7 @@
#define _USE_MATH_DEFINES
#include <math.h>
-// This header defines math and matrix helper functions and structures used
-// by DirectX SDK samples.
+#include "HashUtils.h"
// Common Constants
@@ -930,16 +929,13 @@ inline float4x4 scaleMatrix(float x, float y, float z)
0, 0, 0, 1);
}
-inline float4x4 rotationX(float degreeX)
+inline float4x4 rotationX(float angleInRadians)
{
- float angleInRadians = degreeX * (PI_F / 180.0f);
-
float sinAngle = sinf(angleInRadians);
float cosAngle = cosf(angleInRadians);
float4x4 mOut;
- UNSUPPORTED("This function is not tested, it might be incorrect.")
mOut._11 = 1.0f; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = 0.0f;
mOut._21 = 0.0f; mOut._22 = cosAngle; mOut._23 = -sinAngle; mOut._24 = 0.0f;
mOut._31 = 0.0f; mOut._32 = sinAngle; mOut._33 = cosAngle; mOut._34 = 0.0f;
@@ -948,16 +944,13 @@ inline float4x4 rotationX(float degreeX)
return mOut;
}
-inline float4x4 rotationY(float degreeY)
+inline float4x4 rotationY(float angleInRadians)
{
- float angleInRadians = degreeY * (PI_F / 180.0f);
-
float sinAngle = sinf(angleInRadians);
float cosAngle = cosf(angleInRadians);
float4x4 mOut;
- UNSUPPORTED("This function is not tested, it might be incorrect.")
mOut._11 = cosAngle; mOut._12 = 0.0f; mOut._13 = sinAngle; mOut._14 = 0.0f;
mOut._21 = 0.0f; mOut._22 = 1.0f; mOut._23 = 0.0f; mOut._24 = 0.0f;
mOut._31 = -sinAngle; mOut._32 = 0.0f; mOut._33 = cosAngle; mOut._34 = 0.0f;
@@ -966,16 +959,13 @@ inline float4x4 rotationY(float degreeY)
return mOut;
}
-inline float4x4 rotationZ(float degreeZ)
+inline float4x4 rotationZ(float angleInRadians)
{
- float angleInRadians = degreeZ * (PI_F / 180.0f);
-
float sinAngle = sinf(angleInRadians);
float cosAngle = cosf(angleInRadians);
float4x4 mOut;
- UNSUPPORTED("This function is not tested, it might be incorrect.")
mOut._11 = cosAngle; mOut._12 = -sinAngle; mOut._13 = 0.0f; mOut._14 = 0.0f;
mOut._21 = sinAngle; mOut._22 = cosAngle; mOut._23 = 0.0f; mOut._24 = 0.0f;
mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = 1.0f; mOut._34 = 0.0f;
@@ -1341,4 +1331,59 @@ namespace std
std::min( Left.w, Right.w )
);
}
-} \ No newline at end of file
+
+
+ template<typename T>
+ struct hash<Vector2<T>>
+ {
+ size_t operator()( const Vector2<T> &v2 ) const
+ {
+ return Diligent::ComputeHash(v2.x, v2.y);
+ }
+ };
+
+ template<typename T>
+ struct hash<Vector3<T>>
+ {
+ size_t operator()( const Vector3<T> &v3 ) const
+ {
+ return Diligent::ComputeHash(v3.x, v3.y, v3.z);
+ }
+ };
+
+ template<typename T>
+ struct hash<Vector4<T>>
+ {
+ size_t operator()( const Vector4<T> &v4 ) const
+ {
+ return Diligent::ComputeHash(v4.x, v4.y, v4.z, v4.w);
+ }
+ };
+
+ template<typename T>
+ struct hash<Matrix3x3<T>>
+ {
+ size_t operator()( const Matrix3x3<T> &m ) const
+ {
+ return Diligent::ComputeHash(
+ m._m00, m._m01, m._m02,
+ m._m10, m._m11, m._m12,
+ m._m20, m._m21, m._m22
+ );
+ }
+ };
+
+ template<typename T>
+ struct hash<Matrix4x4<T>>
+ {
+ size_t operator()( const Matrix4x4<T> &m ) const
+ {
+ return Diligent::ComputeHash(
+ m._m00, m._m01, m._m02, m._m03,
+ m._m10, m._m11, m._m12, m._m13,
+ m._m20, m._m21, m._m22, m._m23,
+ m._m30, m._m31, m._m32, m._m33
+ );
+ }
+ };
+}
diff --git a/Common/interface/Object.h b/Common/interface/Object.h
index 88181522..a4ac6c2d 100644
--- a/Common/interface/Object.h
+++ b/Common/interface/Object.h
@@ -71,7 +71,7 @@ public:
/// Returns the pointer to IReferenceCounters interface of the associated
- /// reference counters object. The metod does *NOT* increment
+ /// reference counters object. The method does *NOT* increment
/// the number of strong references to the returned object.
virtual IReferenceCounters* GetReferenceCounters()const = 0;
};