More cleanups of custom classes in favor of .NET runtime types.

This commit is contained in:
hondacrx
2021-11-15 18:04:57 -05:00
parent a9a51d0641
commit b026ee7ef8
132 changed files with 373 additions and 6833 deletions
@@ -19,6 +19,7 @@ using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using System.Runtime.InteropServices;
namespace Game.Collision
@@ -76,12 +77,12 @@ namespace Game.Collision
Vector3 d = gridBox.hi - gridBox.lo;
for (int i = 0; i < 3; i++)
{
if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
if (nodeBox.hi.GetAt(i) < gridBox.lo.GetAt(i) || nodeBox.lo.GetAt(i) > gridBox.hi.GetAt(i))
Log.outError(LogFilter.Server, "Reached tree area in error - discarding node with: {0} objects", right - left + 1);
}
// find longest axis
axis = (int)d.primaryAxis();
split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
split = 0.5f * (gridBox.lo.GetAt(axis) + gridBox.hi.GetAt(axis));
// partition L/R subsets
clipL = float.NegativeInfinity;
clipR = float.PositiveInfinity;
@@ -91,8 +92,8 @@ namespace Game.Collision
for (int i = left; i <= right; )
{
int obj = (int)dat.indices[i];
float minb = dat.primBound[obj].Lo[axis];
float maxb = dat.primBound[obj].Hi[axis];
float minb = dat.primBound[obj].Lo.GetAt(axis);
float maxb = dat.primBound[obj].Hi.GetAt(axis);
float center = (minb + maxb) * 0.5f;
if (center <= split)
{
@@ -115,9 +116,9 @@ namespace Game.Collision
nodeR = Math.Max(nodeR, maxb);
}
// check for empty space
if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
if (nodeL > nodeBox.lo.GetAt(axis) && nodeR < nodeBox.hi.GetAt(axis))
{
float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
float nodeBoxW = nodeBox.hi.GetAt(axis) - nodeBox.lo.GetAt(axis);
float nodeNewW = nodeR - nodeL;
// node box is too big compare to space occupied by primitives?
if (1.3f * nodeNewW < nodeBoxW)
@@ -134,8 +135,8 @@ namespace Game.Collision
tempTree[nodeIndex + 1] = FloatToRawIntBits(nodeL);
tempTree[nodeIndex + 2] = FloatToRawIntBits(nodeR);
// update nodebox and recurse
nodeBox.lo[axis] = nodeL;
nodeBox.hi[axis] = nodeR;
nodeBox.lo.SetAt(nodeL, axis);
nodeBox.hi.SetAt(nodeR, axis);
Subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex1, depth + 1, stats);
return;
}
@@ -154,12 +155,12 @@ namespace Game.Collision
if (clipL <= split)
{
// keep looping on left half
gridBox.hi[axis] = split;
gridBox.hi.SetAt(split, axis);
prevClip = clipL;
wasLeft = true;
continue;
}
gridBox.hi[axis] = split;
gridBox.hi.SetAt(split, axis);
prevClip = float.NaN;
}
else if (left > right)
@@ -177,12 +178,12 @@ namespace Game.Collision
if (clipR >= split)
{
// keep looping on right half
gridBox.lo[axis] = split;
gridBox.lo.SetAt(split, axis);
prevClip = clipR;
wasLeft = false;
continue;
}
gridBox.lo[axis] = split;
gridBox.lo.SetAt(split, axis);
prevClip = float.NaN;
}
else
@@ -254,9 +255,12 @@ namespace Game.Collision
AABound gridBoxR = gridBox;
AABound nodeBoxL = nodeBox;
AABound nodeBoxR = nodeBox;
gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
nodeBoxL.hi[axis] = clipL;
nodeBoxR.lo[axis] = clipR;
gridBoxR.lo.SetAt(split, axis);
gridBoxL.hi.SetAt(split, axis);
nodeBoxL.hi.SetAt(clipL, axis);
nodeBoxR.lo.SetAt(clipR, axis);
// recurse
if (nl > 0)
Subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
@@ -325,11 +329,11 @@ namespace Game.Collision
Vector3 invDir = new();
for (int i = 0; i < 3; ++i)
{
invDir[i] = 1.0f / dir[i];
if (MathFunctions.fuzzyNe(dir[i], 0.0f))
invDir.SetAt(1.0f / dir.GetAt(i), i);
if (MathFunctions.fuzzyNe(dir.GetAt(i), 0.0f))
{
float t1 = (bounds.Lo[i] - org[i]) * invDir[i];
float t2 = (bounds.Hi[i] - org[i]) * invDir[i];
float t1 = (bounds.Lo.GetAt(i) - org.GetAt(i)) * invDir.GetAt(i);
float t2 = (bounds.Hi.GetAt(i) - org.GetAt(i)) * invDir.GetAt(i);
if (t1 > t2)
MathFunctions.Swap<float>(ref t1, ref t2);
if (t1 > intervalMin)
@@ -356,7 +360,7 @@ namespace Game.Collision
for (int i = 0; i < 3; ++i)
{
offsetFront[i] = FloatToRawIntBits(dir[i]) >> 31;
offsetFront[i] = FloatToRawIntBits(dir.GetAt(i)) >> 31;
offsetBack[i] = offsetFront[i] ^ 1;
offsetFront3[i] = offsetFront[i] * 3;
offsetBack3[i] = offsetBack[i] * 3;
@@ -383,8 +387,8 @@ namespace Game.Collision
if (axis < 3)
{
// "normal" interior node
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org.GetAt(axis)) * invDir.GetAt(axis);
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org.GetAt(axis)) * invDir.GetAt(axis);
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break;
@@ -432,8 +436,8 @@ namespace Game.Collision
{
if (axis > 2)
return; // should not happen
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org.GetAt(axis)) * invDir.GetAt(axis);
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org.GetAt(axis)) * invDir.GetAt(axis);
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
@@ -484,18 +488,18 @@ namespace Game.Collision
float tl = IntBitsToFloat(tree[node + 1]);
float tr = IntBitsToFloat(tree[node + 2]);
// point is between clip zones
if (tl < p[(int)axis] && tr > p[axis])
if (tl < p.GetAt(axis) && tr > p.GetAt(axis))
break;
int right = offset + 3;
node = right;
// point is in right node only
if (tl < p[(int)axis])
if (tl < p.GetAt(axis))
{
continue;
}
node = offset; // left
// point is in left node only
if (tr > p[axis])
if (tr > p.GetAt(axis))
{
continue;
}
@@ -525,7 +529,7 @@ namespace Game.Collision
float tl = IntBitsToFloat(tree[node + 1]);
float tr = IntBitsToFloat(tree[node + 2]);
node = offset;
if (tl > p[axis] || tr < p[axis])
if (tl > p.GetAt(axis) || tr < p.GetAt(axis))
break;
continue;
}
@@ -17,6 +17,7 @@
using Framework.GameMath;
using System.Collections.Generic;
using System.Numerics;
namespace Game.Collision
{
+10 -9
View File
@@ -19,6 +19,7 @@ using Framework.Constants;
using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Game.Collision
{
@@ -43,8 +44,8 @@ namespace Game.Collision
Vector3 lo = vertices[(int)tri.idx0];
Vector3 hi = lo;
lo = (lo.Min(vertices[(int)tri.idx1])).Min(vertices[(int)tri.idx2]);
hi = (hi.Max(vertices[(int)tri.idx1])).Max(vertices[(int)tri.idx2]);
lo = Vector3.Min(Vector3.Min(lo, vertices[(int)tri.idx1]), vertices[(int)tri.idx2]);
hi = Vector3.Max(Vector3.Max(hi, vertices[(int)tri.idx1]), vertices[(int)tri.idx2]);
value = new AxisAlignedBox(lo, hi);
}
@@ -119,8 +120,8 @@ namespace Game.Collision
Vector3 e1 = points[(int)tri.idx1] - points[(int)tri.idx0];
Vector3 e2 = points[(int)tri.idx2] - points[(int)tri.idx0];
Vector3 p = new(ray.Direction.cross(e2));
float a = e1.dot(p);
Vector3 p = Vector3.Cross(ray.Direction, e2);
float a = Vector3.Dot(e1, p);
if (Math.Abs(a) < EPS)
{
@@ -129,8 +130,8 @@ namespace Game.Collision
}
float f = 1.0f / a;
Vector3 s = new(ray.Origin - points[(int)tri.idx0]);
float u = f * s.dot(p);
Vector3 s = ray.Origin - points[(int)tri.idx0];
float u = f * Vector3.Dot(s, p);
if ((u < 0.0f) || (u > 1.0f))
{
@@ -138,8 +139,8 @@ namespace Game.Collision
return false;
}
Vector3 q = new(s.cross(e1));
float v = f * ray.Direction.dot(q);
Vector3 q = Vector3.Cross(s, e1);
float v = f * Vector3.Dot(ray.Direction, q);
if ((v < 0.0f) || ((u + v) > 1.0f))
{
@@ -147,7 +148,7 @@ namespace Game.Collision
return false;
}
float t = f * e2.dot(q);
float t = f * Vector3.Dot(e2, q);
if ((t > 0.0f) && (t < distance))
{
+4 -3
View File
@@ -16,6 +16,7 @@
*/
using Framework.GameMath;
using System.Numerics;
namespace Game.Collision
{
@@ -64,7 +65,7 @@ namespace Game.Collision
public bool GetObjectHitPos(Vector3 startPos, Vector3 endPos, ref Vector3 resultHitPos, float modifyDist, PhaseShift phaseShift)
{
bool result;
float maxDist = (endPos - startPos).magnitude();
float maxDist = (endPos - startPos).Length();
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
Cypher.Assert(maxDist < float.MaxValue);
// prevent NaN values which can cause BIH intersection to enter infinite loop
@@ -81,7 +82,7 @@ namespace Game.Collision
resultHitPos = startPos + dir * dist;
if (modifyDist < 0)
{
if ((resultHitPos - startPos).magnitude() > -modifyDist)
if ((resultHitPos - startPos).Length() > -modifyDist)
resultHitPos += dir * modifyDist;
else
resultHitPos = startPos;
@@ -101,7 +102,7 @@ namespace Game.Collision
public bool IsInLineOfSight(Vector3 startPos, Vector3 endPos, PhaseShift phaseShift)
{
float maxDist = (endPos - startPos).magnitude();
float maxDist = (endPos - startPos).Length();
if (!MathFunctions.fuzzyGt(maxDist, 0))
return true;
@@ -16,10 +16,10 @@
*/
using Framework.Constants;
using Framework.GameMath;
using Framework.Dynamic;
using System;
using System.Collections.Generic;
using Framework.Dynamic;
using System.Numerics;
namespace Game.Collision
{
+4 -3
View File
@@ -20,6 +20,7 @@ using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
namespace Game.Collision
{
@@ -346,7 +347,7 @@ namespace Game.Collision
public bool GetObjectHitPos(Vector3 pPos1, Vector3 pPos2, out Vector3 pResultHitPos, float pModifyDist)
{
bool result;
float maxDist = (pPos2 - pPos1).magnitude();
float maxDist = (pPos2 - pPos1).Length();
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
Cypher.Assert(maxDist < float.MaxValue);
// prevent NaN values which can cause BIH intersection to enter infinite loop
@@ -363,7 +364,7 @@ namespace Game.Collision
pResultHitPos = pPos1 + dir * dist;
if (pModifyDist < 0)
{
if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
if ((pResultHitPos - pPos1).Length() > -pModifyDist)
{
pResultHitPos += dir * pModifyDist;
}
@@ -388,7 +389,7 @@ namespace Game.Collision
public bool IsInLineOfSight(Vector3 pos1, Vector3 pos2, ModelIgnoreFlags ignoreFlags)
{
float maxDist = (pos2 - pos1).magnitude();
float maxDist = (pos2 - pos1).Length();
// return false if distance is over max float, in case of cheater teleporting to the end of the universe
if (maxDist == float.MaxValue ||
maxDist == float.PositiveInfinity)
+18 -17
View File
@@ -15,11 +15,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.IO;
using Framework.Constants;
using System.Numerics;
namespace Game.Collision
{
@@ -64,13 +65,13 @@ namespace Game.Collision
iScale = modelOwner.GetScale();
iInvScale = 1.0f / iScale;
Matrix3 iRotation = Matrix3.fromEulerAnglesZYX(modelOwner.GetOrientation(), 0, 0);
iInvRot = iRotation.inverse();
Matrix4x4 iRotation = Extensions.fromEulerAnglesZYX(modelOwner.GetOrientation(), 0, 0);
Matrix4x4.Invert(iRotation, out iInvRot);
// transform bounding box:
mdl_box = new AxisAlignedBox(mdl_box.Lo * iScale, mdl_box.Hi * iScale);
AxisAlignedBox rotated_bounds = new();
for (int i = 0; i < 8; ++i)
rotated_bounds.merge(iRotation * mdl_box.corner(i));
rotated_bounds.merge(Vector3.Transform(mdl_box.corner(i), iRotation));
iBound = rotated_bounds + iPos;
owner = modelOwner;
@@ -100,8 +101,8 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 p = iInvRot * (ray.Origin - iPos) * iInvScale;
Ray modRay = new(p, iInvRot * ray.Direction);
Vector3 p = Vector3.Transform((ray.Origin - iPos) * iInvScale, iInvRot);
Ray modRay = new Ray(p, Vector3.Transform(ray.Direction, iInvRot));
float distance = maxDist * iInvScale;
bool hit = iModel.IntersectRay(modRay, ref distance, stopAtFirstHit, ignoreFlags);
if (hit)
@@ -124,13 +125,13 @@ namespace Game.Collision
return;
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
Vector3 zDirModel = iInvRot * new Vector3(0.0f, 0.0f, -1.0f);
Vector3 pModel = Vector3.Transform((point - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
float zDist;
if (iModel.IntersectPoint(pModel, zDirModel, out zDist, info))
{
Vector3 modelGround = pModel + zDist * zDirModel;
float world_Z = ((modelGround * iInvRot) * iScale + iPos).Z;
float world_Z = (Vector3.Transform(modelGround, iInvRot) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -151,13 +152,13 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
Vector3 zDirModel = iInvRot * new Vector3(0.0f, 0.0f, -1.0f);
Vector3 pModel = Vector3.Transform((point - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
float zDist;
if (iModel.GetLocationInfo(pModel, zDirModel, out zDist, info))
{
Vector3 modelGround = pModel + zDist * zDirModel;
float world_Z = ((modelGround * iInvRot) * iScale + iPos).Z;
float world_Z = (Vector3.Transform(modelGround, iInvRot) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -171,7 +172,7 @@ namespace Game.Collision
public bool GetLiquidLevel(Vector3 point, LocationInfo info, ref float liqHeight)
{
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
Vector3 pModel = Vector3.Transform((point - iPos) * iInvScale, iInvRot);
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
float zDist;
if (info.hitModel.GetLiquidLevel(pModel, out zDist))
@@ -203,13 +204,13 @@ namespace Game.Collision
iPos = owner.GetPosition();
Matrix3 iRotation = Matrix3.fromEulerAnglesZYX(owner.GetOrientation(), 0, 0);
iInvRot = iRotation.inverse();
Matrix4x4 iRotation = Extensions.fromEulerAnglesZYX(owner.GetOrientation(), 0, 0);
Matrix4x4.Invert(iRotation, out iInvRot);
// transform bounding box:
mdl_box = new AxisAlignedBox(mdl_box.Lo * iScale, mdl_box.Hi * iScale);
AxisAlignedBox rotated_bounds = new();
for (int i = 0; i < 8; ++i)
rotated_bounds.merge(iRotation * mdl_box.corner(i));
rotated_bounds.merge(Vector3.Transform(mdl_box.corner(i), iRotation));
iBound = rotated_bounds + iPos;
@@ -269,7 +270,7 @@ namespace Game.Collision
bool _collisionEnabled;
AxisAlignedBox iBound;
Matrix3 iInvRot;
Matrix4x4 iInvRot;
Vector3 iPos;
float iInvScale;
float iScale;
+2 -1
View File
@@ -15,8 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.GameMath;
using Framework.Constants;
using Framework.GameMath;
using System.Numerics;
namespace Game.Collision
{
+13 -11
View File
@@ -19,6 +19,7 @@ using Framework.Constants;
using Framework.GameMath;
using System;
using System.IO;
using System.Numerics;
namespace Game.Collision
{
@@ -85,7 +86,7 @@ namespace Game.Collision
public class ModelInstance : ModelMinimalData
{
Matrix3 iInvRot;
Matrix4x4 iInvRot;
float iInvScale;
WorldModel iModel;
@@ -107,7 +108,8 @@ namespace Game.Collision
iModel = model;
iInvRot = Matrix3.fromEulerAnglesZYX(MathFunctions.PI * spawn.iRot.Y / 180.0f, MathFunctions.PI * spawn.iRot.X / 180.0f, MathFunctions.PI * spawn.iRot.Z / 180.0f).inverse();
Matrix4x4.Invert(Extensions.fromEulerAnglesZYX(MathFunctions.PI * spawn.iRot.Y / 180.0f, MathFunctions.PI * spawn.iRot.X / 180.0f, MathFunctions.PI * spawn.iRot.Z / 180.0f), out iInvRot);
iInvScale = 1.0f / iScale;
}
@@ -121,8 +123,8 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 p = iInvRot * (pRay.Origin - iPos) * iInvScale;
Ray modRay = new(p, iInvRot * pRay.Direction);
Vector3 p = Vector3.Transform((pRay.Origin - iPos) * iInvScale, iInvRot);
Ray modRay = new Ray(p, Vector3.Transform(pRay.Direction, iInvRot));
float distance = pMaxDist * iInvScale;
bool hit = iModel.IntersectRay(modRay, ref distance, pStopAtFirstHit, ignoreFlags);
if (hit)
@@ -144,8 +146,8 @@ namespace Game.Collision
if (!iBound.contains(p))
return;
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
Vector3 zDirModel = iInvRot * new Vector3(0.0f, 0.0f, -1.0f);
Vector3 pModel = Vector3.Transform((p - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
float zDist;
if (iModel.IntersectPoint(pModel, zDirModel, out zDist, info))
{
@@ -153,7 +155,7 @@ namespace Game.Collision
// Transform back to world space. Note that:
// Mat * vec == vec * Mat.transpose()
// and for rotation matrices: Mat.inverse() == Mat.transpose()
float world_Z = ((modelGround * iInvRot) * iScale + iPos).Z;
float world_Z = ((Vector3.Transform(modelGround, iInvRot)) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -165,7 +167,7 @@ namespace Game.Collision
public bool GetLiquidLevel(Vector3 p, LocationInfo info, ref float liqHeight)
{
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
Vector3 pModel = Vector3.Transform((p - iPos) * iInvScale, iInvRot);
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
float zDist;
if (info.hitModel.GetLiquidLevel(pModel, out zDist))
@@ -189,8 +191,8 @@ namespace Game.Collision
if (!iBound.contains(p))
return false;
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
Vector3 zDirModel = iInvRot * new Vector3(0.0f, 0.0f, -1.0f);
Vector3 pModel = Vector3.Transform((p - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
float zDist;
if (iModel.GetLocationInfo(pModel, zDirModel, out zDist, info))
{
@@ -198,7 +200,7 @@ namespace Game.Collision
// Transform back to world space. Note that:
// Mat * vec == vec * Mat.transpose()
// and for rotation matrices: Mat.inverse() == Mat.transpose()
float world_Z = ((modelGround * iInvRot) * iScale + iPos).Z;
float world_Z = (Vector3.Transform(modelGround, iInvRot) * iScale + iPos).Z;
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
{
info.ground_Z = world_Z;
@@ -20,6 +20,7 @@ using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
namespace Game.Collision
{
+1
View File
@@ -18,6 +18,7 @@
using Framework.GameMath;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Game.Collision
{