Tessellate() 공개 메소드

public Tessellate ( WindingRule windingRule, ElementType elementType, int polySize ) : void
windingRule WindingRule
elementType ElementType
polySize int
리턴 void
예제 #1
0
        public static void GenerateTestData()
        {
            foreach (var name in _loader.AssetNames)
            {
                var pset = _loader.GetAsset(name).Polygons;

                var lines = new List<string>();
                var indices = new List<int>();

                foreach (WindingRule winding in Enum.GetValues(typeof(WindingRule)))
                {
                    var tess = new Tess();
                    PolyConvert.ToTess(pset, tess);
                    tess.Tessellate(winding, ElementType.Polygons, 3);

                    lines.Add(string.Format("{0} {1}", winding, 3));
                    for (int i = 0; i < tess.ElementCount; i++)
                    {
                        indices.Clear();
                        for (int j = 0; j < 3; j++)
                        {
                            int index = tess.Elements[i * 3 + j];
                            indices.Add(index);
                        }
                        lines.Add(string.Join(" ", indices));
                    }
                    lines.Add("");
                }

                File.WriteAllLines(Path.Combine(TestDataPath, name + ".testdat"), lines);
            }
        }
예제 #2
0
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    public static List <int> GetIndices(ref List <Vector2> aPoints, bool aTreatAsPath, bool aInvert)
    {
        Vector4 bounds = GetBounds(aPoints);

        LibTessDotNet.Tess tess = new LibTessDotNet.Tess();

        LibTessDotNet.ContourVertex[] verts = new LibTessDotNet.ContourVertex[aPoints.Count];
        for (int i = 0; i < aPoints.Count; i++)
        {
            verts[i]            = new LibTessDotNet.ContourVertex();
            verts[i].Position   = new LibTessDotNet.Vec3();
            verts[i].Position.X = aPoints[i].x;
            verts[i].Position.Y = aPoints[i].y;
            verts[i].Position.Z = 0;
        }
        tess.AddContour(verts, LibTessDotNet.ContourOrientation.Original);
        if (aInvert)
        {
            aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4
            aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3
            aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2
            aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1
            LibTessDotNet.ContourVertex[] outer = new LibTessDotNet.ContourVertex[4];
            for (int i = 0; i < 4; i++)
            {
                outer[i]            = new LibTessDotNet.ContourVertex();
                outer[i].Position   = new LibTessDotNet.Vec3();
                outer[i].Position.X = aPoints[(aPoints.Count - 4) + i].x;
                outer[i].Position.Y = aPoints[(aPoints.Count - 4) + i].y;
                outer[i].Position.Z = 0;
            }
            tess.AddContour(outer, aInvert ? LibTessDotNet.ContourOrientation.CounterClockwise : LibTessDotNet.ContourOrientation.Clockwise);
        }
        tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);
        List <int> result = new List <int>();

        for (int i = 0; i < tess.Elements.Length; i += 3)
        {
            for (int t = 0; t < 3; t++)
            {
                if (tess.Elements[i + t] == -1)
                {
                    continue;
                }
                for (int v = 0; v < aPoints.Count; v++)
                {
                    if (aPoints[v].x == tess.Vertices[tess.Elements[i + t]].Position.X &&
                        aPoints[v].y == tess.Vertices[tess.Elements[i + t]].Position.Y)
                    {
                        result.Add(v);
                        break;
                    }
                }
            }
        }
        return(result);
    }
