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); }
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 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); }
// 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); }
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)); }
public void GetWaterPolygons() { foreach (Polygon poly in m_Polygons) { if (!hillPolys.Contains(poly) && !landPolys.Contains(poly)) { water.Add(poly); } } }
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); }
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); }
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 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); }
// 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 void CreatePlanet() { // Create an icosahedron, subdivide it three times so that we have plenty of polys to work with. m_NumberOfContinents = minNumContinents; System.Random rnd = new System.Random(); //planetSize = rnd.Next(1, 11); planetSize = 10; InitAsIcosohedron(planetSize); 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. // Picks a random planet type initially planetType = (PlanetType)rnd.Next(5); //planetType = PlanetType.Volcanic; // = new Color32(255, 0, 255, 255); hot pink switch (planetType) { case PlanetType.Earthlike: colorOcean = new Color32(0, 80, 220, 0); colorGrass = new Color32(0, 220, 0, 0); colorDirt = new Color32(180, 140, 20, 0); colorDeepOcean = new Color32(0, 40, 110, 0); break; case PlanetType.Volcanic: //colorOcean = new Color32(0, 80, 220, 0); colorOcean = HueColour.HueColourValue(HueColour.HueColorNames.Red); colorGrass = HueColour.HueColourValue(HueColour.HueColorNames.GrayDark); colorDirt = HueColour.HueColourValue(HueColour.HueColorNames.RedDeep); colorDeepOcean = HueColour.HueColourValue(HueColour.HueColorNames.RedDeep); break; default: colorOcean = new Color32(0, 80, 220, 0); colorGrass = new Color32(0, 220, 0, 0); colorDirt = new Color32(180, 140, 20, 0); colorDeepOcean = new Color32(0, 40, 110, 0); break; } //pick the planet size attributes m_NumberOfContinents = rnd.Next(1, 10); m_NumberOfHills = rnd.Next(0, 10); 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); }
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 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() { 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); }
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); } } } }