Exemplo n.º 1
0
        public static (int, int) FillBetweenEdges(DMesh3Builder meshBuilder, Edge a, Edge b, Vector3f normal)
        {
            //var sideA = a.EndVertex - a.BeginVertex;
            //var sideB = b.EndVertex - b.BeginVertex;
            //var normal =
            var a0 = meshBuilder.AppendVertex(new NewVertexInfo(a.BeginVertex, normal));
            var a1 = meshBuilder.AppendVertex(new NewVertexInfo(a.EndVertex, normal));
            var b0 = meshBuilder.AppendVertex(new NewVertexInfo(b.BeginVertex, normal));
            var b1 = meshBuilder.AppendVertex(new NewVertexInfo(b.EndVertex, normal));

            return(meshBuilder.AppendTriangle(a0, b1, b0),
                   meshBuilder.AppendTriangle(a0, a1, b1));
        }
Exemplo n.º 2
0
    void Start()
    {
        if (model != null)
        {
            mesh          = model.sharedMesh;
            meshVertices  = mesh.vertices;
            meshTriangles = mesh.triangles;
            for (int i = 0; i < meshVertices.Length; i++)
            {
                meshVertices[i] = model.transform.TransformPoint(meshVertices[i]);
            }
            binarySpacePartition = new BSP(mesh, 14);

#if G3_USING_UNITY
            DMesh3Builder dMeshBuilder = new DMesh3Builder();
            dMeshBuilder.AppendNewMesh(false, false, false, false);
            foreach (Vector3 vertex in meshVertices)
            {
                dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z);
            }
            for (int i = 0; i < meshTriangles.Length; i += 3)
            {
                dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]);
            }
            g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]);
            g3MeshTree.Build();
#endif
        }
    }
Exemplo n.º 3
0
    void Start()
    {
        if (model != null)
        {
            mesh          = model.sharedMesh;
            meshVertices  = mesh.vertices;
            meshTriangles = mesh.triangles;
            for (int i = 0; i < meshVertices.Length; i++)
            {
                meshVertices[i] = model.transform.TransformPoint(meshVertices[i]);
            }
            binarySpacePartition = new BSP(mesh, 14);

            if (diskMaterial)
            {
                int numDisksToDraw = Mathf.Min(binarySpacePartition.splittingDisks.Length, 15);
                diskMatrices = new Matrix4x4[numDisksToDraw];
                for (int i = 0; i < numDisksToDraw; i++)
                {
                    diskMatrices[i] = Matrix4x4.TRS(
                        binarySpacePartition.splittingDisks[i].average,
                        Quaternion.LookRotation(binarySpacePartition.splittingDisks[i].plane),
                        new Vector3(1f, 1f, 0.0001f) * Mathf.Sqrt(binarySpacePartition.splittingDisks[i].sqRadius));
                }
            }

#if G3_USING_UNITY
            DMesh3Builder dMeshBuilder = new DMesh3Builder();
            dMeshBuilder.AppendNewMesh(false, false, false, false);
            foreach (Vector3 vertex in meshVertices)
            {
                dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z);
            }
            for (int i = 0; i < meshTriangles.Length; i += 3)
            {
                dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]);
            }
            g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]);
            g3MeshTree.Build();