예제 #3
0
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    public static List<int> GetIndices(ref List<Vector2> aPoints, bool aTreatAsPath, bool aInvert)
    {
        Vector4 bounds = GetBounds(aPoints);
        LibTessDotNet.Tess tess = new LibTessDotNet.Tess();

        LibTessDotNet.ContourVertex[] verts = new LibTessDotNet.ContourVertex[aPoints.Count];
        for (int i = 0; i < aPoints.Count; i++)
        {
            verts[i] = new LibTessDotNet.ContourVertex();
            verts[i].Position = new LibTessDotNet.Vec3();
            verts[i].Position.X = aPoints[i].x;
            verts[i].Position.Y = aPoints[i].y;
            verts[i].Position.Z = 0;
        }
        tess.AddContour(verts, LibTessDotNet.ContourOrientation.Original);
        if (aInvert)
        {
            aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4
            aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3
            aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2
            aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1
            LibTessDotNet.ContourVertex[] outer = new LibTessDotNet.ContourVertex[4];
            for (int i = 0; i < 4; i++)
            {
                outer[i] = new LibTessDotNet.ContourVertex();
                outer[i].Position = new LibTessDotNet.Vec3();
                outer[i].Position.X = aPoints[(aPoints.Count - 4) + i].x;
                outer[i].Position.Y = aPoints[(aPoints.Count - 4) + i].y;
                outer[i].Position.Z = 0;
            }
            tess.AddContour(outer, aInvert ? LibTessDotNet.ContourOrientation.CounterClockwise : LibTessDotNet.ContourOrientation.Clockwise);
        }
        tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);
        List<int> result = new List<int>();
        for (int i = 0; i < tess.Elements.Length; i += 3)
        {
            for (int t = 0; t < 3; t++)
            {
                if (tess.Elements[i + t] == -1)
                {
                    continue;
                }
                for (int v = 0; v < aPoints.Count; v++)
                {
                    if (aPoints[v].x == tess.Vertices[tess.Elements[i + t]].Position.X &&
                        aPoints[v].y == tess.Vertices[tess.Elements[i + t]].Position.Y)
                    {
                        result.Add(v);
                        break;
                    }
                }
            }
        }
        return result;
    }
예제 #4
0
        public static Cad2D.Polygon Tesselate(List <Cad2D.Polygon> Polygons)
        {
            // Create an instance of the tessellator. Can be reused.
            var tess = new LibTessDotNet.Tess();

            // Construct the contours from input polygons

            // A polygon can be composed of multiple contours which are all tessellated at the same time.

            foreach (Cad2D.Polygon poly in Polygons)
            {
                int numPoints = poly.Vertices.Count;

                var contour = new LibTessDotNet.ContourVertex[numPoints];
                for (int i = 0; i < numPoints; i++)
                {
                    // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important.
                    contour[i].Position = new LibTessDotNet.Vec3 {
                        X = poly.Vertices[i].X, Y = poly.Vertices[i].Y, Z = 0.0f
                    };

                    // Data can contain any per-vertex data, here a constant color.
                    contour[i].Data = Color.Azure;
                }

                // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation.
                tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise);
            }


            // Tessellate!
            // The winding rule determines how the different contours are combined together.
            // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information.
            // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon.
            tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine);

            // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated.
            //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case.

            Cad2D.Polygon result = new Cad2D.Polygon();

            int numTriangles = tess.ElementCount;

            result.Triangles = new List <Cad2D.Triangle>();
            for (int i = 0; i < numTriangles; i++)
            {
                var v0 = tess.Vertices[tess.Elements[i * 3]].Position;
                var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;

                result.Triangles.Add(new Cad2D.Triangle(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y));
            }

            return(result);
        }
