예제 #1
0
    public PolySet Inset(PolySet polys, float interpolation)
    {
        PolySet    stitchedPolys = StitchIdentifiedPolys(polys);
        List <int> verts         = polys.GetUniqueVerts();

        //Calculate the average center of all the vertices in these Polygons.
        Vector3 center = Vector3.zero;

        foreach (int vert in verts)
        {
            center += m_Vertices[vert];
        }
        center /= verts.Count;

        // Pull each vertex towards the center, then correct it's height so that it's as far from the center of
        // the planet as it was before.
        foreach (int vert in verts)
        {
            Vector3 v      = m_Vertices[vert];
            float   height = v.magnitude;
            v = Vector3.Lerp(v, center, interpolation);
            v = v.normalized * height;
            m_Vertices[vert] = v;
        }

        return(stitchedPolys);
    }
예제 #2
0
    private KeyValuePair <bool, PolySet> IsZoneCircled(Polygon currentPoly, PolySet checkedPolys, int depth = 0)
    {
        depth++;
        checkedPolys.Add(currentPoly);

        /*
         * if (depth > 10 || checkedPolys.Count > 10)
         * {
         *  return new KeyValuePair<bool, PolySet>(false, checkedPolys);
         * }*/
        bool isCircled = true;

        foreach (Polygon neighborPoly in currentPoly.m_Neighbors)
        {
            if (neighborPoly.m_territory == Territory.Cliff || neighborPoly.m_territory == Territory.Ocean)
            {
                return(new KeyValuePair <bool, PolySet>(false, checkedPolys));
            }
            else if (!checkedPolys.Contains(neighborPoly) &&
                     (neighborPoly.m_territory == Territory.Neutral ||
                      neighborPoly.m_territory == Territory.BlueClan))
            {
                KeyValuePair <bool, PolySet> result = IsZoneCircled(neighborPoly, checkedPolys, depth);
                checkedPolys = result.Value;
                isCircled   &= result.Key;
            }
        }
        return(new KeyValuePair <bool, PolySet>(isCircled, checkedPolys));
    }
    // RemoveEdges - Remove any poly from this set that borders the edge of the set, including those that just
    // touch the edge with a single vertex. The PolySet could be empty after this operation.

    public PolySet RemoveEdges()
    {
        var newSet = new PolySet();

        var edgeSet = CreateEdgeSet();

        var edgeVertices = edgeSet.GetUniqueVertices();

        foreach (Polygon poly in this)
        {
            bool polyTouchesEdge = false;

            for (int i = 0; i < 3; i++)
            {
                if (edgeVertices.Contains(poly.m_Vertices[i]))
                {
                    polyTouchesEdge = true;
                    break;
                }
            }

            if (polyTouchesEdge)
            {
                continue;
            }

            newSet.Add(poly);
        }

        return(newSet);
    }
예제 #4
0
    public void SpawnNodes(PolySet water)
    {
        List <Vector3> spawnPoints = new List <Vector3>();
        List <Polygon> _water      = new List <Polygon>(water);

        for (int i = 0; i < m_NumberOfShops; i++)
        {
            Polygon poly = _water[Random.Range(0, water.Count)];
            Vector3 ab   = m_Vertices[poly.m_Vertices[1]] - m_Vertices[poly.m_Vertices[0]];
            Vector3 ac   = m_Vertices[poly.m_Vertices[2]] - m_Vertices[poly.m_Vertices[0]];

            Vector3 normal = Vector3.Cross(ab, ac).normalized;

            Vector3 shopToPlace = m_PlanetMesh.transform.TransformPoint(normal);
            if (checkShopDistance(shopToPlace, spawnPoints))
            {
                spawnPoints.Add(shopToPlace);
            }
            else
            {
                i--;
                m_shopRangeMin -= 0.02f;
            }
        }

        m_nodeController.GenerateNodes(_nodePrefab, spawnPoints, m_PlanetMesh.transform);
    }
예제 #5
0
    private static PolySet StitchPolys(ICollection <Polygon> polygons, IList <Vector3> vertices, PolySet polys, out EdgeSet stitchedEdge)
    {
        var stichedPolys = new PolySet {
            StitchedVertexThreshold = vertices.Count
        };

        stitchedEdge = PolySet.CreateEdgeSet(polys);
        IList <int> originalVerts = EdgeSet.GetUniqueVertices(stitchedEdge);
        IList <int> newVerts      = CloneVertices(vertices, originalVerts);

        stitchedEdge.Split(originalVerts, newVerts);

        foreach (Edge edge in stitchedEdge)
        {
            // Create new polys along the stitched edge. These
            // will connect the original poly to its former
            // neighbor.

            var stitchPoly1 = new Polygon(edge.OuterVerts[0],
                                          edge.OuterVerts[1],
                                          edge.InnerVerts[0]);
            var stitchPoly2 = new Polygon(edge.OuterVerts[1],
                                          edge.InnerVerts[1],
                                          edge.InnerVerts[0]);
            // Add the new stitched faces as neighbors to
            // the original Polys.
            Polygon.ReplacePolygon(edge.InnerPoly.Neighbors, edge.OuterPoly, stitchPoly2);
            Polygon.ReplacePolygon(edge.OuterPoly.Neighbors, edge.InnerPoly, stitchPoly1);

            polygons.Add(stitchPoly1);
            polygons.Add(stitchPoly2);

            stichedPolys.Add(stitchPoly1);
            stichedPolys.Add(stitchPoly2);
        }

        //Swap to the new vertices on the inner polys.
        foreach (Polygon poly in polys)
        {
            for (int i = 0; i < 3; i++)
            {
                int vertID = poly.Vertices[i];
                if (!originalVerts.Contains(vertID))
                {
                    continue;
                }

                int vertIndex = originalVerts.IndexOf(vertID);
                poly.Vertices[i] = newVerts[vertIndex];
            }
        }

        return(stichedPolys);
    }
