Beispiel #1
0
 private int XMax(InsideData a, InsideData b)
 {
     if (a.xMaxPoint.x > b.xMaxPoint.x)
     {
         return(-1);
     }
     if (b.xMaxPoint.x > a.xMaxPoint.x)
     {
         return(1);
     }
     return(0);
 }
Beispiel #2
0
 private int XMax(InsideData a, InsideData b)
 {
     if (a.xMaxPoint.x > b.xMaxPoint.x) return -1;
     if (b.xMaxPoint.x > a.xMaxPoint.x) return 1;
     return 0;
 }
Beispiel #3
0
        public bool SetMeshData(int resolution)
        {
            var pointsList2 = new List<Vector2[]>(_contourList.Count);

            // Sort any inside lines by largest X value
            var xMaxVertices = new int[_contourList.Count];
            var xMaxPoints = new Vector2[_contourList.Count];
            for (int i = 0; i < _contourList.Count; i++) {
            if (_contourList[i].side == Side.Out) {
                pointsList2.Add (RenderContourPoints (_contourList[i], resolution, false));
                continue;
            }

            var insideList = new List<InsideData>();
            int arrayIdx = i;
            for (; i < _contourList.Count; i++) {
                var inside = new InsideData();
                inside.points = RenderContourPoints (_contourList[i], resolution, false);
                var points = inside.points;
                int xMaxVertex = 0;
                float xMax = points[0].x;
                float yVal = points[0].y;
                int end = points.Length;
                for (int j = 1; j < end; j++) {
                    if (points[j].x > xMax) {
                        xMax = points[j].x;
                        yVal = points[j].y;
                        xMaxVertex = j;
                    }
                }

                inside.xMaxPoint = new Vector2(xMax, yVal);
                inside.xMaxVertex = xMaxVertex;
                insideList.Add (inside);

                if (i+1 == _contourList.Count || _contourList[i+1].side == Side.Out) {
                    insideList.Sort (XMax);
                    for (int j = 0; j < insideList.Count; j++) {
                        pointsList2.Add (insideList[j].points);
                        xMaxVertices[arrayIdx] = insideList[j].xMaxVertex;
                        xMaxPoints[arrayIdx++] = insideList[j].xMaxPoint;
                    }
                    break;
                }
            }
            }

            // Find out how many triangles/vertices there will be, and make a list that holds an array of vertex references for each line
            var vertexCounts = new int[pointsList2.Count];
            var vertexList = new List<int[]>(pointsList2.Count);
            int vertexIndex = 0;
            int totalVertices = 0;
            int pointCount = 0;
            int totalTriangles = 0;

            for (int i = 0; i < pointsList2.Count; i++) {
            if (_contourList[i].side == Side.Out && i > 0) {
                totalTriangles += (pointCount-2) * 3;
                pointCount = 0;
            }

            var points = pointsList2[i];

            int vertexCount = points.Length;
            if (points.Length > 2 && points[0] == points[vertexCount-1]) vertexCount--;
            if (vertexCount < 3) {
                vertexList.Add (null);
                continue;
            }
            vertexCounts[i] = vertexCount;
            totalVertices += vertexCount;

            if (_contourList[i].side == Side.Out) vertexIndex = 0;
            var vertexArray = new int[vertexCount];
            for (var j = 0; j < vertexCount; j++) {
                vertexArray[j] = j + vertexIndex;
            }
            vertexIndex += vertexCount;
            vertexList.Add (vertexArray);

            pointCount += vertexCount;
            if (_contourList[i].side == Side.In) pointCount += 2;	// Because each interior line requires a "cut" with 2 additional points
            }

            // Debug outlines ---
            //		for (int i = 0; i < pointsList2.Count; i++) {
            //			if (vertexCounts[i] < 3) continue;
            //			var lineColor = _contourList[i].side == Side.Out? Color.green : Color.red;
            //			var outline = new VectorLine("contour "+i, pointsList2[i], lineColor, null, 2.0f, LineType.Continuous);
            //			outline.depth = 1;
            //			outline.Draw();
            //		}

            totalTriangles += (pointCount-2) * 3;
            int totalFrontVertices = totalVertices;
            int totalFrontTriangles = totalTriangles;
            // Allow for backface
            totalVertices *= 2;
            totalTriangles *= 2;
            // Allow for extrusion
            for (int i = 0; i < vertexCounts.Length; i++) {
            totalVertices += vertexCounts[i] * 4;
            totalTriangles += vertexCounts[i] * 6;
            }

            if (totalVertices > 65534) {
            Debug.LogError ("Too many points...resolution is too high or character is too complex");
            return false;
            }
            var meshVertices = new Vector3[totalVertices];
            var meshTriangles = new int[totalTriangles];

            // Copy all Vector2 points to the mesh vertices array
            int idx = 0;
            for (int i = 0; i < pointsList2.Count; i++) {
            var points = pointsList2[i];
            int vertexCount = vertexCounts[i];
            for (int j = 0; j < vertexCount; j++) {
                meshVertices[idx  ].x = points[j].x;
                meshVertices[idx++].y = points[j].y;
            }
            }

            int triIdx = 0;
            int triAdd = 0;
            if (!Triangulate.Compute (_contourList, vertexList, vertexCounts, xMaxVertices, xMaxPoints, pointsList2, meshTriangles, ref triIdx, ref triAdd)) {
            return false;
            }

            // Do verts and triangles for back face
            Array.Copy (meshVertices, 0, meshVertices, totalFrontVertices, totalFrontVertices);
            for (int i = 0; i < totalFrontTriangles; i += 3) {
            meshTriangles[i + totalFrontTriangles    ] = meshTriangles[i + 2] + totalFrontVertices;
            meshTriangles[i + totalFrontTriangles + 1] = meshTriangles[i + 1] + totalFrontVertices;
            meshTriangles[i + totalFrontTriangles + 2] = meshTriangles[i    ] + totalFrontVertices;
            }

            // Do edges for extrusion
            int frontIdx = 0;
            int backIdx = totalFrontVertices;
            int edgeIdx = totalFrontVertices * 2;
            Vector2 l1, l2;
            float p2x, p2y;
            float smoothAngle = Mathf.Clamp (FlyingText.smoothingAngle, 0.0f, 180.0f);
            triIdx = totalFrontTriangles * 2;
            triAdd *= 2;
            int edgeVertCount = 0, edgeTriCount = 0;

            for (int i = 0; i < pointsList2.Count; i++) {
            if (vertexCounts[i] < 3) continue;
            int vEnd = vertexCounts[i], j1 = 0, j2 = 0;
            int originalTriAdd = triAdd;
            int vCount = 0;
            for (int j = 0; j < vEnd; j++) {
                j1 = j+1;
                if (j1 == vEnd) j1 = 0;
                j2 = j1+1;
                if (j2 == vEnd) j2 = 0;

                // Get this segment and the next one, so the angle can be computed
                p2x = meshVertices[frontIdx + j1].x; p2y = meshVertices[frontIdx + j1].y;
                l1.x = meshVertices[frontIdx + j].x - p2x; l1.y = meshVertices[frontIdx + j].y - p2y;
                l2.x = meshVertices[frontIdx + j2].x - p2x; l2.y = meshVertices[frontIdx + j2].y - p2y;

                meshVertices[edgeIdx    ] = meshVertices[frontIdx + j];
                meshVertices[edgeIdx + 1] = meshVertices[backIdx + j];
                if (vCount != 0) {
                    AddTriangle (meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount);
                }
                if (180.0f - Vector2.Angle(l1, l2) >= smoothAngle) {
                    meshVertices[edgeIdx + 2] = meshVertices[frontIdx + j1];
                    meshVertices[edgeIdx + 3] = meshVertices[backIdx + j1];
                    edgeIdx += 4;
                    vCount = 4;
                    edgeVertCount += 4;
                }
                else {
                    edgeIdx += 2;
                    vCount = 2;
                    edgeVertCount += 2;
                }
            }
            if (vCount == 4) {
                AddTriangle (meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount);
            }
            else {
                meshTriangles[triIdx    ] = triAdd;
                meshTriangles[triIdx + 1] = triAdd + 1;
                meshTriangles[triIdx + 2] = originalTriAdd;

                meshTriangles[triIdx + 3] = triAdd + 1;
                meshTriangles[triIdx + 4] = originalTriAdd + 1;
                meshTriangles[triIdx + 5] = originalTriAdd;

                triIdx += 6;
                triAdd += vCount;
                edgeTriCount += 6;
            }
            idx += vEnd;
            frontIdx += vEnd;
            backIdx += vEnd;
            }

            if (meshVertices.Length != totalFrontVertices * 2 + edgeVertCount) {
            Array.Resize (ref meshVertices, totalFrontVertices * 2 + edgeVertCount);
            }
            if (meshTriangles.Length != totalFrontTriangles * 2 + edgeTriCount) {
            Array.Resize (ref meshTriangles, totalFrontTriangles * 2 + edgeTriCount);
            }
            _baseVertices = meshVertices;
            _baseTriangles = meshTriangles;
            _frontVertIndex = totalFrontVertices;
            _frontTriIndex = totalFrontTriangles;
            _scaleFactor = -1.0f;
            return true;
        }
