/// <summary> /// CollDetectBoxStaticMeshOverlap /// </summary> /// <param name="oldBox"></param> /// <param name="newBox"></param> /// <param name="mesh"></param> /// <param name="info"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> /// <returns>bool</returns> private static bool CollDetectBoxStaticMeshOverlap(Box oldBox, Box newBox, TriangleMesh mesh, ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { float boxRadius = newBox.GetBoundingRadiusAroundCentre(); #region REFERENCE: Vector3 boxCentre = newBox.GetCentre(); Vector3 boxCentre; newBox.GetCentre(out boxCentre); // Deano need to trasnform the box center into mesh space Matrix invTransformMatrix = mesh.InverseTransformMatrix; Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre); #endregion BoundingBox bb = BoundingBoxHelper.InitialBox; BoundingBoxHelper.AddBox(newBox, ref bb); bool collision = false; int[] potTriArray = IntStackAlloc(); // aabox is done in mesh space and handles the mesh transform correctly int numTriangles = mesh.GetTrianglesIntersectingtAABox(potTriArray, MaxLocalStackTris, ref bb); for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle) { IndexedTriangle meshTriangle = mesh.GetTriangle(potTriArray[iTriangle]); // quick early test is done in mesh space float dist = meshTriangle.Plane.DotCoordinate(boxCentre); // BEN-BUG-FIX: Fixed by chaning 0.0F to -boxRadius. if (dist > boxRadius || dist < -boxRadius) { continue; } if (DoOverlapBoxTriangleTest( oldBox, newBox, ref meshTriangle, mesh, ref info, collTolerance, collisionFunctor)) { collision = true; } } FreeStackAlloc(potTriArray); return(collision); }
private static void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { var mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh; var oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box; var newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box; oldBox.GetCentre(out var oldCentre); newBox.GetCentre(out var newCentre); Vector3.Subtract(ref newCentre, ref oldCentre, out var delta); var boxMinLen = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z)); var nPositions = 1 + (int)(delta.Length() / boxMinLen); if (nPositions > 50) { System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test"); nPositions = 50; } if (nPositions == 1) { CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor); } else { var bb = BoundingBoxHelper.InitialBox; BoundingBoxHelper.AddBox(oldBox, ref bb); BoundingBoxHelper.AddBox(newBox, ref bb); unsafe { var potentialTriangles = stackalloc int[MaxLocalStackTris]; { var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb); if (numTriangles <= 0) { return; } for (var i = 0; i <= nPositions; ++i) { var frac = (float)i / nPositions; Vector3.Multiply(ref delta, frac, out var centre); Vector3.Add(ref centre, ref oldCentre, out centre); var orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac)); var box = new Box(centre - 0.5f * Vector3.TransformNormal(newBox.SideLengths, orient), orient, newBox.SideLengths); CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor); } } } } }
private static bool CollDetectBoxStaticMeshOverlap(Box oldBox, Box newBox, TriangleMesh mesh, ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { var boxRadius = newBox.GetBoundingRadiusAroundCentre(); newBox.GetCentre(out var boxCentre); var invTransformMatrix = mesh.InverseTransformMatrix; Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre); var bb = BoundingBoxHelper.InitialBox; BoundingBoxHelper.AddBox(newBox, ref bb); unsafe { var collision = false; var potentialTriangles = stackalloc int[MaxLocalStackTris]; { var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb); for (var iTriangle = 0; iTriangle < numTriangles; ++iTriangle) { var meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]); var dist = meshTriangle.Plane.DotCoordinate(boxCentre); if (dist > boxRadius || dist < -boxRadius) { continue; } if (DoOverlapBoxTriangleTest(oldBox, newBox, ref meshTriangle, mesh, ref info, collTolerance, collisionFunctor)) { collision = true; } } } return(collision); } }
private void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { // todo - proper swept test // note - mesh is static and its triangles are in world space TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh; Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box; Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box; Vector3 oldCentre; oldBox.GetCentre(out oldCentre); Vector3 newCentre; newBox.GetCentre(out newCentre); Vector3 delta; Vector3.Subtract(ref newCentre, ref oldCentre, out delta); float boxMinLen = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z)); int nPositions = 1 + (int)(delta.Length() / boxMinLen); // limit the max positions... if (nPositions > 50) { System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test"); nPositions = 50; } if (nPositions == 1) { CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor); } else { BoundingBox bb = BoundingBoxHelper.InitialBox; BoundingBoxHelper.AddBox(oldBox, ref bb); BoundingBoxHelper.AddBox(newBox, ref bb); unsafe { #if USE_STACKALLOC int *potentialTriangles = stackalloc int[MaxLocalStackTris]; { #else int[] potTriArray = IntStackAlloc(); fixed(int *potentialTriangles = potTriArray) { #endif int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb); if (numTriangles > 0) { for (int i = 0; i <= nPositions; ++i) { float frac = ((float)i) / nPositions; Vector3 centre; Vector3.Multiply(ref delta, frac, out centre); Vector3.Add(ref centre, ref oldCentre, out centre); Matrix orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac)); Box box = new Box(centre - 0.5f * Vector3.Transform(newBox.SideLengths, orient), orient, newBox.SideLengths); // ideally we'd break if we get one collision... but that stops us getting multiple collisions // when we enter a corner (two walls meeting) - can let us pass through CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor); } } #if USE_STACKALLOC } #else } FreeStackAlloc(potTriArray); #endif } } }