diff --git a/ClassicalSharp/Map/ChunkMeshBuilder.cs b/ClassicalSharp/Map/ChunkMeshBuilder.cs index f9580dacb..e8e198bdb 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilder.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilder.cs @@ -40,10 +40,13 @@ namespace ClassicalSharp { for( int y = y1, yy = 0; y < yMax; y++, yy++ ) { for( int z = z1, zz = 0; z < zMax; z++, zz++ ) { - int chunkIndex = ( yy + 1 ) * extChunkSize2 + ( zz + 1 ) * extChunkSize + ( -1 + 1 ); + int chunkIndex = ( yy + 1 ) * extChunkSize2 + ( zz + 1 ) * extChunkSize + ( 0 + 1 ) - 1; for( int x = x1, xx = 0; x < xMax; x++, xx++ ) { chunkIndex++; - RenderTile( chunkIndex, xx, yy, zz, x, y, z ); + tile = chunk[chunkIndex]; + if( tile != 0 ) { + RenderTile( chunkIndex, xx, yy, zz, x, y, z ); + } } } } @@ -55,7 +58,7 @@ namespace ClassicalSharp { fixed( byte* chunkPtr = chunk, mapPtr = map.mapData ) { int* chunkIntPtr = (int*)chunkPtr; - for( int i = 0; i < extChunkSize3 / 4; i++ ) { + for( int i = 0; i < extChunkSize3 / sizeof( int ); i++ ) { *chunkIntPtr++ = 0; } @@ -107,11 +110,7 @@ namespace ClassicalSharp { } public void RenderTile( int chunkIndex, int xx, int yy, int zz, int x, int y, int z ) { - tile = chunk[chunkIndex]; - if( tile == 0 ) return; - X = x; - Y = y; - Z = z; + X = x; Y = y; Z = z; blockHeight = -1; int index = ( ( yy << 8 ) + ( zz << 4 ) + xx ) * 6; int count = 0; @@ -148,7 +147,7 @@ namespace ClassicalSharp { if( count != 0 ) { DrawTopFace( count ); } - } + } void Stretch( int x1, int y1, int z1 ) { for( int i = 0; i < counts.Length; i++ ) { @@ -172,100 +171,49 @@ namespace ClassicalSharp { // Note that sprites are not drawn with any of the DrawXFace, they are drawn using DrawSprite. if( BlockInfo.IsSprite( tile ) ) { if( counts[countIndex + TileSide.Top] != 0 ) { - startX = x; - startY = y; - startZ = z; + X = x; Y = y; Z = z; int count = StretchX( xx, countIndex, x, y, z, chunkIndex, tile, TileSide.Top ); AddSpriteVertices( tile, count ); counts[countIndex + TileSide.Top] = (byte)count; } - } else { // Do the full calculation for all six faces. - DoStretchTerrain( xx, yy, zz, x, y, z, countIndex, tile, chunkIndex ); + } else { + X = x; Y = y; Z = z; + TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, 0, TileSide.Left, -1 ); + TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, maxX, TileSide.Right, 1 ); + TestAndStretchX( xx, countIndex, tile, chunkIndex, z, 0, TileSide.Front, -18 ); + TestAndStretchX( xx, countIndex, tile, chunkIndex, z, maxZ, TileSide.Back, 18 ); + TestAndStretchX( xx, countIndex, tile, chunkIndex, y, 0, TileSide.Bottom, -324 ); + TestAndStretchX( xx, countIndex, tile, chunkIndex, y, maxY + 2, TileSide.Top, 324 ); } } } } } - int startX, startY, startZ; - void DoStretchTerrain( int xx, int yy, int zz, int x, int y, int z, int index, byte tile, int chunkIndex ) { - startX = x; - startY = y; - startZ = z; - - if( x == 0 ) { - counts[index + TileSide.Left] = 0; - } else if( counts[index + TileSide.Left] != 0 ) { - byte left = chunk[chunkIndex - 1]; // x - 1 - if( BlockInfo.IsFaceHidden( tile, left, TileSide.Left ) ) { - counts[index + TileSide.Left] = 0; + void TestAndStretchX( int xx, int index, byte tile, int chunkIndex, int value, int test, int tileSide, int offset ) { + if( value == test ) { + counts[index + tileSide] = 0; + } else if( counts[index + tileSide] != 0 ) { + if( BlockInfo.IsFaceHidden( tile, chunk[chunkIndex + offset], tileSide ) ) { + counts[index + tileSide] = 0; } else { - int count = StretchZ( zz, index, x, y, z, chunkIndex, tile, TileSide.Left ); - AddVertices( tile, count, TileSide.Left ); - counts[index + TileSide.Left] = (byte)count; + int count = StretchX( xx, index, X, Y, Z, chunkIndex, tile, tileSide ); + AddVertices( tile, count, tileSide ); + counts[index + tileSide] = (byte)count; } } - - if( x == maxX ) { - counts[index + TileSide.Right] = 0; - } else if( counts[index + TileSide.Right] != 0 ) { - byte right = chunk[chunkIndex + 1]; // x + 1 - if( BlockInfo.IsFaceHidden( tile, right, TileSide.Right ) ) { - counts[index + TileSide.Right] = 0; + } + + void TestAndStretchZ( int zz, int index, byte tile, int chunkIndex, int value, int test, int tileSide, int offset ) { + if( value == test ) { + counts[index + tileSide] = 0; + } else if( counts[index + tileSide] != 0 ) { + if( BlockInfo.IsFaceHidden( tile, chunk[chunkIndex + offset], tileSide ) ) { + counts[index + tileSide] = 0; } else { - int count = StretchZ( zz, index, x, y, z, chunkIndex, tile, TileSide.Right ); - AddVertices( tile, count, TileSide.Right ); - counts[index + TileSide.Right] = (byte)count; - } - } - - if( z == 0 ) { - counts[index + TileSide.Front] = 0; - } else if( counts[index + TileSide.Front] != 0 ) { - byte front = chunk[chunkIndex - 18]; // z - 1 - if( BlockInfo.IsFaceHidden( tile, front, TileSide.Front ) ) { - counts[index + TileSide.Front] = 0; - } else { - int count = StretchX( xx, index, x, y, z, chunkIndex, tile, TileSide.Front ); - AddVertices( tile, count, TileSide.Front ); - counts[index + TileSide.Front] = (byte)count; - } - } - - if( z == maxZ ) { - counts[index + TileSide.Back] = 0; - } else if( counts[index + TileSide.Back] != 0 ) { - byte back = chunk[chunkIndex + 18]; // z + 1 - if( BlockInfo.IsFaceHidden( tile, back, TileSide.Right ) ) { - counts[index + TileSide.Back] = 0; - } else { - int count = StretchX( xx, index, x, y, z, chunkIndex, tile, TileSide.Back ); - AddVertices( tile, count, TileSide.Back ); - counts[index + TileSide.Back] = (byte)count; - } - } - - if( y == 0 ) { - counts[index + TileSide.Bottom] = 0; - } else if( counts[index + TileSide.Bottom] != 0 ) { - byte below = chunk[chunkIndex - 324]; // y - 1 - if( BlockInfo.IsFaceHidden( tile, below, TileSide.Bottom ) ) { - counts[index + TileSide.Bottom] = 0; - } else { - int count = StretchX( xx, index, x, y, z, chunkIndex, tile, TileSide.Bottom ); - AddVertices( tile, count, TileSide.Bottom ); - counts[index + TileSide.Bottom] = (byte)count; - } - } - - if( counts[index + TileSide.Top] != 0 ) { - byte above = chunk[chunkIndex + 324]; // y + 1 - if( BlockInfo.IsFaceHidden( tile, above, TileSide.Top ) ) { - counts[index + TileSide.Top] = 0; - } else { - int count = StretchX( xx, index, x, y, z, chunkIndex, tile, TileSide.Top ); - AddVertices( tile, count, TileSide.Top ); - counts[index + TileSide.Top] = (byte)count; + int count = StretchZ( zz, index, X, Y, Z, chunkIndex, tile, tileSide ); + AddVertices( tile, count, tileSide ); + counts[index + tileSide] = (byte)count; } } } @@ -342,7 +290,7 @@ namespace ClassicalSharp { public struct ChunkPartInfo { public int VbId, IndicesCount; - public int leftIndex, rightIndex, frontIndex, + public int leftIndex, rightIndex, frontIndex, backIndex, bottomIndex, topIndex; public ushort leftCount, rightCount, frontCount, backCount, bottomCount, topCount, spriteCount; diff --git a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs index 0dff1f115..a6569dcb1 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs @@ -64,48 +64,32 @@ namespace ClassicalSharp { bool CanStretch( byte initialTile, int chunkIndex, int x, int y, int z, int face ) { byte tile = chunk[chunkIndex]; return tile == initialTile && !BlockInfo.IsFaceHidden( tile, GetNeighbour( chunkIndex, face ), face ) && - ( IsLit( startX, startY, startZ, face ) == IsLit( x, y, z, face ) ); + ( IsLit( X, Y, Z, face ) == IsLit( x, y, z, face ) ); } bool IsLit( int x, int y, int z, int face ) { switch( face ) { case TileSide.Left: - return x <= 0 || y > GetLightHeightAdj( x - 1, z ); + return x <= 0 || y > map.heightmap[( z * width ) + (x - 1)]; case TileSide.Right: - return x >= maxX || y > GetLightHeightAdj( x + 1, z ); + return x >= maxX || y > map.heightmap[( z * width ) + (x + 1)]; case TileSide.Front: - return z <= 0 || y > GetLightHeightAdj( x, z - 1 ); + return z <= 0 || y > map.heightmap[( (z - 1) * width ) + x]; case TileSide.Back: - return z >= maxZ || y > GetLightHeightAdj( x, z + 1 ); + return z >= maxZ || y > map.heightmap[( (z + 1) * width ) + x]; case TileSide.Bottom: - return y <= 0 || ( y - 1 ) > map.heightmap[( z * width ) + x]; + return y <= 0 || (y - 1) > map.heightmap[( z * width ) + x]; case TileSide.Top: - return y >= maxY || ( y + 1 ) > map.heightmap[( z * width ) + x]; + return y >= maxY || (y + 1) > map.heightmap[( z * width ) + x]; } return true; } - FastColour GetColour( int x, int y, int z, ref FastColour sunlight, ref FastColour shadow ) { - if( !map.IsValidPos( x, y, z ) ) return sunlight; - return y > map.heightmap[( z * width ) + x] ? sunlight : shadow; - } - - FastColour GetColourAdj( int x, int y, int z, ref FastColour sunlight, ref FastColour shadow ) { - if( !map.IsValidPos( x, y, z ) ) return sunlight; - return y > GetLightHeightAdj( x, z ) ? sunlight : shadow; - } - - int GetLightHeightAdj( int x, int z ) { - int y = map.heightmap[( z * width ) + x]; - return y == -1 ? -1 : - ( BlockInfo.BlockHeight( map.GetBlock( x, y, z ) ) == 1 ? y : y - 1 ); - } - void SetPartInfo( DrawInfo part, int i, ref ChunkPartInfo[] parts ) { if( part.iCount == 0 ) return; @@ -174,9 +158,7 @@ namespace ClassicalSharp { part.iCount += 6; DrawInfoFaceData counts = part.Count; - int* ptr = &counts.left; - ptr += face; - *ptr += 6; + *( &counts.left + face ) += 6; part.Count = counts; } @@ -184,7 +166,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Left ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColourAdj( X - 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide ); + FastColour col = X > 0 ? ( Y > map.heightmap[( Z * width ) + (X - 1)] ? map.SunlightXSide : map.ShadowlightXSide ) + : map.SunlightXSide; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -204,7 +187,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColourAdj( X + 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide ); + FastColour col = X < maxX ? ( Y > map.heightmap[( Z * width ) + (X + 1)] ? map.SunlightXSide : map.ShadowlightXSide ) + : map.SunlightXSide; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -224,7 +208,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Back ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColourAdj( X, Y, Z + 1, ref map.SunlightZSide, ref map.ShadowlightZSide ); + FastColour col = Z < maxZ ? ( Y > map.heightmap[( (Z + 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) + : map.SunlightZSide; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -244,7 +229,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Front ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColourAdj( X, Y, Z - 1, ref map.SunlightZSide, ref map.ShadowlightZSide ); + FastColour col = Z > 0 ? ( Y > map.heightmap[( (Z - 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) + : map.SunlightZSide; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -264,7 +250,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Bottom ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColour( X, Y - 1, Z, ref map.SunlightYBottom, ref map.ShadowlightYBottom ); + FastColour col = Y > 0 ? ( (Y - 1) > map.heightmap[( Z * width ) + X] ? map.SunlightYBottom : map.ShadowlightYBottom ) + : map.SunlightYBottom; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -281,7 +268,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Top ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight ); + FastColour col = Y < maxY ? ( (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) + : map.Sunlight; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); isTranslucent = BlockInfo.IsTranslucent( tile ); @@ -298,7 +286,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight ); + FastColour col = Y < maxY ? ( (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) + : map.Sunlight; if( blockHeight == -1 ) { blockHeight = BlockInfo.BlockHeight( tile ); } diff --git a/ClassicalSharp/Map/Map.cs b/ClassicalSharp/Map/Map.cs index bea8b8231..aea570a2d 100644 --- a/ClassicalSharp/Map/Map.cs +++ b/ClassicalSharp/Map/Map.cs @@ -119,14 +119,14 @@ namespace ClassicalSharp { for( int y = maxY; y >= 0; y-- ) { byte block = mapData[mapIndex]; if( info.BlocksLight( block ) ) { - heightmap[index] = (short)y; + heightmap[index] = (short)( y - 1 ); return y; } mapIndex -= oneY; } - heightmap[index] = -1; - return -1; + heightmap[index] = -10; + return -10; } void UpdateHeight( int x, int y, int z, byte oldBlock, byte newBlock ) { @@ -140,9 +140,9 @@ namespace ClassicalSharp { // We have to calculate the entire column for visibility, because the old/new block info is // useless if there is another block higher than block.y that stops rain. CalcHeightAt( x, maxY, z, index ); - } else if( y >= height ) { + } else if( y > height ) { if( nowBlocks ) { - heightmap[index] = (short)y; + heightmap[index] = (short)( y - 1 ); } else { // Part of the column is now visible to light, we don't know how exactly how high it should be though. // However, we know that if the old block was above or equal to light height, then the new light height must be <= old block.y @@ -255,7 +255,7 @@ namespace ClassicalSharp { x += curRunCount; mapIndex += curRunCount; index += curRunCount; if( x < xCount && info.blocksLight[mapPtr[mapIndex]] ) { - heightmap[heightmapIndex + x] = (short)y; + heightmap[heightmapIndex + x] = (short)( y - 1 ); elemsLeft--; skip[index] = 0; int offset = prevRunCount + curRunCount; @@ -290,7 +290,7 @@ namespace ClassicalSharp { for( int x = 0; x < xCount; x++ ) { int height = heightmap[heightmapIndex]; if( height == short.MaxValue ) - heightmap[heightmapIndex] = -1; + heightmap[heightmapIndex] = -10; heightmapIndex++; } }