예제 #6
0
    private static PolySet CreateOcean(IEnumerable <Polygon> polygons, PolySet landPolys)
    {
        var oceanPolys = new PolySet();

        foreach (Polygon poly in polygons.Where(poly => !landPolys.Contains(poly)))
        {
            oceanPolys.Add(poly);
        }

        return(oceanPolys);
    }
예제 #7
0
    public PolySet StitchPolys(PolySet polys, out EdgeSet stitchedEdge)
    {
        PolySet stichedPolys = new PolySet();

        stichedPolys.m_StitchedVertexThreshold = m_Vertices.Count;

        stitchedEdge = polys.CreateEdgeSet();
        var originalVerts = stitchedEdge.GetUniqueVertices();
        var newVerts      = CloneVertices(originalVerts);

        stitchedEdge.Split(originalVerts, newVerts);

        foreach (Edge edge in stitchedEdge)
        {
            // Create new polys along the stitched edge. These
            // will connect the original poly to its former
            // neighbor.

            var stitch_poly1 = new Polygon(edge.m_OuterVerts[0],
                                           edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[0]);
            var stitch_poly2 = new Polygon(edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[1],
                                           edge.m_InnerVerts[0]);
            // Add the new stitched faces as neighbors to
            // the original Polys.
            edge.m_InnerPoly.ReplaceNeighbor(edge.m_OuterPoly, stitch_poly2);
            edge.m_OuterPoly.ReplaceNeighbor(edge.m_InnerPoly, stitch_poly1);

            m_Polygons.Add(stitch_poly1);
            m_Polygons.Add(stitch_poly2);

            stichedPolys.Add(stitch_poly1);
            stichedPolys.Add(stitch_poly2);
        }

        //Swap to the new vertices on the inner polys.
        foreach (Polygon poly in polys)
        {
            for (int i = 0; i < 3; i++)
            {
                int vert_id = poly.m_Vertices[i];
                if (!originalVerts.Contains(vert_id))
                {
                    continue;
                }
                int vert_index = originalVerts.IndexOf(vert_id);
                poly.m_Vertices[i] = newVerts[vert_index];
            }
        }

        return(stichedPolys);
    }
예제 #8
0
    public PolySet Extrude(PolySet polys, float height)
    {
        PolySet    stitchedPolys = StitchPolys(polys);
        List <int> verts         = polys.GetUniqueVertices();

        foreach (int vert in verts)
        {
            Vector3 v = m_Vertices[vert];
            v = v.normalized * (v.magnitude + height);
            m_Vertices[vert] = v;
        }
        return(stitchedPolys);
    }
예제 #9
0
    private static PolySet GetPolysInSphere(IList <Vector3> vertices, Vector3 center, float radius, IEnumerable <Polygon> source)
    {
        var newSet = new PolySet();

        foreach (Polygon p in source)
        {
            if (p.Vertices.Select(vertexIndex => Vector3.Distance(center, vertices[vertexIndex])).Any(distanceToSphere => distanceToSphere <= radius))
            {
                newSet.Add(p);
            }
        }

        return(newSet);
    }
예제 #10
0
    public PolySet Extrude(PolySet polys, float height)
    {
        PolySet    stitchedPolys = StitchIdentifiedPolys(polys);
        List <int> verts         = polys.GetUniqueVerts();

        // Take each vertex in this list of polys, and push it away from the center of the Planet by the height parameter.
        foreach (int vert in verts)
        {
            Vector3 v = m_Vertices[vert];
            v = v.normalized * (v.magnitude + height);
            m_Vertices[vert] = v;
        }

        return(stitchedPolys);
    }
예제 #11
0
    public PolySet StitchIdentifiedPolys(PolySet polys)
    {
        PolySet stichedPolys = new PolySet();

        var edgeSet       = polys.GenerateEdgeSet();
        var originalVerts = edgeSet.GetUniqueVertices();

        var newVerts = CloneVertices(originalVerts);

        edgeSet.Split(originalVerts, newVerts);

        foreach (Edge edge in edgeSet)
        {
            // Create new polys along the stitched edge.
            var stitch_poly1 = new Polygon(edge.m_OuterVerts[0],
                                           edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[0]);
            var stitch_poly2 = new Polygon(edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[1],
                                           edge.m_InnerVerts[0]);
            // Add the new stitched faces as neighbors to the original Polys.
            edge.m_InnerPoly.ReplaceNeighbor(edge.m_OuterPoly, stitch_poly2);
            edge.m_OuterPoly.ReplaceNeighbor(edge.m_InnerPoly, stitch_poly1);

            m_Polygons.Add(stitch_poly1);
            m_Polygons.Add(stitch_poly2);

            stichedPolys.Add(stitch_poly1);
            stichedPolys.Add(stitch_poly2);
        }

        //Vertices on inner polys are swapped.
        foreach (Polygon poly in polys)
        {
            for (int i = 0; i < 3; i++)
            {
                int vert_id = poly.m_Vertices[i];
                if (!originalVerts.Contains(vert_id))
                {
                    continue;
                }
                int vert_index = originalVerts.IndexOf(vert_id);
                poly.m_Vertices[i] = newVerts[vert_index];
            }
        }

        return(stichedPolys);
    }
