public IEnumerable <Rect> SweepDirtyRect(GStylizedTerrain terrain) { if (terrain.TerrainData == null) { return(new List <Rect>()); } int gridSize = terrain.TerrainData.Geometry.ChunkGridSize; List <Rect> uvRects = new List <Rect>(); for (int x = 0; x < gridSize; ++x) { for (int z = 0; z < gridSize; ++z) { uvRects.Add(GCommon.GetUvRange(gridSize, x, z)); } } HashSet <Rect> dirtyRects = new HashSet <Rect>(); Vector3 terrainSize = new Vector3( terrain.TerrainData.Geometry.Width, terrain.TerrainData.Geometry.Height, terrain.TerrainData.Geometry.Length); float splineSize = Mathf.Max(1, Width + FalloffWidth * 2); Vector2 sweepRectSize = new Vector2( Mathf.InverseLerp(0, terrainSize.x, splineSize), Mathf.InverseLerp(0, terrainSize.z, splineSize)); Rect sweepRect = new Rect(); sweepRect.size = sweepRectSize; int segmentCount = Spline.Segments.Count; for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { float tStep = 1f / (Smoothness - 1); for (int tIndex = 0; tIndex < Smoothness - 1; ++tIndex) { float t = tIndex * tStep; Vector3 worldPos = transform.TransformPoint(Spline.EvaluatePosition(sIndex, t)); Vector3 scale = transform.TransformVector(Spline.EvaluateScale(sIndex, t)); float maxScaleComponent = Mathf.Max(Mathf.Abs(scale.x), Mathf.Abs(scale.y), Mathf.Abs(scale.z)); Vector3 normalizedPos = terrain.WorldPointToNormalized(worldPos); sweepRect.center = new Vector2(normalizedPos.x, normalizedPos.z); sweepRect.size = sweepRectSize * maxScaleComponent; for (int rIndex = 0; rIndex < uvRects.Count; ++rIndex) { if (uvRects[rIndex].Overlaps(sweepRect)) { dirtyRects.Add(uvRects[rIndex]); } } } } return(dirtyRects); }