Utility.Polygon SetOuterQuadsAndTris(List <LineSegment> lines)
    {
        Utility.Polygon mesh = new Utility.Polygon();

        for (int i = 0; i < lines.Count - 1; i++)
        {
            if (lines[i].v1 == lines[i + 1].v1)
            {
                mesh.AddTri(lines[i].v1, lines[i + 1].v2, lines[i].v2, ToUV(lines[i].v1), ToUV(lines[i + 1].v2), ToUV(lines[i].v2), flipMesh);
            }
            else if (lines[i].v2 == lines[i + 1].v2)
            {
                mesh.AddTri(lines[i].v1, lines[i + 1].v1, lines[i].v2, ToUV(lines[i].v1), ToUV(lines[i + 1].v1), ToUV(lines[i].v2), flipMesh);
            }
            else
            {
                mesh.AddQuad(lines[i].v1, lines[i + 1].v1, lines[i].v2, lines[i + 1].v2, ToUV(lines[i].v1), ToUV(lines[i + 1].v1), ToUV(lines[i].v2), ToUV(lines[i + 1].v2), flipMesh);
            }
        }
        if (lines[lines.Count - 1].v1 == lines[0].v1 && lines[lines.Count - 1].v2 != lines[0].v2)
        {
            mesh.AddTri(lines[lines.Count - 1].v1, lines[0].v2, lines[lines.Count - 1].v2, ToUV(lines[lines.Count - 1].v1), ToUV(lines[0].v2), ToUV(lines[lines.Count - 1].v2), flipMesh);
        }
        else if (lines[lines.Count - 1].v2 == lines[0].v2 && lines[lines.Count - 1].v1 != lines[0].v1)
        {
            mesh.AddTri(lines[lines.Count - 1].v1, lines[0].v1, lines[lines.Count - 1].v2, ToUV(lines[lines.Count - 1].v1), ToUV(lines[0].v1), ToUV(lines[lines.Count - 1].v2), flipMesh);
        }

        return(mesh);
    }
Example #2
0
    Utility.Polygon GetRidgeBounded(Vector3[] edge1, Vector3[] edge2, Vector3[] startEdge, Vector3[] endEdge)
    {
        Utility.Polygon mesh = new Utility.Polygon();

        List <List <Vector3> > rows = new List <List <Vector3> >();

        if (startEdge != null)
        {
            rows.Add(new List <Vector3>(startEdge));
        }
        for (int i = 0; i <= edge1.Length - 1; i++)
        {
            int rowI = rows.Count;
            rows.Add(GetBoundedRow(edge1[i], i != edge1.Length - 1 ? edge1[i + 1] : edge1[i] * 2 - edge1[i - 1], edge2[i], i / (edge1.Length - 1f), 1 / (edge1.Length - 1f)));

            if (rowI > 0)
            {
                AddToMesh(mesh, rows[rowI - 1], rows[rowI], rowI, edge1.Length);
            }
        }
        if (endEdge != null)
        {
            AddToMesh(mesh, rows[rows.Count - 1], new List <Vector3>(endEdge), rows.Count, (rows.Count + .5f) / (rows.Count + 1), true);
        }

        return(mesh);
    }
