Exemple #1
0
    private void FillCutEdges(Hull a, Hull b, IList <Edge> edgesA, IList <Edge> edgesB, Vector3 planeNormal, UvMapper uvMapper)
    {
        // Create outline data
        int outlineEdgeCount = edgesA.Count;

        Vector3[] outlinePoints = new Vector3[outlineEdgeCount];
        int[]     outlineEdges  = new int[outlineEdgeCount * 2];

        int startIndex = 0;

        for (int i = 0; i < outlineEdgeCount; i++)
        {
            int currentIndex = i;
            int nextIndex    = (i + 1) % outlineEdgeCount;

            Edge current = edgesA[currentIndex];
            Edge next    = edgesA[nextIndex];

            // Set point
            outlinePoints[i] = current.point0.position;

            // Set edge
            outlineEdges[i * 2 + 0] = currentIndex;

            if (current.point1 == next.point0)
            {
                outlineEdges[i * 2 + 1] = nextIndex;
            }
            else
            {
                outlineEdges[i * 2 + 1] = startIndex;

                startIndex = nextIndex;
            }
        }

        // Triangulate
        int[] newEdges, newTriangles, newTriangleEdges;

        ITriangulator triangulator = new Triangulator(outlinePoints, outlineEdges, planeNormal);

        triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

        // Calculate vertex properties
        Vector3 normalA = -planeNormal;
        Vector3 normalB = planeNormal;

        Vector4[] tangentsA, tangentsB;
        Vector2[] uvsA, uvsB;

        uvMapper.Map(outlinePoints, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

        // Create new vertices
        int[] verticesA = new int[outlineEdgeCount];
        int[] verticesB = new int[outlineEdgeCount];

        for (int i = 0; i < outlineEdgeCount; i++)
        {
            a.AddVertex(outlinePoints[i], normalA, tangentsA[i], uvsA[i], edgesA[i].point0, out verticesA[i]);

            b.AddVertex(outlinePoints[i], normalB, tangentsB[i], uvsB[i], edgesB[i].point0, out verticesB[i]);
        }

        // Create new edges
        for (int i = 0; i < newEdges.Length / 2; i++)
        {
            int point0 = newEdges[i * 2 + 0];
            int point1 = newEdges[i * 2 + 1];

            Edge edgeA = new Edge(edgesA[point0].point0, edgesA[point1].point0);
            Edge edgeB = new Edge(edgesB[point0].point0, edgesB[point1].point0);

            edgesA.Add(edgeA);
            edgesB.Add(edgeB);

            a.edges.Add(edgeA);
            b.edges.Add(edgeB);
        }

        // Create new triangles
        for (int i = 0; i < newTriangles.Length / 3; i++)
        {
            int point0 = newTriangles[i * 3 + 0];
            int point1 = newTriangles[i * 3 + 1];
            int point2 = newTriangles[i * 3 + 2];

            int edge0 = newTriangleEdges[i * 3 + 0];
            int edge1 = newTriangleEdges[i * 3 + 1];
            int edge2 = newTriangleEdges[i * 3 + 2];

            Triangle triangleA = new Triangle(verticesA[point0], verticesA[point2], verticesA[point1], edgesA[point0].point0, edgesA[point2].point0, edgesA[point1].point0, edgesA[edge2], edgesA[edge1], edgesA[edge0]);
            Triangle triangleB = new Triangle(verticesB[point0], verticesB[point1], verticesB[point2], edgesB[point0].point0, edgesB[point1].point0, edgesB[point2].point0, edgesB[edge0], edgesB[edge1], edgesB[edge2]);

            a.triangles.Add(triangleA);
            b.triangles.Add(triangleB);
        }
    }
Exemple #2
0
    public void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (isTriangulated)
            {
                Reset();
            }

            // Add the mouse world position to the list of points
            Vector3 screenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10.0f);
            Vector3 worldPosition  = Camera.main.ScreenToWorldPoint(screenPosition);

            points.Add(worldPosition);

            // Add an edge from the previous point to the new point
            if (LoopPointCount >= 2)
            {
                edges.Add(points.Count - 2);
                edges.Add(points.Count - 1);
            }

            // Set flag
            isLoopClosed = false;
        }
        else if (Input.GetMouseButtonDown(1))
        {
            if (LoopPointCount >= 3)
            {
                // Add the last edge to close the current loop
                edges.Add(points.Count - 1);
                edges.Add(loopStart);

                // Set flag
                isLoopClosed = true;

                // Start a new loop
                loopStart = points.Count;
            }
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (!isTriangulated && isLoopClosed)
            {
                // Triangulate
                int[] newEdges, newTriangles, newTriangleEdges;

                ITriangulator triangulator = new Triangulator(points, edges, Vector3.up);

                triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

                // Add the new edges and triangles
                edges.AddRange(newEdges);

                triangles.AddRange(newTriangles);

                triangleEdges.AddRange(newTriangleEdges);

                // Set flag
                isTriangulated = true;
            }
        }
    }
