コード例 #1
0
ファイル: VoxelCollision.cs プロジェクト: nhippenmeyer/CS248
 public void UpdateCollision()
 {
     if (geometry.CanRender)
     {
         Body[] bodies = PhysicsHelper.PhysicsBodiesVolume(boundsWorldSpaceCollision);
         if(CollisionMesh == null && bodies.Length > 0)
         {
             GenerateCollisionMesh();
             CollisionDeleteTime = CollisionDeleteTimeS;
         }
         else if (CollisionMesh != null)
         {
             if (bodies.Length < 1)
             {
                 CollisionDeleteTime -= Time.GameTime.ElapsedTime;
                 if (CollisionDeleteTime <= 0)
                 {
                     PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.RemoveCollisionSkin(Collision);
                     Collision = null;
                     CollisionMesh = null;
                 }
             }
             else
             {
                 CollisionDeleteTime = CollisionDeleteTimeS;
             }
         }
     }
 }
コード例 #2
0
ファイル: TriangleMesh.cs プロジェクト: bradleat/trafps
 public override Primitive Clone()
 {
     TriangleMesh triangleMesh = new TriangleMesh();
     //            triangleMesh.CreateMesh(vertices, triangleVertexIndices, maxTrianglesPerCell, minCellSize);
     // its okay to share the octree
     triangleMesh.octree = this.octree;
     triangleMesh.Transform = Transform;
     return triangleMesh;
 }
コード例 #3
0
        public TriangleMeshObject(Game game, Model model, Matrix orientation, Vector3 position)
            : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(null);

            triangleMesh = new TriangleMesh();

            List<Vector3> vertexList = new List<Vector3>();
            List<TriangleVertexIndices> indexList = new List<TriangleVertexIndices>();

            ExtractData(vertexList, indexList, model);

            triangleMesh.CreateMesh(vertexList,indexList, 4, 1.0f);
            collision.AddPrimitive(triangleMesh,new MaterialProperties(0.8f,0.7f,0.6f));
            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision);
        }
コード例 #4
0
        // Sets the model being simulated, extracts vertices, etc.
        public void SetModel(string ModelName)
        {
            Model Model = Engine.Content.Load<Model>(ModelName);
            this.modelName = ModelName;

            CollisionSkin.RemoveAllPrimitives();
            triangleMesh = new TriangleMesh();

            List<Vector3> vertexList = new List<Vector3>();
            List<TriangleVertexIndices> indexList =
                new List<TriangleVertexIndices>();

            ExtractData(vertexList, indexList, Model);

            triangleMesh.CreateMesh(vertexList, indexList, 4, 1.0f);
            CollisionSkin.AddPrimitive(triangleMesh,
                new MaterialProperties(0.8f, 0.7f, 0.6f));

            Mass = Mass;
        }
コード例 #5
0
        public TriangleMeshObject(Game game, Model model, Matrix orientation, Vector3 position)
            : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(null);

            triangleMesh = new TriangleMesh();

            List<Vector3> vertexList = new List<Vector3>();
            List<TriangleVertexIndices> indexList = new List<TriangleVertexIndices>();

            ExtractData(vertexList, indexList, model);

            triangleMesh.CreateMesh(vertexList,indexList, 4, 1.0f);
            collision.AddPrimitive(triangleMesh,new MaterialProperties(0.8f,0.7f,0.6f));
            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision);

            // Transform
            collision.ApplyLocalTransform(new JigLibX.Math.Transform(position, orientation));
            // we also need to move this dummy, so the object is *rendered* at the correct positiob
            body.MoveTo(position, orientation);
        }
コード例 #6
0
        /// <summary>
        /// CollDetectCapsuleStaticMeshOverlap
        /// </summary>
        /// <param name="oldCapsule"></param>
        /// <param name="newCapsule"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        private void CollDetectCapsuleStaticMeshOverlap(Capsule oldCapsule, Capsule newCapsule,
            TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            float capsuleTolR = collTolerance + newCapsule.Radius;
            float capsuleTolR2 = capsuleTolR * capsuleTolR;

            Vector3 collNormal = Vector3.Zero;

            BoundingBox bb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddCapsule(newCapsule, ref bb);

            unsafe
            {
            #if USE_STACKALLOC
                SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                int* potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
                    {
            #else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed (SmallCollPointInfo* collPts = collPtArray)
                {
                    int[] potTriArray = IntStackAlloc();
                    fixed (int* potentialTriangles = potTriArray)
                    {
            #endif
                        int numCollPts = 0;

                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                        Vector3 capsuleStart = newCapsule.Position;
                        Vector3 capsuleEnd = newCapsule.GetEnd();
                        Matrix4 meshInvTransform = mesh.InverseTransformMatrix;

                        Vector3 meshSpaceCapsuleStart = Vector3.Transform(capsuleStart, meshInvTransform);
                        Vector3 meshSpaceCapsuleEnd = Vector3.Transform(capsuleEnd, meshInvTransform);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);

                            // we do the plane test using the capsule in mesh space
                            float distToStart = meshTriangle.Plane.DotCoordinate(meshSpaceCapsuleStart);
                            float distToEnd = meshTriangle.Plane.DotCoordinate(meshSpaceCapsuleEnd);

                            // BEN-BUG-FIX: Fixed by replacing 0.0F with -capsuleTolR.
                            if ((distToStart > capsuleTolR && distToEnd > capsuleTolR)
                                || (distToStart < -capsuleTolR && distToEnd < -capsuleTolR))
                                continue;

                            // we now transform the triangle into world space (we could keep leave the mesh alone
                            // but at this point 3 vector transforms is probably not a major slow down)
                            int i0, i1, i2;
                            meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                            Vector3 triVec0;
                            Vector3 triVec1;
                            Vector3 triVec2;
                            mesh.GetVertex(i0, out triVec0);
                            mesh.GetVertex(i1, out triVec1);
                            mesh.GetVertex(i2, out triVec2);

                            // Deano move tri into world space
                            Matrix4 transformMatrix = mesh.TransformMatrix;
                            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
                            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
                            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);
                            Triangle triangle = new Triangle(ref triVec0, ref triVec1, ref triVec2);

                            Segment seg = new Segment(capsuleStart, capsuleEnd - capsuleStart);

                            float tS, tT0, tT1;
                            float d2 = Distance.SegmentTriangleDistanceSq(out tS, out tT0, out tT1, seg, triangle);

                            if (d2 < capsuleTolR2)
                            {
                                Vector3 oldCapsuleStart = oldCapsule.Position;
                                Vector3 oldCapsuleEnd = oldCapsule.GetEnd();
                                Segment oldSeg = new Segment(oldCapsuleStart, oldCapsuleEnd - oldCapsuleStart);
                                d2 = Distance.SegmentTriangleDistanceSq(out tS, out tT0, out tT1, oldSeg, triangle);
                                // report result from old position
                                float dist = (float)System.Math.Sqrt(d2);
                                float depth = oldCapsule.Radius - dist;
                                Vector3 pt = triangle.GetPoint(tT0, tT1);
                                Vector3 collisionN = (d2 > JiggleMath.Epsilon) ? JiggleMath.NormalizeSafe(oldSeg.GetPoint(tS) - pt) :
                                    meshTriangle.Plane.Normal;
                                if (numCollPts < MaxLocalStackSCPI)
                                {
                                    // BEN-OPTIMISATION: Reused existing collPts.
                                    collPts[numCollPts].R0 = pt - body0Pos;
                                    collPts[numCollPts].R1 = pt - body1Pos;
                                    collPts[numCollPts++].InitialPenetration = depth;
                                }
                                collNormal += collisionN;
                            }
                        }
                        if (numCollPts > 0)
                        {
                            JiggleMath.NormalizeSafe(ref collNormal);
                            collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                        }
            #if USE_STACKALLOC
                    }
               }
            #else
                    }
                    FreeStackAlloc(potTriArray);
                }
                FreeStackAlloc(collPtArray);
            #endif
            }
        }
