void CalculateBlend2() { float max = 0f; VertexMap map = DynamicTerrain.Instance.VertexMap; Vertex l = map.VertexAt(_x - 1, _y); if (l != null && l._loaded) { float diff = Mathf.Abs(l._height - _height); if (diff > max) { max = diff; } } Vertex r = map.VertexAt(_x + 1, _y); if (r != null && r._loaded) { float diff = Mathf.Abs(r._height - _height); if (diff > max) { max = diff; } } Vertex u = map.VertexAt(_x, _y + 1); if (u != null && u._loaded) { float diff = Mathf.Abs(u._height - _height); if (diff > max) { max = diff; } } Vertex d = map.VertexAt(_x, _y - 1); if (d != null && d._loaded) { float diff = Mathf.Abs(d._height - _height); if (diff > max) { max = diff; } } _color.a = Mathf.Clamp01(max / 50f); }
/// <summary> /// Resets necessary variables after de-pooling a chunk. /// </summary> public void Reuse(int x, int y) { DynamicTerrain terrain = DynamicTerrain.Instance; VertexMap vmap = terrain.VertexMap; float chunkSize = WorldManager.Instance.ChunkSize; // Update vars _x = x; _y = y; // Move chunk to appropriate position transform.position = new Vector3(x * chunkSize - chunkSize / 2f, 0f, y * chunkSize - chunkSize / 2f); // Update chunk name gameObject.name = "Chunk (" + x + "," + y + ") Position:" + transform.position.ToString(); _priority = 0f; // Clear decoration list _decorations.Clear(); // Register all vertices with vertex map // Move vertices, generate normals/colors for (int i = 0; i < _numVerts; i++) { // Get VMap coords IntVector2 coord = IntToV2(i); _coords[i] = coord; // Get corresponding vertex _mapVerts[i] = vmap.VertexAt(coord, true); // Get height from vertex UpdateVertex(i, _mapVerts[i].Height); } _hasCheckedForRoad = false; UpdateCollider(); }
public void SmoothHeight(float h, float factor, float range) { SetHeight(h); Vector2 v = new Vector2((float)_x, (float)_y); VertexMap map = DynamicTerrain.Instance.VertexMap; for (int ix = map.XMin; ix <= map.XMax; ix++) { if ((float)Mathf.Abs(ix - _x) > range) { continue; } for (int iy = map.YMin; iy <= map.YMax; iy++) { if ((float)Mathf.Abs(iy - _y) > range) { continue; } Vector2 n = new Vector2((float)ix, (float)iy); float dist = Vector2.Distance(n, v); if (dist > range) { continue; } if (ix == _x && iy == _y) { continue; } Vertex vert = map.VertexAt(ix, iy); if (vert != null && !vert._locked) { vert.Smooth(h, factor * (range - dist) / range); } } } }
void CalculateBlend() { bool debug = (UnityEngine.Random.Range(0, 10000) == 1); if (debug) { Debug.Log(ToString()); } int numNeighbors = 0; float delta = 0f; VertexMap map = DynamicTerrain.Instance.VertexMap; Vertex l = map.VertexAt(_x - 1, _y); if (l != null && l._loaded) { numNeighbors++; float diff = Mathf.Abs(_height - l._height); if (debug) { Debug.Log("Left: " + l.ToString() + " " + diff); } delta += diff; } Vertex r = map.VertexAt(_x + 1, _y); if (r != null && r._loaded) { numNeighbors++; float diff = Mathf.Abs(_height - r._height); if (debug) { Debug.Log("Right: " + r.ToString() + " " + diff); } delta += diff; } Vertex u = map.VertexAt(_x, _y + 1); if (u != null && u._loaded) { numNeighbors++; float diff = Mathf.Abs(_height - u._height); if (debug) { Debug.Log("Up: " + u.ToString() + " " + diff); } delta += diff; } Vertex d = map.VertexAt(_x, _y - 1); if (d != null && d._loaded) { numNeighbors++; float diff = Mathf.Abs(_height - d._height); if (debug) { Debug.Log("Down: " + d.ToString() + " " + diff); } delta += diff; } _color.a = delta / (float)numNeighbors / 100f; if (debug) { Debug.Log("final blend: " + _color.a); } }
/// <summary> /// Initializes a brand new chunk at x and y. /// </summary> public void Initialize(int x, int y) { DynamicTerrain terrain = DynamicTerrain.Instance; // Init vars _x = x; _y = y; VertexMap vmap = terrain.VertexMap; int chunkRes = WorldManager.Instance.ChunkResolution; float chunkSize = WorldManager.Instance.ChunkSize; // Generate vertices _verts = CreateUniformVertexArray(chunkRes); _numVerts = _verts.Length; // Generate triangles _triangles = CreateSquareArrayTriangles(chunkRes); // Init normals _normals = new Vector3[_numVerts]; // Generate UVs _uvs = CreateUniformUVArray(chunkRes); // Init colors _colors = new Color[_numVerts]; // Init coords and mapVerts _coords = new IntVector2[_numVerts]; _mapVerts = new Vertex[_numVerts]; // Build initial chunk mesh _mesh = CreateChunkMesh(); // Assign mesh GetComponent <MeshFilter>().mesh = _mesh; // Move GameObject to appropriate position transform.position = new Vector3(x * chunkSize - chunkSize / 2f, 0f, y * chunkSize - chunkSize / 2f); // Initialize name gameObject.name = "Chunk (" + x + "," + y + ") Position:" + transform.position.ToString(); // Init decorations list _decorations = new List <GameObject>(); // Register all vertices with vertex map // Move vertices, generate normals/colors for (int i = 0; i < _numVerts; i++) { // Init normal/color _normals[i] = Vector3.up; _colors[i] = Color.white; // Get VMap coords IntVector2 coord = IntToV2(i); _coords[i] = coord; // Get corresponding vertex _mapVerts[i] = vmap.VertexAt(coord, true); // If vertex exists, get height UpdateVertex(i, _mapVerts[i].Height); UpdateColor(i, _mapVerts[i].Color); } // Assign material MeshRenderer renderer = GetComponent <MeshRenderer>(); renderer.sharedMaterial = WorldManager.Instance.TerrainMaterial; renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; // Assign collision mesh MeshCollider collider = GetComponent <MeshCollider>(); collider.sharedMesh = _mesh; collider.convex = false; // Init rigidbody Rigidbody rigidbody = GetComponent <Rigidbody>(); rigidbody.freezeRotation = true; rigidbody.isKinematic = true; rigidbody.useGravity = false; rigidbody.constraints = RigidbodyConstraints.FreezeAll; // Add grass system _grassEmitter = GameObject.Instantiate(WorldManager.Instance.GrassEmitterPrefab); _grassEmitter.transform.parent = transform; _grassEmitter.transform.localPosition = Vector3.zero; // Randomize grass density ParticleSystem sys = _grassEmitter.GetComponent <ParticleSystem>(); sys.maxParticles = UnityEngine.Random.Range(0, WorldManager.Instance.GrassPerChunk); sys.playOnAwake = true; // Assign particle system emission shape ParticleSystem.ShapeModule shape = sys.shape; shape.mesh = _mesh; // Assign particle system emission rate ParticleSystem.EmissionModule emit = sys.emission; emit.rate = new ParticleSystem.MinMaxCurve(WorldManager.Instance.DecorationsPerStep); UpdateCollider(); }