Exemple #3
0
    private void FillCutEdges(FastHull a, FastHull b, IList <Vector3> edges, Vector3 planeNormal, UvMapper uvMapper)
    {
        int edgeCount = edges.Count / 2;

        List <Vector3> points  = new List <Vector3>(edgeCount);
        List <int>     outline = new List <int>(edgeCount * 2);

        int start = 0;

        for (int current = 0; current < edgeCount; current++)
        {
            int next = current + 1;

            // Find the next edge
            int   nearest         = start;
            float nearestDistance = (edges[current * 2 + 1] - edges[start * 2 + 0]).sqrMagnitude;

            for (int other = next; other < edgeCount; other++)
            {
                float distance = (edges[current * 2 + 1] - edges[other * 2 + 0]).sqrMagnitude;

                if (distance < nearestDistance)
                {
                    nearest         = other;
                    nearestDistance = distance;
                }
            }

            // Is the current edge the last edge in this edge loop?
            if (nearest == start && current > start)
            {
                int pointStart   = points.Count;
                int pointCounter = pointStart;

                // Add this edge loop to the triangulation lists
                for (int edge = start; edge < current; edge++)
                {
                    points.Add(edges[edge * 2 + 0]);
                    outline.Add(pointCounter++);
                    outline.Add(pointCounter);
                }

                points.Add(edges[current * 2 + 0]);
                outline.Add(pointCounter);
                outline.Add(pointStart);

                // Start a new edge loop
                start = next;
            }
            else if (next < edgeCount)
            {
                // Move the nearest edge so that it follows the current edge
                Vector3 n0 = edges[next * 2 + 0];
                Vector3 n1 = edges[next * 2 + 1];

                edges[next * 2 + 0] = edges[nearest * 2 + 0];
                edges[next * 2 + 1] = edges[nearest * 2 + 1];

                edges[nearest * 2 + 0] = n0;
                edges[nearest * 2 + 1] = n1;
            }
        }

        if (points.Count > 0)
        {
            // Triangulate the outline
            int[] newEdges, newTriangles, newTriangleEdges;

            ITriangulator triangulator = new Triangulator(points, outline, planeNormal);

            triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

            // Calculate the vertex properties
            Vector3   normalA = -planeNormal;
            Vector3   normalB = planeNormal;
            Vector4[] tangentsA, tangentsB;
            Vector2[] uvsA, uvsB;

            uvMapper.Map(points, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

            // Add the new vertices
            int offsetA = a.vertices.Count;
            int offsetB = b.vertices.Count;

            for (int i = 0; i < points.Count; i++)
            {
                a.vertices.Add(points[i]);
                b.vertices.Add(points[i]);
            }

            if (normals != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.normals.Add(normalA);
                    b.normals.Add(normalB);
                }
            }

            if (tangents != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.tangents.Add(tangentsA[i]);
                    b.tangents.Add(tangentsB[i]);
                }
            }

            if (uvs != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.uvs.Add(uvsA[i]);
                    b.uvs.Add(uvsB[i]);
                }
            }

            // Add the new triangles
            int newTriangleCount = newTriangles.Length / 3;

            for (int i = 0; i < newTriangleCount; i++)
            {
                a.indices.Add(offsetA + newTriangles[i * 3 + 0]);
                a.indices.Add(offsetA + newTriangles[i * 3 + 2]);
                a.indices.Add(offsetA + newTriangles[i * 3 + 1]);

                b.indices.Add(offsetB + newTriangles[i * 3 + 0]);
                b.indices.Add(offsetB + newTriangles[i * 3 + 1]);
                b.indices.Add(offsetB + newTriangles[i * 3 + 2]);
            }
        }
    }
 public void Update()
 {
     if (Input.GetMouseButtonDown(0))
     {
         if (isTriangulated)
         {
             Reset();
         }
         
         // Add the mouse world position to the list of points
         Vector3 screenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10.0f);
         Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
         
         points.Add(worldPosition);
         
         // Add an edge from the previous point to the new point
         if (LoopPointCount >= 2)
         {
             edges.Add(points.Count - 2);
             edges.Add(points.Count - 1);
         }
         
         // Set flag
         isLoopClosed = false;
     }
     else if (Input.GetMouseButtonDown(1))
     {
         if (LoopPointCount >= 3)
         {
             // Add the last edge to close the current loop
             edges.Add(points.Count - 1);
             edges.Add(loopStart);
             
             // Set flag
             isLoopClosed = true;
             
             // Start a new loop
             loopStart = points.Count;
         }
     }
     
     if (Input.GetKeyDown(KeyCode.Space))
     {
         if (!isTriangulated && isLoopClosed)
         {
             // Triangulate
             int[] newEdges, newTriangles, newTriangleEdges;
             
             ITriangulator triangulator = new Triangulator(points, edges, Vector3.up);
             
             triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);
             
             // Add the new edges and triangles
             edges.AddRange(newEdges);
             
             triangles.AddRange(newTriangles);
             
             triangleEdges.AddRange(newTriangleEdges);
             
             // Set flag
             isTriangulated = true;
         }
     }
 }