예제 #5
0
        static void Main(string[] args)
        {
            // Example input data in the form of a star that intersects itself.
            var inputData = new float[] { 0.0f, 3.0f, -1.0f, 0.0f, 1.6f, 1.9f, -1.6f, 1.9f, 1.0f, 0.0f };

            // Create an instance of the tessellator. Can be reused.
            var tess = new LibTessDotNet.Tess();

            // Construct the contour from inputData.
            // A polygon can be composed of multiple contours which are all tessellated at the same time.
            int numPoints = inputData.Length / 2;
            var contour   = new LibTessDotNet.ContourVertex[numPoints];

            for (int i = 0; i < numPoints; i++)
            {
                // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important.
                contour[i].Position = new LibTessDotNet.Vec3 {
                    X = inputData[i * 2], Y = inputData[i * 2 + 1], Z = 0.0f
                };
                // Data can contain any per-vertex data, here a constant color.
                contour[i].Data = Color.Azure;
            }
            // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation.
            tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise);

            // Tessellate!
            // The winding rule determines how the different contours are combined together.
            // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information.
            // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon.
            tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine);

            // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated.
            //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case.

            Console.WriteLine("Output triangles:");
            int numTriangles = tess.ElementCount;

            for (int i = 0; i < numTriangles; i++)
            {
                var v0 = tess.Vertices[tess.Elements[i * 3]].Position;
                var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;
                Console.WriteLine("#{0} ({1:F1},{2:F1}) ({3:F1},{4:F1}) ({5:F1},{6:F1})", i, v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
            }
            Console.ReadLine();
        }
예제 #6
0
        static void Main(string[] args)
        {
            // Example input data in the form of a star that intersects itself.
            var inputData = new float[] { 0.0f, 3.0f, -1.0f, 0.0f, 1.6f, 1.9f, -1.6f, 1.9f, 1.0f, 0.0f };

            // Create an instance of the tessellator. Can be reused.
            var tess = new LibTessDotNet.Tess();

            // Construct the contour from inputData.
            // A polygon can be composed of multiple contours which are all tessellated at the same time.
            int numPoints = inputData.Length / 2;
            var contour = new LibTessDotNet.ContourVertex[numPoints];
            for (int i = 0; i < numPoints; i++)
            {
                // NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important.
                contour[i].Position = new LibTessDotNet.Vec3 { X = inputData[i * 2], Y = inputData[i * 2 + 1], Z = 0.0f };
                // Data can contain any per-vertex data, here a constant color.
                contour[i].Data = Color.Azure;
            }
            // Add the contour with a specific orientation, use "Original" if you want to keep the input orientation.
            tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise);

            // Tessellate!
            // The winding rule determines how the different contours are combined together.
            // See http://www.glprogramming.com/red/chapter11.html (section "Winding Numbers and Winding Rules") for more information.
            // If you want triangles as output, you need to use "Polygons" type as output and 3 vertices per polygon.
            tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine);

            // Same call but the last callback is optional. Data will be null because no interpolated data would have been generated.
            //tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); // Some vertices will have null Data in this case.

            Console.WriteLine("Output triangles:");
            int numTriangles = tess.ElementCount;
            for (int i = 0; i < numTriangles; i++)
            {
                var v0 = tess.Vertices[tess.Elements[i * 3]].Position;
                var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;
                Console.WriteLine("#{0} ({1:F1},{2:F1}) ({3:F1},{4:F1}) ({5:F1},{6:F1})", i, v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
            }
            Console.ReadLine();
        }