コード例 #7
0
        /// <summary>
        /// CollDetectCapsulseStaticMeshSweep
        /// </summary>
        /// <param name="oldCapsule"></param>
        /// <param name="newCapsule"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        private void CollDetectCapsulseStaticMeshSweep(Capsule oldCapsule, Capsule newCapsule,
            TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // really use a swept test - or overlap?
            Vector3 delta = newCapsule.Position - oldCapsule.Position;
            if (delta.LengthSquared < (0.25f * newCapsule.Radius * newCapsule.Radius))
            {
                CollDetectCapsuleStaticMeshOverlap(oldCapsule, newCapsule, mesh, info, collTolerance, collisionFunctor);
            }
            else
            {
                float capsuleLen = oldCapsule.Length;
                float capsuleRadius = oldCapsule.Radius;

                int nSpheres = 2 + (int)(capsuleLen / (2.0f * oldCapsule.Radius));
                for (int iSphere = 0; iSphere < nSpheres; ++iSphere)
                {
                    float offset = ((float)iSphere) * capsuleLen / ((float)nSpheres - 1.0f);
                    BoundingSphere oldSphere = new BoundingSphere(oldCapsule.Position + oldCapsule.Orientation.Backward() * offset, capsuleRadius);
                    BoundingSphere newSphere = new BoundingSphere(newCapsule.Position + newCapsule.Orientation.Backward() * offset, capsuleRadius);
                    CollDetectSphereStaticMesh.CollDetectSphereStaticMeshSweep(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
                }
            }
        }
コード例 #8
0
ファイル: TerrainVoxel.cs プロジェクト: MattVitelli/Nosferatu
        void GenerateCollisionMesh(VoxelGeometry geometry)
        {
            List<Vector3> vertices = new List<Vector3>(geometry.verts.Length);
            List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>(geometry.ib.Length / 3);
            Matrix transform = this.Transformation.GetTransform();
            for (int i = 0; i < geometry.verts.Length; i++)
                vertices.Add(Vector3.Transform(geometry.verts[i].Position, transform));
            for (int i = 0; i < geometry.ib.Length; i += 3)
            {
                TriangleVertexIndices tri = new TriangleVertexIndices(geometry.ib[i + 2], geometry.ib[i + 1], geometry.ib[i]);
                indices.Add(tri);
            }

            TriangleMesh collisionMesh = new TriangleMesh(vertices, indices);
            CollisionSkin collision = new CollisionSkin(null);
            collision.AddPrimitive(collisionMesh, (int)MaterialTable.MaterialID.NotBouncyRough);
            CollisionSkin collision2 = new CollisionSkin(null);
            collision2.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, Transformation.GetBounds().Min.Y-3f), (int)MaterialTable.MaterialID.NotBouncyRough);
            scene.GetPhysicsEngine().CollisionSystem.AddCollisionSkin(collision);
            //scene.GetPhysicsEngine().CollisionSystem.AddCollisionSkin(collision2);
        }
