protected override bool ConfigureTriangle(int i, out TriangleIndices indices)
        {
            MeshBoundingBoxTreeData data = mesh.Shape.TriangleMesh.Data;
            int triangleIndex = overlappedTriangles.Elements[i];
            data.GetTriangle(triangleIndex, out localTriangleShape.vA, out localTriangleShape.vB, out localTriangleShape.vC);
            AffineTransform.Transform(ref localTriangleShape.vA, ref mesh.worldTransform, out localTriangleShape.vA);
            AffineTransform.Transform(ref localTriangleShape.vB, ref mesh.worldTransform, out localTriangleShape.vB);
            AffineTransform.Transform(ref localTriangleShape.vC, ref mesh.worldTransform, out localTriangleShape.vC);
            //In instanced meshes, the bounding box we found in local space could collect more triangles than strictly necessary.
            //By doing a second pass, we should be able to prune out quite a few of them.
            BoundingBox triangleAABB;
            Toolbox.GetTriangleBoundingBox(ref localTriangleShape.vA, ref localTriangleShape.vB, ref localTriangleShape.vC, out triangleAABB);
            bool toReturn;
            triangleAABB.Intersects(ref convex.boundingBox, out toReturn);
            if (!toReturn)
            {
                indices = new TriangleIndices();
                return false;
            }

            localTriangleShape.sidedness = mesh.sidedness;
            localTriangleShape.collisionMargin = 0;
            indices = new TriangleIndices()
            {
                A = data.indices[triangleIndex],
                B = data.indices[triangleIndex + 1],
                C = data.indices[triangleIndex + 2]
            };

            return true;
        }