예제 #12
0
    private static PolySet CreateLand(IList <Polygon> polygons, IList <Vector3> vertices, float sizeMin, float sizeMax, int ofContinents)
    {
        var landPolys = new PolySet();

        // Grab polygons that are inside random spheres. These will be the basis of our planet's continents.

        for (int i = 0; i < ofContinents; i++)
        {
            float continentSize = Random.Range(sizeMin, sizeMax);

            PolySet newLand = GetPolysInSphere(vertices, Random.onUnitSphere, continentSize, polygons);

            landPolys.UnionWith(newLand);
        }

        return(landPolys);
    }
예제 #13
0
    public PolySet GetPolysInSphere(Vector3 center, float radius, IEnumerable <Polygon> source)
    {
        PolySet newSet = new PolySet();

        foreach (Polygon p in source)
        {
            foreach (int vertexIndex in p.m_Vertices)
            {
                float distanceToSphere = Vector3.Distance(center, m_Vertices[vertexIndex]);
                if (distanceToSphere <= radius)
                {
                    newSet.Add(p);
                    break;
                }
            }
        }
        return(newSet);
    }
예제 #14
0
    private static PolySet Extrude(ICollection <Polygon> polygons, IList <Vector3> vertices, PolySet polys, float height)
    {
        PolySet     stitchedPolys = StitchPolys(polygons, vertices, polys, out EdgeSet _);
        IList <int> verts         = PolySet.GetUniqueVertices(polys);

        // Take each vertex in this list of polys, and push it
        // away from the center of the Planet by the height
        // parameter.

        foreach (int vert in verts)
        {
            Vector3 v = vertices[vert];
            v = v.normalized * (v.magnitude + height);
            vertices[vert] = v;
        }

        return(stitchedPolys);
    }
예제 #15
0
    private static void GenerateHills(ICollection <Polygon> polygons, IList <Vector3> vertices, PolySet landPolys, Color32 landColor, Color32 sideColor)
    {
        // Grab additional polygons to generate hills, but only from the set of polygons that are land.

        PolySet hillPolys = PolySet.RemoveEdges(landPolys);

        PolySet insetSides = Inset(polygons, vertices, hillPolys, 0.03f);

        PolySet.ApplyColor(insetSides, landColor);
        insetSides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        PolySet extrudeSides = Extrude(polygons, vertices, hillPolys, 0.05f);

        PolySet.ApplyColor(extrudeSides, sideColor);

        //Hills have dark ambient occlusion on the bottom, and light on top.
        extrudeSides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);
    }
예제 #16
0
    public void Update()
    {
        if (Input.GetMouseButton(0))
        {
            RaycastHit hit;
            if (!Physics.Raycast(_mainCamera.ScreenPointToRay(Input.mousePosition), out hit))
            {
                return;
            }

            MeshCollider meshCollider = hit.collider as MeshCollider;
            if (meshCollider == null || meshCollider.sharedMesh == null)
            {
                return;
            }

            Mesh      mesh      = meshCollider.sharedMesh;
            int[]     triangles = mesh.triangles;
            Color32[] colors32  = mesh.colors32;

            // search for the Polygon object representing the clicked triangle among
            // the land polygons of the planet.
            Polygon hitPoly = PolySet.FindPolyInPolyset(hit.triangleIndex, _planet);

            // if the Polygon object is not a land polygon
            if (hitPoly == null || hitPoly.m_territory == Territory.RedClan)
            {
                return;
            }

            // Change the color of the clicked triangle
            ColorTriangle(triangles, hit.triangleIndex, ref colors32, Clan.RedClan);

            // Make sure we update the color and territory properties of the hit polygon
            hitPoly.UpdateClan(Clan.RedClan);

            // See if a zone has been circled
            LookForCircledZonesInNeighbors(hitPoly, triangles, ref colors32);

            mesh.colors32 = colors32;
        }
    }
예제 #17
0
    public PolySet StitchPolys(PolySet polys)
    {
        PolySet stitchedPolys = new PolySet();

        var edgeSet       = polys.CreateEdgeSet();
        var originalVerts = edgeSet.GetUniqueVertices();
        var newVerts      = CloneVertices(originalVerts);

        edgeSet.Split(originalVerts, newVerts);

        foreach (Edge edge in edgeSet)
        {
            var stitch_poly1 = new Polygon(edge.m_OuterVerts[0],
                                           edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[0]);
            var stitch_poly2 = new Polygon(edge.m_OuterVerts[1],
                                           edge.m_InnerVerts[1],
                                           edge.m_InnerVerts[0]);
            edge.m_InnerPoly.ReplaceNeighbor(edge.m_OuterPoly, stitch_poly2);
            edge.m_OuterPoly.ReplaceNeighbor(edge.m_InnerPoly, stitch_poly1);

            m_Polygons.Add(stitch_poly1);
            m_Polygons.Add(stitch_poly2);
            stitchedPolys.Add(stitch_poly1);
            stitchedPolys.Add(stitch_poly2);
        }

        foreach (Polygon poly in polys)
        {
            for (int i = 0; i < 3; i++)
            {
                int vert_id = poly.m_Vertices[i];
                if (!originalVerts.Contains(vert_id))
                {
                    continue;
                }
                int vert_index = originalVerts.IndexOf(vert_id);
                poly.m_Vertices[i] = newVerts[vert_index];
            }
        }
        return(stitchedPolys);
    }
