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); }
protected override bool Interact(bool staticCollision) { try { if (!staticCollision) { TestsCount++; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("BoxTriangleIntersection"); } if (RBElement1.GetElementType() != MyRBElementType.ET_BOX) { SwapElements(); } var boxElement = (MyRBBoxElement)RBElement1; var triangleMeshElem = (MyRBTriangleMeshElement)RBElement2; MyModel model = ((boxElement.Flags & MyElementFlag.EF_MODEL_PREFER_LOD0) > 0 ? triangleMeshElem.ModelLOD0 : triangleMeshElem.Model); Matrix boxMatrix = boxElement.GetGlobalTransformation(); Matrix triangleMeshMatrix = triangleMeshElem.GetGlobalTransformation(); Matrix newMatrix = boxMatrix; if (!staticCollision) { // MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep newMatrix.Translation = newMatrix.Translation + boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; } MyBox oldBox = m_tempBox1; MyBox newBox = m_tempBox2; oldBox.Transform.Orientation = boxMatrix; oldBox.Transform.Orientation.Translation = Vector3.Zero; oldBox.Transform.Position = boxMatrix.Translation - Vector3.TransformNormal(boxElement.Size * 0.5f, boxMatrix); newBox.Transform.Orientation = newMatrix; newBox.Transform.Orientation.Translation = Vector3.Zero; newBox.Transform.Position = newMatrix.Translation - Vector3.TransformNormal(boxElement.Size * 0.5f, newMatrix); oldBox.SideLengths = boxElement.Size; newBox.SideLengths = boxElement.Size; 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 = Matrix.Invert(triangleMeshMatrix); Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre); #endregion BoundingBox bb = boxElement.GetWorldSpaceAABB(); if (staticCollision) { Vector3 bbMin = Vector3.Transform(bb.Min, invTransformMatrix); Vector3 bbMax = Vector3.Transform(bb.Max, invTransformMatrix); BoundingSphere bs = new BoundingSphere((bbMax + bbMin) / 2, Vector3.Distance(bbMin, bbMax)); List <MyTriangle_Vertex_Normal> triangles = MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().GetFreeTriangleList(this); model.GetTrianglePruningStructure().GetTrianglesIntersectingSphere(ref bs, triangles, triangles.Capacity); for (int iTriangle = 0; iTriangle < triangles.Count; iTriangle++) { MyTriangle_Vertex_Normal triangle = triangles[iTriangle]; MyPlane plane = new MyPlane(ref triangle.Vertexes); // quick early test is done in mesh space float dist = MyUtils.GetDistanceFromPointToPlane(ref boxCentre, ref plane); if (dist > boxRadius || dist < -boxRadius) { continue; } Vector3 oldPos = boxMatrix.Translation; Vector3 newPos = newMatrix.Translation; float collisionEpsilon = 0;//pz to test not sure about value if (DoOverlapBoxTriangleStaticTest( oldBox, newBox, triangle, plane, collisionEpsilon, ref triangleMeshMatrix, ref oldPos, ref newPos)) { return(true); } } return(false); } else { bb.Min += boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; bb.Max += boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep; var boxCenter = bb.GetCenter(); // aabox is done in mesh space and handles the mesh transform correctly //int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb); //boxElement.GetRigidBody().Position = Vector3.Zero; //triangleMeshElem.GetRigidBody().Position = Vector3.Zero; //BoundingSphere bs = new BoundingSphere((bbMax + bbMin) / 2, Vector3.Distance(bbMin, bbMax)); var halfSize = bb.Size() / 2; BoundingBox bb2 = new BoundingBox(boxCentre - halfSize, boxCentre + halfSize); List <MyTriangle_Vertex_Normal> triangles = MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().GetFreeTriangleList(this); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PruningStructure"); model.GetTrianglePruningStructure().GetTrianglesIntersectingAABB(ref bb2, triangles, triangles.Capacity); //model.GetTrianglePruningStructure().GetTrianglesIntersectingSphere(ref bs, triangles, triangles.Capacity); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().ProfileCustomValue("Tests count ", TestsCount); MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc(); int refPointer = 0; m_collPoints.Clear(); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Triangles"); for (int iTriangle = 0; iTriangle < triangles.Count; iTriangle++) { MyTriangle_Vertex_Normal triangle = triangles[iTriangle]; //IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]); MyPlane plane = new MyPlane(ref triangle.Vertexes); // quick early test is done in mesh space //float dist = meshTriangle.Plane.DotCoordinate(boxCentre); float dist = MyUtils.GetDistanceFromPointToPlane(ref boxCentre, ref plane); if (dist > boxRadius || dist < -boxRadius) { continue; } Vector3 oldPos = boxMatrix.Translation; Vector3 newPos = newMatrix.Translation; DoOverlapBoxTriangleTest( oldBox, newBox, triangle, plane, MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon, ref triangleMeshMatrix, ref oldPos, ref newPos, m_collPoints); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); TrianglesTested += triangles.Count; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().ProfileCustomValue("Triangles tested ", TrianglesTested); m_collPoints.Sort(m_colPointComparer); refPointer = 0; foreach (MyCollisionPointStruct collPoint in m_collPoints) { collPtArray[refPointer] = collPoint.CollPointInfo; refPointer++; if (refPointer >= MyPhysicsConfig.MaxContactPoints) { break; } } if (refPointer > 0) { MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, refPointer); } MyContactInfoCache.FreeStackAlloc(collPtArray); MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().PushBackTriangleList(triangles); } } catch { throw; } finally { if (!staticCollision) { MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); } } return(false); }