コード例 #9
0
ファイル: Mesh.cs プロジェクト: MattVitelli/Nosferatu
        void CreateCollisionMesh(ModelPart collisionMesh)
        {
            SortedList<ushort, ushort> renamedVertexIndices = new SortedList<ushort, ushort>();
            SortedList<ushort, ushort> renamedVertexIndicesCollision = new SortedList<ushort, ushort>();
            RenderElement collisionElem = collisionMesh.renderElement;
            List<Vector3> collisionVerts = new List<Vector3>();
            List<TriangleVertexIndices> collisionIndices = new List<TriangleVertexIndices>(collisionElem.PrimitiveCount);
            VertexPNTTI[] vertexData = new VertexPNTTI[vertexCount];
            vertexBuffer.GetData<VertexPNTTI>(vertexData);
            ushort[] indexDataCollision = new ushort[collisionElem.PrimitiveCount * 3];
            collisionElem.IndexBuffer.GetData<ushort>(indexDataCollision);

            for (int i = 0; i < collisionElem.PrimitiveCount; i++)
            {
                int index = i * 3;
                for(int j = 0; j < 3; j++)
                {
                    ushort currIdx = indexDataCollision[index + j];
                    if(!renamedVertexIndicesCollision.ContainsKey(currIdx))
                    {
                        renamedVertexIndicesCollision.Add(currIdx, (ushort)collisionVerts.Count);
                        Vector3 pos;
                        pos.X = vertexData[currIdx].Position.X;
                        pos.Y = vertexData[currIdx].Position.Y;
                        pos.Z = vertexData[currIdx].Position.Z;
                        collisionVerts.Add(pos);
                    }
                }
                ushort idx0 = indexDataCollision[index + 0];
                ushort idx1 = indexDataCollision[index + 1];
                ushort idx2 = indexDataCollision[index + 2];
                collisionIndices.Add(new TriangleVertexIndices(renamedVertexIndicesCollision[idx2], renamedVertexIndicesCollision[idx1], renamedVertexIndicesCollision[idx0]));
            }
            /*
            this.collisionMesh = new TriangleMesh();
            this.collisionMesh.CreateMesh(collisionVerts, collisionIndices, 0, 0);
            */
            this.collisionMesh = new TriangleMesh(collisionVerts, collisionIndices);

            List<VertexPNTTI> newVertexData = new List<VertexPNTTI>();
            for (int i = 0; i < parts.Length; i++)
            {
                RenderElement currElem = parts[i].renderElement;
                ushort[] indexData = new ushort[currElem.PrimitiveCount * 3];
                currElem.IndexBuffer.GetData<ushort>(indexData);
                for (int j = 0; j < indexData.Length; j++)
                {
                    if (!renamedVertexIndices.ContainsKey(indexData[j]))
                    {
                        renamedVertexIndices.Add(indexData[j], (ushort)newVertexData.Count);
                        newVertexData.Add(vertexData[indexData[j]]);
                    }
                    indexData[j] = renamedVertexIndices[indexData[j]];
                }
                currElem.IndexBuffer.SetData<ushort>(indexData);
            }
            vertexBuffer.Dispose();

            vertexCount = newVertexData.Count;
            vertexBuffer = new VertexBuffer(GFX.Device, VertexPNTTI.SizeInBytes * newVertexData.Count, BufferUsage.None);
            vertexBuffer.SetData<VertexPNTTI>(newVertexData.ToArray());
            for (int i = 0; i < parts.Length; i++)
                parts[i].renderElement.VertexBuffer = vertexBuffer;
        }