예제 #7
0
        static void Main(string[] args)
        {
            if (args.Length >= 1)
            {
                if (string.Equals(args[0], "gentestdat", StringComparison.OrdinalIgnoreCase))
                {
                    UnitTests.GenerateTestData();
                }
                if (args.Length == 2 && string.Equals(args[0], "profile", StringComparison.OrdinalIgnoreCase))
                {
                    int count = 0;
                    if (!int.TryParse(args[1], out count))
                    {
                        return;
                    }
                    var stopwatch = new Stopwatch();
                    var loader = new DataLoader();
                    for (int i = 0; i < count; i++)
                    {
                        foreach (var name in loader.AssetNames)
                        {
                            var pset = loader.GetAsset(name).Polygons;

                            foreach (WindingRule winding in Enum.GetValues(typeof(WindingRule)))
                            {
                                var tess = new Tess();
                                PolyConvert.ToTess(pset, tess);
                                stopwatch.Start();
                                tess.Tessellate(winding, ElementType.Polygons, 3);
                                stopwatch.Stop();
                            }
                        }
                    }
                    Console.WriteLine("{0:F3}ms", stopwatch.Elapsed.TotalMilliseconds);
                }
                return;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
예제 #8
0
        private void adaptate()
        {
            if (!this.aad.isRectangular() && this.aad.getInfluenceArea() != null)
            {
                this.transform.localScale = new Vector3(1, 1, 1);

                Mesh           mesh     = new Mesh();
                List <Vector3> vertices = new List <Vector3>();
                Tess           tess     = new LibTessDotNet.Tess();

                ContourVertex[] contour = new ContourVertex[aad.getPoints().Count];
                int             i       = 0;

                float minx = float.MaxValue, miny = float.MaxValue, maxx = 0, maxy = 0;
                foreach (Vector2 v in this.aad.getPoints())
                {
                    if (v.x < minx)
                    {
                        minx = v.x;
                    }

                    if (v.x > maxx)
                    {
                        maxx = v.x;
                    }

                    if (v.y < miny)
                    {
                        miny = v.y;
                    }

                    if (v.y > maxy)
                    {
                        maxy = v.y;
                    }
                }

                minx = (minx + (maxx - minx) / 2) / 10;
                miny = 60 - (miny + (maxy - miny) / 2) / 10;

                foreach (Vector2 v in this.aad.getPoints())
                {
                    contour[i].Position = new LibTessDotNet.Vec3 {
                        X = v.x / 10f - minx, Y = 60 - v.y / 10f - miny, Z = this.transform.position.z
                    };
                    i++;
                }

                tess.AddContour(contour, LibTessDotNet.ContourOrientation.CounterClockwise);
                tess.Tessellate(WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

                List <int> triangles    = new List <int>();
                int        numTriangles = tess.ElementCount;
                for (i = 0; i < numTriangles; i++)
                {
                    vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3]].Position));
                    vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 1]].Position));
                    vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 2]].Position));
                    triangles.AddRange(new int[] { i * 3, i * 3 + 1, i * 3 + 2 });
                }

                mesh.SetVertices(vertices);
                mesh.SetTriangles(triangles, 0);

                this.GetComponent <MeshFilter>().sharedMesh   = mesh;
                this.GetComponent <MeshCollider>().sharedMesh = mesh;
            }
        }
예제 #9
0
        public void Tessellate_WithAsset_ReturnsExpectedTriangulation(TestCaseData data)
        {
            var pset = _loader.GetAsset(data.AssetName).Polygons;
            var tess = new Tess();
            PolyConvert.ToTess(pset, tess);
            tess.Tessellate(data.Winding, ElementType.Polygons, data.ElementSize);

            var resourceName = Assembly.GetExecutingAssembly().GetName().Name + ".TestData." + data.AssetName + ".testdat";
            var testData = ParseTestData(data.Winding, data.ElementSize, Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName));
            Assert.IsNotNull(testData);
            Assert.AreEqual(testData.ElementSize, data.ElementSize);

            var indices = new List<int>();
            for (int i = 0; i < tess.ElementCount; i++)
            {
                for (int j = 0; j < data.ElementSize; j++)
                {
                    int index = tess.Elements[i * data.ElementSize + j];
                    indices.Add(index);
                }
            }

            Assert.AreEqual(testData.Indices, indices.ToArray());
        }
예제 #10
0
 public void Tesselate_WithThinQuad_DoesNotCrash()
 {
     string data = "9.5,7.5,-0.5\n9.5,2,-0.5\n9.5,2,-0.4999999701976776123\n9.5,7.5,-0.4999999701976776123";
     using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
     {
         var pset = DataLoader.LoadDat(stream);
         var tess = new Tess();
         PolyConvert.ToTess(pset, tess);
         tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
     }
 }
