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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
// 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); }
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); }
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(); }
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); }
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) { }
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>(); }
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(); }
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(); }