public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { var obj = wrapper.ObjectContainer; if (!obj) { return; } wrapper.GetComponent <TerrainCollider>().enabled = false; wrapper.GetComponent <TerrainCollider>().enabled = true; var children = obj.GetComponentsInChildren <TerrainSurfaceObject>(); for (int i = 0; i < children.Length; i++) { var terrainSurfaceObject = children[i]; if (!terrainSurfaceObject) { continue; } if (terrainSurfaceObject.transform.up.y < RequiredY) { continue; } terrainSurfaceObject.Recalculate(); } Debug.Log(string.Format("Recalculated {0} TerrainSurfaceObjects", children.Length)); }
public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { var trees = wrapper.CompoundTerrainData.Trees; var tSize = wrapper.Terrain.terrainData.size; var terrainY = wrapper.transform.position.y; HashSet <string> removed = new HashSet <string>(); foreach (var treePair in trees) { var wPos = wrapper.Terrain.TreeToWorldPos(treePair.Value.Position); var height = wrapper.GetCompoundHeight(null, wPos) * tSize.y; wPos.y = terrainY + treePair.Value.Position.y + height; RaycastHit hit; if (Physics.Raycast(wPos + Vector3.up * 500, Vector3.down, out hit, 500, Mask) && ((hit.point - wPos).magnitude > Distance)) { removed.Add(treePair.Key); } } layer.TreeRemovals = removed.ToList(); foreach (var treeRemoval in layer.TreeRemovals) { trees.Remove(treeRemoval); } Debug.Log(string.Format("TreeRaycast deleted {0} trees", layer.TreeRemovals.Count)); wrapper.FinaliseTrees(); MiscUtilities.ClearProgressBar(); }
public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { var objects = wrapper.CompoundTerrainData.Objects; var tSize = wrapper.Terrain.terrainData.size; List <string> toRemove = new List <string>(); foreach (var tree in objects) { if (!InvertPrefabMask && Prefabs.Count > 0 && !Prefabs.Contains(tree.Value.Data.Prefab)) { continue; } if (InvertPrefabMask && Prefabs.Count > 0 && Prefabs.Contains(tree.Value.Data.Prefab)) { continue; } var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Data.Position); wPos.y = wrapper.GetCompoundHeight(layer, wPos, true) * tSize.y; var gradient = wrapper.GetNormalFromHeightmap(tree.Value.Data.Position.xz()); if (gradient.y < MinY) { toRemove.Add(tree.Key); continue; } } foreach (var guid in toRemove) { objects.Remove(guid); } Debug.LogFormat("TreeGradientFilter removed {0} trees", toRemove.Count); }
public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { if (layer == null) { Debug.LogError("Layer was null!"); return; } var trees = wrapper.CompoundTerrainData.Trees; HashSet <string> removed = new HashSet <string>(); List <string> neighbours = new List <string>(); foreach (var tree in trees) { if (removed.Contains(tree.Key)) { continue; } if (!Filter.IsNullOrEmpty() && !Filter.Contains(tree.Value.Prototype)) { continue; } var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Position); neighbours.Clear(); var coord = trees.PositionToCoord(tree.Value.Position); trees.AppendPartitionList(coord, neighbours); for (int i = 0; i < neighbours.Count; i++) { var neighbour = trees[neighbours[i]]; if (neighbour.Guid == tree.Value.Guid || removed.Contains(neighbour.Guid)) { continue; } var neighbourPos = wrapper.Terrain.TreeToWorldPos(trees[neighbours[i]].Position); var distSqr = (wPos.xz() - neighbourPos.xz()).sqrMagnitude; if (distSqr < Distance * Distance) { removed.Add(neighbour.Guid); } } } foreach (var guid in removed) { if (!layer.TreeRemovals.Contains(guid)) { layer.TreeRemovals.Add(guid); } trees.Remove(guid); } Debug.Log(string.Format("TreeProximity deleted {0} trees", removed.Count)); }
public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { var trees = wrapper.CompoundTerrainData.Trees; var tSize = wrapper.Terrain.terrainData.size; List <string> toRemove = new List <string>(); foreach (var tree in trees) { if (!InvertPrefabMask && Prefabs.Count > 0 && !Prefabs.Contains(tree.Value.Prototype)) { continue; } if (InvertPrefabMask && Prefabs.Count > 0 && Prefabs.Contains(tree.Value.Prototype)) { continue; } var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Position); wPos.y = wrapper.GetCompoundHeight(layer, wPos, true) * tSize.y; var gradient = wrapper.GetNormalFromHeightmap(tree.Value.Position.xz()); if (gradient.y < MinY) { //Debug.DrawLine(wPos, wPos + gradient, Color.red, 10); toRemove.Add(tree.Key); continue; } //Debug.DrawLine(wPos, wPos + gradient, Color.green, 10); var yPos = Offset.Evaluate(gradient.y); tree.Value.Position.y = Mathf.Min(yPos, tree.Value.Position.y); /*Debug.DrawLine(wPos, wPos + Vector3.up * yPos, Color.yellow, 10); * DebugHelper.DrawPoint(wPos, 0.1f, Color.yellow, 10); * DebugHelper.DrawPoint(wPos + Vector3.up * yPos, 0.1f, Color.blue, 10);*/ } foreach (var guid in toRemove) { trees.Remove(guid); } Debug.LogFormat("TreeGradientFilter removed {0} trees", toRemove.Count); }
public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper) { const float margin = 0.01f; var seed = layer.Seed; var rand = new Random(seed); var tBounds = wrapper.Terrain.GetBounds(); var step = StepDistance / tBounds.size.x; var cellCount = Mathf.CeilToInt(tBounds.size.x / MinDistance); bool[,] proximityCheck = new bool[cellCount, cellCount]; int counter = 0; for (var u = margin; u < 1 - margin; u += step) { if (counter > MaxCount) { break; } for (var v = margin; v < 1 - margin; v += step) { if (counter > MaxCount) { break; } var cellX = Mathf.FloorToInt(u * cellCount); var cellY = Mathf.FloorToInt(v * cellCount); if (proximityCheck[cellX, cellY]) { continue; } var normalizedPos = new Vector2(u, v); var normal = wrapper.GetNormalFromHeightmap(normalizedPos); if (normal.y > RequiredY) { continue; } var prefab = Prefabs.Random(); var prefabEntry = new PrefabObjectData() { Guid = Guid.NewGuid().ToString(), Prefab = prefab, Position = normalizedPos.x0z() + Offset.GetRand(rand), Rotation = Rotation.GetRand(rand), Scale = Scale.GetRand(rand), }; layer.Objects.Add(prefabEntry); counter++; proximityCheck[cellX, cellY] = true; } } Debug.Log(string.Format("GradientObjectPlacer placed {0} objects.", counter)); }
public abstract void Apply(ProceduralLayer layer, TerrainWrapper wrapper);