/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Foundation/Math/Implementation/AllClasses_inl.h
362 строки
11 KB
Trevor Cash
Update (Templatize) Primative Type Tests to test both float and double versions. (#1785)
27 янв 2026, 09:34
Не верифицирован
27 янв 2026, 09:34
6a0df83
Код
Авторство
О чём код?
#pragma once #include <Foundation/Math/BoundingBox.h> #include <Foundation/Math/BoundingSphere.h> #include <Foundation/Math/Mat3.h> #include <Foundation/Math/Mat4.h> #include <Foundation/Math/Plane.h> template <typename Type> EZ_ALWAYS_INLINE bool ezBoundingBoxTemplate<Type>::Contains(const ezBoundingSphereTemplate<Type>& sphere) const { return Contains(sphere.GetBoundingBox()); } template <typename Type> EZ_ALWAYS_INLINE bool ezBoundingBoxTemplate<Type>::Overlaps(const ezBoundingSphereTemplate<Type>& sphere) const { // check whether the closest point between box and sphere is inside the sphere (it is definitely inside the box) return sphere.Contains(GetClampedPoint(sphere.m_vCenter)); } template <typename Type> inline Type ezBoundingBoxTemplate<Type>::GetDistanceTo(const ezBoundingSphereTemplate<Type>& sphere) const { return (GetClampedPoint(sphere.m_vCenter) - sphere.m_vCenter).GetLength() - sphere.m_fRadius; } template <typename Type> inline const ezBoundingSphereTemplate<Type> ezBoundingBoxTemplate<Type>::GetBoundingSphere() const { return ezBoundingSphereTemplate<Type>::MakeFromCenterAndRadius(GetCenter(), (m_vMax - m_vMin).GetLength() * (Type)0.5); } template <typename Type> void ezBoundingSphereTemplate<Type>::ExpandToInclude(const ezBoundingBoxTemplate<Type>& rhs) { // compute the min and max extends of the AABB relative to the sphere (sphere center is the new origin) const ezVec3Template<Type> vDiffMax = rhs.m_vMax - m_vCenter; const ezVec3Template<Type> vDiffMin = rhs.m_vMin - m_vCenter; // compute the absolute distance to each AABB extremum, per axis const ezVec3Template<Type> vDiffMaxAbs(ezMath::Abs(vDiffMax.x), ezMath::Abs(vDiffMax.y), ezMath::Abs(vDiffMax.z)); const ezVec3Template<Type> vDiffMinAbs(ezMath::Abs(vDiffMin.x), ezMath::Abs(vDiffMin.y), ezMath::Abs(vDiffMin.z)); // take the maximum distance for each axis, to compute the point that is the farthest away from the sphere const ezVec3Template<Type> vMostDistantPoint = vDiffMinAbs.CompMax(vDiffMaxAbs); const Type fDistSQR = vMostDistantPoint.GetLengthSquared(); if (ezMath::Square(m_fRadius) < fDistSQR) m_fRadius = ezMath::Sqrt(fDistSQR); } template <typename Type> Type ezBoundingSphereTemplate<Type>::GetDistanceTo(const ezBoundingBoxTemplate<Type>& rhs) const { const ezVec3Template<Type> vPointOnBox = rhs.GetClampedPoint(m_vCenter); return GetDistanceTo(vPointOnBox); } template <typename Type> bool ezBoundingSphereTemplate<Type>::Contains(const ezBoundingBoxTemplate<Type>& rhs) const { // compute the min and max extends of the AABB relative to the sphere (sphere center is the new origin) const ezVec3Template<Type> vDiffMax = rhs.m_vMax - m_vCenter; const ezVec3Template<Type> vDiffMin = rhs.m_vMin - m_vCenter; // compute the absolute distance to each AABB extremum, per axis const ezVec3Template<Type> vDiffMaxAbs(ezMath::Abs(vDiffMax.x), ezMath::Abs(vDiffMax.y), ezMath::Abs(vDiffMax.z)); const ezVec3Template<Type> vDiffMinAbs(ezMath::Abs(vDiffMin.x), ezMath::Abs(vDiffMin.y), ezMath::Abs(vDiffMin.z)); // take the maximum distance for each axis, to compute the point that is the farthest away from the sphere const ezVec3Template<Type> vMostDistantPoint = vDiffMinAbs.CompMax(vDiffMaxAbs); // if the squared length of that point is still smaller than the sphere radius, it is inside the sphere // and thus the whole AABB is inside the sphere return vMostDistantPoint.GetLengthSquared() <= m_fRadius * m_fRadius; } template <typename Type> bool ezBoundingSphereTemplate<Type>::Overlaps(const ezBoundingBoxTemplate<Type>& rhs) const { return Contains(rhs.GetClampedPoint(m_vCenter)); } template <typename Type> const ezBoundingBoxTemplate<Type> ezBoundingSphereTemplate<Type>::GetBoundingBox() const { return ezBoundingBoxTemplate<Type>::MakeFromMinMax(m_vCenter - ezVec3Template<Type>(m_fRadius), m_vCenter + ezVec3Template<Type>(m_fRadius)); } template <typename Type> ezPositionOnPlane::Enum ezPlaneTemplate<Type>::GetObjectPosition(const ezBoundingSphereTemplate<Type>& sphere) const { const Type fDist = GetDistanceTo(sphere.m_vCenter); if (fDist >= sphere.m_fRadius) return ezPositionOnPlane::Front; if (-fDist >= sphere.m_fRadius) return ezPositionOnPlane::Back; return ezPositionOnPlane::Spanning; } template <typename Type> ezPositionOnPlane::Enum ezPlaneTemplate<Type>::GetObjectPosition(const ezBoundingBoxTemplate<Type>& box) const { ezVec3Template<Type> vPos = box.m_vMin; ezVec3Template<Type> vNeg = box.m_vMax; if (m_vNormal.x >= (Type)0) { vPos.x = box.m_vMax.x; vNeg.x = box.m_vMin.x; } if (m_vNormal.y >= (Type)0) { vPos.y = box.m_vMax.y; vNeg.y = box.m_vMin.y; } if (m_vNormal.z >= (Type)0) { vPos.z = box.m_vMax.z; vNeg.z = box.m_vMin.z; } if (GetDistanceTo(vPos) <= (Type)0) return ezPositionOnPlane::Back; if (GetDistanceTo(vNeg) >= (Type)0) return ezPositionOnPlane::Front; return ezPositionOnPlane::Spanning; } template <typename Type> Type ezPlaneTemplate<Type>::GetMinimumDistanceTo(const ezBoundingBoxTemplate<Type>& box) const { ezVec3Template<Type> vNeg = box.m_vMax; if (m_vNormal.x >= (Type)0) { vNeg.x = box.m_vMin.x; } if (m_vNormal.y >= (Type)0) { vNeg.y = box.m_vMin.y; } if (m_vNormal.z >= (Type)0) { vNeg.z = box.m_vMin.z; } return GetDistanceTo(vNeg); } template <typename Type> Type ezPlaneTemplate<Type>::GetMaximumDistanceTo(const ezBoundingBoxTemplate<Type>& box) const { ezVec3Template<Type> vPos = box.m_vMin; if (m_vNormal.x >= (Type)0) { vPos.x = box.m_vMax.x; } if (m_vNormal.y >= (Type)0) { vPos.y = box.m_vMax.y; } if (m_vNormal.z >= (Type)0) { vPos.z = box.m_vMax.z; } return GetDistanceTo(vPos); } template <typename Type> ezMat3Template<Type> ezMat3Template<Type>::MakeAxisRotation(const ezVec3Template<Type>& vAxis, ezAngleTemplate<Type> angle) { EZ_ASSERT_DEBUG(vAxis.IsNormalized(0.1f), "vAxis must be normalized."); const Type cos = ezMath::Cos(angle); const Type sin = ezMath::Sin(angle); const Type oneminuscos = (Type)1 - cos; const Type xy = vAxis.x * vAxis.y; const Type xz = vAxis.x * vAxis.z; const Type yz = vAxis.y * vAxis.z; const Type xsin = vAxis.x * sin; const Type ysin = vAxis.y * sin; const Type zsin = vAxis.z * sin; const Type onecos_xy = oneminuscos * xy; const Type onecos_xz = oneminuscos * xz; const Type onecos_yz = oneminuscos * yz; ezMat3Template<Type> res; // Column 1 res.Element(0, 0) = cos + (oneminuscos * (vAxis.x * vAxis.x)); res.Element(0, 1) = onecos_xy + zsin; res.Element(0, 2) = onecos_xz - ysin; // Column 2 ) res.Element(1, 0) = onecos_xy - zsin; res.Element(1, 1) = cos + (oneminuscos * (vAxis.y * vAxis.y)); res.Element(1, 2) = onecos_yz + xsin; // Column 3 ) res.Element(2, 0) = onecos_xz + ysin; res.Element(2, 1) = onecos_yz - xsin; res.Element(2, 2) = cos + (oneminuscos * (vAxis.z * vAxis.z)); return res; } template <typename Type> ezResult ezMat3Template<Type>::Invert(Type fEpsilon) { const Type fDet = Element(0, 0) * (Element(2, 2) * Element(1, 1) - Element(1, 2) * Element(2, 1)) - Element(0, 1) * (Element(2, 2) * Element(1, 0) - Element(1, 2) * Element(2, 0)) + Element(0, 2) * (Element(2, 1) * Element(1, 0) - Element(1, 1) * Element(2, 0)); if (ezMath::IsZero(fDet, fEpsilon)) return EZ_FAILURE; const Type fOneDivDet = (Type)1 / fDet; ezMat3Template<Type> Inverse; Inverse.Element(0, 0) = (Element(2, 2) * Element(1, 1) - Element(1, 2) * Element(2, 1)); Inverse.Element(0, 1) = -(Element(2, 2) * Element(0, 1) - Element(0, 2) * Element(2, 1)); Inverse.Element(0, 2) = (Element(1, 2) * Element(0, 1) - Element(0, 2) * Element(1, 1)); Inverse.Element(1, 0) = -(Element(2, 2) * Element(1, 0) - Element(1, 2) * Element(2, 0)); Inverse.Element(1, 1) = (Element(2, 2) * Element(0, 0) - Element(0, 2) * Element(2, 0)); Inverse.Element(1, 2) = -(Element(1, 2) * Element(0, 0) - Element(0, 2) * Element(1, 0)); Inverse.Element(2, 0) = (Element(2, 1) * Element(1, 0) - Element(1, 1) * Element(2, 0)); Inverse.Element(2, 1) = -(Element(2, 1) * Element(0, 0) - Element(0, 1) * Element(2, 0)); Inverse.Element(2, 2) = (Element(1, 1) * Element(0, 0) - Element(0, 1) * Element(1, 0)); *this = Inverse * fOneDivDet; return EZ_SUCCESS; } template <typename Type> ezMat4Template<Type> ezMat4Template<Type>::MakeAxisRotation(const ezVec3Template<Type>& vAxis, ezAngleTemplate<Type> angle) { EZ_ASSERT_DEBUG(vAxis.IsNormalized(), "vAxis must be normalized."); const Type cos = ezMath::Cos(angle); const Type sin = ezMath::Sin(angle); const Type oneminuscos = (Type)1 - cos; const Type xy = vAxis.x * vAxis.y; const Type xz = vAxis.x * vAxis.z; const Type yz = vAxis.y * vAxis.z; const Type xsin = vAxis.x * sin; const Type ysin = vAxis.y * sin; const Type zsin = vAxis.z * sin; const Type onecos_xy = oneminuscos * xy; const Type onecos_xz = oneminuscos * xz; const Type onecos_yz = oneminuscos * yz; ezMat4Template<Type> res; // Column 1 res.Element(0, 0) = cos + (oneminuscos * (vAxis.x * vAxis.x)); res.Element(0, 1) = onecos_xy + zsin; res.Element(0, 2) = onecos_xz - ysin; res.Element(0, 3) = 0; // Column 2 res.Element(1, 0) = onecos_xy - zsin; res.Element(1, 1) = cos + (oneminuscos * (vAxis.y * vAxis.y)); res.Element(1, 2) = onecos_yz + xsin; res.Element(1, 3) = 0; // Column 3 res.Element(2, 0) = onecos_xz + ysin; res.Element(2, 1) = onecos_yz - xsin; res.Element(2, 2) = cos + (oneminuscos * (vAxis.z * vAxis.z)); res.Element(2, 3) = 0; // Column 4 res.Element(3, 0) = 0; res.Element(3, 1) = 0; res.Element(3, 2) = 0; res.Element(3, 3) = 1; return res; } template <typename Type> ezResult ezMat4Template<Type>::Invert(Type fEpsilon) { ezMat4Template<Type> Inverse; const Type fDet = GetDeterminantOf4x4Matrix(*this); if (ezMath::IsZero(fDet, fEpsilon)) return EZ_FAILURE; Type fOneDivDet = ezMath::Invert(fDet); for (ezInt32 i = 0; i < 4; ++i) { Inverse.Element(i, 0) = GetDeterminantOf3x3SubMatrix(*this, i, 0) * fOneDivDet; fOneDivDet = -fOneDivDet; Inverse.Element(i, 1) = GetDeterminantOf3x3SubMatrix(*this, i, 1) * fOneDivDet; fOneDivDet = -fOneDivDet; Inverse.Element(i, 2) = GetDeterminantOf3x3SubMatrix(*this, i, 2) * fOneDivDet; fOneDivDet = -fOneDivDet; Inverse.Element(i, 3) = GetDeterminantOf3x3SubMatrix(*this, i, 3) * fOneDivDet; } *this = Inverse; return EZ_SUCCESS; } ////////////////////////////////////////////////////////////////////////// // static template <typename T> bool ezComparisonOperator::Compare(ezComparisonOperator::Enum cmp, const T& a, const T& b) { switch (cmp) { case ezComparisonOperator::Equal: return a == b; case ezComparisonOperator::NotEqual: return !(a == b); case ezComparisonOperator::Less: return a < b; case ezComparisonOperator::LessEqual: return !(b < a); case ezComparisonOperator::Greater: return b < a; case ezComparisonOperator::GreaterEqual: return !(a < b); EZ_DEFAULT_CASE_NOT_IMPLEMENTED; } return false; }