public void Swap() { if (PendingMeshes.Count > 0) { foreach (var mesh in CurrentMeshes) { Object.DestroyImmediate(mesh); } CurrentMeshes.Clear(); foreach (var mesh in PendingMeshes) { CurrentMeshes.Add(mesh); } PendingMeshes.Clear(); } if (PendingSplat != null) { if (CurrentSplat != null) { Object.DestroyImmediate(CurrentSplat); } CurrentSplat = PendingSplat; PendingSplat = null; } CurrentOuter = PendingOuter; CurrentInner = PendingInner; }
private void UpdateColliders(int face, SgtLongBounds rect, long middle) { var cubeC = SgtTerrainTopology.CubeC[face]; var cubeH = SgtTerrainTopology.CubeH[face]; var cubeV = SgtTerrainTopology.CubeV[face]; var step = 1.0 / resolution; var stepX = cubeH * step; var stepY = cubeV * step; var corner = cubeC + stepX * middle + stepY * middle; var centerX = (rect.minX + rect.maxX) / 2; var centerY = (rect.minY + rect.maxY) / 2; if (rect.SizeZ > 0) { for (var y = rect.minY; y < rect.maxY; y++) { for (var x = rect.minX; x < rect.maxX; x++) { var chunk = default(Chunk); var coord = new Coord() { Face = face, X = x, Y = y }; if (chunks.TryGetValue(coord, out chunk) == true) { chunk.Marked = false; } else { chunk = new Chunk() { Face = face, Coord = coord }; var root = new GameObject("Collider"); root.transform.SetParent(transform, false); root.transform.localPosition = Vector3.zero; root.transform.localRotation = Quaternion.identity; root.transform.localScale = Vector3.one; chunk.PointC = corner + x * stepX + y * stepY; chunk.PointH = stepX; chunk.PointV = stepY; chunks.Add(coord, chunk); } var distX = math.abs(centerX - x); var distY = math.abs(centerY - y); chunk.Distance = distX * distX + distY * distY; } } } }
public static SgtLongBounds GetQuadBounds(int index, SgtLongBounds bounds) { switch (index) { case 0: return(new SgtLongBounds(bounds.minZ, bounds.minY, bounds.minX, bounds.maxZ, bounds.maxY, bounds.maxX)); case 1: return(new SgtLongBounds(bounds.minZ, -bounds.maxX, bounds.minY, bounds.maxZ, -bounds.minX, bounds.maxY)); case 2: return(new SgtLongBounds(-bounds.maxX, bounds.minY, bounds.minZ, -bounds.minX, bounds.maxY, bounds.maxZ)); case 3: return(new SgtLongBounds(-bounds.maxZ, bounds.minY, -bounds.maxX, -bounds.minZ, bounds.maxY, -bounds.minX)); case 4: return(new SgtLongBounds(bounds.minZ, bounds.minX, -bounds.maxY, bounds.maxZ, bounds.maxX, -bounds.minY)); case 5: return(new SgtLongBounds(bounds.minX, bounds.minY, -bounds.maxZ, bounds.maxX, bounds.maxY, -bounds.minZ)); } return(bounds); }
private void UpdateRoot() { var point = cachedTerrain.GetAboveGroundObserverCubePoint(); var middle = resolution / 2; var center = middle * point; var bounds = new SgtLongBounds((long)center.x, (long)center.y, (long)center.z, radius); var outer = new SgtLongBounds(-middle, -middle, middle - 1, middle, middle, middle); Mark(); for (var i = 0; i < 6; i++) { var quadBounds = SgtTerrainTopology.GetQuadBounds(i, bounds); quadBounds.ClampTo(outer); UpdateColliders(i, quadBounds, middle); } Sweep(); }
public void UpdateDebris() { if (target != null && cellCount > 0.0f && prefabs != null && debrisCountTarget > 0) { var cellSize = (long)System.Math.Ceiling(hideDistance / cellCount); var worldPoint = target.position - transform.position; var centerX = (long)System.Math.Round(worldPoint.x / cellSize); var centerY = (long)System.Math.Round(worldPoint.y / cellSize); var centerZ = (long)System.Math.Round(worldPoint.z / cellSize); var newBounds = new SgtLongBounds(centerX, centerY, centerZ, cellCount); if (newBounds != bounds) { var probability = debrisCountTarget / (cellSize * cellSize * cellSize); var cellMin = cellSize * (0.5f - cellNoise); var cellMax = cellSize * (0.5f + cellNoise); for (var z = newBounds.minZ; z <= newBounds.maxZ; z++) { for (var y = newBounds.minY; y <= newBounds.maxY; y++) { for (var x = newBounds.minX; x <= newBounds.maxX; x++) { if (bounds.Contains(x, y, z) == false) { SgtHelper.BeginRandomSeed(seed, x, y, z); { // Can debris potentially spawn in this cell? if (Random.value < probability) { var debrisPoint = default(Vector3); debrisPoint.x = x * cellSize + Random.Range(cellMin, cellMax); debrisPoint.y = y * cellSize + Random.Range(cellMin, cellMax); debrisPoint.z = z * cellSize + Random.Range(cellMin, cellMax); // Spawn everywhere, or only inside specified shapes? if (spawnInside == null || Random.value < spawnInside.GetDensity(debrisPoint)) { Spawn(x, y, z, debrisPoint); } } } SgtHelper.EndRandomSeed(); } } } } bounds = newBounds; if (spawnedDebris != null) { for (var i = spawnedDebris.Count - 1; i >= 0; i--) { var debris = spawnedDebris[i]; if (debris == null) { spawnedDebris.RemoveAt(i); } else if (bounds.Contains(debris.Cell) == false) { Despawn(debris, i); } } } } UpdateDebrisScale(target.position); } else { ClearDebris(); } }
private void UpdateLod() { var spherePoint = GetSpherePoint(); for (var i = 0; i < cubes.Count; i++) { var cube = cubes[i]; var cubeBounds = GetCubeBound(i, spherePoint, cube.Middle); var cubeLimits = new SgtLongBounds(0, 0, 0, cube.Middle); for (var j = 0; j < 6; j++) { var quad = cube.Quads[j]; var quadBounds = SgtTerrainTopology.GetQuadBounds(j, cubeBounds); if (i == 0) { quad.PendingOuter = new SgtLongBounds(0, 0, 0, cube.Middle); quad.VirtualOuter = new SgtLongBounds(0, 0, 0, cube.Middle * 2); } else { var prevCube = cubes[i - 1]; var prevQuad = prevCube.Quads[j]; var prevResolution = prevCube.Resolution; quad.PendingOuter = prevQuad.PendingInner * 2; quad.VirtualOuter = prevQuad.VirtualInner * 2; } if (quadBounds.minZ <= cube.Middle && quadBounds.maxZ >= cube.Middle) { quad.VirtualInner = quadBounds; } else { quad.VirtualInner = default(SgtLongBounds); } quad.PendingInner = quad.VirtualInner; quad.PendingInner.ClampTo(cubeLimits); if (quad.PendingOuter.SizeX < 0 || quad.PendingOuter.SizeY < 0 || quad.PendingOuter.SizeZ < 0) { quad.PendingOuter = default(SgtLongBounds); quad.PendingInner = default(SgtLongBounds); } var forceUpdate = false; if (dirty == true) { if (quad.CurrentOuter.Volume > 0 || quad.CurrentInner.Volume > 0) { forceUpdate = true; quad.CurrentOuter.Clear(); quad.CurrentInner.Clear(); } } if (quad.CurrentOuter.Volume == 0) { quad.CurrentOuter = default(SgtLongBounds); } if (quad.PendingOuter.Volume == 0) { quad.PendingOuter = default(SgtLongBounds); } if (quad.CurrentInner.Volume == 0) { quad.CurrentInner = default(SgtLongBounds); } if (quad.PendingInner.Volume == 0) { quad.PendingInner = default(SgtLongBounds); } if (quad.CurrentOuter != quad.PendingOuter || quad.CurrentInner != quad.PendingInner || forceUpdate == true) { pendingQuads.Push(quad); } } } dirty = false; }