/// <summary> /// Loads (creates) the chunk at the given position. /// </summary> /// <param name="index">The index of the chunk.</param> private void LoadChunk( ref Vector3 index ) { // check if the chunk already exists bool contains = false; lock ( _chunks ) { contains = _chunks.ContainsKey( index ); } // if the chunk doesn't exist, create it and add it if ( !contains ) { var chunk = new Chunk( _world, index ); lock ( _chunks ) { _chunks[ index ] = chunk; } } }
/// <summary> /// Creates a new block. /// </summary> /// <param name="type">The block's type.</param> /// <param name="chunk">The chunk this block belongs to.</param> /// <param name="lighting">The initial lighting level for this block.</param> public Block( BlockType type, Chunk chunk, float lighting ) { _type = type; _chunk = chunk; _lighting = lighting; }
/// <summary> /// Creates a new block. /// </summary> /// <param name="type">The block's type.</param> /// <param name="chunk">The chunk this block belongs to.</param> public Block( BlockType type, Chunk chunk ) : this(type, chunk, MinimumLighting) { }
/// <summary> /// Gets the shortest collision distance in the Y direction for this entity. /// </summary> /// <param name="chunk">The current chunk.</param> /// <param name="rayDir">The ray direction.</param> /// <returns></returns> private float GetShortestCollisionDistanceY( Chunk chunk, ref Vector3 rayDir ) { // create our rays Ray ray0 = new Ray( new Vector3( Position.X + Size.X * 0.5f, Position.Y + rayDir.Y * Size.Y * 0.5f, Position.Z + Size.Z * 0.5f ), rayDir ); Ray ray1 = new Ray( new Vector3( Position.X + Size.X * 0.5f, Position.Y + rayDir.Y * Size.Y * 0.5f, Position.Z - Size.Z * 0.5f ), rayDir ); Ray ray2 = new Ray( new Vector3( Position.X - Size.X * 0.5f, Position.Y + rayDir.Y * Size.Y * 0.5f, Position.Z + Size.Z * 0.5f ), rayDir ); Ray ray3 = new Ray( new Vector3( Position.X - Size.X * 0.5f, Position.Y + rayDir.Y * Size.Y * 0.5f, Position.Z - Size.Z * 0.5f ), rayDir ); // get each collision distance List<float> intersections = new List<float>(); chunk.GetIntersectionDistances( ray0, ref intersections ); float dist0 = GetMinimumFromList( intersections ); chunk.GetIntersectionDistances( ray1, ref intersections ); float dist1 = GetMinimumFromList( intersections ); chunk.GetIntersectionDistances( ray2, ref intersections ); float dist2 = GetMinimumFromList( intersections ); chunk.GetIntersectionDistances( ray3, ref intersections ); float dist3 = GetMinimumFromList( intersections ); // now return the absolute minimum return Math.Min( Math.Min( dist0, dist1 ), Math.Min( dist2, dist3 ) ); }
/// <summary> /// Gets the shortest collision distance in the XZ plane for this entity. /// </summary> /// <param name="chunk">The current chunk.</param> /// <param name="rayDir">The direction of the ray.</param> /// <param name="offs">The position offset.</param> /// <returns></returns> private float GetShortestCollisionDistanceXZ( Chunk chunk, Vector3 rayDir, Vector3 offs ) { // loop helpers float startY = -Size.Y * 0.5f; float endY = Size.Y * 0.5f; int countY = (int)Math.Ceiling( Size.Y ) + 1; float yStep = Math.Abs( endY - startY ) / (float)( countY - 1 ); // create the ray Ray ray = new Ray(); ray.Position.X = Position.X + offs.X; ray.Position.Z = Position.Z + offs.Z; ray.Direction = rayDir; // get the nearest collision distance List<float> intersections = new List<float>(); float dist = float.MaxValue; for ( float y = startY; y <= endY; y += yStep ) { ray.Position.Y = Position.Y + offs.Y + y; chunk.GetIntersectionDistances( ray, ref intersections ); dist = Math.Min( dist, GetMinimumFromList( intersections ) ); } return dist; }
/// <summary> /// Sets the current chunk that is having its terrain generated. /// </summary> /// <param name="chunk">The chunk.</param> public void SetCurrentChunk( Chunk chunk ) { const int max = ChunkData.SizeXZ + 2; Vector3 world; for ( int x = 0; x < max; ++x ) { for ( int y = 0; y < ChunkData.SizeY; ++y ) { for ( int z = 0; z < max; ++z ) { Position.LocalToWorld( chunk.Index, x - 1, y, z - 1, out world ); _currentBlocks[ x, y, z ] = GetBlockType( world ); } } } }