Beispiel #1
0
    public static GameObject GeneratePolygon(List <Vector2> vertices2D, PolygonMapGenerator PMG, float layer)
    {
        // Use the triangulator to get indices for creating triangles
        Triangulator tr = new Triangulator(vertices2D.ToArray());

        int[] indices = tr.Triangulate();

        // Create the Vector3 vertices
        Vector3[] vertices = new Vector3[vertices2D.Count];
        Vector4[] tangents = new Vector4[vertices2D.Count];
        Vector2[] uvs      = new Vector2[vertices2D.Count];
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = new Vector3(vertices2D[i].x, layer, vertices2D[i].y);
            if (PMG != null)
            {
                uvs[i] = new Vector2(vertices2D[i].x / PMG.GenerationSettings.Width, vertices2D[i].y / PMG.GenerationSettings.Height);
            }


            // tangent calc
            Vector2 beforeVertex = vertices2D[i == 0 ? vertices2D.Count - 1 : i - 1];
            Vector2 thisVertex   = vertices2D[i];
            Vector2 afterVertex  = vertices2D[i == vertices2D.Count - 1 ? 0 : i + 1];

            Vector2 targetPoint = GeometryFunctions.GetOffsetIntersection(beforeVertex, thisVertex, afterVertex, 1f, 1f, false);

            Vector2 tangent = targetPoint - thisVertex;

            /*
             * float angle = Mathf.Abs(Vector2.Angle((beforeVertex - thisVertex).normalized, (afterVertex - thisVertex).normalized));
             * float factor = (180 - angle) * 0.005f;
             * tangent *= (1 + factor);
             */

            tangents[i] = new Vector4(tangent.x, 0, tangent.y, 0);
        }

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertices;
        msh.tangents  = tangents;
        msh.uv        = uvs;
        msh.triangles = indices;
        msh.RecalculateNormals();
        msh.RecalculateBounds();

        // Set up game object with mesh;
        GameObject   polygon  = new GameObject("Polygon (" + vertices2D.Count + ")");
        MeshRenderer renderer = polygon.AddComponent <MeshRenderer>();
        Color        ranCol   = Color.red; // new Color(Random.Range(0f, 0.3f), Random.Range(0.4f, 1f), Random.Range(0.1f, 0.6f));

        renderer.material.color = ranCol;
        MeshFilter filter = polygon.AddComponent(typeof(MeshFilter)) as MeshFilter;

        filter.mesh = msh;

        return(polygon);
    }
Beispiel #2
0
    public static GameObject CreateSinglePolygonBorder(List <GraphNode> nodes, float width, Color c, float layer, bool clockwise = false)
    {
        List <Vector2> outerVertices = nodes.Select(x => x.Vertex).ToList();
        List <Vector2> innerVertices = new List <Vector2>();

        for (int i = 0; i < outerVertices.Count; i++)
        {
            Vector2 beforeVertex = outerVertices[i == 0 ? outerVertices.Count - 1 : i - 1];
            Vector2 thisVertex   = outerVertices[i];
            Vector2 afterVertex  = outerVertices[i == outerVertices.Count - 1 ? 0 : i + 1];

            Vector2 targetPoint = GeometryFunctions.GetOffsetIntersection(beforeVertex, thisVertex, afterVertex, width, width, clockwise);

            innerVertices.Add(targetPoint);
        }

        // Create full vertex list (outer0, inner0, outer1, inner1, outer2, inner2, ...)
        Vector3[] vertices = new Vector3[outerVertices.Count + innerVertices.Count];
        for (int i = 0; i < outerVertices.Count; i++)
        {
            vertices[2 * i]     = new Vector3(outerVertices[i].x, layer, outerVertices[i].y);
            vertices[2 * i + 1] = new Vector3(innerVertices[i].x, layer, innerVertices[i].y);
        }

        // Create triangles ( 0/2/1, 1/2/3, 2/4/3, 3/4/5, 4/6/5, 5/6/7, ...)
        int[] triangles = new int[vertices.Length * 3];
        for (int i = 0; i < vertices.Length; i++)
        {
            if (clockwise)
            {
                triangles[3 * i]     = i;
                triangles[3 * i + 1] = ((((i + 1) / 2) * 2) + 1) % vertices.Length;
                triangles[3 * i + 2] = (((i / 2) * 2) + 2) % vertices.Length;
            }
            else
            {
                // One column represents one triangle
                triangles[3 * i]     = i;                                             // 0, 1, 2, 3, 4, 5, ...
                triangles[3 * i + 1] = (((i / 2) * 2) + 2) % vertices.Length;         // 2, 2, 4, 4, 6, 6, ...
                triangles[3 * i + 2] = ((((i + 1) / 2) * 2) + 1) % vertices.Length;   // 1, 3, 3, 5, 5, 7, ...
            }
        }

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertices;
        msh.triangles = triangles;
        msh.RecalculateNormals();
        msh.RecalculateBounds();

        GameObject   border   = new GameObject("Border (" + vertices.Length + ")");
        MeshRenderer renderer = border.AddComponent <MeshRenderer>();

        renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
        renderer.receiveShadows    = false;
        renderer.material          = MapDisplayResources.Singleton.DefaultMaterial;
        renderer.material.color    = c;
        MeshFilter filter = border.AddComponent <MeshFilter>();

        filter.mesh = msh;

        return(border);
    }