예제 #11
0
        public void Tesselate_WithSingleTriangle_ProducesSameTriangle()
        {
            string data = "0,0,0\n0,1,0\n1,1,0";
            var indices = new List<int>();
            var expectedIndices = new int[] { 0, 1, 2 };
            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
            {
                var pset = DataLoader.LoadDat(stream);
                var tess = new Tess();

                PolyConvert.ToTess(pset, tess);
                tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);

                indices.Clear();
                for (int i = 0; i < tess.ElementCount; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        int index = tess.Elements[i * 3 + j];
                        indices.Add(index);
                    }
                }

                Assert.AreEqual(expectedIndices, indices.ToArray());
            }
        }
예제 #12
0
 public void Tesselate_WithNoEmptyPolygonsTrue_RemovesEmptyPolygons()
 {
     string data = "2,0,4\n2,0,2\n4,0,2\n4,0,0\n0,0,0\n0,0,4";
     var indices = new List<int>();
     var expectedIndices = new int[] { 0, 1, 2, 2, 3, 4, 3, 1, 5 };
     using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
     {
         var pset = DataLoader.LoadDat(stream);
         var tess = new Tess();
         PolyConvert.ToTess(pset, tess);
         tess.NoEmptyPolygons = true;
         tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
         indices.Clear();
         for (int i = 0; i < tess.ElementCount; i++)
         {
             for (int j = 0; j < 3; j++)
             {
                 int index = tess.Elements[i * 3 + j];
                 indices.Add(index);
             }
         }
         Assert.AreEqual(expectedIndices, indices.ToArray());
     }
 }
예제 #13
0
 public void Tesselate_WithIssue1Quad_ReturnsSameResultAsLibtess2()
 {
     string data = "50,50\n300,50\n300,200\n50,200";
     var indices = new List<int>();
     var expectedIndices = new int[] { 0, 1, 2, 1, 0, 3 };
     using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
     {
         var pset = DataLoader.LoadDat(stream);
         var tess = new Tess();
         PolyConvert.ToTess(pset, tess);
         tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
         indices.Clear();
         for (int i = 0; i < tess.ElementCount; i++)
         {
             for (int j = 0; j < 3; j++)
             {
                 int index = tess.Elements[i * 3 + j];
                 indices.Add(index);
             }
         }
         Assert.AreEqual(expectedIndices, indices.ToArray());
     }
 }
예제 #14
0
    private void adaptate()
    {
        if (!this.aad.isRectangular() && this.aad.getInfluenceArea () != null) {
            this.transform.localScale = new Vector3 (1, 1, 1);

            Mesh mesh = new Mesh ();
            List<Vector3> vertices = new List<Vector3> ();
            List<Vector2> vertices2 = new List<Vector2> ();
            Tess tess = new LibTessDotNet.Tess();

            ContourVertex[] contour = new ContourVertex[aad.getPoints().Count];
            int i = 0;

            float minx = float.MaxValue, miny = float.MaxValue, maxx = 0, maxy = 0;
            foreach (Vector2 v in this.aad.getPoints()) {
                if (v.x < minx)
                    minx = v.x;

                if (v.x > maxx)
                    maxx = v.x;

                if (v.y < miny)
                    miny = v.y;

                if (v.y > maxy)
                    maxy = v.y;
            }

            minx = (minx + (maxx - minx) / 2 ) / 10;
            miny = 60 - (miny + (maxy - miny) / 2 ) / 10;

            foreach (Vector2 v in this.aad.getPoints()) {
                contour[i].Position = new LibTessDotNet.Vec3 { X = v.x / 10f - minx, Y = 60 - v.y / 10f - miny, Z = this.transform.position.z };
                i++;
            }

            tess.AddContour(contour, LibTessDotNet.ContourOrientation.CounterClockwise);
            tess.Tessellate(WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons,3);

            Debug.Log("Output triangles:");
            List<int> triangles = new List<int> ();
            int numTriangles = tess.ElementCount;
            for (i = 0; i < numTriangles; i++){
                vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3]].Position));
                vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 1]].Position));
                vertices.Add(Vec3toVector3(tess.Vertices[tess.Elements[i * 3 + 2]].Position));
                triangles.AddRange(new int[] { i * 3, i * 3+1, i * 3+2 });
            }

            mesh.SetVertices (vertices);
            mesh.SetTriangles (triangles,0);

            this.GetComponent<MeshFilter> ().sharedMesh = mesh;
            this.GetComponent<MeshCollider> ().sharedMesh = mesh;
        }
    }