コード例 #10
0
        /// <summary>
        /// DoOverlapBoxTriangleTest
        /// </summary>
        /// <param name="oldBox"></param>
        /// <param name="newBox"></param>
        /// <param name="triangle"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        /// <returns>bool</returns>
        private static bool DoOverlapBoxTriangleTest(Box oldBox, Box newBox,
            ref IndexedTriangle triangle, TriangleMesh mesh,
            ref CollDetectInfo info, float collTolerance,
            CollisionFunctor collisionFunctor)
        {
            Matrix4 dirs0 = newBox.Orientation;

            #region REFERENCE: Triangle tri = new Triangle(mesh.GetVertex(triangle.GetVertexIndex(0)),mesh.GetVertex(triangle.GetVertexIndex(1)),mesh.GetVertex(triangle.GetVertexIndex(2)));
            Vector3 triVec0;
            Vector3 triVec1;
            Vector3 triVec2;
            mesh.GetVertex(triangle.GetVertexIndex(0), out triVec0);
            mesh.GetVertex(triangle.GetVertexIndex(1), out triVec1);
            mesh.GetVertex(triangle.GetVertexIndex(2), out triVec2);

            // Deano move tri into world space
            Matrix4 transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            Triangle tri = new Triangle(ref triVec0,ref triVec1,ref triVec2);
            #endregion

            #region REFERENCE Vector3 triEdge0 = (tri.GetPoint(1) - tri.GetPoint(0));
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region REFERENCE Vector3 triEdge1 = (tri.GetPoint(2) - tri.GetPoint(1));
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region REFERENCE Vector3 triEdge2 = (tri.GetPoint(0) - tri.GetPoint(2));
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion

            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            // BEN-OPTIMISATION: Replaced loops with code that requires no looping.
            //                   The new code is faster, has less allocations and math especially
            //                   since the method returns as soon as it finds a non-overlapping axis,
            //                   i.e. Before irreleveat allocations occur.
            #region "Old (less efficient) code"
            /*Vector3 triNormal = triangle.Plane.Normal;

            // the 15 potential separating axes
            const int numAxes = 13;
            Vector3[] axes = new Vector3[numAxes];

            axes[0] = triNormal;
            axes[1] = dirs0.Right;
            axes[2] = dirs0.Up;
            axes[3] = dirs0.Backward;
            Vector3.Cross(ref axes[1], ref triEdge0, out axes[4]);
            Vector3.Cross(ref axes[1], ref triEdge1, out axes[5]);
            Vector3.Cross(ref axes[1], ref triEdge2, out axes[6]);
            Vector3.Cross(ref axes[2], ref triEdge0, out axes[7]);
            Vector3.Cross(ref axes[2], ref triEdge1, out axes[8]);
            Vector3.Cross(ref axes[2], ref triEdge2, out axes[9]);
            Vector3.Cross(ref axes[3], ref triEdge0, out axes[10]);
            Vector3.Cross(ref axes[3], ref triEdge1, out axes[11]);
            Vector3.Cross(ref axes[3], ref triEdge2, out axes[12]);

            // the overlap depths along each axis
            float[] overlapDepths = new float[numAxes];

            // 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)
            {
                overlapDepths[i] = 1.0f;
                if (Disjoint(out overlapDepths[i], axes[i], newBox, tri, collTolerance))
                    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 = axes[i].LengthSquared;
                if (l2 < JiggleMath.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 = newBox.GetCentre() - tri.Centre;
            Vector3 N = axes[minAxis];
            float depth = overlapDepths[minAxis];*/
            #endregion
            #region "Optimised code"
            Vector3 triNormal = triangle.Plane.Normal;
            Vector3 right = dirs0.Right();
            Vector3 up = dirs0.Up();
            Vector3 backward = dirs0.Backward();

            float testDepth;

            if (Disjoint(out testDepth, ref triNormal, newBox, ref tri, collTolerance))
                return (false);

            float depth = testDepth;
            Vector3 N = triNormal;

            if (Disjoint(out testDepth, ref right, newBox, ref tri, collTolerance))
                return (false);

            if (testDepth < depth)
            {
                depth = testDepth;
                N = right;
            }

            if (Disjoint(out testDepth, ref up, newBox, ref tri, collTolerance))
                return (false);

            if (testDepth < depth)
            {
                depth = testDepth;
                N = up;
            }

            if (Disjoint(out testDepth, ref backward, newBox, ref tri, collTolerance))
                return (false);

            if (testDepth < depth)
            {
                depth = testDepth;
                N = backward;
            }

            Vector3 axis;

            Vector3.Cross(ref right, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref right, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref right, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref up, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref up, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref up, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref backward, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref backward, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            Vector3.Cross(ref backward, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
                return (false);

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N = axis;
            }

            /*if (N == Vector3.Zero)
                return (false);*/

            Vector3 D = newBox.GetCentre() - tri.Centre;
            N.Normalize();
            int i;

            #endregion

            if (Vector3.Dot(D, N) < 0.0f)
               N *= -1;

            Vector3 boxOldPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            List<Vector3> pts = new List<Vector3>();
            //pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region REFERENCE: Vector3 delta = boxNewPos - boxOldPos;
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region REFERENCE: float oldDepth = depth + Vector3.Dot(delta, N);
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion

            unsafe
            {
                // report collisions
                int numPts = pts.Count;
            #if USE_STACKALLOC
                SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
            #else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed (SmallCollPointInfo* collPts = collPtArray)
            #endif
                {
                    if (numPts > 0)
                    {
                        if (numPts >= MaxLocalStackSCPI)
                        {
                            numPts = MaxLocalStackSCPI - 1;
                        }

                        // adjust positions
                        for (i = 0; i < numPts; ++i)
                        {
                            // BEN-OPTIMISATION: Reused existing SmallCollPointInfo and inlined vector substraction.
                            collPts[i].R0.X = pts[i].X - boxNewPos.X;
                            collPts[i].R0.Y = pts[i].Y - boxNewPos.Y;
                            collPts[i].R0.Z = pts[i].Z - boxNewPos.Z;

                            collPts[i].R1.X = pts[i].X - meshPos.X;
                            collPts[i].R1.Y = pts[i].Y - meshPos.Y;
                            collPts[i].R1.Z = pts[i].Z - meshPos.Z;

                            collPts[i].InitialPenetration = oldDepth;
                        }

                        collisionFunctor.CollisionNotify(ref info, ref N, collPts, numPts);
            #if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
            #endif
                        return true;
                    }
                    else
                    {
            #if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
            #endif
                        return false;
                    }
                }

            }
        }
コード例 #11
0
ファイル: Terrain.cs プロジェクト: colbybhearn/3DPhysics
        public Terrain( Vector3 posCenter,Vector3 size, int cellsX, int cellsZ, GraphicsDevice g, Texture2D tex)
            : base()
        {
            numVertsX = cellsX + 1;
            numVertsZ = cellsZ + 1;
            numVerts = numVertsX * numVertsZ;
            numTriX = cellsX * 2;
            numTriZ = cellsZ;
            numTris = numTriX * numTriZ;
            verts = new VertexPositionNormalTexture[numVerts];
            int numIndices = numTris * 3;
            indices = new int[numIndices];
            float cellSizeX = (float)size.X / cellsX;
            float cellSizeZ = (float)size.Z / cellsZ;
            texture = tex;

            Random r = new Random();
            Random r2 = new Random(DateTime.Now.Millisecond);
            double targetHeight = 0;
            double currentHeight = 0;
            // Fill in the vertices
            int count = 0;
            //float edgeHeigh = 0;
            //float worldZPosition = posCenter.Z - (size.Z / 2);
            float worldZPosition = - (size.Z / 2);
            float height;
            float stair = 0;
            float diff = .5f;
            for (int z = 0; z < numVertsZ; z++)
            {
                //float worldXPosition = posCenter.X - (size.X / 2);
                float worldXPosition = - (size.X / 2);
                for (int x = 0; x < numVertsX; x++)
                {

                    if (count % numVertsX == 0)
                        targetHeight = r2.NextDouble();
                    //targetHeight += Math.Abs(worldZPosition);// +worldXPosition * 1.0f;

                    currentHeight += (targetHeight - currentHeight) * .009f;
                    //if(x!=0)
                    //currentHeight = (targetHeight) / ((float)x / (float)(numVertsX+1));
                    //height = (float)((r.NextDouble() + currentHeight) * size.Y);

                    //height = 1;

                    //stair += diff;
                    //if (z + x == 17)
                        //stair += 10;

                    //height += stair;
                    verts[count].Position = new Vector3(worldXPosition,(float)currentHeight, worldZPosition);
                    verts[count].Normal = Vector3.Zero;
                    verts[count].TextureCoordinate.X = (float)x / (numVertsX - 1);
                    verts[count].TextureCoordinate.Y = (float)z / (numVertsZ - 1);

                    //if (z + x == 17)
                        //stair -= 10;
                    count++;

                    // Advance in x
                    worldXPosition += cellSizeX;
                }

                currentHeight = 0;
                // Advance in z
                worldZPosition += cellSizeZ;
                //diff *= -1;
                //if (diff < 1)
                   // stair += numVertsX * diff;
            }

            int index = 0;
            int startVertex = 0;
            for (int cellZ = 0; cellZ < cellsZ; cellZ++)
            {
                for (int cellX = 0; cellX < cellsX; cellX++)
                {
                    indices[index] = startVertex + 0;
                    indices[index + 1] = startVertex + 1;
                    indices[index + 2] = startVertex + numVertsX;
                    SetNormalOfTriangleAtIndices(indices[index], indices[index + 1], indices[index + 2]);
                    meshIndices.Add(new TriangleVertexIndices(index, index + 1, index + 2));
                    meshVertices.Add(verts[indices[index]].Position);
                    meshVertices.Add(verts[indices[index+1]].Position);
                    meshVertices.Add(verts[indices[index+2]].Position);
                    index += 3;

                    indices[index] = startVertex + 1;
                    indices[index + 1] = startVertex + numVertsX + 1;
                    indices[index + 2] = startVertex + numVertsX;
                    SetNormalOfTriangleAtIndices(indices[index], indices[index + 1], indices[index + 2]);
                    meshIndices.Add(new TriangleVertexIndices(index, index + 1, index + 2));
                    meshVertices.Add(verts[indices[index]].Position);
                    meshVertices.Add(verts[indices[index + 1]].Position);
                    meshVertices.Add(verts[indices[index + 2]].Position);
                    index += 3;

                    startVertex++;
                }
                startVertex++;
            }

            try
            {
                Effect = new BasicEffect(g);
                mesh = new TriangleMesh();
                //mesh.CreateMesh(meshVertices, meshIndices, 2, cellSizeX);
            }
            catch (Exception E)
            {
            }

            this.Body = new Body();
            Skin = new CollisionSkin(Body);
            Body.CollisionSkin = Skin;
            Body.ExternalData = this;
            float heightf = 0;
            try
            {
            Array2D field = new Array2D(numVertsX, numVertsZ);

            int i = 0;
            for (int c = 0; c < verts.Length; c++)
            {
                int x = c / numVertsX;
                int z = c % numVertsX;

                if (i >= verts.Length)
                    i = (i % verts.Length)+1;
                heightf = verts[i].Position.Y + posCenter.Y;
                //heightf = verts[i].Position.Y;
                i += numVertsX;

                field.SetAt(x,z, heightf);
            }

               // Body.MoveTo(Position, Matrix.Identity);

                Heightmap hm = new Heightmap(field,
                                                    (-size.X / 2) / (cellsX+0) + cellSizeX/2,
                                                    (-size.Z / 2) / (cellsZ + 0) + cellSizeZ/2,
                                                    size.X / (cellsX+0),
                                                    size.Z / (cellsZ+0));
                Skin.AddPrimitive(hm, new MaterialProperties(0.7f, 0.7f, 0.6f));
                //Skin.AddPrimitive(GetMesh(), new MaterialProperties(0.7f, 0.7f, 0.6f));
                //VertexPositionColor[] wireFrame = Skin.GetLocalSkinWireframe(); // 1200 across before Z changes to from -7.5/-7.35 to -7.35/-7.2

                PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
                CommonInit(posCenter, new Vector3(0,0,0), null, false);
            }
            catch(Exception E)
            {
            }
        }
コード例 #12
0
        private TriangleMesh GetTriangleMesh(Model model, Transform3D transform)
        {
            TriangleMesh triangleMesh = new TriangleMesh();
            List<Vector3> vertexList = new List<Vector3>();
            List<TriangleVertexIndices> indexList = new List<TriangleVertexIndices>();

            ExtractData(vertexList, indexList, model);

            for (int i = 0; i < vertexList.Count; i++)
            {
                vertexList[i] = Vector3.Transform(vertexList[i], transform.World);
            }

            // create the collision mesh
            triangleMesh.CreateMesh(vertexList, indexList, 1, 1.0f);

            return triangleMesh;
        }
コード例 #13
0
ファイル: VoxelCollision.cs プロジェクト: nhippenmeyer/CS248
        void GenerateCollisionMesh()
        {
            List<Vector3> vertColl = new List<Vector3>();

            for (int i = 0; i < geometry.verts.Length; i++)
            {
                vertColl.Add(Vector3.Transform(new Vector3(geometry.verts[i].Position.X, geometry.verts[i].Position.Y, geometry.verts[i].Position.Z), transformation.GetTransform()));
                //vertColl[i] = Vector3.Transform(new Vector3(geometry.verts[i].Position.X, geometry.verts[i].Position.Y, geometry.verts[i].Position.Z), transformation.GetTransform());
            }

            int triCount = 0;
            TriangleVertexIndices triIdx = new TriangleVertexIndices(0, 0, 0);
            List<TriangleVertexIndices> triColl = new List<TriangleVertexIndices>();
            for (int i = 0; i < geometry.ib.Length; i++)
            {
                //int index = geometry.ib[i];

                //vertColl.Add(Vector3.Transform(new Vector3(geometry.verts[index].Position.X, geometry.verts[index].Position.Y, geometry.verts[index].Position.Z), transformation.GetTransform()));
                switch (triCount)
                {
                    case 0:
                        triIdx.I2 = geometry.ib[i];
                        break;
                    case 1:
                        triIdx.I1 = geometry.ib[i];
                        break;
                    case 2:
                        triIdx.I0 = geometry.ib[i];
                        triCount = -1;
                        triColl.Add(triIdx);
                        triIdx = new TriangleVertexIndices(0, 0, 0);
                        break;
                }
                triCount++;
            }

            CollisionMesh = new TriangleMesh();
            CollisionMesh.CreateMesh(vertColl.ToArray(), triColl.ToArray(), 1500, 0.01f);
            Collision = new CollisionSkin(null);
            Collision.AddPrimitive(CollisionMesh, (int)MaterialTable.MaterialID.NotBouncyRough);
            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Collision);
        }