예제 #18
0
    // RemoveEdges - Remove any poly from this set that borders the edge of the set, including those that just
    // touch the edge with a single vertex. The PolySet could be empty after this operation.

    public static PolySet RemoveEdges(HashSet <Polygon> polygons)
    {
        var newSet = new PolySet();

        var edgeSet = CreateEdgeSet(polygons);

        var edgeVertices = EdgeSet.GetUniqueVertices(edgeSet);

        foreach (Polygon poly in polygons)
        {
            if (poly.Vertices.Any(vertices => edgeVertices.Contains(vertices)))
            {
                continue;
            }

            newSet.Add(poly);
        }

        return(newSet);
    }
예제 #19
0
    public PolySet Inset(PolySet polys, float interpolation)
    {
        PolySet    stitchedPolys = StitchPolys(polys);
        List <int> verts         = polys.GetUniqueVertices();

        Vector3 center = Vector3.zero;

        foreach (int vert in verts)
        {
            center += m_Vertices[vert];
        }
        center /= verts.Count;

        foreach (int vert in verts)
        {
            Vector3 v      = m_Vertices[vert];
            float   height = v.magnitude;
            v = Vector3.Lerp(v, center, interpolation);
            v = v.normalized * height;
            m_Vertices[vert] = v;
        }
        return(stitchedPolys);
    }
예제 #20
0
    public void Start()
    {
        // Create an icosahedron
        test = new Polygon[10];

        for (int i = 0; i < 10; i++)
        {
            test[i] = new Polygon(i, i, i);
        }
        Debug.Log(test[2].m_Color);
        CreateIcosahedron();
        SubdividePlanet(3);

        // Calculates Neighbor vertices
        CalculateNeighborVertices();

        // By default, everything is blue.
        Color32 colorOcean = new Color32(0, 80, 220, 0);
        Color32 colorGrass = new Color32(0, 220, 0, 0);
        Color32 colorDirt  = new Color32(180, 140, 20, 0);

        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }

        // Now we build a set of Polygons that will become the land. We do this by generating randomly sized spheres on the
        // surface of the planet, and adding any Polygon that falls inside that sphere.
        PolySet landPolys = new PolySet();

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);

            PolySet newLand = GetPolysInSphere(Random.onUnitSphere, continentSize, m_Polygons);

            landPolys.UnionWith(newLand);
        }

        // This is our land now, so color it green.
        foreach (Polygon landPoly in landPolys)
        {
            landPoly.m_Color = colorGrass;
        }

        // The Extrude function will raise the land Polygons up out of the water.
        PolySet sides = Extrude(landPolys, 0.01f);

        foreach (Polygon side in sides)
        {
            side.m_Color = colorDirt;
        }

        //Grab additional polygons to generate hills, but only from the set of polygons that are land.
        PolySet hillPolys = new PolySet();

        for (int i = 0; i < m_NumberOfHills; i++)
        {
            float hillSize = Random.Range(m_HillSizeMin, m_HillSizeMax);

            PolySet newHill = GetPolysInSphere(Random.onUnitSphere, hillSize, landPolys);

            hillPolys.UnionWith(newHill);
        }

        sides = Extrude(hillPolys, 0.03f);

        foreach (Polygon side in sides)
        {
            side.m_Color = colorDirt;
        }

        //Generate an actual game mesh for this planet.
        GeneratePlanetMesh();
    }