Exemple #5
0
    private void FillCutEdges(IList <Vector3> edges, Vector3 planeNormal)
    {
        Debug.Log("FillCutEdges " + planeNormal);
        int edgeCount = edges.Count / 2;

        List <Vector3> points  = new List <Vector3>(edgeCount);
        List <int>     outline = new List <int>(edgeCount * 2);

        int start = 0;

        for (int current = 0; current < edgeCount; current++)
        {
            int next = current + 1;

            // Find the next edge
            int   nearest         = start;
            float nearestDistance = (edges[current * 2 + 1] - edges[start * 2 + 0]).sqrMagnitude;

            for (int other = next; other < edgeCount; other++)
            {
                float distance = (edges[current * 2 + 1] - edges[other * 2 + 0]).sqrMagnitude;

                if (distance < nearestDistance)
                {
                    nearest         = other;
                    nearestDistance = distance;
                }
            }

            // Is the current edge the last edge in this edge loop?
            if (nearest == start && current > start)
            {
                int pointStart   = points.Count;
                int pointCounter = pointStart;

                // Add this edge loop to the triangulation lists
                for (int edge = start; edge < current; edge++)
                {
                    points.Add(edges[edge * 2 + 0]);
                    outline.Add(pointCounter++);
                    outline.Add(pointCounter);
                }

                points.Add(edges[current * 2 + 0]);
                outline.Add(pointCounter);
                outline.Add(pointStart);

                // Start a new edge loop
                start = next;
            }
            else if (next < edgeCount)
            {
                // Move the nearest edge so that it follows the current edge
                Vector3 n0 = edges[next * 2 + 0];
                Vector3 n1 = edges[next * 2 + 1];

                edges[next * 2 + 0] = edges[nearest * 2 + 0];
                edges[next * 2 + 1] = edges[nearest * 2 + 1];

                edges[nearest * 2 + 0] = n0;
                edges[nearest * 2 + 1] = n1;
            }
        }

        if (points.Count > 0)
        {
            // Triangulate the outline
            int[] newEdges, newTriangles, newTriangleEdges;

            ITriangulator triangulator = new Triangulator(points, outline, planeNormal);

            triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

            // Calculate the vertex properties
            Vector3   normalA = planeNormal;
            Vector3   normalB = -planeNormal;
            Vector4[] tangentsA, tangentsB;
            Vector2[] uvsA, uvsB;

            UVMap(points, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

            // Add the new vertices
            int offsetA = vertices2.Count;

            for (int i = 0; i < points.Count; i++)
            {
                vertices2.Add(points[i]);

                _vertices1.Add(offsetA + i);
            }

            if (normals2 != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    normals2.Add(normalA);
                }
            }

            if (tangents2 != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    tangents2.Add(tangentsA[i]);
                }
            }

            if (uvs2 != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    uvs2.Add(uvsA[i]);
                }
            }

            // Add the new triangles
            int newTriangleCount = newTriangles.Length / 3;

            int offsetB = vertices2.Count;

            for (int i = 0; i < points.Count; i++)
            {
                vertices2.Add(points[i]);

                _vertices2.Add(offsetB + i);
            }

            if (normals != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    normals2.Add(normalB);
                }
            }

            if (tangents2 != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    tangents2.Add(tangentsB[i]);
                }
            }

            if (uvs2 != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    uvs2.Add(uvsB[i]);
                }
            }

            // Add the new triangles

            Vector3 n = Vector3.Cross(points[2] - points[0], points[1] - points[0]).normalized;
            Debug.Log("cut normal " + n);
            float fN = Vector3.Dot(n, planeNormal);
            for (int i = 0; i < newTriangleCount; i++)
            {
                /*
                 * if (fN > 0) {
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 0]);
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 2]);
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 1]);
                 *
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 0]);
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 1]);
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 2]);
                 * } else {
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 0]);
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 1]);
                 *      indices2.Add (offsetA + newTriangles [i * 3 + 2]);
                 *
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 0]);
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 2]);
                 *      indices2.Add (offsetB + newTriangles [i * 3 + 1]);
                 * }
                 */

                indices2.Add(offsetA + newTriangles [i * 3 + 0]);
                indices2.Add(offsetA + newTriangles [i * 3 + 1]);
                indices2.Add(offsetA + newTriangles [i * 3 + 2]);

                indices2.Add(offsetB + newTriangles [i * 3 + 0]);
                indices2.Add(offsetB + newTriangles [i * 3 + 2]);
                indices2.Add(offsetB + newTriangles [i * 3 + 1]);

                for (int j = 0; j < 6; j++)
                {
                    _tris.Add(indices2.Count - 1 - j);
                }
            }
        }
    }