/// <summary> /// Creates a new chunk. /// </summary> /// <param name="world">The world this chunk belongs to.</param> /// <param name="index">The index of the chunk.</param> /// <param name="generateTerrain">True to generate some initial terrain, false to leave each block empty.</param> private Chunk(World world, Vector3 index, bool generateTerrain) { _world = world; _data = new ChunkData(index); _terrain = new VoxelBuffer(); // create bounds var sizeOffs = ChunkData.SizeXZ * 0.5f - 0.5f; Vector3 boundsMin = new Vector3( index.X - sizeOffs, -0.5f, index.Z - sizeOffs ); Vector3 boundsMax = new Vector3( index.X + sizeOffs, 0.5f + ChunkData.SizeY, index.Z + sizeOffs ); _bounds = new BoundingBox(boundsMin, boundsMax); _octree = new ChunkOctree(_bounds); // check if we need to populate if (generateTerrain) { PopulateTerrain(); } }
/// <summary> /// Creates a new chunk. /// </summary> /// <param name="world">The world this chunk belongs to.</param> /// <param name="index">The index of the chunk.</param> /// <param name="generateTerrain">True to generate some initial terrain, false to leave each block empty.</param> private Chunk( World world, Vector3 index, bool generateTerrain ) { _world = world; _data = new ChunkData( index ); _terrain = new VoxelBuffer(); // create bounds var sizeOffs = ChunkData.SizeXZ * 0.5f - 0.5f; Vector3 boundsMin = new Vector3( index.X - sizeOffs, -0.5f, index.Z - sizeOffs ); Vector3 boundsMax = new Vector3( index.X + sizeOffs, 0.5f + ChunkData.SizeY, index.Z + sizeOffs ); _bounds = new BoundingBox( boundsMin, boundsMax ); _octree = new ChunkOctree( _bounds ); // check if we need to populate if ( generateTerrain ) { PopulateTerrain(); } }
/// <summary> /// Divides this octree into its eight children. /// </summary> private void Divide() { // make sure we haven't divided already if (HasDivided) { throw new InvalidOperationException("This octree has already divided."); } // get helper variables Vector3 center = _bounds.GetCenter(); Vector3 qdim = _bounds.GetDimensions() * 0.25f; // get child centers Vector3 trb = new Vector3(center.X + qdim.X, center.Y + qdim.Y, center.Z + qdim.Z); Vector3 trf = new Vector3(center.X + qdim.X, center.Y + qdim.Y, center.Z - qdim.Z); Vector3 brb = new Vector3(center.X + qdim.X, center.Y - qdim.Y, center.Z + qdim.Z); Vector3 brf = new Vector3(center.X + qdim.X, center.Y - qdim.Y, center.Z - qdim.Z); Vector3 tlb = new Vector3(center.X - qdim.X, center.Y + qdim.Y, center.Z + qdim.Z); Vector3 tlf = new Vector3(center.X - qdim.X, center.Y + qdim.Y, center.Z - qdim.Z); Vector3 blb = new Vector3(center.X - qdim.X, center.Y - qdim.Y, center.Z + qdim.Z); Vector3 blf = new Vector3(center.X - qdim.X, center.Y - qdim.Y, center.Z - qdim.Z); // create children _children[0] = new ChunkOctree(new BoundingBox(tlb - qdim, tlb + qdim)); // top left back _children[1] = new ChunkOctree(new BoundingBox(tlf - qdim, tlf + qdim)); // top left front _children[2] = new ChunkOctree(new BoundingBox(trb - qdim, trb + qdim)); // top right back _children[3] = new ChunkOctree(new BoundingBox(trf - qdim, trf + qdim)); // top right front _children[4] = new ChunkOctree(new BoundingBox(blb - qdim, blb + qdim)); // bottom left back _children[5] = new ChunkOctree(new BoundingBox(blf - qdim, blf + qdim)); // bottom left front _children[6] = new ChunkOctree(new BoundingBox(brb - qdim, brb + qdim)); // bottom right back _children[7] = new ChunkOctree(new BoundingBox(brf - qdim, brf + qdim)); // bottom right front // go through our items and try to move them into children for (int i = 0; i < _objects.Count; ++i) { for (int j = 0; j < 8; ++j) { if (_children[j].Add(_objects[i])) { // move the object from this tree to the child _objects.RemoveAt(i); --i; break; } } } }
/// <summary> /// Divides this octree into its eight children. /// </summary> private void Divide() { // make sure we haven't divided already if ( HasDivided ) { throw new InvalidOperationException( "This octree has already divided." ); } // get helper variables Vector3 center = _bounds.GetCenter(); Vector3 qdim = _bounds.GetDimensions() * 0.25f; // get child centers Vector3 trb = new Vector3( center.X + qdim.X, center.Y + qdim.Y, center.Z + qdim.Z ); Vector3 trf = new Vector3( center.X + qdim.X, center.Y + qdim.Y, center.Z - qdim.Z ); Vector3 brb = new Vector3( center.X + qdim.X, center.Y - qdim.Y, center.Z + qdim.Z ); Vector3 brf = new Vector3( center.X + qdim.X, center.Y - qdim.Y, center.Z - qdim.Z ); Vector3 tlb = new Vector3( center.X - qdim.X, center.Y + qdim.Y, center.Z + qdim.Z ); Vector3 tlf = new Vector3( center.X - qdim.X, center.Y + qdim.Y, center.Z - qdim.Z ); Vector3 blb = new Vector3( center.X - qdim.X, center.Y - qdim.Y, center.Z + qdim.Z ); Vector3 blf = new Vector3( center.X - qdim.X, center.Y - qdim.Y, center.Z - qdim.Z ); // create children _children[ 0 ] = new ChunkOctree( new BoundingBox( tlb - qdim, tlb + qdim ) ); // top left back _children[ 1 ] = new ChunkOctree( new BoundingBox( tlf - qdim, tlf + qdim ) ); // top left front _children[ 2 ] = new ChunkOctree( new BoundingBox( trb - qdim, trb + qdim ) ); // top right back _children[ 3 ] = new ChunkOctree( new BoundingBox( trf - qdim, trf + qdim ) ); // top right front _children[ 4 ] = new ChunkOctree( new BoundingBox( blb - qdim, blb + qdim ) ); // bottom left back _children[ 5 ] = new ChunkOctree( new BoundingBox( blf - qdim, blf + qdim ) ); // bottom left front _children[ 6 ] = new ChunkOctree( new BoundingBox( brb - qdim, brb + qdim ) ); // bottom right back _children[ 7 ] = new ChunkOctree( new BoundingBox( brf - qdim, brf + qdim ) ); // bottom right front // go through our items and try to move them into children for ( int i = 0; i < _objects.Count; ++i ) { for ( int j = 0; j < 8; ++j ) { if ( _children[ j ].Add( _objects[ i ] ) ) { // move the object from this tree to the child _objects.RemoveAt( i ); --i; break; } } } }