예제 #21
0
    public void Start()
    {
        foreach (Transform t in transform)
        {
            if (t.tag == "PlanetTerrain")
            {
                DestroyImmediate(t.gameObject);
            }
        }
        foreach (Transform t in transform)
        {
            if (t.tag == "PlanetTerrain")
            {
                DestroyImmediate(t.gameObject);
            }
        }

        InitAsIcosohedron();
        Subdivide(SUBDIVIDES);
        CalculateNeighbors();

        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }
        PolySet landPolys = new PolySet();
        PolySet sides;

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float   continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);
            PolySet newLand       = GetPolysInSphere(Random.onUnitSphere, continentSize, m_Polygons);
            landPolys.UnionWith(newLand);
        }

        var oceanPolys = new PolySet();

        foreach (Polygon poly in m_Polygons)
        {
            if (!landPolys.Contains(poly))
            {
                oceanPolys.Add(poly);
            }
        }

        var oceanSurface = new PolySet(oceanPolys);

        sides = Inset(oceanSurface, 0.05f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        if (m_OceanMesh != null)
        {
            DestroyImmediate(m_OceanMesh);
        }
        m_OceanMesh = GenerateMesh("Ocean Surface", m_OceanMaterial);

        foreach (Polygon landPoly in landPolys)
        {
            landPoly.m_Color = colorGrass;
        }

        sides = Extrude(landPolys, 0.05f);
        sides.ApplyColor(colorDirt);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        PolySet hillPolys = landPolys.RemoveEdges();

        sides = Inset(hillPolys, 0.03f);
        sides.ApplyColor(colorGrass);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Extrude(hillPolys, 0.05f);
        sides.ApplyColor(colorDirt);

        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        sides = Extrude(oceanPolys, -0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Inset(oceanPolys, 0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        var deepOceanPolys = oceanPolys.RemoveEdges();

        sides = Extrude(deepOceanPolys, -0.05f);
        sides.ApplyColor(colorDeepOcean);
        deepOceanPolys.ApplyColor(colorDeepOcean);

        if (m_GroundMesh != null)
        {
            DestroyImmediate(m_GroundMesh);
        }
        m_GroundMesh = GenerateMesh("Ground Mesh", m_GroundMaterial);
    }
예제 #22
0
    private static Mesh GetGroundMesh(IList <Polygon> polygons, IList <Vector3> vertices, float continentSizeMin, float continentSizeMax, int numberOfContinents, Color32 landColor, Color32 sideColor,
                                      Color32 oceanColor, Color32 deepOceanColor, bool isGenerateHills, bool isGenerateDeepOceans)
    {
        // Now we build a set of Polygons that will become the land. We do this by generating
        // randomly sized spheres on the surface of the planet, and adding any Polygon that falls
        // inside that sphere.

        PolySet landPolys = CreateLand(polygons, vertices, continentSizeMin, continentSizeMax, numberOfContinents);

        // While we're here, let's make a group of oceanPolys. It's pretty simple: Any Polygon that isn't in the landPolys set
        // must be in the oceanPolys set instead.

        PolySet oceanPolys = CreateOcean(polygons, landPolys);

        // Let's create the ocean surface as a separate mesh.
        // First, let's make a copy of the oceanPolys so we can
        // still use them to also make the ocean floor later.

        var oceanSurface = new PolySet(oceanPolys);

        PolySet sides = Inset(polygons, vertices, oceanSurface, 0.05f);

        PolySet.ApplyColor(sides, oceanColor);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        // Time to return to the oceans.

        sides = Extrude(polygons, vertices, oceanPolys, -0.02f);
        PolySet.ApplyColor(sides, oceanColor);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Inset(polygons, vertices, oceanPolys, 0.02f);
        PolySet.ApplyColor(sides, oceanColor);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        if (isGenerateDeepOceans)
        {
            var deepOceanPolys = PolySet.RemoveEdges(oceanPolys);

            sides = Extrude(polygons, vertices, deepOceanPolys, -0.05f);
            PolySet.ApplyColor(sides, deepOceanColor);

            PolySet.ApplyColor(deepOceanPolys, deepOceanColor);
        }

        // Back to land for a while! We start by making it green. =)

        PolySet.ApplyColor(landPolys, landColor);

        // The Extrude function will raise the land Polygons up out of the water.
        // It also generates a strip of new Polygons to connect the newly raised land
        // back down to the water level. We can color this vertical strip of land brown like dirt.

        sides = Extrude(polygons, vertices, landPolys, 0.05f);
        PolySet.ApplyColor(sides, sideColor);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        if (isGenerateHills)
        {
            GenerateHills(polygons, vertices, landPolys, landColor, sideColor);
        }

        return(GenerateMesh("Ground Mesh", polygons, vertices));
    }
 public PolySet(PolySet source) : base(source)
 {
 }
예제 #24
0
    public void Start()
    {
        // Create an icosahedron, subdivide it three times so that we have plenty of polys
        // to work with.

        InitAsIcosohedron();
        Subdivide(4);

        // When we begin extruding polygons, we'll need each one to know who its immediate
        //neighbors are. Calculate that now.

        CalculateNeighbors();

        // By default, everything is colored blue. As we extrude land forms, we'll change their colors to match.

        Color32 colorOcean     = new Color32(0, 80, 220, 0);
        Color32 colorGrass     = new Color32(0, 220, 0, 0);
        Color32 colorDirt      = new Color32(180, 140, 20, 0);
        Color32 colorDeepOcean = new Color32(0, 40, 110, 0);

        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }

        // Now we build a set of Polygons that will become the land. We do this by generating
        // randomly sized spheres on the surface of the planet, and adding any Polygon that falls
        // inside that sphere.

        PolySet landPolys = new PolySet();
        PolySet sides;

        // Grab polygons that are inside random spheres. These will be the basis of our planet's continents.

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);

            PolySet newLand = GetPolysInSphere(Random.onUnitSphere, continentSize, m_Polygons);

            landPolys.UnionWith(newLand);
        }

        m_landPolys = landPolys;

        // While we're here, let's make a group of oceanPolys. It's pretty simple: Any Polygon that isn't in the landPolys set
        // must be in the oceanPolys set instead.

        var oceanPolys = new PolySet();

        foreach (Polygon poly in m_Polygons)
        {
            if (!landPolys.Contains(poly))
            {
                oceanPolys.Add(poly);
            }
        }

        m_oceanPolys = oceanPolys;

        // Let's create the ocean surface as a separate mesh.
        // First, let's make a copy of the oceanPolys so we can
        // still use them to also make the ocean floor later.

        var oceanSurface = new PolySet(oceanPolys);

        sides = Inset(oceanSurface, 0.05f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        if (m_OceanMesh != null)
        {
            Destroy(m_OceanMesh);
        }

        m_OceanMesh = GenerateMesh("Ocean Surface", m_OceanMaterial);

        // Back to land for a while! We start by making it green. =)

        //landPolys.ApplyRandomClanColors(colorBlueClan, colorRedClan);
        landPolys.ApplyColor(colorGrass);
        landPolys.ApplyTerritory(Territory.Neutral);
        // The Extrude function will raise the land Polygons up out of the water.
        // It also generates a strip of new Polygons to connect the newly raised land
        // back down to the water level. We can color this vertical strip of land brown like dirt.

        sides = Extrude(landPolys, 0.05f);

        sides.ApplyColor(colorDirt);
        sides.ApplyTerritory(Territory.Cliff);

        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        /*
         * // Grab additional polygons to generate hills, but only from the set of polygons that are land.
         *
         * PolySet hillPolys = landPolys.RemoveEdges();
         *
         * sides = Inset(hillPolys, 0.03f);
         * sides.ApplyRandomClanColors(colorBlueClan, colorRedClan);
         * sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);
         *
         * sides = Extrude(hillPolys, 0.05f);
         * sides.ApplyColor(colorDirt);
         *
         * //Hills have dark ambient occlusion on the bottom, and light on top.
         * sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);
         */
        // Time to return to the oceans.

        sides = Extrude(oceanPolys, -0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyTerritory(Territory.Ocean);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Inset(oceanPolys, 0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyTerritory(Territory.Ocean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        var deepOceanPolys = oceanPolys.RemoveEdges();

        sides = Extrude(deepOceanPolys, -0.05f);
        sides.ApplyColor(colorDeepOcean);
        sides.ApplyTerritory(Territory.Ocean);

        deepOceanPolys.ApplyColor(colorDeepOcean);
        deepOceanPolys.ApplyTerritory(Territory.Ocean);


        // Okay, we're done! Let's generate an actual game mesh for this planet.

        if (m_GroundMesh != null)
        {
            Destroy(m_GroundMesh);
        }

        m_GroundMesh = GenerateMesh("Ground Mesh", m_GroundMaterial);
        m_GroundMesh.AddComponent <ClickableTriangles>();
    }
예제 #25
0
    public void Start()
    {
        // Create an icosahedron, subdivide it three times so that we have plenty of polys
        // to work with.

        InitAsIcosohedron();
        Subdivide(m_Subdivisions);

        // When we begin extruding polygons, we'll need each one to know who its immediate
        //neighbors are. Calculate that now.

        CalculateNeighbors();

        // By default, everything is colored blue. As we extrude land forms, we'll change their colors to match.

        Color32 colorOcean     = new Color32(0, 80, 220, 0);
        Color32 colorGrass     = new Color32(0, 220, 0, 0);
        Color32 colorDirt      = new Color32(180, 140, 20, 0);
        Color32 colorDeepOcean = new Color32(0, 40, 110, 0);

        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }

        // Now we build a set of Polygons that will become the land. We do this by generating
        // randomly sized spheres on the surface of the planet, and adding any Polygon that falls
        // inside that sphere.

        PolySet landPolys = new PolySet();
        PolySet sides;

        // Grab polygons that are inside random spheres. These will be the basis of our planet's continents.

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);

            PolySet newLand = GetPolysInSphere(Random.onUnitSphere, continentSize, m_Polygons);

            landPolys.UnionWith(newLand);
        }

        // While we're here, let's make a group of oceanPolys. It's pretty simple: Any Polygon that isn't in the landPolys set
        // must be in the oceanPolys set instead.

        var oceanPolys = new PolySet();

        foreach (Polygon poly in m_Polygons)
        {
            if (!landPolys.Contains(poly))
            {
                oceanPolys.Add(poly);
            }
        }

        // Let's create the ocean surface as a separate mesh.
        // First, let's make a copy of the oceanPolys so we can
        // still use them to also make the ocean floor later.

        var oceanSurface = new PolySet(oceanPolys);

        sides = Inset(oceanSurface, 0.05f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        if (m_OceanMesh != null)
        {
            Destroy(m_OceanMesh);
        }

        m_OceanMesh = GenerateMesh("Ocean Surface", m_OceanMaterial);

        // Back to land for a while! We start by making it green. =)

        foreach (Polygon landPoly in landPolys)
        {
            landPoly.m_Color = colorGrass;
        }

        // The Extrude function will raise the land Polygons up out of the water.
        // It also generates a strip of new Polygons to connect the newly raised land
        // back down to the water level. We can color this vertical strip of land brown like dirt.

        sides = Extrude(landPolys, 0.05f);

        sides.ApplyColor(colorDirt);

        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        // Grab additional polygons to generate hills, but only from the set of polygons that are land.

        PolySet hillPolys = landPolys.RemoveEdges();

        sides = Inset(hillPolys, 0.03f);
        sides.ApplyColor(colorGrass);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Extrude(hillPolys, 0.05f);
        sides.ApplyColor(colorDirt);

        // Hills have dark ambient occlusion on the bottom, and light on top.
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        // Time to return to the oceans.

        sides = Extrude(oceanPolys, -0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        sides = Inset(oceanPolys, 0.02f);
        sides.ApplyColor(colorOcean);
        sides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        var deepOceanPolys = oceanPolys.RemoveEdges();

        sides = Extrude(deepOceanPolys, -0.05f);
        sides.ApplyColor(colorDeepOcean);

        deepOceanPolys.ApplyColor(colorDeepOcean);

        // Okay, we're done! Let's generate an actual game mesh for this planet.

        if (m_GroundMesh != null)
        {
            Destroy(m_GroundMesh);
        }

        m_GroundMesh = GenerateMesh("Ground Mesh", m_GroundMaterial);

        // Spawn in the trees.

        Mesh groundMesh = m_GroundMesh.GetComponent <MeshFilter>().mesh;
        Mesh oceanMesh  = m_OceanMesh.GetComponent <MeshFilter>().mesh;

        for (int i = 0; i < groundMesh.vertices.Length; ++i)
        {
            if (Random.value < m_TreeSpawnRate)
            {
                float randA = Random.value;
                float randB = Random.value;
                float randC = Random.value;

                Vector3 pointA = groundMesh.vertices[groundMesh.triangles[i + 0]];
                Vector3 pointB = groundMesh.vertices[groundMesh.triangles[i + 1]];
                Vector3 pointC = groundMesh.vertices[groundMesh.triangles[i + 2]];

                Vector3 randPoint = (randA * pointA + randB * pointB + randC * pointC) / (randA + randB + randC);

                GameObject tree = Instantiate(m_Tree, randPoint, Quaternion.FromToRotation(Vector3.up, randPoint.normalized));

                // Translate the tree so that it is not sticking into the ground.
                tree.transform.Translate(new Vector3(0, 0.2f, 0), Space.Self);

                if (oceanMesh.bounds.Intersects(tree.GetComponentInChildren <MeshFilter>().mesh.bounds))
                {
                    // Destroy(tree);
                }
            }
        }
    }
    public PlanetGenerator(GameObject _planet, Material m_GroundMaterial, Material m_OceanMaterial, bool withRocket)
    {
        planet = _planet;
        if (!withRocket)
        {
            colorGrass     = new Color32(99, 61, 72, 0);
            colorDirt      = new Color32(59, 30, 39, 0);
            colorOcean     = new Color32(26, 67, 92, 0);
            colorDeepOcean = new Color32(11, 34, 48, 0);
        }

        landPolys = new PolySet();
        m_Objects = new List <Polygon>();
        // Create an icosahedron, subdivide it three times so that we have plenty of polys
        // to work with.

        InitAsIcosohedron();
        Subdivide(3);

        // When we begin extruding polygons, we'll need each one to know who its immediate
        //neighbors are. Calculate that now.

        CalculateNeighbors();

        // By default, everything is colored blue. As we extrude land forms, we'll change their colors to match.
        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }

        // Now we build a set of Polygons that will become the land. We do this by generating
        // randomly sized spheres on the surface of the planet, and adding any Polygon that falls
        // inside that sphere.
        // Grab polygons that are inside random spheres. These will be the basis of our planet's continents.

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);

            Vector3 center = Random.onUnitSphere;
            if (i == 0)
            {
                center.Set(-1, 0, 0);
            }
            PolySet newLand = GetPolysInSphere(center, continentSize, m_Polygons);

            landPolys.UnionWith(newLand);
        }

        // While we're here, let's make a group of oceanPolys. It's pretty simple: Any Polygon that isn't in the landPolys set
        // must be in the oceanPolys set instead.

        var oceanPolys = new PolySet();

        surfacePolys = new List <Polygon>();

        foreach (Polygon poly in m_Polygons)
        {
            if (!landPolys.Contains(poly))
            {
                oceanPolys.Add(poly);
            }
            else
            {
                surfacePolys.Add(poly);
            }
        }

        // Let's create the ocean surface as a separate mesh.
        // First, let's make a copy of the oceanPolys so we can
        // still use them to also make the ocean floor later.

        // Back to land for a while! We start by making it green. =)

        foreach (Polygon landPoly in landPolys)
        {
            landPoly.m_Color = colorGrass;
        }

        // The Extrude function will raise the land Polygons up out of the water.
        // It also generates a strip of new Polygons to connect the newly raised land
        // back down to the water level. We can color this vertical strip of land brown like dirt.

        PolySet lowLandSides = Extrude(landPolys, 0.05f);

        lowLandSides.ApplyColor(colorDirt);
        lowLandSides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        // Grab additional polygons to generate hills, but only from the set of polygons that are land.

        PolySet hillPolys      = landPolys.RemoveEdges();
        PolySet insetLandPolys = Inset(hillPolys, 0.03f);

        insetLandPolys.ApplyColor(colorGrass);
        insetLandPolys.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        PolySet topLandSides = Extrude(hillPolys, 0.05f);

        topLandSides.ApplyColor(colorDirt);

        //Hills have dark ambient occlusion on the bottom, and light on top.
        topLandSides.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        landPolys.UnionWith(lowLandSides);
        landPolys.UnionWith(insetLandPolys);
        landPolys.UnionWith(topLandSides);

        // Time to return to the oceans.

        PolySet insetOceanPolys = Inset(oceanPolys, 0.05f);

        insetOceanPolys.ApplyColor(colorOcean);
        insetOceanPolys.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        PolySet highOceanSides = Extrude(oceanPolys, -0.02f);

        highOceanSides.ApplyColor(colorOcean);
        highOceanSides.ApplyAmbientOcclusionTerm(0.0f, 1.0f);

        PolySet insetOceanPolys2 = Inset(oceanPolys, 0.02f);

        insetOceanPolys2.ApplyColor(colorOcean);
        insetOceanPolys2.ApplyAmbientOcclusionTerm(1.0f, 0.0f);

        var deepOceanPolys = oceanPolys.RemoveEdges();

        PolySet lowOceanSides = Extrude(deepOceanPolys, -0.05f);

        lowOceanSides.ApplyColor(colorDeepOcean);

        deepOceanPolys.ApplyColor(colorDeepOcean);

        oceanPolys.UnionWith(insetOceanPolys);
        oceanPolys.UnionWith(highOceanSides);
        oceanPolys.UnionWith(insetOceanPolys2);
        oceanPolys.UnionWith(lowOceanSides);


        PolySet allPolys = new PolySet(oceanPolys);

        allPolys.UnionWith(landPolys);

        // Okay, we're done! Let's generate an actual game mesh for this planet.

        for (int i = 0; i < m_Vertices.Count; i++)
        {
            m_Vertices[i] *= 0.1f;
            m_Vertices[i] += planet.transform.position;
        }

        //GenerateMesh(planet, oceanPolys, "Ocean Mesh", m_OceanMaterial);
        GenerateMesh(planet, allPolys, "Ground Mesh", m_GroundMaterial);
    }
    public void GenerateMesh(GameObject planet, PolySet terrianPolys, string name, Material material)
    {
        GameObject meshObject = new GameObject(name);

        meshObject.transform.parent = planet.transform;

        MeshRenderer surfaceRenderer = meshObject.AddComponent <MeshRenderer>();

        surfaceRenderer.material = material;

        Mesh terrainMesh = new Mesh();

        int vertexCount = terrianPolys.Count * 3;

        int[] indices = new int[vertexCount];

        Vector3[] vertices = new Vector3[vertexCount];
        Vector3[] normals  = new Vector3[vertexCount];
        Color32[] colors   = new Color32[vertexCount];
        Vector2[] uvs      = new Vector2[vertexCount];

        List <Polygon> polyList = terrianPolys.ToList();

        for (int i = 0; i < polyList.Count; i++)
        {
            var poly = polyList[i];

            indices[i * 3 + 0] = i * 3 + 0;
            indices[i * 3 + 1] = i * 3 + 1;
            indices[i * 3 + 2] = i * 3 + 2;

            vertices[i * 3 + 0] = m_Vertices[poly.m_Vertices[0]];
            vertices[i * 3 + 1] = m_Vertices[poly.m_Vertices[1]];
            vertices[i * 3 + 2] = m_Vertices[poly.m_Vertices[2]];

            uvs[i * 3 + 0] = poly.m_UVs[0];
            uvs[i * 3 + 1] = poly.m_UVs[1];
            uvs[i * 3 + 2] = poly.m_UVs[2];

            colors[i * 3 + 0] = poly.m_Color;
            colors[i * 3 + 1] = poly.m_Color;
            colors[i * 3 + 2] = poly.m_Color;

            if (poly.m_SmoothNormals)
            {
                normals[i * 3 + 0] = m_Vertices[poly.m_Vertices[0]].normalized;
                normals[i * 3 + 1] = m_Vertices[poly.m_Vertices[1]].normalized;
                normals[i * 3 + 2] = m_Vertices[poly.m_Vertices[2]].normalized;
            }
            else
            {
                Vector3 ab = m_Vertices[poly.m_Vertices[1]] - m_Vertices[poly.m_Vertices[0]];
                Vector3 ac = m_Vertices[poly.m_Vertices[2]] - m_Vertices[poly.m_Vertices[0]];

                Vector3 normal = Vector3.Cross(ab, ac).normalized;

                normals[i * 3 + 0] = normal;
                normals[i * 3 + 1] = normal;
                normals[i * 3 + 2] = normal;
            }
        }

        terrainMesh.vertices = vertices;
        terrainMesh.normals  = normals;
        terrainMesh.colors32 = colors;
        terrainMesh.uv       = uvs;

        terrainMesh.SetTriangles(indices, 0);

        MeshFilter terrainFilter = meshObject.AddComponent <MeshFilter>();

        terrainFilter.mesh = terrainMesh;

        //string localPath = "Assets/" + "planet" + ".asset";

        // Make sure the file name is unique, in case an existing Prefab has the same name.
        //localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);

        //AssetDatabase.CreateAsset(terrainMesh, localPath);
        //AssetDatabase.SaveAssets();
    }