Пример #2
0
        protected override bool ConfigureTriangle(int i, out TriangleIndices indices)
        {
            indices = overlappedTriangles.Elements[i];
            terrain.Shape.GetTriangle(ref indices, ref terrain.worldTransform, out localTriangleShape.vA, out localTriangleShape.vB, out localTriangleShape.vC);
            localTriangleShape.collisionMargin = 0;

            //Calibrate the sidedness of the triangle such that it's always facing up.
            //TODO: There's quite a bit of redundancy in here with other systems.

            Vector3 AB, AC, normal;
            Vector3.Subtract(ref localTriangleShape.vB, ref localTriangleShape.vA, out AB);
            Vector3.Subtract(ref localTriangleShape.vC, ref localTriangleShape.vA, out AC);
            Vector3.Cross(ref AB, ref AC, out normal);

            Vector3 terrainUp = new Vector3(terrain.worldTransform.LinearTransform.M21, terrain.worldTransform.LinearTransform.M22, terrain.worldTransform.LinearTransform.M23);
            float dot;
            Vector3.Dot(ref terrainUp, ref normal, out dot);
            if (dot > 0)
            {
                localTriangleShape.sidedness = TriangleSidedness.Clockwise;
            }
            else
            {
                localTriangleShape.sidedness = TriangleSidedness.Counterclockwise;
            }
            //Unlike other 'instanced' geometries, terrains are almost always axis aligned in some way and/or have low triangle density relative to what they are colliding with.
            //Instead of performing additional tests, just assume that it's a fairly regular situation.
            return true;
        }
 protected override bool ConfigureTriangle(int i, out TriangleIndices indices)
 {
     int triangleIndex = overlappedTriangles.Elements[i];
     mesh.Mesh.Data.GetTriangle(triangleIndex, out localTriangleShape.vA, out localTriangleShape.vB, out localTriangleShape.vC);
     localTriangleShape.sidedness = mesh.sidedness;
     localTriangleShape.collisionMargin = 0;
     indices = new TriangleIndices();
     indices.A = mesh.Mesh.Data.indices[triangleIndex];
     indices.B = mesh.Mesh.Data.indices[triangleIndex + 1];
     indices.C = mesh.Mesh.Data.indices[triangleIndex + 2];
     return true;
 }
 protected override bool ConfigureLocalTriangle(int i, TriangleShape localTriangleShape, out TriangleIndices indices)
 {
     int triangleIndex = overlappedTriangles.Elements[i];
     var data = mesh.Mesh.Data;
     localTriangleShape.vA = data.vertices[data.indices[triangleIndex]];
     localTriangleShape.vB = data.vertices[data.indices[triangleIndex + 1]];
     localTriangleShape.vC = data.vertices[data.indices[triangleIndex + 2]];
     localTriangleShape.sidedness = mesh.sidedness;
     localTriangleShape.collisionMargin = 0;
     indices = new TriangleIndices
                   {
                       A = data.indices[triangleIndex],
                       B = data.indices[triangleIndex + 1],
                       C = data.indices[triangleIndex + 2]
                   };
     return true;
 }
        protected override bool ConfigureLocalTriangle(int i, TriangleShape localTriangleShape, out TriangleIndices indices)
        {
            TerrainVertexIndices a, b, c;
            terrain.Shape.GetLocalIndices(overlappedTriangles[i], out a, out b, out c);
            int terrainWidth = terrain.Shape.Heights.GetLength(0);
            indices.A = a.ToSequentialIndex(terrainWidth);
            indices.B = b.ToSequentialIndex(terrainWidth);
            indices.C = c.ToSequentialIndex(terrainWidth);
            terrain.Shape.GetLocalPosition(a.ColumnIndex, a.RowIndex, out localTriangleShape.vA);
            terrain.Shape.GetLocalPosition(b.ColumnIndex, b.RowIndex, out localTriangleShape.vB);
            terrain.Shape.GetLocalPosition(c.ColumnIndex, c.RowIndex, out localTriangleShape.vC);
            localTriangleShape.collisionMargin = 0;

            localTriangleShape.sidedness = terrain.sidedness;
 
            //Unlike other 'instanced' geometries, terrains are almost always axis aligned in some way and/or have low triangle density relative to what they are colliding with.
            //Instead of performing additional tests, just assume that it's a fairly regular situation.
            return true;
        }
        protected override bool ConfigureLocalTriangle(int i, TriangleShape localTriangleShape, out TriangleIndices indices)
        {
            MeshBoundingBoxTreeData data = mesh.Shape.TriangleMesh.Data;
            int triangleIndex = overlappedTriangles.Elements[i];
            localTriangleShape.sidedness = mesh.sidedness;
            localTriangleShape.collisionMargin = 0;
            indices = new TriangleIndices
            {
                A = data.indices[triangleIndex],
                B = data.indices[triangleIndex + 1],
                C = data.indices[triangleIndex + 2]
            };

            localTriangleShape.vA = data.vertices[indices.A];
            localTriangleShape.vB = data.vertices[indices.B];
            localTriangleShape.vC = data.vertices[indices.C];

            return true;
        }
        protected override bool ConfigureLocalTriangle(int i, TriangleShape localTriangleShape, out TriangleIndices indices)
        {
            var data = mesh.Shape.TriangleMesh.Data;
            int triangleIndex = overlappedTriangles.Elements[i];

            TriangleSidedness sidedness;
            switch (mesh.Shape.solidity)
            {
                case MobileMeshSolidity.Clockwise:
                    sidedness = TriangleSidedness.Clockwise;
                    break;
                case MobileMeshSolidity.Counterclockwise:
                    sidedness = TriangleSidedness.Counterclockwise;
                    break;
                case MobileMeshSolidity.DoubleSided:
                    sidedness = TriangleSidedness.DoubleSided;
                    break;
                default:
                    sidedness = mesh.Shape.SidednessWhenSolid;
                    break;
            }
            localTriangleShape.sidedness = sidedness;
            localTriangleShape.collisionMargin = 0;
            indices = new TriangleIndices
            {
                A = data.indices[triangleIndex],
                B = data.indices[triangleIndex + 1],
                C = data.indices[triangleIndex + 2]
            };

            localTriangleShape.vA = data.vertices[indices.A];
            localTriangleShape.vB = data.vertices[indices.B];
            localTriangleShape.vC = data.vertices[indices.C];

            return true;
        }
Пример #8
0
        private void SetTriangleEdgePointers(TriangleIndices tri)
        {
            // Remove the reference to this triangle from all edges
            foreach (var edge in tri.edges)
            {
                edge.triangles.RemoveAll(t => t == tri);
            }

            // Then rebuild the edges
            tri.edges.Clear();
            tri.edges.Add(AddEdge(tri.a, tri.b));
            tri.edges.Add(AddEdge(tri.b, tri.c));
            tri.edges.Add(AddEdge(tri.c, tri.a));
            tri.edges[0].triangles.Add(tri);
            tri.edges[1].triangles.Add(tri);
            tri.edges[2].triangles.Add(tri);
        }
Пример #9
0
 /// <summary>
 /// Add a new triangle with vertices a, b, and c.
 /// Vertices must be specified in counter-clockwise order when viewed from front.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="c"></param>
 public void AddTriangle(Vector3 a, Vector3 b, Vector3 c)
 {
     var newTriangle = new TriangleIndices() { a = AddVertex(a), b = AddVertex(b), c = AddVertex(c) };
     if (newTriangle.a != newTriangle.b && newTriangle.b != newTriangle.c && newTriangle.c != newTriangle.a)
     {
         triangles.Add(newTriangle);
         var triangle = triangles[triangles.Count - 1];
         SetTriangleEdgePointers(triangle);
     }
     else
     {
         // Bad triangle = has colinear edges.
     }
 }
