mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -04:00
Minor optimisations in ChunkMeshBuilder, store (y - 1) in heightmap so we don't have to also check against block height.
This commit is contained in:
parent
2ffa078e75
commit
fece6e6da0
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user