private void AddObject(Face face, SgtTerrain.Ring ring, long x, long y) { if (Prefabs != null && Prefabs.Count > 0) { var index = Random.Range(0, Prefabs.Count); var prefab = Prefabs[index]; if (prefab != null) { var stepX = ring.ExtentsX / ring.Detail; var stepY = ring.ExtentsY / ring.Detail; var point = ring.Center + x * stepX + y * stepY; var height = terrain.GetLocalHeight(point); if (height >= HeightMin && height < HeightMax) { var clone = Spawn(prefab); clone.Prefab = prefab; clone.X = x; clone.Y = y; clone.Spawn(terrain, face.Level, point); if (face.Clones == null) { face.Clones = new List <SgtTerrainObject>(); } face.Clones.Add(clone); } } } }
private void CalculateLevel(SgtTerrainLevel level, SgtTerrain.Ring ring) { var face = GetFace(level); if (level.Index == Depth && ring != null) { if (face == null) { face = new Face(); face.Level = level; faces.Add(face); } face.Clear(ring); for (var y = ring.Outer.minY; y <= ring.Outer.maxY; y++) { for (var x = ring.Outer.minX; x <= ring.Outer.maxX; x++) { if (x >= face.Rect.minX && x < face.Rect.maxX && y >= face.Rect.minY && y < face.Rect.maxY) { continue; } if (Random.value < SpawnProbability) { AddObject(face, ring, x, y); } } } face.Rect = ring.Outer; } else { if (face != null) { face.Clear(); faces.Remove(face); } } }
public void Clear(SgtTerrain.Ring ring) { if (Clones != null) { for (var i = Clones.Count - 1; i >= 0; i--) { var clone = Clones[i]; if (clone != null) { if (ring.Outer.Contains(clone.X, clone.Y) == false) { Despawn(clone); Clones.RemoveAt(i); } } else { Clones.RemoveAt(i); } } } }
public void Write(SgtTerrain.Ring ring) { if (ring.Outer == outerRegion && ring.Inner == innerRegion) { return; } size = ring.Limit + 3; var terrain = Face.Terrain; var total = size * size; var newBasicRegion = ring.Outer.GetExpanded(1); if (positions == null || positions.Length != total) { basicRegion.Clear(); outerRegion.Clear(); positions = new Vector3[total]; normals = new Vector3[total]; coords1 = new Vector2[total]; coords2 = new Vector2[total]; } // Write position & uv data var stepX = ring.ExtentsX / ring.Detail; var stepY = ring.ExtentsY / ring.Detail; for (var y = newBasicRegion.minY; y <= newBasicRegion.maxY; y++) { for (var x = newBasicRegion.minX; x <= newBasicRegion.maxX; x++) { if (basicRegion.Contains(x, y) == false) { var index = Wrap(x, y, size); var point = ring.Center + x * stepX + y * stepY; var coord1U = (x / (double)ring.Detail + 1.0) / 2.0; // 0 .. 1 var coord1V = (y / (double)ring.Detail + 1.0) / 2.0; // 0 .. 1 var coord2U = x / (double)ring.Limit; // -u .. u var coord2V = y / (double)ring.Limit; // -v .. v var height = terrain.GetLocalHeight(point); var direction = point.normalized; var position = direction * height; positions[index] = (Vector3)position; coords1[index] = new Vector2((float)coord1U, (float)coord1V); coords2[index] = new Vector2((float)coord2U, (float)coord2V); } } } var parent = Face.LastLevel; WriteNormals(ring.Outer, outerRegion); if (parent != null) { // Write edges from parent to avoid normal seams from resolution shift if (ring.Outer.minX > -ring.Detail) { WriteParentNormals(parent, ring.Outer.minX, ring.Outer.minY, ring.Outer.minX, ring.Outer.maxY); // Left } if (ring.Outer.maxX < ring.Detail) { WriteParentNormals(parent, ring.Outer.maxX, ring.Outer.minY, ring.Outer.maxX, ring.Outer.maxY); // Right } if (ring.Outer.minY > -ring.Detail) { WriteParentNormals(parent, ring.Outer.minX, ring.Outer.minY, ring.Outer.maxX, ring.Outer.minY); // Bottom } if (ring.Outer.maxY < ring.Detail) { WriteParentNormals(parent, ring.Outer.minX, ring.Outer.maxY, ring.Outer.maxX, ring.Outer.maxY); // Top } } // Write indices WriteIndices(ring.Outer, ring.Inner, ring.Detail, size); var mesh = GetMesh(); mesh.Clear(); mesh.vertices = positions; mesh.normals = normals; mesh.uv = coords1; mesh.uv2 = coords2; mesh.SetTriangles(indices, 0); mesh.bounds = terrain.GetBounds(); if (terrain.MaxColliderDepth > Index) { if (meshCollider == null) { meshCollider = GetComponent <MeshCollider>(); } if (meshCollider == null) { meshCollider = gameObject.AddComponent <MeshCollider>(); } // Is this the last collider, but not the last LOD level? if (terrain.MaxColliderDepth == Index + 1 && ring.Inner.SizeX > 0 && ring.Inner.SizeY > 0) { var colliderMesh = GetColliderMesh(); WriteIndices(ring.Outer, default(SgtRectL), ring.Detail, size); colliderMesh.Clear(); colliderMesh.vertices = positions; colliderMesh.SetTriangles(indices, 0); meshCollider.sharedMesh = colliderMesh; } // If not, use the visual mesh else { PoolColliderMeshNow(false); meshCollider.sharedMesh = mesh; } } else { PoolColliderMeshNow(); } basicRegion = newBasicRegion; outerRegion = ring.Outer; innerRegion = ring.Inner; Face.LastLevel = this; if (terrain.OnCalculateLevel != null) { terrain.OnCalculateLevel(this, ring); } }