diff --git a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs index b283c83f1..924777102 100644 --- a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs +++ b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs @@ -30,6 +30,11 @@ namespace ClassicalSharp { if( max.X != 1 ) flags &= ~(1 << TileSide.Right); if( min.Z != 0 ) flags &= ~(1 << TileSide.Front); if( max.Z != 1 ) flags &= ~(1 << TileSide.Back); + + if( (min.Y != 0 && max.Y == 1) || IsAir[tile] ) { + flags &= ~(1 << TileSide.Top); + flags &= ~(1 << TileSide.Bottom); + } LightOffset[tile] = (byte)flags; } } diff --git a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs index fba17bda5..7b772f70e 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs @@ -81,9 +81,9 @@ namespace ClassicalSharp { case TileSide.Back: return z > (maxZ - offset) || y > map.heightmap[((z + offset) * width) + x]; case TileSide.Bottom: - return y <= 0 || (y - 1) > map.heightmap[(z * width) + x]; + return y <= 0 || (y - 1 - offset) >= (map.heightmap[(z * width) + x]); case TileSide.Top: - return y >= maxY || y > map.heightmap[(z * width) + x]; + return y >= maxY || (y - offset) >= (map.heightmap[(z * width) + x]); } return true; } @@ -241,12 +241,13 @@ namespace ClassicalSharp { int texId = info.textures[tile * TileSide.Sides + TileSide.Bottom]; int i = texId / elementsPerAtlas1D; float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize; + int offset = (lightFlags >> TileSide.Bottom) & 1; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float v1 = vOrigin + minBB.Z * invVerElementSize; float v2 = vOrigin + maxBB.Z * invVerElementSize * 15.99f/16f; DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i]; - FastColour col = fullBright ? FastColour.White : ((Y - 1) > map.heightmap[(Z * width) + X] ? map.SunlightYBottom : map.ShadowlightYBottom); + FastColour col = fullBright ? FastColour.White : ((Y - 1 - offset) >= map.heightmap[(Z * width) + X] ? map.SunlightYBottom : map.ShadowlightYBottom); part.vertices[part.vIndex.bottom++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y1, z2, u2, v2, col ); part.vertices[part.vIndex.bottom++] = new VertexPos3fTex2fCol4b( x1, y1, z2, u1, v2, col ); @@ -258,12 +259,13 @@ namespace ClassicalSharp { int texId = info.textures[tile * TileSide.Sides + TileSide.Top]; int i = texId / elementsPerAtlas1D; float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize; + int offset = (lightFlags >> TileSide.Top) & 1; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float v1 = vOrigin + minBB.Z * invVerElementSize; float v2 = vOrigin + maxBB.Z * invVerElementSize * 15.99f/16f; DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i]; - FastColour col = fullBright ? FastColour.White : (Y > map.heightmap[(Z * width) + X] ? map.Sunlight : map.Shadowlight); + FastColour col = fullBright ? FastColour.White : ((Y - offset) >= map.heightmap[(Z * width) + X] ? map.Sunlight : map.Shadowlight); part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y2, z1, u2, v1, col ); part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b( x1, y2, z1, u1, v1, col ); diff --git a/ClassicalSharp/Map/Map.HeightmapCalc.cs b/ClassicalSharp/Map/Map.HeightmapCalc.cs index e39f3f3d5..547ab2ea3 100644 --- a/ClassicalSharp/Map/Map.HeightmapCalc.cs +++ b/ClassicalSharp/Map/Map.HeightmapCalc.cs @@ -7,16 +7,16 @@ namespace ClassicalSharp { public sealed partial class Map { int CalcHeightAt( int x, int maxY, int z, int index ) { - int mapIndex = ( maxY * Length + z ) * Width + x; + int mapIndex = (maxY * Length + z) * Width + x; for( int y = maxY; y >= 0; y-- ) { byte block = mapData[mapIndex]; if( info.BlocksLight[block] ) { - heightmap[index] = (short)(y - 1); - return y - 1; + int offset = (info.LightOffset[block] >> TileSide.Top) & 1; + heightmap[index] = (short)(y - offset); + return y - offset; } mapIndex -= oneY; - } - + } heightmap[index] = -10; return -10; } @@ -25,6 +25,7 @@ namespace ClassicalSharp { bool didBlock = info.BlocksLight[oldBlock]; bool nowBlocks = info.BlocksLight[newBlock]; if( didBlock == nowBlocks ) return; + int offset = (info.LightOffset[newBlock] >> TileSide.Top) & 1; int index = (z * Width) + x; int height = heightmap[index]; @@ -32,14 +33,16 @@ 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 blocks sunlight. CalcHeightAt( x, maxY, z, index ); - } else if( y > height ) { + } else if( (y - offset >= height) ) { if( nowBlocks ) { - heightmap[index] = (short)(y - 1); + heightmap[index] = (short)(y - offset); } 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 CalcHeightAt( x, y, z, index ); } + } else { + CalcHeightAt( x, maxY, z, index ); } } @@ -96,7 +99,8 @@ namespace ClassicalSharp { x += curRunCount; mapIndex += curRunCount; index += curRunCount; if( x < xCount && info.BlocksLight[mapPtr[mapIndex]] ) { - heightmap[heightmapIndex + x] = (short)( y - 1 ); + int lightOffset = (info.LightOffset[mapPtr[mapIndex]] >> TileSide.Top) & 1; + heightmap[heightmapIndex + x] = (short)(y - lightOffset); elemsLeft--; skip[index] = 0; int offset = prevRunCount + curRunCount; diff --git a/ClassicalSharp/Map/Map.cs b/ClassicalSharp/Map/Map.cs index b3e3610c3..06387d578 100644 --- a/ClassicalSharp/Map/Map.cs +++ b/ClassicalSharp/Map/Map.cs @@ -197,9 +197,8 @@ namespace ClassicalSharp { if( CloudHeight == -1 ) CloudHeight = height + 2; heightmap = new short[width * length]; - for( int i = 0; i < heightmap.Length; i++ ) { + for( int i = 0; i < heightmap.Length; i++ ) heightmap[i] = short.MaxValue; - } } /// Sets the block at the given world coordinates without bounds checking,