예제 #28
0
    public void GeneratePlanet()
    {
        // Create an icosahedron, subdivide it three times so that we have plenty of polys
        // to work with.

        InitAsIcosohedron();
        Subdivide(1);



        // When we begin extruding polygons, we'll need each one to know who its immediate
        //neighbors are. Calculate that now.

        CalculateNeighbors();

        // By default, everything is colored blue. As we extrude land forms, we'll change their colors to match.

        Color32 colorOcean = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 0);
        Color32 colorGrass = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 0);
        Color32 colorDirt  = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 0);

        foreach (Polygon p in m_Polygons)
        {
            p.m_Color = colorOcean;
        }

        // Now we build a set of Polygons that will become the land. We do this by generating
        // randomly sized spheres on the surface of the planet, and adding any Polygon that falls
        // inside that sphere.

        PolySet landPolys = new PolySet();

        for (int i = 0; i < m_NumberOfContinents; i++)
        {
            float continentSize = Random.Range(m_ContinentSizeMin, m_ContinentSizeMax);

            PolySet newLand = GetPolysInSphere(Random.onUnitSphere, continentSize, m_Polygons);

            landPolys.UnionWith(newLand);
        }

        // This is our land now, so color it green. =)

        foreach (Polygon landPoly in landPolys)
        {
            landPoly.m_Color = colorGrass;
        }

        // The Extrude function will raise the land Polygons up out of the water.
        // It also generates a strip of new Polygons to connect the newly raised land
        // back down to the water level. We can color this vertical strip of land brown like dirt.

        PolySet sides = Extrude(landPolys, 0.05f);

        foreach (Polygon side in sides)
        {
            side.m_Color = colorDirt;
        }

        // Grab additional polygons to generate hills, but only from the set of polygons that are land.

        PolySet hillPolys = new PolySet();

        for (int i = 0; i < m_NumberOfHills; i++)
        {
            float hillSize = Random.Range(m_HillSizeMin, m_HillSizeMax);

            PolySet newHill = GetPolysInSphere(Random.onUnitSphere, hillSize, landPolys);

            hillPolys.UnionWith(newHill);
        }

        sides = Extrude(hillPolys, 0.05f);

        foreach (Polygon side in sides)
        {
            side.m_Color = colorDirt;
        }

        // Okay, we're done! Let's generate an actual game mesh for this planet.

        GenerateMesh();
    }