예제 #15
0
        public void DrawPath(Path path, VBO vbo)
        {
            List <List <Vector2> > shapes     = new List <List <Vector2> >();
            List <Vector2>         positions  = new List <Vector2>();
            List <Vector2>         tesselated = new List <Vector2>();
            Point position = new Point();

            foreach (var op in path.Operations)
            {
                var mt = op as MoveTo;
                if (mt != null)
                {
                    shapes.Add(positions);
                    positions = new List <Vector2>();

                    positions.Add(Vec2(mt.Point));
                    position = mt.Point;
                    continue;
                }
                var lt = op as LineTo;
                if (lt != null)
                {
                    positions.Add(Vec2(lt.Point));
                    position = lt.Point;
                    continue;
                }
                var at = op as ArcTo;
                if (at != null)
                {
                    var p = nsvg.nsvg__pathArcTo((Vector2d)Vec2(position), at);
                    positions.AddRange(p);
                    position = at.Point;
                    continue;
                }
                var ct = op as CurveTo;
                if (ct != null)
                {
                    if (double.IsNaN(ct.Control1.X) && double.IsNaN(ct.Control1.Y))
                    {
                        BezierCurveQuadric b = new BezierCurveQuadric(Vec2(position), Vec2(ct.EndPoint),
                                                                      Vec2(ct.Control2));
                        Vector2 old = b.CalculatePoint(0f);
                        positions.Add(old);
                        var precision = 0.05f;
                        for (float i = precision; i < 1f + precision; i += precision)
                        {
                            Vector2 j = b.CalculatePoint(i);
                            positions.Add(j);
                            old = j;
                        }
                    }
                    else
                    {
                        BezierCurveCubic b = new BezierCurveCubic(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control1),
                                                                  Vec2(ct.Control2));
                        Vector2 old = b.CalculatePoint(0f);
                        positions.Add(old);
                        var precision = 0.05f;
                        for (float i = precision; i < 1f + precision; i += precision)
                        {
                            Vector2 j = b.CalculatePoint(i);
                            positions.Add(j);
                        }
                    }
                    position = ct.EndPoint;
                }
                var cp = op as ClosePath;
                if (cp != null)
                {
                    if (positions.Count > 0)
                    {
                        positions.Add(positions[0]);
                        shapes.Add(positions);
                    }
                    positions = new List <Vector2>();
                    position  = new Point();
                    continue;
                }
            }
            shapes.Add(positions);

            brushcheck(path.Brush);
            LibTessDotNet.Tess t        = new LibTessDotNet.Tess();
            List <Vec3>        vertices = new List <Vec3>();

            foreach (var s in shapes)
            {
                ContourVertex[] cv = new ContourVertex[s.Count];
                for (int i = 0; i < s.Count; i++)
                {
                    var v = s[i];
                    cv[i] = new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = v.X, Y = v.Y
                        }
                    };
                }
                t.AddContour(cv);
            }
            var rule = LibTessDotNet.WindingRule.NonZero;

            if (path.Brush != null)
            {
                rule = path.Brush.FillMode == FillMode.EvenOdd ? LibTessDotNet.WindingRule.EvenOdd : LibTessDotNet.WindingRule.NonZero;
            }
            t.Tessellate(rule, LibTessDotNet.ElementType.Polygons, 3);
            for (var i = 0; i < t.ElementCount; i++)
            {
                for (var tri = 0; tri < 3; tri++)
                {
                    vertices.Add(t.Vertices[t.Elements[(i * 3) + tri]].Position);
                }
            }
            for (int i = 0; i < vertices.Count; i++)
            {
                tesselated.Add(new Vector2(vertices[i].X, vertices[i].Y));
            }
            var lineshapes = new List <List <Vector2> >();

            foreach (var s in shapes)
            {
                if (s.Count == 0)
                {
                    continue;
                }
                List <Vector2> add = new List <Vector2>();
                for (int i = 0; i < s.Count; i++)
                {
                    add.Add(new Vector2(s[i].X, s[i].Y));
                }
                lineshapes.Add(add);
            }

            if (path.Brush is SolidBrush || path.Pen != null)
            {
                if (path.Brush is SolidBrush)
                {
                    var sb = path.Brush as SolidBrush;
                    for (int i = 0; i < tesselated.Count; i++)
                    {
                        vbo.AddVertex(new Vertex(tesselated[i], color(sb.Color)));
                    }
                }
                if (path.Pen != null)
                {
                    foreach (var list in lineshapes)
                    {
                        foreach (var v in TesselateLines(list, path.Pen))
                        {
                            vbo.AddVertex(v);
                        }
                    }
                }
            }
        }