Beispiel #3
0
        public static River CreateRiverObject(GraphPath riverPath, PolygonMapGenerator PMG)
        {
            //Debug.Log("Creating mesh for river with " + riverPath.Nodes.Count + " points");

            // Calculate vertices of river polygon
            List <Vector2> polygonVerticesHalf1 = new List <Vector2>();
            List <Vector2> polygonVerticesHalf2 = new List <Vector2>();

            for (int i = 1; i < riverPath.Nodes.Count - 1; i++)
            {
                Vector2 startPoint = riverPath.Nodes[i - 1].Vertex;
                Vector2 thisPoint  = riverPath.Nodes[i].Vertex;
                Vector2 nextPoint  = riverPath.Nodes[i + 1].Vertex;

                float startWidth = riverPath.Nodes[i - 1].RiverWidth;
                float endWidth   = riverPath.Nodes[i].RiverWidth;

                //Debug.Log("River point " + i + ": startWidth = " + startWidth + ", endWidth = " + endWidth);

                if (i == 1) // Add two starting points
                {
                    Vector2 rotatedVector = GeometryFunctions.RotateVector((thisPoint - startPoint).normalized * startWidth, 90);
                    polygonVerticesHalf1.Add(startPoint + rotatedVector);
                    polygonVerticesHalf2.Add(startPoint - rotatedVector);
                }

                polygonVerticesHalf1.Add(GeometryFunctions.GetOffsetIntersection(startPoint, thisPoint, nextPoint, startWidth, endWidth, true));
                polygonVerticesHalf2.Add(GeometryFunctions.GetOffsetIntersection(startPoint, thisPoint, nextPoint, startWidth, endWidth, false));

                if (i == riverPath.Nodes.Count - 2) // Add two ending points (calculate river delta by taking intersecion between river and shoreline
                {
                    GraphNode lastNode = riverPath.Nodes.Last();
                    List <GraphConnection> shoreDelta       = lastNode.Connections.Where(x => x.Type == BorderType.Shore).ToList();
                    List <GraphNode>       riverDeltaPoints = new List <GraphNode>();
                    foreach (GraphConnection delta in shoreDelta)
                    {
                        if (delta.StartNode == lastNode)
                        {
                            riverDeltaPoints.Add(delta.EndNode);
                        }
                        else
                        {
                            riverDeltaPoints.Add(delta.StartNode);
                        }
                    }

                    Vector2 endPoint1, endPoint2;

                    // BUG: this method doesn't work 100%
                    GraphPolygon firstPolygon = riverPath.Nodes[i].Polygons.FirstOrDefault(x => GeometryFunctions.IsPointInPolygon4(x.Nodes.Select(x => x.Vertex).ToList(), polygonVerticesHalf1.Last()));
                    if (firstPolygon == null)
                    {
                        throw new Exception("Couldn't find direction of river delta. is river too short? length = " + riverPath.Nodes.Count);
                    }

                    bool addDeltaMidPoint = true;
                    if (riverDeltaPoints[0].Polygons.Contains(firstPolygon))
                    {
                        endPoint1 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[0].Vertex, endWidth, 0f, true);
                        endPoint2 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[1].Vertex, endWidth, 0f, false);

                        if (!GeometryFunctions.IsPointOnLineSegment(endPoint1, riverDeltaPoints[0].Vertex, lastNode.Vertex))
                        {
                            endPoint1        = lastNode.Vertex;
                            addDeltaMidPoint = false;
                        }
                        if (!GeometryFunctions.IsPointOnLineSegment(endPoint2, riverDeltaPoints[1].Vertex, lastNode.Vertex))
                        {
                            endPoint2        = lastNode.Vertex;
                            addDeltaMidPoint = false;
                        }
                    }
                    else
                    {
                        endPoint1 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[1].Vertex, endWidth, 0f, true);
                        endPoint2 = GeometryFunctions.GetOffsetIntersection(thisPoint, nextPoint, riverDeltaPoints[0].Vertex, endWidth, 0f, false);

                        if (!GeometryFunctions.IsPointOnLineSegment(endPoint1, riverDeltaPoints[1].Vertex, lastNode.Vertex))
                        {
                            endPoint1        = lastNode.Vertex;
                            addDeltaMidPoint = false;
                        }
                        if (!GeometryFunctions.IsPointOnLineSegment(endPoint2, riverDeltaPoints[0].Vertex, lastNode.Vertex))
                        {
                            endPoint2        = lastNode.Vertex;
                            addDeltaMidPoint = false;
                        }
                    }

                    polygonVerticesHalf1.Add(endPoint1);
                    if (addDeltaMidPoint)
                    {
                        polygonVerticesHalf1.Add(lastNode.Vertex);
                    }
                    polygonVerticesHalf2.Add(endPoint2);
                }
            }

            polygonVerticesHalf2.Reverse();
            List <Vector2> polygonVertices = polygonVerticesHalf1;

            polygonVertices.AddRange(polygonVerticesHalf2);

            List <Vector2> polygonVerticesList = polygonVertices.ToList();

            if (GeometryFunctions.IsClockwise(polygonVerticesList))
            {
                polygonVerticesList.Reverse();
            }

            // Create object
            GameObject riverObject = MeshGenerator.GeneratePolygon(polygonVerticesList, PMG, layer: PolygonMapGenerator.LAYER_RIVER);

            River river = riverObject.AddComponent <River>();

            river.Init(riverPath.Nodes.Select(x => x.BorderPoint).ToList(), riverPath.Connections.Select(x => x.Border).ToList(), riverPath.Polygons.Select(x => x.Region).ToList());

            riverObject.GetComponent <MeshRenderer>().material.color = Color.red;

            riverObject.name = "River";

            return(river);
        }