コード例 #14
0
ファイル: SphereStaticMesh.cs プロジェクト: bradleat/trafps
        internal static void CollDetectSphereStaticMeshSweep(BoundingSphere oldSphere, BoundingSphere newSphere, TriangleMesh mesh,
            CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // really use a swept test - or overlap?
            Vector3 delta = newSphere.Center - oldSphere.Center;
            if (delta.LengthSquared() < (0.25f * newSphere.Radius * newSphere.Radius))
            {
                CollDetectSphereStaticMeshOverlap(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
            }
            else
            {
                Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
                Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

                float sphereTolR = collTolerance + oldSphere.Radius;
                float sphereToR2 = sphereTolR * sphereTolR;

                Vector3 collNormal = Vector3.Zero;

                BoundingBox bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddSphere(oldSphere, ref bb);
                BoundingBoxHelper.AddSphere(newSphere, ref bb);

                // get the spheres centers in triangle mesh space
                Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                unsafe
                {
            #if USE_STACKALLOC
                    SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                    int* potentialTriangles = stackalloc int[MaxLocalStackTris];
                    {
                        {
            #else
                    SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                    fixed (SmallCollPointInfo* collPts = collPtArray)
                    {
                        int[] potTriArray = IntStackAlloc();
                        fixed( int* potentialTriangles = potTriArray)
                        {
            #endif
                            int numCollPts = 0;

                            int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                            {

                                // first test the old sphere for being on the wrong side
                                IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
                                float distToCentreOld = meshTriangle.Plane.DotCoordinate(oldSphereCen);
                                if (distToCentreOld <= 0.0f)
                                    continue;
                                // now test the new sphere for being clear

                                float distToCentreNew = meshTriangle.Plane.DotCoordinate(newSphereCen);
                                if (distToCentreNew > sphereTolR)
                                    continue;

                                int i0, i1, i2;
                                meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                                Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                                // If the old sphere is intersecting, just use that result
                                float s, t;
                                float d2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);

                                if (d2 < sphereToR2)
                                {
                                    float dist = (float)System.Math.Sqrt(d2);
                                    float depth = oldSphere.Radius - dist;
                                    Vector3 triangleN = triangle.Normal;
                                    Vector3 normSafe = oldSphereCen - triangle.GetPoint(s, t);

                                    JiggleMath.NormalizeSafe(ref normSafe);

                                    Vector3 collisionN = (dist > float.Epsilon) ? normSafe : triangleN;
                                    // since impulse gets applied at the old position
                                    Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;
                                    if (numCollPts < MaxLocalStackSCPI)
                                    {
                                        collPts[numCollPts++] = new SmallCollPointInfo(pt - body0Pos, pt - body1Pos, depth);
                                    }
                                    collNormal += collisionN;
                                }
                                else if (distToCentreNew < distToCentreOld)
                                {
                                    // old sphere is not intersecting - do a sweep, but only if the sphere is moving into the
                                    // triangle
                                    Vector3 pt, N; // CHECK THIS
                                    float depth;
                                    if (Intersection.SweptSphereTriangleIntersection(out pt, out N, out depth, oldSphere, newSphere, triangle,
                                        distToCentreOld, distToCentreNew, Intersection.EdgesToTest.EdgeAll, Intersection.CornersToTest.CornerAll))
                                    {
                                        // collision point etc must be relative to the old position because that's
                                        //where the impulses are applied
                                        float dist = (float)System.Math.Sqrt(d2);
                                        float depth2 = oldSphere.Radius - dist;
                                        Vector3 triangleN = triangle.Normal;
                                        Vector3 normSafe = oldSphereCen - triangle.GetPoint(s, t);
                                        JiggleMath.NormalizeSafe(ref normSafe);
                                        Vector3 collisionN = (dist > JiggleMath.Epsilon) ? normSafe : triangleN;
                                        // since impulse gets applied at the old position
                                        Vector3 pt2 = oldSphere.Center - oldSphere.Radius * collisionN;
                                        if (numCollPts < MaxLocalStackSCPI)
                                        {
                                            collPts[numCollPts++] = new SmallCollPointInfo(pt2 - body0Pos, pt2 - body1Pos, depth);
                                        }
                                        collNormal += collisionN;
                                    }
                                }
                            }
                            if (numCollPts > 0)
                            {
                                JiggleMath.NormalizeSafe(ref collNormal);
                                collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                            }
                        }
            #if USE_STACKALLOC
                    }
               }
            #else

                        FreeStackAlloc(potTriArray);
                    }
                    FreeStackAlloc(collPtArray);
                }
            #endif
            }
        }
