private float Disjoint(out bool b, Vector3 axis, MyBox box, MyColDetVoxelTriangle triangle, float collTolerance) { float ret; b = Disjoint(out ret, axis, box, triangle, collTolerance); return(ret); }
// Disjoint Returns true if disjoint. Returns false if intersecting, // and sets the overlap depth, d scaled by the axis length private static bool Disjoint(out float d, Vector3 axis, MyBox box, MyColDetVoxelTriangle triangle, float collTolerance) { float min0, max0, min1, max1; box.GetSpan(out min0, out max0, axis); triangle.GetSpan(out min1, out max1, axis); if (min0 > (max1 + collTolerance) || min1 > (max0 + collTolerance)) { d = 0.0f; return(true); } if ((max0 > max1) && (min1 > min0)) { // triangleVertexes is inside - choose the min dist to move it out d = System.Math.Min(max0 - min1, max1 - min0); } else if ((max1 > max0) && (min0 > min1)) { // box is inside - choose the min dist to move it out d = System.Math.Min(max1 - min0, max0 - min1); } else { // objects overlap d = (max0 < max1) ? max0 : max1; d -= (min0 > min1) ? min0 : min1; } return(false); }
// GetBoxTriangleIntersectionPoints // Pushes intersection points onto the back of pts. Returns the // number of points found. // Points that are close together (compared to // combinationDistance) get combined private int GetBoxTriangleIntersectionPoints(List <MyCP> pts, MyBox box, MyColDetVoxelTriangle triangle, float combinationDistance) { // first intersect each edge of the box with the triangleVertexes MyBox.Edge[] edges; box.GetEdges(out edges); Vector3[] boxPts; box.GetCornerPoints(out boxPts); float tS; float tv1, tv2; int iEdge; for (iEdge = 0; iEdge < 12; ++iEdge) { MyBox.Edge edge = edges[iEdge]; MySegment seg = new MySegment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]); if (this.SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle)) { float depthA = Vector3.Dot(boxPts[(int)edge.Ind0] - seg.GetPoint(tS), triangle.Normal); float depthB = Vector3.Dot(boxPts[(int)edge.Ind1] - seg.GetPoint(tS), triangle.Normal); AddPoint(pts, seg.GetPoint(tS), triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } Vector3 pos, n; // now each edge of the triangleVertexes with the box for (iEdge = 0; iEdge < 3; ++iEdge) { Vector3 pt0 = triangle.GetPoint(iEdge); Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3); MySegment s1 = new MySegment(pt0, pt1 - pt0); MySegment s2 = new MySegment(pt1, pt0 - pt1); if (box.SegmentIntersect(out tS, out pos, out n, s1)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } if (box.SegmentIntersect(out tS, out pos, out n, s2)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } return(pts.Count); }
public bool SegmentTriangleIntersection(out float tS, out float tT0, out float tT1, MySegment seg, MyColDetVoxelTriangle triangle) { /// the parameters - if hit then they get copied into the args float u, v, t; tS = 0; tT0 = 0; tT1 = 0; Vector3 e1 = triangle.Edge0; Vector3 e2 = triangle.Edge1; Vector3 p = Vector3.Cross(seg.Delta, e2); float a = Vector3.Dot(e1, p); if (a > -MyPhysicsConfig.Epsilon && a < MyPhysicsConfig.Epsilon) { return(false); } float f = 1.0f / a; Vector3 s = seg.Origin - triangle.Origin; u = f * Vector3.Dot(s, p); if (u < 0.0f || u > 1.0f) { return(false); } Vector3 q = Vector3.Cross(s, e1); v = f * Vector3.Dot(seg.Delta, q); if (v < 0.0f || (u + v) > 1.0f) { return(false); } t = f * Vector3.Dot(e2, q); if (t < 0.0f || t > 1.0f) { return(false); } tS = t; tT0 = u; tT1 = v; //if (tS != 0) tS = t; //if (tT0 != 0) tT0 = u; //if (tT1 != 0) tT1 = v; return(true); }
public static void LoadData() { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyVoxelMaps.LoadData"); MyMwcLog.WriteLine("MyVoxelMaps.LoadData() - START"); MyMwcLog.IncreaseIndent(); m_voxelMaps.Clear(); m_voxelMapsSafeIterationHelper.Clear(); MyMwcLog.DecreaseIndent(); MyMwcLog.WriteLine("MyVoxelMaps.LoadData() - END"); for (int i = 0; i < MyVoxelConstants.MAX_POTENTIAL_COLDET_TRIANGLES_COUNT; i++) { PotentialColDetTriangles[i] = new MyColDetVoxelTriangle(); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }
protected override bool Interact(bool staticCollision) { if (staticCollision) { //MyCommonDebugUtils.AssertDebug(false, "Sphere-voxel static interaction called! And that's wrong."); } else { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("SphereVoxelInteraction"); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Transformations"); if (RBElement1.GetElementType() != MyRBElementType.ET_SPHERE) { SwapElements(); } Matrix matrix0 = RBElement1.GetGlobalTransformation(); Matrix matrix1 = RBElement2.GetGlobalTransformation(); float sphereRadius = ((MyRBSphereElement)RBElement1).Radius; Vector3 body0Pos = matrix0.Translation; // sphere pos Vector3 body1Pos = matrix1.Translation; float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; float epsylon = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon; Vector3 newBody0Pos = matrix0.Translation + GetRigidBody1().LinearVelocity *dt; float sphereTolR = epsylon + sphereRadius; float sphereTolR2 = sphereTolR * sphereTolR; MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc(); int numCollPts = 0; Vector3 collNormal = Vector3.Zero; //var colDetThroughVoxels = MyConstants.SPHERE_VOXELMAP_COLDET_THROUGH_VOXELS; var colDetThroughVoxels = !GetRigidBody1().ReadFlag(RigidBodyFlag.RBF_COLDET_THROUGH_VOXEL_TRIANGLES); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); if (colDetThroughVoxels) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("colDetThroughVoxels"); BoundingSphere newSphere; newSphere.Center = newBody0Pos; newSphere.Radius = sphereRadius; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PoolList.Get"); using (var voxelMapsFounded = PoolList <MyVoxelMap> .Get()) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere"); MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref newSphere, voxelMapsFounded, null); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("foreach (MyVoxelMap voxelMap in voxelMapsFounded)"); foreach (MyVoxelMap voxelMap in voxelMapsFounded) { if (voxelMap != null) { // We will iterate only voxels contained in the bounding box of new sphere, so here we get min/max corned in voxel units MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3( newSphere.Center.X - newSphere.Radius, newSphere.Center.Y - newSphere.Radius, newSphere.Center.Z - newSphere.Radius)); MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3( newSphere.Center.X + newSphere.Radius, newSphere.Center.Y + newSphere.Radius, newSphere.Center.Z + newSphere.Radius)); voxelMap.FixVoxelCoord(ref minCorner); voxelMap.FixVoxelCoord(ref maxCorner); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("for loop"); MyMwcVector3Int tempVoxelCoord; for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++) { for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++) { for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++) { byte voxelContent = voxelMap.GetVoxelContent(ref tempVoxelCoord); // Ignore voxels bellow the ISO value (empty, partialy empty...) if (voxelContent < MyVoxelConstants.VOXEL_ISO_LEVEL) { continue; } Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord); //float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF; float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_RADIUS; // If distance to voxel border is less than sphere radius, we have a collision // So now we calculate normal vector and penetration depth but on OLD sphere float newDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize; if (newDistanceToVoxel < (epsylon + newSphere.Radius)) { Vector3 collisionN = MyMwcUtils.Normalize(voxelPosition - body0Pos); if (numCollPts < MyPhysicsConfig.MaxContactPoints) { // Calculate penetration depth, but from old sphere (not new) float oldDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize; float oldPenetrationDepth = oldDistanceToVoxel - sphereRadius; // Vector3 pt = body0Pos + sphereRadius * collisionN; Vector3 pt = voxelPosition - collisionN * (voxelSize - epsylon); collPtArray[numCollPts++] = new MySmallCollPointInfo(pt - body0Pos, pt - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, oldPenetrationDepth, pt); } collNormal -= collisionN; } } } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } else //if (colDetThroughVoxels) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ColDet triangles"); int optimalIterationCount = (int)(GetRigidBody1().LinearVelocity.Length() * dt / sphereRadius); int maxIndex = (int)MathHelper.Min(MathHelper.Max(optimalIterationCount, 1), 16); for (int i = 0; i < maxIndex; i++) { float velocityAdd = GetRigidBody1().LinearVelocity.Length() * dt / (float)maxIndex; Vector3 interpolatedPosition = body0Pos + GetRigidBody1().LinearVelocity *dt *i / (float)maxIndex; BoundingSphere newSphere; newSphere.Center = interpolatedPosition; newSphere.Radius = sphereRadius; int numTriangles; BoundingBox bb = BoundingBox.CreateFromSphere(newSphere); MyVoxelMaps.GetPotentialTrianglesForColDet(out numTriangles, ref bb); for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle) { MyColDetVoxelTriangle meshTriangle = MyVoxelMaps.PotentialColDetTriangles[iTriangle]; // mesh.GetTriangle(potentialTriangles[iTriangle]); MyTriangle_Vertex_Normal triangle = new MyTriangle_Vertex_Normal(); triangle.Vertexes.Vertex0 = meshTriangle.Vertex0; triangle.Vertexes.Vertex1 = meshTriangle.Vertex1; triangle.Vertexes.Vertex2 = meshTriangle.Vertex2; // skip too narrow triangles causing instability if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon) { continue; } if ((triangle.Vertexes.Vertex1 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon) { continue; } if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon) { continue; } MyPlane plane = new MyPlane(ref triangle.Vertexes); Vector3?pt = MyUtils.GetSphereTriangleIntersection(ref newSphere, ref plane, ref triangle.Vertexes); if (pt == null) { continue; } Vector3 collisionN = plane.Normal; // skip triangle in case the normal is in wrong dir (narrow walls) Vector3 tempV = (newBody0Pos - pt.Value); if (Vector3.Dot(collisionN, tempV) >= 0.8f * tempV.Length()) // equivalent to dot(collisionN, normalize(tempV)) > 0.8f, but works for zero vectors { continue; } float depth = Vector3.Distance(pt.Value, body0Pos) - sphereRadius; if (numCollPts < MyPhysicsConfig.MaxContactPoints) { // since impulse get applied at the old position Vector3 p2 = pt.Value; collPtArray[numCollPts++] = new MySmallCollPointInfo(p2 - body0Pos, p2 - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, depth, p2); } collNormal += collisionN; } } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } if (numCollPts > 0) { MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numCollPts); } MyContactInfoCache.FreeStackAlloc(collPtArray); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } return(false); }
private bool DoOverlapBoxTriangleTest(MyBox box, ref MyColDetVoxelTriangle triangle) { Matrix dirs0 = box.Orientation; Vector3 triEdge0; Vector3 triEdge1; Vector3 triEdge2; triEdge0 = MyMwcUtils.Normalize(triangle.Edge0); triEdge1 = MyMwcUtils.Normalize(triangle.Edge1); triEdge2 = MyMwcUtils.Normalize(triangle.Edge2); Vector3 triNormal = triangle.Plane.Normal; // the 15 potential separating axes (comment by Marek Rosa: note says 15 but code uses 13... I don't know why, mistake in the note??) const int NUM_AXES = 13; MyVector3Array13 axes = new MyVector3Array13(); axes[0] = triNormal; axes[1] = dirs0.Right; axes[2] = dirs0.Up; axes[3] = dirs0.Backward; axes[4] = Vector3.Cross(axes[1], triEdge0); axes[5] = Vector3.Cross(axes[1], triEdge1); axes[6] = Vector3.Cross(axes[1], triEdge2); axes[7] = Vector3.Cross(axes[2], triEdge0); axes[8] = Vector3.Cross(axes[2], triEdge1); axes[9] = Vector3.Cross(axes[2], triEdge2); axes[10] = Vector3.Cross(axes[3], triEdge0); axes[11] = Vector3.Cross(axes[3], triEdge1); axes[12] = Vector3.Cross(axes[3], triEdge2); // the overlap depths along each axis MyFloatArray13 overlapDepths = new MyFloatArray13(); // see if the boxes are separate along any axis, and if not keep a // record of the depths along each axis int i; for (i = 0; i < NUM_AXES; ++i) { overlapDepths[i] = 1.0f; bool b; overlapDepths[i] = Disjoint(out b, axes[i], box, triangle, MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon); if (b) { return(false); } } // The box overlap, find the separation depth closest to 0. float minDepth = float.MaxValue; int minAxis = -1; for (i = 0; i < NUM_AXES; ++i) { // If we can't normalise the axis, skip it float l2 = axes[i].LengthSquared(); if (l2 < MyPhysicsConfig.Epsilon) { continue; } // Normalise the separation axis and the depth float invl = 1.0f / (float)System.Math.Sqrt(l2); axes[i] *= invl; overlapDepths[i] *= invl; // If this axis is the minimum, select it if (overlapDepths[i] < minDepth) { minDepth = overlapDepths[i]; minAxis = i; } } if (minAxis == -1) { return(false); } // Make sure the axis is facing towards the 0th box. // if not, invert it Vector3 D = box.GetCentre() - triangle.Centre; Vector3 N = axes[minAxis]; float depth = overlapDepths[minAxis]; if (Vector3.Dot(D, N) < 0.0f) { N *= -1; } MyRigidBody rbo0 = GetRigidBody1(); MyRigidBody rbo1 = GetRigidBody2(); float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; Vector3 boxOldPos = rbo0.Position; Vector3 boxNewPos = rbo0.Position + rbo0.LinearVelocity * dt; Vector3 meshPos = rbo1.Position; m_CPList.Clear(); GetBoxTriangleIntersectionPoints(m_CPList, box, triangle, MyPhysicsConfig.CollisionEpsilon); // adjust the depth #region delta Vector3 delta; Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta); #endregion // report collisions int numPts = m_CPList.Count; MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc(); { if (numPts > 0) { if (numPts >= MyPhysicsConfig.MaxContactPoints) { numPts = MyPhysicsConfig.MaxContactPoints - 1; } // adjust positions for (i = 0; i < numPts; ++i) { collPtArray[i] = new MySmallCollPointInfo(m_CPList[i].m_Position - boxOldPos, m_CPList[i].m_Position - meshPos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, m_CPList[i].m_Normal, m_CPList[i].m_Depth, m_CPList[i].m_Position); } MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numPts); MyContactInfoCache.FreeStackAlloc(collPtArray); return(true); } else { MyContactInfoCache.FreeStackAlloc(collPtArray); return(false); } } }
private bool DoOverlapBoxTriangleTest(MyBox box, ref MyColDetVoxelTriangle triangle) { Matrix dirs0 = box.Orientation; Vector3 triEdge0; Vector3 triEdge1; Vector3 triEdge2; triEdge0 = MyMwcUtils.Normalize(triangle.Edge0); triEdge1 = MyMwcUtils.Normalize(triangle.Edge1); triEdge2 = MyMwcUtils.Normalize(triangle.Edge2); Vector3 triNormal = triangle.Plane.Normal; // the 15 potential separating axes (comment by Marek Rosa: note says 15 but code uses 13... I don't know why, mistake in the note??) const int NUM_AXES = 13; MyVector3Array13 axes = new MyVector3Array13(); axes[0] = triNormal; axes[1] = dirs0.Right; axes[2] = dirs0.Up; axes[3] = dirs0.Backward; axes[4] = Vector3.Cross(axes[1], triEdge0); axes[5] = Vector3.Cross(axes[1], triEdge1); axes[6] = Vector3.Cross(axes[1], triEdge2); axes[7] = Vector3.Cross(axes[2], triEdge0); axes[8] = Vector3.Cross(axes[2], triEdge1); axes[9] = Vector3.Cross(axes[2], triEdge2); axes[10] = Vector3.Cross(axes[3], triEdge0); axes[11] = Vector3.Cross(axes[3], triEdge1); axes[12] = Vector3.Cross(axes[3], triEdge2); // the overlap depths along each axis MyFloatArray13 overlapDepths = new MyFloatArray13(); // see if the boxes are separate along any axis, and if not keep a // record of the depths along each axis int i; for (i = 0; i < NUM_AXES; ++i) { overlapDepths[i] = 1.0f; bool b; overlapDepths[i] = Disjoint(out b, axes[i], box, triangle, MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon); if (b) return false; } // The box overlap, find the separation depth closest to 0. float minDepth = float.MaxValue; int minAxis = -1; for (i = 0; i < NUM_AXES; ++i) { // If we can't normalise the axis, skip it float l2 = axes[i].LengthSquared(); if (l2 < MyPhysicsConfig.Epsilon) continue; // Normalise the separation axis and the depth float invl = 1.0f / (float)System.Math.Sqrt(l2); axes[i] *= invl; overlapDepths[i] *= invl; // If this axis is the minimum, select it if (overlapDepths[i] < minDepth) { minDepth = overlapDepths[i]; minAxis = i; } } if (minAxis == -1) return false; // Make sure the axis is facing towards the 0th box. // if not, invert it Vector3 D = box.GetCentre() - triangle.Centre; Vector3 N = axes[minAxis]; float depth = overlapDepths[minAxis]; if (Vector3.Dot(D, N) < 0.0f) N *= -1; MyRigidBody rbo0 = GetRigidBody1(); MyRigidBody rbo1 = GetRigidBody2(); float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; Vector3 boxOldPos = rbo0.Position; Vector3 boxNewPos = rbo0.Position + rbo0.LinearVelocity * dt; Vector3 meshPos = rbo1.Position; m_CPList.Clear(); GetBoxTriangleIntersectionPoints(m_CPList, box, triangle, MyPhysicsConfig.CollisionEpsilon); // adjust the depth #region delta Vector3 delta; Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta); #endregion // report collisions int numPts = m_CPList.Count; MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc(); { if (numPts > 0) { if (numPts >= MyPhysicsConfig.MaxContactPoints) { numPts = MyPhysicsConfig.MaxContactPoints - 1; } // adjust positions for (i = 0; i < numPts; ++i) { collPtArray[i] = new MySmallCollPointInfo(m_CPList[i].m_Position - boxOldPos, m_CPList[i].m_Position - meshPos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, m_CPList[i].m_Normal, m_CPList[i].m_Depth, m_CPList[i].m_Position); } MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numPts); MyContactInfoCache.FreeStackAlloc(collPtArray); return true; } else { MyContactInfoCache.FreeStackAlloc(collPtArray); return false; } } }
public bool SegmentTriangleIntersection(out float tS, out float tT0, out float tT1, MySegment seg, MyColDetVoxelTriangle triangle) { /// the parameters - if hit then they get copied into the args float u, v, t; tS = 0; tT0 = 0; tT1 = 0; Vector3 e1 = triangle.Edge0; Vector3 e2 = triangle.Edge1; Vector3 p = Vector3.Cross(seg.Delta, e2); float a = Vector3.Dot(e1, p); if (a > -MyPhysicsConfig.Epsilon && a < MyPhysicsConfig.Epsilon) return false; float f = 1.0f / a; Vector3 s = seg.Origin - triangle.Origin; u = f * Vector3.Dot(s, p); if (u < 0.0f || u > 1.0f) return false; Vector3 q = Vector3.Cross(s, e1); v = f * Vector3.Dot(seg.Delta, q); if (v < 0.0f || (u + v) > 1.0f) return false; t = f * Vector3.Dot(e2, q); if (t < 0.0f || t > 1.0f) return false; tS = t; tT0 = u; tT1 = v; //if (tS != 0) tS = t; //if (tT0 != 0) tT0 = u; //if (tT1 != 0) tT1 = v; return true; }
private bool DoOverlapBoxTriangleStaticTest(MyBox box, ref MyColDetVoxelTriangle triangle) { Matrix dirs0 = box.Orientation; #region triEdge0 Vector3 pt0; Vector3 pt1; triangle.GetPoint(0, out pt0); triangle.GetPoint(1, out pt1); Vector3 triEdge0; Vector3.Subtract(ref pt1, ref pt0, out triEdge0); if (triEdge0.LengthSquared() < MyPhysicsConfig.Epsilon) { return(false); } #endregion #region triEdge1 Vector3 pt2; triangle.GetPoint(2, out pt2); Vector3 triEdge1; Vector3.Subtract(ref pt2, ref pt1, out triEdge1); if (triEdge1.LengthSquared() < MyPhysicsConfig.Epsilon) { return(false); } #endregion #region triEdge2 Vector3 triEdge2; Vector3.Subtract(ref pt0, ref pt2, out triEdge2); if (triEdge2.LengthSquared() < MyPhysicsConfig.Epsilon) { return(false); } #endregion triEdge0.Normalize(); triEdge1.Normalize(); triEdge2.Normalize(); Vector3 triNormal = triangle.Plane.Normal; m_axes[0] = triNormal; m_axes[1] = dirs0.Right; m_axes[2] = dirs0.Up; m_axes[3] = dirs0.Backward; Vector3.Cross(ref m_axes[1], ref triEdge0, out m_axes[4]); Vector3.Cross(ref m_axes[1], ref triEdge1, out m_axes[5]); Vector3.Cross(ref m_axes[1], ref triEdge2, out m_axes[6]); Vector3.Cross(ref m_axes[2], ref triEdge0, out m_axes[7]); Vector3.Cross(ref m_axes[2], ref triEdge1, out m_axes[8]); Vector3.Cross(ref m_axes[2], ref triEdge2, out m_axes[9]); Vector3.Cross(ref m_axes[3], ref triEdge0, out m_axes[10]); Vector3.Cross(ref m_axes[3], ref triEdge1, out m_axes[11]); Vector3.Cross(ref m_axes[3], ref triEdge2, out m_axes[12]); // the overlap depths along each axis // see if the boxes are separate along any axis, and if not keep a // record of the depths along each axis int i; for (i = 0; i < numAxes; ++i) { m_overlapDepths[i] = 1.0f; if (Disjoint(out m_overlapDepths[i], m_axes[i], box, triangle, MyPhysicsConfig.CollisionEpsilon)) { return(false); } } // The box overlap, find the separation depth closest to 0. float minDepth = float.MaxValue; int minAxis = -1; for (i = 0; i < numAxes; ++i) { // If we can't normalise the axis, skip it float l2 = m_axes[i].LengthSquared(); if (l2 < MyPhysicsConfig.Epsilon) { continue; } // Normalise the separation axis and the depth float invl = 1.0f / (float)System.Math.Sqrt(l2); m_axes[i] *= invl; m_overlapDepths[i] *= invl; // If this axis is the minimum, select it if (m_overlapDepths[i] < minDepth) { minDepth = m_overlapDepths[i]; minAxis = i; } } if (minAxis == -1) { return(false); } // Make sure the axis is facing towards the 0th box. // if not, invert it Vector3 D = box.GetCentre() - triangle.Centre; Vector3 N = m_axes[minAxis]; float depth = m_overlapDepths[minAxis]; if (Vector3.Dot(D, N) < 0.0f) { N *= -1; } MyRigidBody rbo0 = GetRigidBody1(); MyRigidBody rbo1 = GetRigidBody2(); float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; Vector3 boxOldPos = rbo0.Position; Vector3 boxNewPos = rbo0.Position + rbo0.LinearVelocity * dt; Vector3 meshPos = rbo1.Position; m_CPList.Clear(); GetBoxTriangleIntersectionPoints(m_CPList, box, triangle, MyPhysicsConfig.CollisionEpsilon); // adjust the depth #region delta Vector3 delta; Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta); #endregion int numPts = m_CPList.Count; if (numPts > 0) { return(true); } else { return(false); } }
// GetBoxTriangleIntersectionPoints // Pushes intersection points onto the back of pts. Returns the // number of points found. // Points that are close together (compared to // combinationDistance) get combined private int GetBoxTriangleIntersectionPoints(List<MyCP> pts, MyBox box, MyColDetVoxelTriangle triangle, float combinationDistance) { // first intersect each edge of the box with the triangleVertexes MyBox.Edge[] edges; box.GetEdges(out edges); Vector3[] boxPts; box.GetCornerPoints(out boxPts); float tS; float tv1, tv2; int iEdge; for (iEdge = 0; iEdge < 12; ++iEdge) { MyBox.Edge edge = edges[iEdge]; MySegment seg = new MySegment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]); if (this.SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle)) { float depthA = Vector3.Dot(boxPts[(int)edge.Ind0] - seg.GetPoint(tS), triangle.Normal); float depthB = Vector3.Dot(boxPts[(int)edge.Ind1] - seg.GetPoint(tS), triangle.Normal); AddPoint(pts, seg.GetPoint(tS),triangle.Normal, depthA < depthB ? depthA : depthB , combinationDistance * combinationDistance); } } Vector3 pos, n; // now each edge of the triangleVertexes with the box for (iEdge = 0; iEdge < 3; ++iEdge) { Vector3 pt0 = triangle.GetPoint(iEdge); Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3); MySegment s1 = new MySegment(pt0, pt1 - pt0); MySegment s2 = new MySegment(pt1, pt0 - pt1); if (box.SegmentIntersect(out tS, out pos, out n, s1)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } if (box.SegmentIntersect(out tS, out pos, out n, s2)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } return pts.Count; }
// Disjoint Returns true if disjoint. Returns false if intersecting, // and sets the overlap depth, d scaled by the axis length private static bool Disjoint(out float d, Vector3 axis, MyBox box, MyColDetVoxelTriangle triangle, float collTolerance) { float min0, max0, min1, max1; box.GetSpan(out min0, out max0, axis); triangle.GetSpan(out min1, out max1, axis); if (min0 > (max1 + collTolerance ) || min1 > (max0 + collTolerance )) { d = 0.0f; return true; } if ((max0 > max1) && (min1 > min0)) { // triangleVertexes is inside - choose the min dist to move it out d = System.Math.Min(max0 - min1, max1 - min0); } else if ((max1 > max0) && (min0 > min1)) { // box is inside - choose the min dist to move it out d = System.Math.Min(max1 - min0, max0 - min1); } else { // objects overlap d = (max0 < max1) ? max0 : max1; d -= (min0 > min1) ? min0 : min1; } return false; }
private float Disjoint(out bool b, Vector3 axis, MyBox box, MyColDetVoxelTriangle triangle, float collTolerance) { float ret; b = Disjoint(out ret, axis, box, triangle, collTolerance); return ret; }
/// <summary> /// point vs Voxel triangle distancesq /// </summary> public static float PointColDetVoxelTriangleDistanceSq(out float pfSParam, out float pfTParam, Vector3 rkPoint, MyColDetVoxelTriangle rkTri) { Vector3 kDiff = rkTri.Origin - rkPoint; float fA00 = rkTri.Edge0.LengthSquared(); float fA01 = Vector3.Dot(rkTri.Edge0, rkTri.Edge1); float fA11 = rkTri.Edge1.LengthSquared(); float fB0 = Vector3.Dot(kDiff, rkTri.Edge0); float fB1 = Vector3.Dot(kDiff, rkTri.Edge1); float fC = kDiff.LengthSquared(); float fDet = System.Math.Abs(fA00 * fA11 - fA01 * fA01); float fS = fA01 * fB1 - fA11 * fB0; float fT = fA01 * fB0 - fA00 * fB1; float fSqrDist; if (fS + fT <= fDet) { if (fS < 0.0f) { if (fT < 0.0f) // region 4 { if (fB0 < 0.0f) { fT = 0.0f; if (-fB0 >= fA00) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } else { fS = 0.0f; if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else if (-fB1 >= fA11) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else // region 3 { fS = 0.0f; if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else if (-fB1 >= fA11) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else if (fT < 0.0f) // region 5 { fT = 0.0f; if (fB0 >= 0.0f) { fS = 0.0f; fSqrDist = fC; } else if (-fB0 >= fA00) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } else // region 0 { // minimum at interior point float fInvDet = 1.0f / fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { float fTmp0, fTmp1, fNumer, fDenom; if (fS < 0.0f) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if (fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fS = 1.0f; fT = 0.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = fNumer / fDenom; fT = 1.0f - fS; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { fS = 0.0f; if (fTmp1 <= 0.0f) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else if (fT < 0.0f) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if (fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fT = 1.0f; fS = 0.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = fNumer / fDenom; fS = 1.0f - fT; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { fT = 0.0f; if (fTmp1 <= 0.0f) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else if (fB0 >= 0.0f) { fS = 0.0f; fSqrDist = fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if (fNumer <= 0.0f) { fS = 0.0f; fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fS = 1.0f; fT = 0.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = fNumer / fDenom; fT = 1.0f - fS; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } } } pfSParam = fS; pfTParam = fT; return(System.Math.Abs(fSqrDist)); }
protected override bool Interact(bool staticCollision) { if (RBElement1.GetElementType() != MyRBElementType.ET_BOX) { SwapElements(); } if (!staticCollision) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("BoxVoxelInteraction"); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Transformations"); MyRBBoxElement rbbox0 = (MyRBBoxElement)RBElement1; Matrix matrix0 = RBElement1.GetGlobalTransformation(); MyBox box = tempBox; box.Transform.Orientation = matrix0; box.Transform.Orientation.Translation = Vector3.Zero; box.Transform.Position = matrix0.Translation - Vector3.TransformNormal(rbbox0.Size * 0.5f, matrix0); box.SideLengths = rbbox0.Size; float boxRadius = box.GetBoundingRadiusAroundCentre(); #region boxCentre Vector3 boxCentre; box.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 = RBElement1.GetWorldSpaceAABB(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("GetPotentialTrianglesForColDet"); // extent bb for the movement int numTriangles; MyVoxelMaps.GetPotentialTrianglesForColDet(out numTriangles, ref bb); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); if (staticCollision) { for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle) { MyColDetVoxelTriangle triangle = MyVoxelMaps.PotentialColDetTriangles[iTriangle]; // quick early test is done in mesh space float dist = triangle.Plane.DotCoordinate(boxCentre); if (dist > boxRadius) { continue; } // skip too narrow triangles causing destability if ((triangle.Vertex0 - triangle.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon || (triangle.Vertex1 - triangle.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon || (triangle.Vertex0 - triangle.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon ) { continue; } if (DoOverlapBoxTriangleStaticTest(box, ref triangle)) { return(true); } } } else { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("for DoOverlapBoxTriangleTest"); for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle) { MyColDetVoxelTriangle triangle = MyVoxelMaps.PotentialColDetTriangles[iTriangle]; // skip too narrow triangles causing destability if ((triangle.Vertex0 - triangle.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon || (triangle.Vertex1 - triangle.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon || (triangle.Vertex0 - triangle.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon ) { continue; } DoOverlapBoxTriangleTest(box, ref triangle); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } if (!staticCollision) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } return(false); }
/// <summary> /// point vs Voxel triangle distancesq /// </summary> public static float PointColDetVoxelTriangleDistanceSq(out float pfSParam, out float pfTParam, Vector3 rkPoint, MyColDetVoxelTriangle rkTri) { Vector3 kDiff = rkTri.Origin - rkPoint; float fA00 = rkTri.Edge0.LengthSquared(); float fA01 = Vector3.Dot(rkTri.Edge0, rkTri.Edge1); float fA11 = rkTri.Edge1.LengthSquared(); float fB0 = Vector3.Dot(kDiff, rkTri.Edge0); float fB1 = Vector3.Dot(kDiff, rkTri.Edge1); float fC = kDiff.LengthSquared(); float fDet = System.Math.Abs(fA00 * fA11 - fA01 * fA01); float fS = fA01 * fB1 - fA11 * fB0; float fT = fA01 * fB0 - fA00 * fB1; float fSqrDist; if (fS + fT <= fDet) { if (fS < 0.0f) { if (fT < 0.0f) // region 4 { if (fB0 < 0.0f) { fT = 0.0f; if (-fB0 >= fA00) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } else { fS = 0.0f; if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else if (-fB1 >= fA11) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else // region 3 { fS = 0.0f; if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else if (-fB1 >= fA11) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else if (fT < 0.0f) // region 5 { fT = 0.0f; if (fB0 >= 0.0f) { fS = 0.0f; fSqrDist = fC; } else if (-fB0 >= fA00) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } else // region 0 { // minimum at interior point float fInvDet = 1.0f / fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { float fTmp0, fTmp1, fNumer, fDenom; if (fS < 0.0f) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if (fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fS = 1.0f; fT = 0.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = fNumer / fDenom; fT = 1.0f - fS; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { fS = 0.0f; if (fTmp1 <= 0.0f) { fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else if (fB1 >= 0.0f) { fT = 0.0f; fSqrDist = fC; } else { fT = -fB1 / fA11; fSqrDist = fB1 * fT + fC; } } } else if (fT < 0.0f) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if (fTmp1 > fTmp0) { fNumer = fTmp1 - fTmp0; fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fT = 1.0f; fS = 0.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fT = fNumer / fDenom; fS = 1.0f - fT; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } else { fT = 0.0f; if (fTmp1 <= 0.0f) { fS = 1.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else if (fB0 >= 0.0f) { fS = 0.0f; fSqrDist = fC; } else { fS = -fB0 / fA00; fSqrDist = fB0 * fS + fC; } } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if (fNumer <= 0.0f) { fS = 0.0f; fT = 1.0f; fSqrDist = fA11 + 2.0f * fB1 + fC; } else { fDenom = fA00 - 2.0f * fA01 + fA11; if (fNumer >= fDenom) { fS = 1.0f; fT = 0.0f; fSqrDist = fA00 + 2.0f * fB0 + fC; } else { fS = fNumer / fDenom; fT = 1.0f - fS; fSqrDist = fS * (fA00 * fS + fA01 * fT + 2.0f * fB0) + fT * (fA01 * fS + fA11 * fT + 2.0f * fB1) + fC; } } } } pfSParam = fS; pfTParam = fT; return System.Math.Abs(fSqrDist); }
private bool DoOverlapBoxTriangleStaticTest(MyBox box, ref MyColDetVoxelTriangle triangle) { Matrix dirs0 = box.Orientation; #region triEdge0 Vector3 pt0; Vector3 pt1; triangle.GetPoint(0, out pt0); triangle.GetPoint(1, out pt1); Vector3 triEdge0; Vector3.Subtract(ref pt1, ref pt0, out triEdge0); if (triEdge0.LengthSquared() < MyPhysicsConfig.Epsilon) return false; #endregion #region triEdge1 Vector3 pt2; triangle.GetPoint(2, out pt2); Vector3 triEdge1; Vector3.Subtract(ref pt2, ref pt1, out triEdge1); if (triEdge1.LengthSquared() < MyPhysicsConfig.Epsilon) return false; #endregion #region triEdge2 Vector3 triEdge2; Vector3.Subtract(ref pt0, ref pt2, out triEdge2); if (triEdge2.LengthSquared() < MyPhysicsConfig.Epsilon) return false; #endregion triEdge0.Normalize(); triEdge1.Normalize(); triEdge2.Normalize(); Vector3 triNormal = triangle.Plane.Normal; m_axes[0] = triNormal; m_axes[1] = dirs0.Right; m_axes[2] = dirs0.Up; m_axes[3] = dirs0.Backward; Vector3.Cross(ref m_axes[1], ref triEdge0, out m_axes[4]); Vector3.Cross(ref m_axes[1], ref triEdge1, out m_axes[5]); Vector3.Cross(ref m_axes[1], ref triEdge2, out m_axes[6]); Vector3.Cross(ref m_axes[2], ref triEdge0, out m_axes[7]); Vector3.Cross(ref m_axes[2], ref triEdge1, out m_axes[8]); Vector3.Cross(ref m_axes[2], ref triEdge2, out m_axes[9]); Vector3.Cross(ref m_axes[3], ref triEdge0, out m_axes[10]); Vector3.Cross(ref m_axes[3], ref triEdge1, out m_axes[11]); Vector3.Cross(ref m_axes[3], ref triEdge2, out m_axes[12]); // the overlap depths along each axis // see if the boxes are separate along any axis, and if not keep a // record of the depths along each axis int i; for (i = 0; i < numAxes; ++i) { m_overlapDepths[i] = 1.0f; if (Disjoint(out m_overlapDepths[i], m_axes[i], box, triangle, MyPhysicsConfig.CollisionEpsilon)) return false; } // The box overlap, find the separation depth closest to 0. float minDepth = float.MaxValue; int minAxis = -1; for (i = 0; i < numAxes; ++i) { // If we can't normalise the axis, skip it float l2 = m_axes[i].LengthSquared(); if (l2 < MyPhysicsConfig.Epsilon) continue; // Normalise the separation axis and the depth float invl = 1.0f / (float)System.Math.Sqrt(l2); m_axes[i] *= invl; m_overlapDepths[i] *= invl; // If this axis is the minimum, select it if (m_overlapDepths[i] < minDepth) { minDepth = m_overlapDepths[i]; minAxis = i; } } if (minAxis == -1) return false; // Make sure the axis is facing towards the 0th box. // if not, invert it Vector3 D = box.GetCentre() - triangle.Centre; Vector3 N = m_axes[minAxis]; float depth = m_overlapDepths[minAxis]; if (Vector3.Dot(D, N) < 0.0f) N *= -1; MyRigidBody rbo0 = GetRigidBody1(); MyRigidBody rbo1 = GetRigidBody2(); float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; Vector3 boxOldPos = rbo0.Position; Vector3 boxNewPos = rbo0.Position + rbo0.LinearVelocity * dt; Vector3 meshPos = rbo1.Position; m_CPList.Clear(); GetBoxTriangleIntersectionPoints(m_CPList, box, triangle, MyPhysicsConfig.CollisionEpsilon); // adjust the depth #region delta Vector3 delta; Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta); #endregion int numPts = m_CPList.Count; if (numPts > 0) return true; else return false; }