예제 #16
0
        private List <Vertex> TesselateLines(List <Vector2> points, Pen p)
        {
            List <ContourVertex> vecs = new List <ContourVertex>();
            List <Vertex>        ret  = new List <Vertex>();

            if (points.Count < 2)
            {
                return(ret);
            }
            var co = color(p.Color);

            MatterHackers.Agg.VertexSource.PathStorage ps = new MatterHackers.Agg.VertexSource.PathStorage();
            ps.remove_all();
            ps.MoveTo(points[0].X, points[0].Y);

            for (int i = 1; i < points.Count; i++)
            {
                ps.LineTo(points[i].X, points[i].Y);
            }
            ps.end_poly();

            MatterHackers.Agg.VertexSource.Stroke str = new MatterHackers.Agg.VertexSource.Stroke(ps, p.Width);
            switch (p.Join)
            {
            case LineJoin.Round:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Round);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Round);

                break;

            case LineJoin.Miter:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Miter);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Miter);
                str.inner_miter_limit(p.MiterLimit);
                str.miter_limit(p.MiterLimit);
                break;
            }
            switch (p.Cap)
            {
            case LineCaps.Butt:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Butt);
                break;

            case LineCaps.Round:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Round);
                break;

            case LineCaps.Square:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Square);
                break;
            }
            str.rewind(0);
            double x, y;

            LibTessDotNet.Tess t = new LibTessDotNet.Tess();

            ShapePath.FlagsAndCommand cmd;
            do
            {
                cmd = str.vertex(out x, out y);
                if (ShapePath.is_vertex(cmd))
                {
                    vecs.Add(new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = (float)x, Y = (float)y
                        }
                    });
                }
                if (ShapePath.is_end_poly(cmd))
                {
                    t.AddContour(vecs.ToArray());
                    vecs.Clear();
                }
            } while (!ShapePath.is_stop(cmd));

            /*
             * foreach (var v in vertices)
             * {
             * if (!ShapePath.is_close(v.command) && !ShapePath.is_stop(v.command))
             * vecs.Add(new Vector2((float)v.position.x, (float)v.position.y));
             * }*/
            if (vecs.Count != 0)
            {
                t.AddContour(vecs.ToArray());
            }
            t.Tessellate(LibTessDotNet.WindingRule.NonZero, LibTessDotNet.ElementType.Polygons, 3);
            for (var i = 0; i < t.ElementCount; i++)
            {
                for (var tri = 0; tri < 3; tri++)
                {
                    var v = t.Vertices[t.Elements[(i * 3) + tri]].Position;
                    ret.Add(new Vertex(v.X, v.Y, co));
                }
            }
            return(ret);
        }
	void StartOld() {
		OsmBuilding building = Data.Instance.buildings [buildingId];
		//float[] points = building.getPolygon ();
		Vector3[] points = building.getPolygonAsVector3 ();
		var tess = new LibTessDotNet.Tess();

		//Debug.Log ("-"  + buildingId);
		var contour = new LibTessDotNet.ContourVertex[points.Length];
		for (int i = 0; i < points.Length; i++)
		{
			// NOTE : Z is here for convenience if you want to keep a 3D vertex position throughout the tessellation process but only X and Y are important.
			contour[i].Position = new LibTessDotNet.Vec3 { X = points[i].x, Y = points[i].y, Z = points[i].z };
			// Data can contain any per-vertex data, here a constant color.
			contour[i].Data = Color.cyan;
			if (i != points.Length-1) {
				Debug.DrawLine(points [i], points [i + 1],Color.red,2000f);
			}

		}
		tess.AddContour(contour, LibTessDotNet.ContourOrientation.Original);
		tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3, VertexCombine);

		//gameObject.AddComponent<MeshFilter>();
		//gameObject.AddComponent<MeshRenderer>();
		Mesh mesh = new Mesh ();
		mesh.Clear();
		mesh.name = "Building";
		mesh.vertices = points;
		mesh.RecalculateNormals();
		mesh.RecalculateBounds();

		Vector2[] uvs = new Vector2[points.Length];
		Bounds bounds = mesh.bounds;
		for(int i = 0; i < points.Length; i++) {
			uvs[i] = new Vector2(points[i].x / bounds.size.x, points[i].z / bounds.size.x);
		}
		mesh.uv = uvs;
		mesh.triangles = tess.Elements;
	
		GameObject meshObject = new GameObject ();
		meshObject.AddComponent<MeshFilter> ().mesh = mesh;
		Renderer renderer = meshObject.AddComponent<MeshRenderer> ();
		meshObject.transform.parent = this.transform;

		//meshObject.transform.position = new Vector3(-mesh.bounds.center.x, -mesh.bounds.center.y, -mesh.bounds.center.z);

		//gameObject.transform.position = new Vector3(-mesh.bounds.center.x, -mesh.bounds.center.y, -mesh.bounds.center.z);
		//GetComponent<MeshRenderer> ().material = Resources.Load<Material> ("Source/Red");
	}