Example #3
0
    Utility.Polygon GetRidgeWalkway(Vector3[] center, Vector3[] normals, Vector3[] startEdge, Vector3[] endEdge)
    {
        Utility.Polygon mesh = new Utility.Polygon();

        List <List <Vector3> > rows = new List <List <Vector3> >();

        if (startEdge != null)
        {
            rows.Add(new List <Vector3>(startEdge));
        }
        for (int i = 0; i < center.Length; i++)
        {
            int rowI = rows.Count;
            rows.Add(GetWalkwayRow(center[i], i != center.Length - 1 ? center[i + 1] : center[i] * 2 - center[i - 1], normals[i], i / (center.Length - 1f), 1 / (center.Length - 1f)));

            if (rowI > 0 && rows[rowI - 1].Count > 0)
            {
                AddToMesh(mesh, rows[rowI - 1], rows[rowI], rowI, center.Length);
            }
        }
        if (endEdge != null && endEdge.Length > 0)
        {
            AddToMesh(mesh, rows[rows.Count - 1], new List <Vector3>(endEdge), rows.Count, (rows.Count + .5f) / (rows.Count + 1), true);
        }

        return(mesh);
    }
    Utility.Polygon AddInnerQuadsAndTris(List <Vector3> validQuads, List <Vector3> validTris)
    {
        Utility.Polygon poly = new Utility.Polygon();

        foreach (Vector3 quad in validQuads)
        {
            bool    xEven = Mathf.Round(quad.x * gridScale) % 2 == 0;
            bool    zEven = Mathf.Round(quad.z * gridScale) % 2 == 0;
            Vector3 quadR = Vector3.right * gridScale;
            Vector3 quadF = Vector3.forward * gridScale;



            if (!IsHole(quad, quad + quadF, quad + quadR, quad + quadR + quadF))
            {
                if (xEven == zEven)
                {
                    poly.AddQuad(quad, quad + quadF, quad + quadR, quad + quadR + quadF, ToUV(quad), ToUV(quad + quadF), ToUV(quad + quadR), ToUV(quad + quadR + quadF), flipMesh);
                }
                else
                {
                    poly.AddQuad(quad + quadF, quad + quadR + quadF, quad, quad + quadR, ToUV(quad + quadF), ToUV(quad + quadR + quadF), ToUV(quad), ToUV(quad + quadR), flipMesh);
                }
            }
        }
        for (int t = 0; t < validTris.Count; t += 3)
        {
            if (Vector3.Cross(validTris[t + 1] - validTris[t], validTris[t + 2] - validTris[t]).normalized == Vector3.up)
            {
                poly.AddTri(validTris[t], validTris[t + 1], validTris[t + 2], ToUV(validTris[t]), ToUV(validTris[t + 1]), ToUV(validTris[t + 2]), flipMesh);
            }
            else
            {
                poly.AddTri(validTris[t], validTris[t + 2], validTris[t + 1], ToUV(validTris[t]), ToUV(validTris[t + 2]), ToUV(validTris[t + 1]), flipMesh);
            }
        }

        return(poly);
    }
