void PushCuboid(Octree cuboid) { if (chunkRequestLast >= chunkRequests.Length - 1) { ShowMessage("Chunk creation buffer exhausted. Delaying creation..."); return; } // Compare distances from last cuboid if (chunkRequestLast >= 0) { Octree prev = chunkRequests [chunkRequestLast]; float distCuboid = (cuboid.center.x - currentCamPos.x) * (cuboid.center.x - currentCamPos.x) + (cuboid.center.y - currentCamPos.y) * (cuboid.center.y - currentCamPos.y); float distPrev = (prev.center.x - currentCamPos.x) * (prev.center.x - currentCamPos.x) + (prev.center.y - currentCamPos.y) * (prev.center.y - currentCamPos.y); if (distPrev < distCuboid) { chunkRequests [chunkRequestLast] = cuboid; cuboid = prev; } } chunkRequests [++chunkRequestLast] = cuboid; }
void CheckCuboidVisibility(Octree cuboid) { if (cuboid.exploredChildren >= 8) { return; } Vector3 cuboidCenter = cuboid.center; float dx = cuboidCenter.x - currentCamPos.x; if (dx < 0) { dx = -dx; // simple abs() } dx -= cuboid.extents; dx /= 16f; if (dx > _visibleChunksDistance) { return; } float dy = cuboidCenter.y - currentCamPos.y; if (dy < 0) { dy = -dy; } dy -= cuboid.extents; dy /= 16f; int chunksYDistance = _visibleChunksDistance >= 8 ? 8 : _visibleChunksDistance; if (dy > chunksYDistance) { return; } float dz = cuboidCenter.z - currentCamPos.z; if (dz < 0) { dz = -dz; } dz -= cuboid.extents; dz /= 16f; if (dz > _visibleChunksDistance) { return; } Vector3 cuboidMin, cuboidMax; cuboidMin.x = cuboidCenter.x - cuboid.extents; cuboidMin.y = cuboidCenter.y - cuboid.extents; cuboidMin.z = cuboidCenter.z - cuboid.extents; cuboidMax.x = cuboidCenter.x + cuboid.extents; cuboidMax.y = cuboidCenter.y + cuboid.extents; cuboidMax.z = cuboidCenter.z + cuboid.extents; bool inFrustum; if (onlyRenderInFrustum) { inFrustum = GeometryUtilityNonAlloc.TestPlanesAABB(frustumPlanesNormals, frustumPlanesDistances, ref cuboidMin, ref cuboidMax); } else { inFrustum = true; } if (inFrustum) { int cuboidSize = cuboid.extents * 2; if (cuboidSize > 16) { if (cuboid.children == null) { cuboid.Explode(); } for (int k = 0; k < 8; k++) { if (!cuboid.children [k].explored) { PushCuboid(cuboid.children [k]); } } return; } // cuboid is less than a chunk - use that chunk int chunkX, chunkY, chunkZ; GetChunkCoordinates(cuboid.center, out chunkX, out chunkY, out chunkZ); int hash = GetChunkHash(chunkX, chunkY, chunkZ); CachedChunk cachedChunk; if (cachedChunks.TryGetValue(hash, out cachedChunk)) { cachedChunk.octree = cuboid; cuboid.parent.exploredChildren++; cuboid.explored = true; VoxelChunk chunk = cachedChunk.chunk; if (chunk == null) { return; } if (chunk.isPopulated) { // If this chunk has been created but not rendered yet, request it // if (chunk.renderState == ChunkRenderState.Pending && !chunk.inqueue) { if (chunk.renderState != ChunkRenderState.RenderingComplete || !chunk.mr.enabled) { if (chunk.inqueue) { chunk.needsMeshRebuild = true; } else { ChunkRequestRefresh(chunk, false, true); } } return; } } CreateChunk(hash, chunkX, chunkY, chunkZ, false); chunkCreationCountThisFrame++; } }
public Octree(Octree parent, Vector3 center, int extents) { this.parent = parent; this.center = center; this.extents = extents; }