PhysicsBlock GetNewPhysicsBlock(Block block, Vector3 blockWorldPosition, IndexPosition blockIPos, Chunk chunk) { if (unusedPhysBlocks.Count > 0) { PhysicsBlock b = unusedPhysBlocks.Dequeue() as PhysicsBlock; b.Block = block; b.Transform.Position = blockWorldPosition; b.BlockPos = blockIPos; b.Chunk = chunk; return(b); } else { return(new PhysicsBlock(block, blockWorldPosition, blockIPos, chunk)); } }
public IEnumerable <PhysicsBodyComponent> GetBroadphaseIntersections(AxisAlignedBoundingBox broad) { _terrainBlockCache.Clear(); // Convert the broad AABB to an IndexPosition AABB IndexPosition min = new IndexPosition( Maths.NegativeRound(broad.Min.X / Block.CUBE_SIZE), Maths.NegativeRound(broad.Min.Y / Block.CUBE_SIZE), Maths.NegativeRound(broad.Min.Z / Block.CUBE_SIZE)); IndexPosition max = new IndexPosition( (int)Math.Ceiling(broad.Max.X / Block.CUBE_SIZE), (int)Math.Ceiling(broad.Max.Y / Block.CUBE_SIZE), (int)Math.Ceiling(broad.Max.Z / Block.CUBE_SIZE)); // Calculate the chunk index to use as reference IndexPosition chunkIndex = Terrain.WorldToChunkCoords(broad.Center); // Try each block for (int x = min.X; x <= max.X; x++) { for (int y = min.Y; y <= max.Y; y++) { for (int z = min.Z; z <= max.Z; z++) { // Calculate the index positions for the current block IndexPosition blockIndexWorld = new IndexPosition(x, y, z); IndexPosition blockChunkIndex = Chunk.BlockToChunkBlockCoords(chunkIndex, blockIndexWorld); // Find the block Chunk chunk; int fx, fy, fz; Block block = Terrain.FindBlock(chunkIndex, blockChunkIndex.X, blockChunkIndex.Y, blockChunkIndex.Z, out fx, out fy, out fz, out chunk); // If this block has collision, process it if (block.HasCollision()) { IndexPosition blockIPos = new IndexPosition(fx, fy, fz); // Calculate the blocks world position and create a PhyicsBlock from it Vector3 blockWorldPosition = Chunk.ChunkBlockToWorldCoords(chunk.Position, blockIPos); PhysicsBlock physBlock = GetNewPhysicsBlock(block, blockWorldPosition, blockIPos, chunk); // Grab its collider PhysicsBodyComponent physicsBody = physBlock.GetComponent <PhysicsBodyComponent>(); AxisAlignedBoundingBox physBlockCollider = physicsBody.GetCollider(); //DebugAABBs.Add(physBlockCollider as AABoundingBox); // Check if the block intersects the broad, // if it does this block is valid for collision response // TODO: Might be able to remove the intersect check if (broad.Intersects(physBlockCollider)) { _terrainBlockStorage.Add(physBlock); _terrainBlockCache.Add(physicsBody); } else { unusedPhysBlocks.Enqueue(physBlock); } } } } } return(_terrainBlockCache); }