Example #5
0
    public override Mesh CreateMesh()
    {
        if (gridCount < 1)
        {
            gridCount = 1;
        }

        debugList1 = new List <LineSegment>();
        ClearOutput();

        if (pathCreator != null)
        {
            Utility.Polygon poly = GetRidgeWalkway(pathCreator.path.vertices, pathCreator.path.normals, CheckConnection(0) ? inputs[0].Edge : null, CheckConnection(1) ? inputs[1].Edge : null);

            Mesh mesh = new Mesh()
            {
                vertices  = poly.verts.ToArray(),
                triangles = poly.tris.ToArray(),
                uv        = poly.uvs.Select(u => new Vector2(u.y, u.x)).ToArray()
            };
            mesh.RecalculateNormals();

            FinishOutputs(null);

            return(mesh);
        }
        else if (inputs != null)
        {
            List <List <Vector3> > edges = new List <List <Vector3> >();
            for (int i = 0; i < inputs.Length; i++)
            {
                if (CheckConnection(i))
                {
                    edges.Add(new List <Vector3>(inputs[i].Edge));
                }
                else
                {
                    edges.Add(null);
                }
            }

            if (edges.Count < 2 || edges[0] == null || edges[0].Count < 2 || edges[1] == null || edges[1].Count < 2)
            {
                return(new Mesh());
            }

            int minLength = Mathf.Min(edges[0].Count, edges[1].Count);
            edges[0] = edges[0].GetRange(0, minLength);
            edges[1] = edges[1].GetRange(0, minLength);

            Utility.Polygon poly = GetRidgeBounded(edges[0].ToArray(), edges[1].ToArray(), edges.Count > 2 && edges[2] != null ? edges[2].ToArray() : null, edges.Count > 3 && edges[3] != null ? edges[3].ToArray() : null);

            Mesh mesh = new Mesh()
            {
                vertices  = poly.verts.ToArray(),
                triangles = poly.tris.ToArray(),
                uv        = poly.uvs.ToArray()
            };
            mesh.RecalculateNormals();

            FinishOutputs(null);

            return(mesh);
        }

        return(new Mesh());
    }
    /*
     * private void OnDrawGizmos() {
     *  if (debug) {
     *      if (debugSegList != null) {
     *          for (int i = 0; i < debugSegList.Count; i++) {
     *              Gizmos.color = Color.magenta;
     *              Gizmos.DrawLine(debugSegList[i].v1, debugSegList[i].v2);
     *          }
     *      }
     *  }
     * }
     */

    public override Mesh CreateMesh()
    {
        //print("Updating " + typeof(PathGroundCreator));
        debugSegList          = new List <LineSegment>();
        leaveHeightsUnchanged = new List <Vector3>();
        if (gridScale <= 0)
        {
            gridScale = 1f;
        }
        ClearOutput();
        if (pathCreator != null)
        {
            pathHeight = pathCreator.bezierPath.HeightOffset;
            if (!pathCreator.bezierPath.IsClosed && CheckConnection(0))
            {
                outerRing = new List <Vector3>(pathCreator.path.vertices);
                for (int i = 0; i < inputs.Length; i++)
                {
                    if (CheckConnection(i))
                    {
                        List <Vector3> edgeList = new List <Vector3>(inputs[i].Edge);
                        leaveHeightsUnchanged.AddRange(edgeList);
                        AddEdge(outerRing, edgeList);
                    }
                }
                ClosePath(outerRing, gridScale, pathHeight);
                bounds = GetBounds(outerRing);
            }
            else
            {
                outerRing = new List <Vector3>(pathCreator.path.vertices);
                bounds    = pathCreator.path.bounds;
            }
        }
        else if (CheckConnection(0))
        {
            outerRing = new List <Vector3>();
            for (int i = 0; i < inputs.Length; i++)
            {
                if (CheckConnection(i))
                {
                    if (outerRing.Count == 0)
                    {
                        outerRing.AddRange(new List <Vector3>(inputs[i].Edge));
                    }
                    else
                    {
                        AddEdge(outerRing, new List <Vector3>(inputs[i].Edge));
                    }
                }
            }
            if (outerRing.Count == 0)
            {
                print("Failed Ground Build");
                return(new Mesh());
            }

            leaveHeightsUnchanged.AddRange(outerRing);
            if (closed)
            {
                outerRing.Add(outerRing[0]);
            }
            else
            {
                ClosePath(outerRing, gridScale, 0);
            }

            bounds = GetBounds(outerRing);
        }
        else
        {
            return(new Mesh());
        }

        if (flipBorder)
        {
            outerRing.Reverse();
        }

        List <Vector3> validQuads = new List <Vector3>();
        List <Vector3> validTris  = new List <Vector3>();

        SetInnerRing(outerRing.ToArray(), validQuads, validTris);

        lineRing = SetLineSegmentRing(outerRing, innerRing);
        Utility.Polygon poly = SetOuterQuadsAndTris(lineRing);
        poly.Combine(AddInnerQuadsAndTris(validQuads, validTris));
        poly.verts = ModifyGroundHeights(poly.verts);

        Mesh mesh = new Mesh()
        {
            vertices  = poly.verts.ToArray(),
            triangles = poly.tris.ToArray(),
            uv        = poly.uvs.ToArray()
        };

        mesh.RecalculateNormals();

        FinishOutputs(ModifyGroundHeights(outerRing));

        return(mesh);
    }
    protected void AddToMesh(Utility.Polygon mesh, List <Vector3> row1, List <Vector3> row2, int rowI, float widthMax, bool end = false)
    {
        float widthDelta  = 1f / widthMax * .5f;
        float heightDelta = 1f / row1.Count * .5f;
        float width1      = (rowI - 1) / widthMax;
        float width2      = (rowI) / widthMax;

        if (row1.Count == row2.Count)
        {
            for (int j = 0; j < row2.Count - 1 && j < row1.Count - 1; j++)
            {
                float height1 = (float)(j) / (row1.Count);
                float height2 = (float)(j + 1) / (row2.Count);
                if (!CheckQuadInHole(row1[j], row1[j + 1], row2[j], row2[j + 1], width1, width2, widthDelta, height2, height2, heightDelta))
                {
                    if ((rowI + j) % 2 == 0)
                    {
                        mesh.AddQuad(row1[j], row1[j + 1], row2[j], row2[j + 1], new Vector2(width1, height1), new Vector2(width1, height2), new Vector2(width2, height1), new Vector2(width2, height2), flipMesh);
                    }
                    else
                    {
                        mesh.AddQuad(row1[j + 1], row2[j + 1], row1[j], row2[j], new Vector2(width1, height2), new Vector2(width2, height2), new Vector2(width1, height1), new Vector2(width2, height1), flipMesh);
                    }
                }
            }
        }
        else
        {
            if (end)
            {
                if (Vector3.Distance(row1[0], row2[0]) > Vector3.Distance(row1[0], row2[row2.Count - 1]))
                {
                    row2.Reverse();
                }
            }
            else
            {
                if (Vector3.Distance(row1[0], row2[0]) > Vector3.Distance(row1[row1.Count - 1], row2[0]))
                {
                    row1.Reverse();
                }
            }

            int     i = 0, j = 0;
            Vector3 start1 = row1[0], start2 = row2[0];
            while (i < row1.Count - 1 && j < row2.Count - 1)
            {
                float height1 = (float)(i + 1) / (row1.Count);
                float height2 = (float)(j + 1) / (row2.Count);

                if (!CheckQuadInHole(row1[i], row1[i + 1], row2[j], row2[j + 1], width1, width2, widthDelta, height1, height2, heightDelta))
                {
                    if (Vector3.Distance(row1[i], row2[j + 1]) < Vector3.Distance(row2[j], row1[i + 1]))
                    {
                        ++j;
                        mesh.AddTri(start1, row2[j], start2, new Vector2(width1, height1), new Vector2(width2, height2), new Vector2(width2, height1), flipMesh);
                        start2 = row2[j];
                    }
                    else
                    {
                        ++i;
                        mesh.AddTri(start1, row1[i], start2, new Vector2(width1, height1), new Vector2(width1, height2), new Vector2(width2, height1), flipMesh);
                        start1 = row1[i];
                    }
                }
                else
                {
                    ++j;
                    ++i;
                }
            }
            if (i < row1.Count - 1)
            {
                while (i < row1.Count - 1)
                {
                    ++i;
                    float height1 = (float)(i + 1) / (row1.Count);
                    float height2 = (float)(j + 1) / (row2.Count);
                    if (!CheckQuadInHole(row1[i - 1], row1[i], row2[j], row2[j], width1, width2, widthDelta, height1, height2, heightDelta))
                    {
                        mesh.AddTri(start1, row1[i], start2, new Vector2(width1, height1), new Vector2(width1, height2), new Vector2(width2, height1), flipMesh);
                    }
                    start1 = row1[i];
                }
            }
            else if (j < row2.Count - 1)
            {
                while (j < row2.Count - 1)
                {
                    ++j;
                    float height1 = (float)(i + 1) / (row1.Count);
                    float height2 = (float)(j + 1) / (row2.Count);
                    if (!CheckQuadInHole(row1[i], row1[i], row2[j - 1], row2[j], width1, width2, widthDelta, height1, height2, heightDelta))
                    {
                        mesh.AddTri(start1, row2[j], start2, new Vector2(width1, height1), new Vector2(width2, height2), new Vector2(width2, height1), flipMesh);
                    }
                    start2 = row2[j];
                }
            }
        }
    }
