Refactor engine to support double-precision vectors
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
#if USE_LARGE_WORLDS
|
||||
using Real = System.Double;
|
||||
#else
|
||||
using Real = System.Single;
|
||||
#endif
|
||||
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -31,8 +37,7 @@ using System.Runtime.InteropServices;
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a frustum which can be used in frustum culling, zoom to Extents (zoom to fit) operations,
|
||||
/// (matrix, frustum, camera) interchange, and many kind of intersection testing.
|
||||
/// Defines a frustum which can be used in frustum culling, zoom to Extents (zoom to fit) operations, (matrix, frustum, camera) interchange, and many kind of intersection testing.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
@@ -102,9 +107,7 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return pMatrix.GetHashCode();
|
||||
@@ -114,9 +117,7 @@ namespace FlaxEngine
|
||||
/// Determines whether the specified <see cref="BoundingFrustum" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="BoundingFrustum" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="BoundingFrustum" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if the specified <see cref="BoundingFrustum" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref BoundingFrustum other)
|
||||
{
|
||||
@@ -127,9 +128,7 @@ namespace FlaxEngine
|
||||
/// Determines whether the specified <see cref="BoundingFrustum" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="BoundingFrustum" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="BoundingFrustum" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if the specified <see cref="BoundingFrustum" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(BoundingFrustum other)
|
||||
{
|
||||
@@ -140,16 +139,10 @@ namespace FlaxEngine
|
||||
/// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is BoundingFrustum))
|
||||
return false;
|
||||
|
||||
var strongValue = (BoundingFrustum)obj;
|
||||
return Equals(ref strongValue);
|
||||
return obj is BoundingFrustum other && Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,9 +150,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(BoundingFrustum left, BoundingFrustum right)
|
||||
{
|
||||
@@ -171,9 +162,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(BoundingFrustum left, BoundingFrustum right)
|
||||
{
|
||||
@@ -184,7 +173,7 @@ namespace FlaxEngine
|
||||
/// Returns one of the 6 planes related to this frustum.
|
||||
/// </summary>
|
||||
/// <param name="index">Plane index where 0 fro Left, 1 for Right, 2 for Top, 3 for Bottom, 4 for Near, 5 for Far</param>
|
||||
/// <returns></returns>
|
||||
/// <returns>The frustum plane.</returns>
|
||||
public Plane GetPlane(int index)
|
||||
{
|
||||
switch (index)
|
||||
@@ -251,9 +240,9 @@ namespace FlaxEngine
|
||||
Vector3.Cross(ref p2.Normal, ref p3.Normal, out var n2Xn3);
|
||||
Vector3.Cross(ref p3.Normal, ref p1.Normal, out var n3Xn1);
|
||||
Vector3.Cross(ref p1.Normal, ref p2.Normal, out var n1Xn2);
|
||||
float div1 = Vector3.Dot(ref p1.Normal, ref n2Xn3);
|
||||
float div2 = Vector3.Dot(ref p2.Normal, ref n3Xn1);
|
||||
float div3 = Vector3.Dot(ref p3.Normal, ref n1Xn2);
|
||||
var div1 = Vector3.Dot(ref p1.Normal, ref n2Xn3);
|
||||
var div2 = Vector3.Dot(ref p2.Normal, ref n3Xn1);
|
||||
var div3 = Vector3.Dot(ref p3.Normal, ref n1Xn2);
|
||||
if (Mathf.IsZero(div1 * div2 * div3))
|
||||
return Vector3.Zero;
|
||||
return n2Xn3 * (-p1.D / div1) - n3Xn1 * (p2.D / div2) - n1Xn2 * (p3.D / div3);
|
||||
@@ -266,8 +255,8 @@ namespace FlaxEngine
|
||||
/// <param name="lookDir">The look dir.</param>
|
||||
/// <param name="upDir">Up dir.</param>
|
||||
/// <param name="fov">The fov.</param>
|
||||
/// <param name="znear">The znear.</param>
|
||||
/// <param name="zfar">The zfar.</param>
|
||||
/// <param name="znear">The Z near.</param>
|
||||
/// <param name="zfar">The Z far.</param>
|
||||
/// <param name="aspect">The aspect.</param>
|
||||
/// <returns>The bounding frustum calculated from perspective camera</returns>
|
||||
public static BoundingFrustum FromCamera(Vector3 cameraPos, Vector3 lookDir, Vector3 upDir, float fov, float znear, float zfar, float aspect)
|
||||
@@ -414,53 +403,6 @@ namespace FlaxEngine
|
||||
return Contains(ref point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a group of points lay totally inside the frustum (Contains), or lay partially inside the frustum
|
||||
/// (Intersects), or lay outside the frustum (Disjoint).
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <returns>Type of the containment</returns>
|
||||
public ContainmentType Contains(Vector3[] points)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/* TODO: (PMin) This method is wrong, does not calculate case where only plane from points is intersected
|
||||
var containsAny = false;
|
||||
var containsAll = true;
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
{
|
||||
switch (Contains(ref points[i]))
|
||||
{
|
||||
case ContainmentType.Contains:
|
||||
case ContainmentType.Intersects:
|
||||
containsAny = true;
|
||||
break;
|
||||
case ContainmentType.Disjoint:
|
||||
containsAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (containsAny)
|
||||
{
|
||||
if (containsAll)
|
||||
return ContainmentType.Contains;
|
||||
else
|
||||
return ContainmentType.Intersects;
|
||||
}
|
||||
else
|
||||
return ContainmentType.Disjoint; */
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a group of points lay totally inside the frustum (Contains), or lay partially inside the frustum
|
||||
/// (Intersects), or lay outside the frustum (Disjoint).
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="result">Type of the containment.</param>
|
||||
public void Contains(Vector3[] points, out ContainmentType result)
|
||||
{
|
||||
result = Contains(points);
|
||||
}
|
||||
|
||||
private void GetBoxToPlanePVertexNVertex(ref BoundingBox box, ref Vector3 planeNormal, out Vector3 p, out Vector3 n)
|
||||
{
|
||||
p = box.Minimum;
|
||||
@@ -588,36 +530,6 @@ namespace FlaxEngine
|
||||
result = Contains(ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the intersection relationship between the frustum and another bounding frustum.
|
||||
/// </summary>
|
||||
/// <param name="frustum">The frustum.</param>
|
||||
/// <returns>Type of the containment</returns>
|
||||
public bool Contains(ref BoundingFrustum frustum)
|
||||
{
|
||||
return Contains(frustum.GetCorners()) != ContainmentType.Disjoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the intersection relationship between the frustum and another bounding frustum.
|
||||
/// </summary>
|
||||
/// <param name="frustum">The frustum.</param>
|
||||
/// <returns>Type of the containment</returns>
|
||||
public bool Contains(BoundingFrustum frustum)
|
||||
{
|
||||
return Contains(ref frustum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the intersection relationship between the frustum and another bounding frustum.
|
||||
/// </summary>
|
||||
/// <param name="frustum">The frustum.</param>
|
||||
/// <param name="result">Type of the containment.</param>
|
||||
public void Contains(ref BoundingFrustum frustum, out bool result)
|
||||
{
|
||||
result = Contains(frustum.GetCorners()) != ContainmentType.Disjoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the current BoundingFrustum intersects a BoundingSphere.
|
||||
/// </summary>
|
||||
@@ -735,21 +647,18 @@ namespace FlaxEngine
|
||||
/// Checks whether the current BoundingFrustum intersects the specified Ray.
|
||||
/// </summary>
|
||||
/// <param name="ray">The Ray to check for intersection with.</param>
|
||||
/// <param name="inDistance">
|
||||
/// The distance at which the ray enters the frustum if there is an intersection and the ray
|
||||
/// starts outside the frustum.
|
||||
/// </param>
|
||||
/// <param name="inDistance">The distance at which the ray enters the frustum if there is an intersection and the ray starts outside the frustum.</param>
|
||||
/// <param name="outDistance">The distance at which the ray exits the frustum if there is an intersection.</param>
|
||||
/// <returns><c>true</c> if the current BoundingFrustum intersects the specified Ray.</returns>
|
||||
public bool Intersects(ref Ray ray, out float? inDistance, out float? outDistance)
|
||||
public bool Intersects(ref Ray ray, out Real? inDistance, out Real? outDistance)
|
||||
{
|
||||
if (Contains(ray.Position) != ContainmentType.Disjoint)
|
||||
{
|
||||
float nearstPlaneDistance = float.MaxValue;
|
||||
Real nearstPlaneDistance = Real.MaxValue;
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
Plane plane = GetPlane(i);
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out float distance) && (distance < nearstPlaneDistance))
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out Real distance) && (distance < nearstPlaneDistance))
|
||||
nearstPlaneDistance = distance;
|
||||
}
|
||||
|
||||
@@ -760,15 +669,15 @@ namespace FlaxEngine
|
||||
//We will find the two points at which the ray enters and exists the frustum
|
||||
//These two points make a line which center inside the frustum if the ray intersects it
|
||||
//Or outside the frustum if the ray intersects frustum planes outside it.
|
||||
float minDist = float.MaxValue;
|
||||
float maxDist = float.MinValue;
|
||||
Real minDist = Real.MaxValue;
|
||||
Real maxDist = Real.MinValue;
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
Plane plane = GetPlane(i);
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out float distance))
|
||||
if (CollisionsHelper.RayIntersectsPlane(ref ray, ref plane, out Real distance))
|
||||
{
|
||||
minDist = Math.Min(minDist, distance);
|
||||
maxDist = Math.Max(maxDist, distance);
|
||||
minDist = Mathf.Min(minDist, distance);
|
||||
maxDist = Mathf.Max(maxDist, distance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,15 +696,13 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents
|
||||
/// (zoom to fit) operation,
|
||||
/// so all the passed points will fit in the current view.
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <returns>The zoom to fit distance</returns>
|
||||
public float GetZoomToExtentsShiftDistance(Vector3[] points)
|
||||
public Real GetZoomToExtentsShiftDistance(Vector3[] points)
|
||||
{
|
||||
var vAngle = (float)(Math.PI / 2.0 - Math.Acos(Vector3.Dot(pNear.Normal, pTop.Normal)));
|
||||
var vSin = (float)Math.Sin(vAngle);
|
||||
@@ -805,37 +712,32 @@ namespace FlaxEngine
|
||||
|
||||
BoundingFrustum ioFrustrum = GetInsideOutClone();
|
||||
|
||||
float maxPointDist = float.MinValue;
|
||||
var maxPointDist = Real.MinValue;
|
||||
for (var i = 0; i < points.Length; i++)
|
||||
{
|
||||
float pointDist = CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pTop, ref points[i]);
|
||||
pointDist = Math.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pBottom, ref points[i]));
|
||||
pointDist = Math.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pLeft, ref points[i]) * horizontalToVerticalMapping);
|
||||
pointDist = Math.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pRight, ref points[i]) * horizontalToVerticalMapping);
|
||||
|
||||
maxPointDist = Math.Max(maxPointDist, pointDist);
|
||||
var pointDist = CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pTop, ref points[i]);
|
||||
pointDist = Mathf.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pBottom, ref points[i]));
|
||||
pointDist = Mathf.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pLeft, ref points[i]) * horizontalToVerticalMapping);
|
||||
pointDist = Mathf.Max(pointDist, CollisionsHelper.DistancePlanePoint(ref ioFrustrum.pRight, ref points[i]) * horizontalToVerticalMapping);
|
||||
maxPointDist = Mathf.Max(maxPointDist, pointDist);
|
||||
}
|
||||
return -maxPointDist / vSin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents
|
||||
/// (zoom to fit) operation,
|
||||
/// so all the passed points will fit in the current view.
|
||||
/// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
|
||||
/// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
|
||||
/// </summary>
|
||||
/// <param name="boundingBox">The bounding box.</param>
|
||||
/// <returns>The zoom to fit distance</returns>
|
||||
public float GetZoomToExtentsShiftDistance(ref BoundingBox boundingBox)
|
||||
public Real GetZoomToExtentsShiftDistance(ref BoundingBox boundingBox)
|
||||
{
|
||||
return GetZoomToExtentsShiftDistance(boundingBox.GetCorners());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit)
|
||||
/// operation,
|
||||
/// so all the passed points will fit in the current view.
|
||||
/// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <returns>The zoom to fit vector</returns>
|
||||
@@ -845,10 +747,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit)
|
||||
/// operation,
|
||||
/// so all the passed points will fit in the current view.
|
||||
/// </summary>
|
||||
/// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit) operation, so all the passed points will fit in the current view.</summary>
|
||||
/// <param name="boundingBox">The bounding box.</param>
|
||||
/// <returns>The zoom to fit vector</returns>
|
||||
public Vector3 GetZoomToExtentsShiftVector(ref BoundingBox boundingBox)
|
||||
@@ -859,9 +758,6 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Indicate whether the current BoundingFrustum is Orthographic.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the current BoundingFrustum is Orthographic; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsOrthographic => (pLeft.Normal == -pRight.Normal) && (pTop.Normal == -pBottom.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user