コード例 #15
0
ファイル: Terrain.cs プロジェクト: colbybhearn/3DPhysics
        public Terrain( Vector3 posCenter,Vector3 size, int cellsX, int cellsZ, GraphicsDevice g, Texture2D tex)
            : base()
        {
            numVertsX = cellsX + 1;
            numVertsZ = cellsZ + 1;
            numVerts = numVertsX * numVertsZ;
            numTriX = cellsX * 2;
            numTriZ = cellsZ;
            numTris = numTriX * numTriZ;
            verts = new VertexPositionNormalTexture[numVerts];
            int numIndices = numTris * 3;
            indices = new int[numIndices];
            float cellSizeX = (float)size.X / cellsX;
            float cellSizeZ = (float)size.Z / cellsZ;
            texture = tex;

            Random r = new Random();
            Random r2 = new Random(DateTime.Now.Millisecond);
            double targetHeight = 0;
            double currentHeight = 0;
            // Fill in the vertices
            int count = 0;

            // distribute height nodes across the map.
            // for each vert, calculate the height by summing (node height / distance)
            int numHeightNodes = 10;
            heightNodes = new Vector3[numHeightNodes];
            for (int i = 0; i < numHeightNodes; i++)
            {
                heightNodes[i] = new Vector3((float)((-size.X / 2) + (r.NextDouble() * size.X)),
                                                (float)(r.NextDouble() * 0),
                                                (float)((-size.Z / 2) + (r.NextDouble() * size.Z)));
            }

            bool stretchTexture=false;
            float textureTileCount=10000;

            float worldZPosition = - (size.Z / 2);
            for (int z = 0; z < numVertsZ; z++)
            {
                float worldXPosition = - (size.X / 2);
                for (int x = 0; x < numVertsX; x++)
                {

                    if (count % numVertsX == 0)
                        targetHeight = r2.NextDouble();

                    //currentHeight += (targetHeight - currentHeight) * .009f;

                    float height = GetNodeBasedHeight(worldXPosition, worldZPosition);
                    height = 0;
                    verts[count].Position = new Vector3(worldXPosition, height, worldZPosition);
                    verts[count].Normal = Vector3.Zero;

                    if (stretchTexture)
                    {
                        verts[count].TextureCoordinate.X = (float)x / (numVertsX - 1);
                        verts[count].TextureCoordinate.Y = (float)z / (numVertsZ - 1);
                    }
                    else
                    {
                        verts[count].TextureCoordinate.X = ((float)x / (numVertsX - 1))*textureTileCount;
                        verts[count].TextureCoordinate.Y = ((float)z / (numVertsZ - 1))*textureTileCount;
                    }

                    count++;

                    // Advance in x
                    worldXPosition += cellSizeX;
                }

                currentHeight = 0;
                // Advance in z
                worldZPosition += cellSizeZ;
            }

            int index = 0;
            int startVertex = 0;
            for (int cellZ = 0; cellZ < cellsZ; cellZ++)
            {
                for (int cellX = 0; cellX < cellsX; cellX++)
                {
                    indices[index] = startVertex + 0;
                    indices[index + 1] = startVertex + 1;
                    indices[index + 2] = startVertex + numVertsX;
                    SetNormalOfTriangleAtIndices(indices[index], indices[index + 1], indices[index + 2]);
                    meshIndices.Add(new TriangleVertexIndices(index, index + 1, index + 2));
                    meshVertices.Add(verts[indices[index]].Position);
                    meshVertices.Add(verts[indices[index+1]].Position);
                    meshVertices.Add(verts[indices[index+2]].Position);
                    index += 3;

                    indices[index] = startVertex + 1;
                    indices[index + 1] = startVertex + numVertsX + 1;
                    indices[index + 2] = startVertex + numVertsX;
                    SetNormalOfTriangleAtIndices(indices[index], indices[index + 1], indices[index + 2]);
                    meshIndices.Add(new TriangleVertexIndices(index, index + 1, index + 2));
                    meshVertices.Add(verts[indices[index]].Position);
                    meshVertices.Add(verts[indices[index + 1]].Position);
                    meshVertices.Add(verts[indices[index + 2]].Position);
                    index += 3;

                    startVertex++;
                }
                startVertex++;
            }

            try
            {
                Effect = new BasicEffect(g);
                mesh = new TriangleMesh();
                //mesh.CreateMesh(meshVertices, meshIndices, 2, cellSizeX);
            }
            catch (Exception E)
            {
                System.Diagnostics.Debug.WriteLine(E.StackTrace);
            }

            this.Body = new Body();
            Skin = new CollisionSkin(Body);
            Body.CollisionSkin = Skin;
            Body.ExternalData = this;
            float heightf = 0;
            try
            {
            Array2D field = new Array2D(numVertsX, numVertsZ);

            int i = 0;
            for (int c = 0; c < verts.Length; c++)
            {
                int x = c / numVertsX;
                int z = c % numVertsX;

                if (i >= verts.Length)
                    i = (i % verts.Length)+1;
                heightf = verts[i].Position.Y + posCenter.Y; // works
                //heightf = verts[i].Position.Y;
                i += numVertsX;

                field.SetAt(x,z, heightf);
            }

               // Body.MoveTo(Position, Matrix.Identity);

                Heightmap hm = new Heightmap(field,
                                                    (-size.X / 2) / (cellsX+0) + cellSizeX/2,
                                                    (-size.Z / 2) / (cellsZ + 0) + cellSizeZ/2,
                                                    size.X / (cellsX+0),
                                                    size.Z / (cellsZ+0));
                Skin.AddPrimitive(hm, new MaterialProperties(0.7f, 0.7f, 0.6f));
                //Skin.AddPrimitive(GetMesh(), new MaterialProperties(0.7f, 0.7f, 0.6f));
                //VertexPositionColor[] wireFrame = Skin.GetLocalSkinWireframe(); // 1200 across before Z changes to from -7.5/-7.35 to -7.35/-7.2

                PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
                CommonInit(posCenter, new Vector3(0,0,0), null, false, 0);
            }
            catch(Exception E)
            {
                System.Diagnostics.Debug.WriteLine(E.StackTrace);
            }
        }