Example #8
0
    public override Mesh CreateMesh()
    {
        //print("Updating " + typeof(PathWallCreator));
        ClearOutput();

        List <Vector3[]> setWall = new List <Vector3[]>();

        Vector3[] setNorm = new Vector3[0];
        if (closed)
        {
            List <Vector3> edgeList = new List <Vector3>();
            List <Vector3> normList = new List <Vector3>();
            if (pathCreator != null)
            {
                edgeList.AddRange(pathCreator.path.vertices);
                normList.AddRange(pathCreator.path.normals);
            }
            for (int i = 0; i < inputs.Length; i++)
            {
                if (CheckConnection(i))
                {
                    AddEdge(edgeList, normList, inputs[i].Edge, inputs[i].Norm);
                }
            }
            if (pathCreator != null && edgeList.Count > pathCreator.path.NumVertices)
            {
                edgeList.Add(edgeList[0]);
                normList.Add(normList[0]);
            }


            if (pathClosed = Vector3.Distance(edgeList[0], edgeList[edgeList.Count - 1]) <= .001f)
            {
                edgeList[edgeList.Count - 1] = edgeList[0];
            }

            setWall.Add(edgeList.ToArray());
            setNorm = normList.ToArray();
        }
        else
        {
            if (pathCreator != null)
            {
                setWall.Add(pathCreator.path.vertices);
                setNorm    = pathCreator.path.normals;
                pathClosed = pathCreator.bezierPath.IsClosed;
            }
            for (int i = 0; i < inputs.Length; i++)
            {
                if (CheckConnection(i))
                {
                    setWall.Add(inputs[i].Edge);
                    if (setWall.Count == 1)
                    {
                        setNorm = inputs[i].Norm;
                        if (setWall[0].Length == setNorm.Length + 1)
                        {
                            setWall[0] = new List <Vector3>(setWall[0]).GetRange(1, setNorm.Length).ToArray();
                        }
                    }
                }
                else
                {
                    setWall.Add(null);
                }
            }
        }

        if (wallHeight != 0 && gridScale > 0.01f && setWall.Count > 0 && setWall[0] != null)
        {
            if (pathClosed = setWall[0][0] == setWall[0][setWall[0].Length - 1])
            {
                setNorm[0] = ((setNorm[0] + setNorm[setNorm.Length - 1]) * .5f).normalized;
                setNorm[setNorm.Length - 1] = setNorm[0];
            }
        }
        else
        {
            print("No path: " + typeof(PathWallCreator));
            return(new Mesh());
        }

        Utility.Polygon poly = GetWall(setWall[0], setNorm, setWall.Count > 1 ? setWall[1] : null, setWall.Count > 2 ? setWall[2] : null, setWall.Count > 3 ? setWall[3] : null);

        Mesh mesh = new Mesh()
        {
            vertices  = poly.verts.ToArray(),
            triangles = poly.tris.ToArray(),
            uv        = poly.uvs.ToArray()
        };

        mesh.RecalculateNormals();

        FinishOutputs(new List <Vector3>(setWall[0]));

        return(mesh);
    }