Пример #10
0
        /// <summary>
        /// Get all connected triangles that satisfy a certain criteria
        /// </summary>
        /// <returns></returns>
        public TriangleIndices[] GetConnectedTriangles(TriangleIndices triangleIndices, List<TriangleIndices> ignoreIndices, Func<Triangle, bool> dotCriteria)
        {
            List<TriangleIndices> connected = new List<TriangleIndices>();
            connected.Add(triangleIndices);
            //ignoreIndices.Add(triangleIndices);

            foreach (var edge in triangleIndices.edges)
            {
                foreach (var otherindex in edge.triangles)
                {
                    if (ignoreIndices.Contains(otherindex) || connected.Contains(otherindex))
                    {
                        // Don't need to look at this one
                    }
                    else
                    {
                        var triangle = new Triangle(vertices[otherindex.a], vertices[otherindex.b], vertices[otherindex.c]);
                        var dot = Vector3.Dot(triangle.Plane.Normal, Vector3.UnitZ);
                        if (dotCriteria(triangle))
                        {
                            // Satisfies criteria, keep the triangle
                            List<TriangleIndices> newIgnore = new List<TriangleIndices>();
                            newIgnore.AddRange(ignoreIndices);
                            newIgnore.AddRange(connected);
                            var moreconnected = GetConnectedTriangles(otherindex, newIgnore, dotCriteria);
                            //ignoreIndices.AddRange(moreconnected);
                            connected.AddRange(moreconnected);
                        }
                    }
                }
            }

            return connected.ToArray();
        }
Пример #11
0
        public List<TriangleIndices> GetConnected(ref List<TriangleIndices> tempTriangles, TriangleIndices first)
        {
            List<TriangleIndices> connected = new List<TriangleIndices>();
            connected.Add(first);
            tempTriangles.Remove(first);

            foreach (var edge in first.edges)
            {
                foreach (var tri in edge.triangles)
                {
                    if (tempTriangles.Contains(tri))
                    {
                        connected.AddRange(GetConnected(ref tempTriangles, tri));
                    }
                }
            }

            return connected;
        }
Пример #12
0
        protected override bool ConfigureLocalTriangle(int i, TriangleShape localTriangleShape, out TriangleIndices indices)
        {
            int triangleIndex = overlappedTriangles.Elements[i];
            var data          = mesh.Mesh.Data;

            localTriangleShape.vA = data.vertices[data.indices[triangleIndex]];
            localTriangleShape.vB = data.vertices[data.indices[triangleIndex + 1]];
            localTriangleShape.vC = data.vertices[data.indices[triangleIndex + 2]];
            //TODO: Note the IsQuery hack to avoid missing contacts. Avoid doing this in v2.
            localTriangleShape.sidedness       = IsQuery ? TriangleSidedness.DoubleSided : mesh.sidedness;
            localTriangleShape.collisionMargin = 0;
            indices = new TriangleIndices
            {
                A = data.indices[triangleIndex],
                B = data.indices[triangleIndex + 1],
                C = data.indices[triangleIndex + 2]
            };
            return(true);
        }
        protected override bool ConfigureTriangle(int i, out TriangleIndices indices)
        {
            MeshBoundingBoxTreeData data = mesh.Shape.TriangleMesh.Data;
            int triangleIndex = overlappedTriangles.Elements[i];
            data.GetTriangle(triangleIndex, out localTriangleShape.vA, out localTriangleShape.vB, out localTriangleShape.vC);
            AffineTransform transform;
            AffineTransform.CreateFromRigidTransform(ref mesh.worldTransform, out transform);
            AffineTransform.Transform(ref localTriangleShape.vA, ref transform, out localTriangleShape.vA);
            AffineTransform.Transform(ref localTriangleShape.vB, ref transform, out localTriangleShape.vB);
            AffineTransform.Transform(ref localTriangleShape.vC, ref transform, out localTriangleShape.vC);
            //In instanced meshes, the bounding box we found in local space could collect more triangles than strictly necessary.
            //By doing a second pass, we should be able to prune out quite a few of them.
            BoundingBox triangleAABB;
            Toolbox.GetTriangleBoundingBox(ref localTriangleShape.vA, ref localTriangleShape.vB, ref localTriangleShape.vC, out triangleAABB);
            bool toReturn;
            triangleAABB.Intersects(ref convex.boundingBox, out toReturn);
            if (!toReturn)
            {
                indices = new TriangleIndices();
                return false;
            }

            TriangleSidedness sidedness;
            switch (mesh.Shape.solidity)
            {
                case MobileMeshSolidity.Clockwise:
                    sidedness = TriangleSidedness.Clockwise;
                    break;
                case MobileMeshSolidity.Counterclockwise:
                    sidedness = TriangleSidedness.Counterclockwise;
                    break;
                case MobileMeshSolidity.DoubleSided:
                    sidedness = TriangleSidedness.DoubleSided;
                    break;
                default:
                    sidedness = mesh.Shape.SidednessWhenSolid;
                    break;
            }
            localTriangleShape.sidedness = sidedness;
            localTriangleShape.collisionMargin = 0;
            indices = new TriangleIndices()
            {
                A = data.indices[triangleIndex],
                B = data.indices[triangleIndex + 1],
                C = data.indices[triangleIndex + 2]
            };
            return true;
        }