コード例 #16
0
ファイル: SphereStaticMesh.cs プロジェクト: bradleat/trafps
        public static void CollDetectSphereStaticMeshOverlap(BoundingSphere oldSphere, BoundingSphere newSphere,
            TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            float sphereTolR = collTolerance + newSphere.Radius;
            float sphereTolR2 = sphereTolR * sphereTolR;

            unsafe
            {
            #if USE_STACKALLOC
                SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                int* potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
                    {
            #else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed (SmallCollPointInfo* collPts = collPtArray)
                {
                    int[] potTriArray = IntStackAlloc();
                    fixed( int* potentialTriangles = potTriArray)
                    {
            #endif
                        int numCollPts = 0;

                        Vector3 collNormal = Vector3.Zero;

                        BoundingBox bb = BoundingBoxHelper.InitialBox;
                        BoundingBoxHelper.AddSphere(newSphere, ref bb);
                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                        // Deano : get the spheres centers in triangle mesh space
                        Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                        Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
                            float distToCentre = meshTriangle.Plane.DotCoordinate(newSphereCen);

                            if (distToCentre <= 0.0f)
                                continue;
                            if (distToCentre >= sphereTolR)
                                continue;
                            int i0, i1, i2;
                            meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                            Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                            float s, t;
                            float newD2 = Distance.PointTriangleDistanceSq(out s, out t, newSphereCen, triangle);

                            if (newD2 < sphereTolR2)
                            {
                                // have overlap - but actually report the old intersection
                                float oldD2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);
                                float dist = (float)System.Math.Sqrt((float)oldD2);
                                float depth = oldSphere.Radius - dist;

                                Vector3 triPointSTNorm = oldSphereCen - triangle.GetPoint(s, t);
                                JiggleMath.NormalizeSafe(ref triPointSTNorm);

                                Vector3 collisionN = (dist > float.Epsilon) ? triPointSTNorm : triangle.Normal;

                                // since impulse get applied at the old position
                                Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;

                                if (numCollPts < MaxLocalStackSCPI)
                                {
                                    collPts[numCollPts++] = new SmallCollPointInfo(pt - body0Pos, pt - body1Pos, depth);
                                }
                                collNormal += collisionN;
                            }
                        }

                        if (numCollPts > 0)
                        {
                            JiggleMath.NormalizeSafe(ref collNormal);
                            collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                        }
            #if USE_STACKALLOC
                    }
               }
            #else

                        FreeStackAlloc(potTriArray);
                    }
                    FreeStackAlloc(collPtArray);
                }
            #endif
            }
        }