Example #9
0
    Utility.Polygon GetWall(Vector3[] wallBase, Vector3[] normals, Vector3[] startEdge, Vector3[] endEdge, Vector3[] topEdge)
    {
        Utility.Polygon mesh = new Utility.Polygon();

        float maxVerts = (wallBase.Length - 1) * density;

        List <List <Vector3> > rows = new List <List <Vector3> > {
            GetWallRow(wallBase[0], Vector3.zero, normals[0], 0, 1 / maxVerts)
        };

        if (topEdge != null)
        {
            if (heightCurve.Evaluate(0) == 0)
            {
                rows[0].Add(CheckAddOutput(topEdge[0], 0, 1 / maxVerts, 1.1f, 0));
            }
            else
            {
                rows[0].Add(CheckAddOutput(Utility.GetClosest(topEdge, rows[0][rows[0].Count - 1]), 0, 1 / maxVerts, 1.1f, gridScale / Mathf.Abs(wallHeight * heightCurve.Evaluate(0)) * .5f));
            }
        }
        if (startEdge != null && startEdge.Length > 0)
        {
            if (startEdge[0] == rows[0][0])
            {
                EditOutput(rows[0][rows[0].Count - 1], startEdge[startEdge.Length - 1]);
                rows[0][rows[0].Count - 1] = startEdge[startEdge.Length - 1];
            }
            AddToMesh(mesh, new List <Vector3>(startEdge), rows[0], 0, maxVerts);
        }
        for (int i = 0; i < wallBase.Length - 1; i++)
        {
            for (float d = 1; d <= density; d++)
            {
                int rowIndex = rows.Count;
                if (rowIndex == maxVerts && pathClosed)
                {
                    rows.Add(rows[0]);
                }
                else
                {
                    float   rowDelta   = d / density;
                    Vector3 edgeNorm   = Vector3.Lerp(normals[i], normals[i + 1], rowDelta).normalized;
                    Vector3 normOffset = edgeNorm * (1 - Mathf.Pow(2 * (rowDelta - .5f), 2)) * Mathf.Clamp(Vector3.SignedAngle(edgeNorm, normals[i], Vector3.up), -10, 10) * Mathf.Deg2Rad * edgeNormMult;
                    Vector3 edgeVert   = Vector3.Lerp(wallBase[i], wallBase[i + 1], rowDelta);
                    rows.Add(GetWallRow(edgeVert, normOffset, edgeNorm, rowIndex / maxVerts, 1 / maxVerts));
                    if (topEdge != null)
                    {
                        rows[rowIndex].Add(CheckAddOutput(Utility.GetClosest(topEdge, rows[rowIndex][rows[rowIndex].Count - 1]), rowIndex / maxVerts, 1 / maxVerts, 1.1f, gridScale / Mathf.Abs(wallHeight * heightCurve.Evaluate(rowIndex / maxVerts)) * .5f));
                    }
                }

                if (rowIndex > 0)
                {
                    if (rowIndex == maxVerts && endEdge != null && endEdge.Length > 0 && endEdge[0] == rows[rows.Count - 1][0])
                    {
                        EditOutput(rows[rows.Count - 1][rows[rows.Count - 1].Count - 1], endEdge[endEdge.Length - 1]);
                        rows[rows.Count - 1][rows[rows.Count - 1].Count - 1] = endEdge[endEdge.Length - 1];
                    }
                    AddToMesh(mesh, rows[rowIndex - 1], rows[rowIndex], rowIndex, maxVerts);
                }
            }
        }
        if (endEdge != null && endEdge.Length > 0)
        {
            AddToMesh(mesh, rows[rows.Count - 1], new List <Vector3>(endEdge), (int)maxVerts + 1, maxVerts, true);
        }

        return(mesh);
    }