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) { 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)); }