コード例 #17
0
        private static bool DoOverlapBoxTriangleTest(Box oldBox, Box newBox,
            ref IndexedTriangle triangle, TriangleMesh mesh,
            ref CollDetectInfo info, float collTolerance,
            CollisionFunctor collisionFunctor)
        {
            Matrix dirs0 = newBox.Orientation;

            #region REFERENCE: Triangle tri = new Triangle(mesh.GetVertex(triangle.GetVertexIndex(0)),mesh.GetVertex(triangle.GetVertexIndex(1)),mesh.GetVertex(triangle.GetVertexIndex(2)));
            Vector3 triVec0;
            Vector3 triVec1;
            Vector3 triVec2;
            mesh.GetVertex(triangle.GetVertexIndex(0), out triVec0);
            mesh.GetVertex(triangle.GetVertexIndex(1), out triVec1);
            mesh.GetVertex(triangle.GetVertexIndex(2), out triVec2);

            // Deano move tri into world space
            Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            Triangle tri = new Triangle(ref triVec0,ref triVec1,ref triVec2);
            #endregion

            #region REFERENCE Vector3 triEdge0 = (tri.GetPoint(1) - tri.GetPoint(0));
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region REFERENCE Vector3 triEdge1 = (tri.GetPoint(2) - tri.GetPoint(1));
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region REFERENCE Vector3 triEdge2 = (tri.GetPoint(0) - tri.GetPoint(2));
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion

            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            Vector3 triNormal = triangle.Plane.Normal;

            // the 15 potential separating axes
            const int numAxes = 13;
            Vector3[] axes = new Vector3[numAxes];

            axes[0] = triNormal;
            axes[1] = dirs0.Right;
            axes[2] = dirs0.Up;
            axes[3] = dirs0.Backward;
            Vector3.Cross(ref axes[1], ref triEdge0, out axes[4]);
            Vector3.Cross(ref axes[1], ref triEdge1, out axes[5]);
            Vector3.Cross(ref axes[1], ref triEdge2, out axes[6]);
            Vector3.Cross(ref axes[2], ref triEdge0, out axes[7]);
            Vector3.Cross(ref axes[2], ref triEdge1, out axes[8]);
            Vector3.Cross(ref axes[2], ref triEdge2, out axes[9]);
            Vector3.Cross(ref axes[3], ref triEdge0, out axes[10]);
            Vector3.Cross(ref axes[3], ref triEdge1, out axes[11]);
            Vector3.Cross(ref axes[3], ref triEdge2, out axes[12]);

            // the overlap depths along each axis
            float[] overlapDepths = new float[numAxes];

            // 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)
            {
                overlapDepths[i] = 1.0f;
                if (Disjoint(out overlapDepths[i], axes[i], newBox, tri, collTolerance))
                    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 = axes[i].LengthSquared();
                if (l2 < JiggleMath.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 = newBox.GetCentre() - tri.Centre;
            Vector3 N = axes[minAxis];
            float depth = overlapDepths[minAxis];

            if (Vector3.Dot(D, N) < 0.0f)
               N *= -1;

            Vector3 boxOldPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            List<Vector3> pts = new List<Vector3>();
            //pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region REFERENCE: Vector3 delta = boxNewPos - boxOldPos;
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region REFERENCE: float oldDepth = depth + Vector3.Dot(delta, N);
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion

            unsafe
            {
                // report collisions
                int numPts = pts.Count;
            #if USE_STACKALLOC
                SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
            #else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed (SmallCollPointInfo* collPts = collPtArray)
            #endif
                {
                    if (numPts > 0)
                    {
                        if (numPts >= MaxLocalStackSCPI)
                        {
                            numPts = MaxLocalStackSCPI - 1;
                        }

                        // adjust positions
                        for (i = 0; i < numPts; ++i)
                        {
                            collPts[i] = new SmallCollPointInfo(pts[i] - boxNewPos, pts[i] - meshPos, oldDepth);
                        }

                        collisionFunctor.CollisionNotify(ref info, ref N, collPts, numPts);
            #if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
            #endif
                        return true;
                    }
                    else
                    {
            #if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
            #endif
                        return false;
                    }
                }

            }
        }
コード例 #18
0
        /// <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
            Matrix4 invTransformMatrix = mesh.InverseTransformMatrix;
            Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);
            #endregion

            BoundingBox bb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddBox(newBox, ref bb);

            unsafe
            {
                bool collision = false;

            #if USE_STACKALLOC
                int* potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
            #else
                int[] potTriArray = IntStackAlloc();
                fixed( int* potentialTriangles = potTriArray)
                {
            #endif
                    // aabox is done in mesh space and handles the mesh transform correctly
                    int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                    for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                    {
                        IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[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;
                        }
                    }
            #if USE_STACKALLOC
                }
            #else
                }
                FreeStackAlloc(potTriArray);
            #endif
                return collision;
            }
        }
コード例 #19
0
ファイル: Mesh.cs プロジェクト: MattVitelli/Nosferatu
        void ModifyMesh()
        {
            List<ModelPart> meshes = new List<ModelPart>();
            ModelPart collisionMesh = null;
            List<ModelPart> interactables = new List<ModelPart>();
            for (int i = 0; i < parts.Length; i++)
            {
                string[] meshName = parts[i].name.Split(':');
                if (meshName.Length == 1)
                {
                    if (meshName[0] == "COLLISION")
                        collisionMesh = parts[i];
                    else
                        meshes.Add(parts[i]);
                }
                else
                {
                    if (meshName[0] == "INTERACT")
                    {
                        interactables.Add(parts[i]);
                    }
                    else
                    {
                        if (!LODS.ContainsKey(meshName[0]))
                            LODS.Add(meshName[0], new List<ModelPart>());
                        int currLODValue = int.Parse(meshName[1].Substring(3));
                        parts[i].name = currLODValue.ToString();
                        bool addedPart = false;
                        for (int j = 0; j < LODS[meshName[0]].Count; j++)
                        {
                            int LODValue = int.Parse(LODS[meshName[0]][j].name);
                            if (currLODValue < LODValue)
                            {
                                LODS[meshName[0]].Insert(j, parts[i]);
                                addedPart = true;
                                break;
                            }
                        }
                        if (!addedPart)
                            LODS[meshName[0]].Add(parts[i]);
                    }
                }
            }

            if (collisionMesh != null)
                CreateCollisionMesh(collisionMesh);

            interactNodes = new InteractNode[interactables.Count];
            for (int i = 0; i < interactables.Count; i++)
            {
                interactNodes[i] = new InteractNode();
                interactNodes[i].NodeName = interactables[i].name;
                interactNodes[i].Dimensions = interactables[i].bounds;
            }

            parts = meshes.ToArray();
        }