Beispiel #4
0
        public bool SetMeshData(int resolution)
        {
            var pointsList2 = new List <Vector2[]>(_contourList.Count);

            // Sort any inside lines by largest X value
            var xMaxVertices = new int[_contourList.Count];
            var xMaxPoints   = new Vector2[_contourList.Count];

            for (int i = 0; i < _contourList.Count; i++)
            {
                if (_contourList[i].side == Side.Out)
                {
                    pointsList2.Add(RenderContourPoints(_contourList[i], resolution, false));
                    continue;
                }

                var insideList = new List <InsideData>();
                int arrayIdx   = i;
                for (; i < _contourList.Count; i++)
                {
                    var inside = new InsideData();
                    inside.points = RenderContourPoints(_contourList[i], resolution, false);
                    var   points     = inside.points;
                    int   xMaxVertex = 0;
                    float xMax       = points[0].x;
                    float yVal       = points[0].y;
                    int   end        = points.Length;
                    for (int j = 1; j < end; j++)
                    {
                        if (points[j].x > xMax)
                        {
                            xMax       = points[j].x;
                            yVal       = points[j].y;
                            xMaxVertex = j;
                        }
                    }

                    inside.xMaxPoint  = new Vector2(xMax, yVal);
                    inside.xMaxVertex = xMaxVertex;
                    insideList.Add(inside);

                    if (i + 1 == _contourList.Count || _contourList[i + 1].side == Side.Out)
                    {
                        insideList.Sort(XMax);
                        for (int j = 0; j < insideList.Count; j++)
                        {
                            pointsList2.Add(insideList[j].points);
                            xMaxVertices[arrayIdx] = insideList[j].xMaxVertex;
                            xMaxPoints[arrayIdx++] = insideList[j].xMaxPoint;
                        }
                        break;
                    }
                }
            }

            // Find out how many triangles/vertices there will be, and make a list that holds an array of vertex references for each line
            var vertexCounts   = new int[pointsList2.Count];
            var vertexList     = new List <int[]>(pointsList2.Count);
            int vertexIndex    = 0;
            int totalVertices  = 0;
            int pointCount     = 0;
            int totalTriangles = 0;

            for (int i = 0; i < pointsList2.Count; i++)
            {
                if (_contourList[i].side == Side.Out && i > 0)
                {
                    totalTriangles += (pointCount - 2) * 3;
                    pointCount      = 0;
                }

                var points = pointsList2[i];

                int vertexCount = points.Length;
                if (points.Length > 2 && points[0] == points[vertexCount - 1])
                {
                    vertexCount--;
                }
                if (vertexCount < 3)
                {
                    vertexList.Add(null);
                    continue;
                }
                vertexCounts[i] = vertexCount;
                totalVertices  += vertexCount;

                if (_contourList[i].side == Side.Out)
                {
                    vertexIndex = 0;
                }
                var vertexArray = new int[vertexCount];
                for (var j = 0; j < vertexCount; j++)
                {
                    vertexArray[j] = j + vertexIndex;
                }
                vertexIndex += vertexCount;
                vertexList.Add(vertexArray);

                pointCount += vertexCount;
                if (_contourList[i].side == Side.In)
                {
                    pointCount += 2;                                            // Because each interior line requires a "cut" with 2 additional points
                }
            }

            // Debug outlines ---
//		for (int i = 0; i < pointsList2.Count; i++) {
//			if (vertexCounts[i] < 3) continue;
//			var lineColor = _contourList[i].side == Side.Out? Color.green : Color.red;
//			var outline = new VectorLine("contour "+i, pointsList2[i], lineColor, null, 2.0f, LineType.Continuous);
//			outline.depth = 1;
//			outline.Draw();
//		}

            totalTriangles += (pointCount - 2) * 3;
            int totalFrontVertices  = totalVertices;
            int totalFrontTriangles = totalTriangles;

            // Allow for backface
            totalVertices  *= 2;
            totalTriangles *= 2;
            // Allow for extrusion
            for (int i = 0; i < vertexCounts.Length; i++)
            {
                totalVertices  += vertexCounts[i] * 4;
                totalTriangles += vertexCounts[i] * 6;
            }

            if (totalVertices > 65534)
            {
                Debug.LogError("Too many points...resolution is too high or character is too complex");
                return(false);
            }
            var meshVertices  = new Vector3[totalVertices];
            var meshTriangles = new int[totalTriangles];

            // Copy all Vector2 points to the mesh vertices array
            int idx = 0;

            for (int i = 0; i < pointsList2.Count; i++)
            {
                var points      = pointsList2[i];
                int vertexCount = vertexCounts[i];
                for (int j = 0; j < vertexCount; j++)
                {
                    meshVertices[idx].x   = points[j].x;
                    meshVertices[idx++].y = points[j].y;
                }
            }

            int triIdx = 0;
            int triAdd = 0;

            if (!Triangulate.Compute(_contourList, vertexList, vertexCounts, xMaxVertices, xMaxPoints, pointsList2, meshTriangles, ref triIdx, ref triAdd))
            {
                return(false);
            }

            // Do verts and triangles for back face
            Array.Copy(meshVertices, 0, meshVertices, totalFrontVertices, totalFrontVertices);
            for (int i = 0; i < totalFrontTriangles; i += 3)
            {
                meshTriangles[i + totalFrontTriangles]     = meshTriangles[i + 2] + totalFrontVertices;
                meshTriangles[i + totalFrontTriangles + 1] = meshTriangles[i + 1] + totalFrontVertices;
                meshTriangles[i + totalFrontTriangles + 2] = meshTriangles[i] + totalFrontVertices;
            }

            // Do edges for extrusion
            int     frontIdx = 0;
            int     backIdx = totalFrontVertices;
            int     edgeIdx = totalFrontVertices * 2;
            Vector2 l1, l2;
            float   p2x, p2y;
            float   smoothAngle = Mathf.Clamp(FlyingText.smoothingAngle, 0.0f, 180.0f);

            triIdx  = totalFrontTriangles * 2;
            triAdd *= 2;
            int edgeVertCount = 0, edgeTriCount = 0;

            for (int i = 0; i < pointsList2.Count; i++)
            {
                if (vertexCounts[i] < 3)
                {
                    continue;
                }
                int vEnd = vertexCounts[i], j1 = 0, j2 = 0;
                int originalTriAdd = triAdd;
                int vCount         = 0;
                for (int j = 0; j < vEnd; j++)
                {
                    j1 = j + 1;
                    if (j1 == vEnd)
                    {
                        j1 = 0;
                    }
                    j2 = j1 + 1;
                    if (j2 == vEnd)
                    {
                        j2 = 0;
                    }

                    // Get this segment and the next one, so the angle can be computed
                    p2x  = meshVertices[frontIdx + j1].x; p2y = meshVertices[frontIdx + j1].y;
                    l1.x = meshVertices[frontIdx + j].x - p2x; l1.y = meshVertices[frontIdx + j].y - p2y;
                    l2.x = meshVertices[frontIdx + j2].x - p2x; l2.y = meshVertices[frontIdx + j2].y - p2y;

                    meshVertices[edgeIdx]     = meshVertices[frontIdx + j];
                    meshVertices[edgeIdx + 1] = meshVertices[backIdx + j];
                    if (vCount != 0)
                    {
                        AddTriangle(meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount);
                    }
                    if (180.0f - Vector2.Angle(l1, l2) >= smoothAngle)
                    {
                        meshVertices[edgeIdx + 2] = meshVertices[frontIdx + j1];
                        meshVertices[edgeIdx + 3] = meshVertices[backIdx + j1];
                        edgeIdx       += 4;
                        vCount         = 4;
                        edgeVertCount += 4;
                    }
                    else
                    {
                        edgeIdx       += 2;
                        vCount         = 2;
                        edgeVertCount += 2;
                    }
                }
                if (vCount == 4)
                {
                    AddTriangle(meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount);
                }
                else
                {
                    meshTriangles[triIdx]     = triAdd;
                    meshTriangles[triIdx + 1] = triAdd + 1;
                    meshTriangles[triIdx + 2] = originalTriAdd;

                    meshTriangles[triIdx + 3] = triAdd + 1;
                    meshTriangles[triIdx + 4] = originalTriAdd + 1;
                    meshTriangles[triIdx + 5] = originalTriAdd;

                    triIdx       += 6;
                    triAdd       += vCount;
                    edgeTriCount += 6;
                }
                idx      += vEnd;
                frontIdx += vEnd;
                backIdx  += vEnd;
            }

            if (meshVertices.Length != totalFrontVertices * 2 + edgeVertCount)
            {
                Array.Resize(ref meshVertices, totalFrontVertices * 2 + edgeVertCount);
            }
            if (meshTriangles.Length != totalFrontTriangles * 2 + edgeTriCount)
            {
                Array.Resize(ref meshTriangles, totalFrontTriangles * 2 + edgeTriCount);
            }
            _baseVertices   = meshVertices;
            _baseTriangles  = meshTriangles;
            _frontVertIndex = totalFrontVertices;
            _frontTriIndex  = totalFrontTriangles;
            _scaleFactor    = -1.0f;
            return(true);
        }