예제 #18
0
        public List <Triangle> TrianglateGlyph(Glyph g)
        {
            var re = new List <Triangle>();


            var tess = new LibTessDotNet.Tess();


            var c    = 0;
            var last = 0;


            var vecs = new List <Vec3>();

            for (var i = 0; i < g.Points.Count; i++)
            {
                var glyphPointA = g.Points[i];


                vecs.Add(new Vec3()
                {
                    X = glyphPointA["x"],
                    Y = glyphPointA["y"],
                    Z = 0
                });

                if (i == g.ContourEnds[c])
                {
                    c += 1;
                    var contour = new LibTessDotNet.ContourVertex[vecs.Count];

                    for (var index = 0; index < vecs.Count; index++)
                    {
                        contour[index].Position = vecs[index];
                        contour[index].Data     = Color.Black;
                    }
                    tess.AddContour(contour, LibTessDotNet.ContourOrientation.Clockwise);

                    vecs.Clear();
                }
            }

            tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);


            Console.WriteLine("Output triangles:");
            int numTriangles = tess.ElementCount;

            for (int i = 0; i < numTriangles; i++)
            {
                var v0 = tess.Vertices[tess.Elements[i * 3]].Position;
                var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;


                re.Add(new Triangle(new Point((int)v0.X, (int)v0.Y),
                                    new Point((int)v1.X, (int)v1.Y),
                                    new Point((int)v2.X, (int)v2.Y)));
            }

            return(re);
        }