#endif
        }
    }
        public override bool BuildOnMesh(DMesh3Builder meshBuilder)
        {
            var intrude = double.MaxValue;

            for (int p = 0; p < BaseShape.Count; ++p)
            {
                var nextP = (p + 1) % BaseShape.Count;
                for (int otherP = 0; otherP < BaseShape.Count; ++otherP)
                {
                    if (otherP == p || otherP == nextP)
                    {
                        continue;
                    }
                    intrude = Math.Min(intrude, Geometry.PointSqrDistanceToSegment(
                                           Tuple.Create(BaseShape[p], BaseShape[nextP]), BaseShape[otherP]));
                }
                intrude = Math.Min(intrude, (BaseShape[nextP] - BaseShape[p]).LengthSquared);
            }
            if (intrude < 0.0)
            {
                throw new Exception("Invalid intrude");
            }
            //intrude /= BaseShape.Count;
            intrude = Math.Sqrt(intrude) / 5;

            // scale up base shape and connect to base
            var newBasePolygon = CompressAndOffsetPolygon(BaseShape, -intrude / 2, Vector3d.Zero);

            FillBetweenPolygons(meshBuilder, BaseShape, newBasePolygon);

            // elevale big shape a bit up and connect to big shape
            var elevation       = Vector3d.AxisY * RoofHeight * 0.15;
            var topOuterPolygon = newBasePolygon.Select(p => p + elevation).ToList();

            for (int p = 0; p < newBasePolygon.Count; ++p)
            {
                var nextP  = ((p + 1) + newBasePolygon.Count) % newBasePolygon.Count;
                var side   = newBasePolygon[nextP] - newBasePolygon[p];
                var normal = new Vector3f(side.UnitCross(Vector3d.AxisY));
                MeshUtility.FillBetweenEdges(meshBuilder,
                                             new MeshUtility.Edge(newBasePolygon[p], newBasePolygon[nextP]),
                                             new MeshUtility.Edge(topOuterPolygon[p], topOuterPolygon[nextP]),
                                             normal);
            }

            // find small polygons on top
            var topPolygon = CompressAndOffsetPolygon(BaseShape, intrude, Vector3d.AxisY * RoofHeight * 0.85);
            var brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(topPolygon);

            //brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(brokenSelfIntersections);
            //brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(brokenSelfIntersections);

            // fill some edges of base and top
            for (int p = 0; p < brokenSelfIntersections.Count; ++p)
            {
                var nextP    = ((p + 1) + topOuterPolygon.Count) % topOuterPolygon.Count;
                var sideBase = topPolygon[nextP] - topPolygon[p];
                var sideTop  = brokenSelfIntersections[nextP].First() - brokenSelfIntersections[p].Last();
                var normal   = new Vector3f(sideTop.UnitCross(sideBase));
                MeshUtility.FillBetweenEdges(meshBuilder,
                                             new MeshUtility.Edge(topOuterPolygon[p], topOuterPolygon[nextP]),
                                             new MeshUtility.Edge(brokenSelfIntersections[p].Last(), brokenSelfIntersections[nextP].First()),
                                             normal);
            }

            //return true;
            // fill triangle fan for multi-point and top
            var subTopPolygon   = new List <Vector3d>();
            int firstMultiPoint = Enumerable.Range(0, brokenSelfIntersections.Count)
                                  .FirstOrDefault(p => brokenSelfIntersections[p].Count >= 2);

            for (int pU = firstMultiPoint; pU < brokenSelfIntersections.Count + firstMultiPoint + 1; ++pU)
            {
                int p = pU % brokenSelfIntersections.Count;
                subTopPolygon.Add(brokenSelfIntersections[p].First());
                if (brokenSelfIntersections[p].Count > 1)
                {
                    MeshUtility.FillPolygon(meshBuilder, subTopPolygon, Vector3f.AxisY);
                    subTopPolygon.Clear();
                    var firstP = topOuterPolygon[p];

                    var limit = brokenSelfIntersections[p].Count;
                    for (int i = 0; i < limit - 1; ++i)
                    {
                        var curP   = brokenSelfIntersections[p][i];
                        var nextP  = brokenSelfIntersections[p][(i + 1) % limit];
                        var normal = (Vector3f)(firstP - curP).UnitCross(nextP - curP);
                        var firstV = meshBuilder.AppendVertex(new NewVertexInfo
                        {
                            v = firstP,
                            n = normal,
                        });
                        var curV = meshBuilder.AppendVertex(new NewVertexInfo
                        {
                            v = curP,
                            n = normal,
                        });
                        var nextV = meshBuilder.AppendVertex(new NewVertexInfo
                        {
                            v = nextP,
                            n = normal,
                        });
                        meshBuilder.AppendTriangle(firstV, nextV, curV);
                    }
                    subTopPolygon.Add(brokenSelfIntersections[p].Last());
                }
            }
            subTopPolygon.Add(brokenSelfIntersections[0].First());
            MeshUtility.FillPolygon(meshBuilder, subTopPolygon, Vector3f.AxisY);

            return(true);
        }
 public int AppentVertex(DMesh3Builder meshBuilder, NewVertexInfo vInfo, Vector3d vertex)
 {
     vInfo.v = vertex;
     return(meshBuilder.AppendVertex(vInfo));
 }