Пример #14
0
        //Generate+scale
        public void Generate(List <double> parameterList, float scale)
        {
            Object3DGenerate(parameterList);
            if (parameterList == null)
            {
                return;
            }
            if (parameterList.Count < 1)
            {
                return;
            }
            numberOfLongitudePoints = (int)Math.Round(parameterList[0]);
            double deltaU = 1 / (double)numberOfLongitudePoints;
            List <List <List <double> > > pointList = new List <List <List <double> > >();

            for (int iZ = 0; iZ < horizontalBezierCurveList.Count; iZ++)
            {
                List <List <double> > slicePointList        = new List <List <double> >();
                BezierCurve           horizontalBezierCurve = horizontalBezierCurveList[iZ];
                double z = horizontalBezierCurve.SplineList[0].ControlPointList[0].CoordinateList[2] * scale;
                for (int iLongitude = 0; iLongitude < numberOfLongitudePoints; iLongitude++)
                {
                    double uGlobal = iLongitude * deltaU;
                    if (iZ % 2 == 0)
                    {
                        uGlobal += deltaU / 2;
                    }                                           // Shift points in every other layer
                    PointND point = horizontalBezierCurve.GetPoint(uGlobal);
                    double  x     = point.CoordinateList[0] * scale;
                    double  y     = point.CoordinateList[1] * scale;
                    slicePointList.Add(new List <double>()
                    {
                        x, y, z
                    });
                    Vertex3D vertex = new Vertex3D(x, y, z);
                    vertexList.Add(vertex);
                }
                pointList.Add(slicePointList);
            }

            for (int iZ = 1; iZ < horizontalBezierCurveList.Count; iZ++)
            {
                int iSumPrevious = (iZ - 1) * numberOfLongitudePoints;
                int iSum         = iZ * numberOfLongitudePoints;
                for (int iPhi = 0; iPhi < numberOfLongitudePoints; iPhi++)
                {
                    if (iZ % 2 == 0)
                    {
                        int i1 = iSumPrevious + iPhi;
                        int i3 = iSum + iPhi;
                        int i2 = iSumPrevious + iPhi + 1;


                        if ((iPhi + 1) >= numberOfLongitudePoints)
                        {
                            i2 -= numberOfLongitudePoints;
                        }
                        TriangleIndices triangleIndices1 = new TriangleIndices(i1, i2, i3);
                        triangleIndicesList.Add(triangleIndices1);
                        i1 = iSum + iPhi;
                        i3 = iSum + iPhi + 1;
                        i2 = iSumPrevious + iPhi + 1;
                        if ((iPhi + 1) >= numberOfLongitudePoints)
                        {
                            i2 -= numberOfLongitudePoints;
                            i3 -= numberOfLongitudePoints;
                        }
                        TriangleIndices triangleIndices2 = new TriangleIndices(i1, i2, i3);
                        triangleIndicesList.Add(triangleIndices2);
                    }
                    else
                    {
                        int i1 = iSumPrevious + iPhi;
                        int i3 = iSum + iPhi + 1;
                        int i2 = iSumPrevious + iPhi + 1;
                        if ((iPhi + 1) >= numberOfLongitudePoints)
                        {
                            i2 -= numberOfLongitudePoints;
                            i3 -= numberOfLongitudePoints;
                        }
                        TriangleIndices triangleIndices1 = new TriangleIndices(i1, i2, i3);
                        triangleIndicesList.Add(triangleIndices1);
                        i1 = iSum + iPhi;
                        i3 = iSum + iPhi + 1;
                        i2 = iSumPrevious + iPhi;
                        if ((iPhi + 1) >= numberOfLongitudePoints)
                        {
                            i3 -= numberOfLongitudePoints;
                        }
                        TriangleIndices triangleIndices2 = new TriangleIndices(i1, i2, i3);
                        triangleIndicesList.Add(triangleIndices2);
                    }
                }
            }
            GenerateTriangleConnectionLists();
            ComputeTriangleNormalVectors();
            ComputeVertexNormalVectors();
        }