/// <summary> /// Event raised by Surface when its being destroyed /// </summary> public void SurfaceDestroyed(Surface surface) { for (int f = 0; f < foliageTypes.Length; f++) { MeshInstanceList toBeRemoved = null; for (int i = 0; i < foliageTypes[f].meshLists.Count; i++) { if (foliageTypes[f].meshLists[i].surface == surface) { toBeRemoved = foliageTypes[f].meshLists[i]; break; } } if (toBeRemoved != null) { foliageTypes[f].meshLists.Remove(toBeRemoved); } } }
/// <summary> /// Event raised by the planet when a new surface is generated. /// If enabled, adds SurfaceObjects component to the Surface and populates it with objects /// </summary> public void OnSurfaceGenerated(Surface surface) { for(int f = 0; f < foliageTypes.Length; f++) { if(surface.lodLevel == foliageTypes[f].lodLevel) { // create new list MeshInstanceList mil = new MeshInstanceList(); mil.meshInstances = new List<MeshInstance>(); // save surface reference and listen for its destruction mil.surface = surface; surface.SurfaceDestroyed += SurfaceDestroyed; // get mesh Vector3[] vertices = surface.mesh.vertices; Vector3[] normals = surface.mesh.normals; Color[] colors = surface.mesh.colors; Vector3 right = Vector3.zero; //, perpendicular = Vector3.one, normalized = Vector3.zero; //float vertexDistance = 0f; for(int i = 0; i < vertices.Length; i++) { if(i + 1 < vertices.Length) { right = vertices[i] - vertices[i+1]; //vertexDistance = right.magnitude; right.Normalize(); } if(colors[i].r >= foliageTypes[f].minHeight && colors[i].r <= foliageTypes[f].maxHeight && colors[i].g >= foliageTypes[f].minPolarity && colors[i].g <= foliageTypes[f].maxPolarity && colors[i].b >= foliageTypes[f].minSlope && colors[i].b <= foliageTypes[f].maxSlope ) { float terrainValue = terrainModule.module.GetValue(vertices[i].normalized); if(terrainValue >= foliageTypes[f].minNoiseValue && terrainValue <= foliageTypes[f].maxNoiseValue) { MeshInstance newInstance = new MeshInstance(); Vector3 vertex = planet.transform.TransformPoint(vertices[i]); Vector3 normal = planet.transform.TransformDirection(normals[i]); /*if(foliageTypes[f].positionVariation != Vector3.zero) { normalized = vertices[i].normalized; perpendicular = Vector3.Cross(right, normalized); newInstance.position += right * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.x, foliageTypes[f].positionVariation.x); newInstance.position += normalized * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.y, foliageTypes[f].positionVariation.y); newInstance.position += perpendicular * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.z, foliageTypes[f].positionVariation.z); }*/ Quaternion adjustedRotation; if(foliageTypes[f].useGroundNormalAsUp) adjustedRotation = Quaternion.LookRotation(normal); else adjustedRotation = Quaternion.LookRotation(vertex.normalized); adjustedRotation *= Quaternion.Euler(foliageTypes[f].rotation); adjustedRotation *= Quaternion.Euler(new Vector3(Random.Range(-foliageTypes[f].rotationVariation.x, foliageTypes[f].rotationVariation.x), Random.Range(-foliageTypes[f].rotationVariation.y, foliageTypes[f].rotationVariation.y), Random.Range(-foliageTypes[f].rotationVariation.z, foliageTypes[f].rotationVariation.z))); Vector3 adjustedScale = foliageTypes[f].scale * (1f + foliageTypes[f].scaleVariation * Random.Range(0f, 1f)); newInstance.position = vertex; newInstance.scale = adjustedScale; newInstance.matrix = new Matrix4x4(); newInstance.matrix.SetTRS(newInstance.position, adjustedRotation, adjustedScale); newInstance.mesh = foliageTypes[f].mesh; newInstance.materials = foliageTypes[f].materials; newInstance.layer = foliageTypes[f].meshLayer; newInstance.castShadows = foliageTypes[f].castShadows; newInstance.receiveShadows = foliageTypes[f].receiveShadows; mil.meshInstances.Add(newInstance); } } } // add list to other lists foliageTypes[f].meshLists.Add(mil); } } }
/// <summary> /// Event raised by the planet when a new surface is generated. /// If enabled, adds SurfaceObjects component to the Surface and populates it with objects /// </summary> public void OnSurfaceGenerated(Surface surface) { for (int f = 0; f < foliageTypes.Length; f++) { if (surface.lodLevel == foliageTypes[f].lodLevel) { // create new list MeshInstanceList mil = new MeshInstanceList(); mil.meshInstances = new List <MeshInstance>(); // save surface reference and listen for its destruction mil.surface = surface; surface.SurfaceDestroyed += SurfaceDestroyed; // get mesh Vector3[] vertices = surface.mesh.vertices; Vector3[] normals = surface.mesh.normals; Color[] colors = surface.mesh.colors; Vector3 right = Vector3.zero, perpendicular = Vector3.one, normalized = Vector3.zero; float vertexDistance = 0f; for (int i = 0; i < vertices.Length; i++) { if (i + 1 < vertices.Length) { right = vertices[i] - vertices[i + 1]; vertexDistance = right.magnitude; right.Normalize(); } if (colors[i].r >= foliageTypes[f].minHeight && colors[i].r <= foliageTypes[f].maxHeight && colors[i].g >= foliageTypes[f].minPolarity && colors[i].g <= foliageTypes[f].maxPolarity && colors[i].b >= foliageTypes[f].minSlope && colors[i].b <= foliageTypes[f].maxSlope) { float terrainValue = terrainModule.module.GetValue(vertices[i].normalized); if (terrainValue >= foliageTypes[f].minNoiseValue && terrainValue <= foliageTypes[f].maxNoiseValue) { MeshInstance newInstance = new MeshInstance(); Vector3 vertex = planet.transform.TransformPoint(vertices[i]); Vector3 normal = planet.transform.TransformDirection(normals[i]); /*if(foliageTypes[f].positionVariation != Vector3.zero) { * normalized = vertices[i].normalized; * perpendicular = Vector3.Cross(right, normalized); * newInstance.position += right * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.x, foliageTypes[f].positionVariation.x); * newInstance.position += normalized * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.y, foliageTypes[f].positionVariation.y); * newInstance.position += perpendicular * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.z, foliageTypes[f].positionVariation.z); * }*/ Quaternion adjustedRotation; if (foliageTypes[f].useGroundNormalAsUp) { adjustedRotation = Quaternion.LookRotation(normal); } else { adjustedRotation = Quaternion.LookRotation(vertex.normalized); } adjustedRotation *= Quaternion.Euler(foliageTypes[f].rotation); adjustedRotation *= Quaternion.Euler(new Vector3(Random.Range(-foliageTypes[f].rotationVariation.x, foliageTypes[f].rotationVariation.x), Random.Range(-foliageTypes[f].rotationVariation.y, foliageTypes[f].rotationVariation.y), Random.Range(-foliageTypes[f].rotationVariation.z, foliageTypes[f].rotationVariation.z))); Vector3 adjustedScale = foliageTypes[f].scale * (1f + foliageTypes[f].scaleVariation * Random.Range(0f, 1f)); newInstance.position = vertex; newInstance.scale = adjustedScale; newInstance.matrix = new Matrix4x4(); newInstance.matrix.SetTRS(newInstance.position, adjustedRotation, adjustedScale); newInstance.mesh = foliageTypes[f].mesh; newInstance.materials = foliageTypes[f].materials; newInstance.layer = foliageTypes[f].meshLayer; newInstance.castShadows = foliageTypes[f].castShadows; newInstance.receiveShadows = foliageTypes[f].receiveShadows; mil.meshInstances.Add(newInstance); } } } // add list to other lists foliageTypes[f].meshLists.Add(mil); } } }