Fix lighting for non 0 minX/Y/Z and non 1 maxX/Z blocks.

This commit is contained in:
UnknownShadow200 2015-12-24 12:43:56 +11:00
parent 1852330219
commit 2b3326197f
5 changed files with 62 additions and 42 deletions

View File

@ -11,7 +11,7 @@ namespace ClassicalSharp {
public Vector3[] MaxBB = new Vector3[BlocksCount];
void InitBoundingBoxes() {
for( int i = 0; i < 256; i++ ) {
for( int i = 0; i < BlocksCount; i++ ) {
if( IsSprite[i] ) {
MinBB[i] = new Vector3( 2.50f/16f, 0, 2.50f/16f );
MaxBB[i] = new Vector3( 13.5f/16f, 1, 13.5f/16f );
@ -22,8 +22,20 @@ namespace ClassicalSharp {
}
}
internal void InitLightOffsets() {
for( int tile = 0; tile < BlocksCount; tile++ ) {
int flags = 0xFF;
Vector3 min = MinBB[tile], max = MaxBB[tile];
if( min.X != 0 ) flags &= ~(1 << TileSide.Left);
if( max.X != 1 ) flags &= ~(1 << TileSide.Right);
if( min.Z != 0 ) flags &= ~(1 << TileSide.Front);
if( max.Z != 1 ) flags &= ~(1 << TileSide.Back);
LightOffset[tile] = (byte)flags;
}
}
public void RecalculateSpriteBB( FastBitmap fastBmp ) {
for( int i = 0; i < 256; i++ ) {
for( int i = 0; i < BlocksCount; i++ ) {
if( IsSprite[i] ) RecalculateBB( i, fastBmp );
}
}

View File

@ -46,6 +46,8 @@ namespace ClassicalSharp {
public bool[] CullWithNeighbours = new bool[BlocksCount];
public byte[] LightOffset = new byte[BlocksCount];
public const byte MaxDefinedCpeBlock = (byte)Block.StoneBrick;
public const int CpeBlocksCount = MaxDefinedCpeBlock + 1;
public const byte MaxDefinedBlock = byte.MaxValue;
@ -100,6 +102,7 @@ namespace ClassicalSharp {
InitBoundingBoxes();
InitSounds();
InitLightOffsets();
SetupCullingCache();
}

View File

@ -140,7 +140,7 @@
<Compile Include="Audio\AudioPlayer.Sounds.cs" />
<Compile Include="Audio\Soundboard.cs" />
<Compile Include="Blocks\Block.cs" />
<Compile Include="Blocks\BlockInfo.BoundingBox.cs" />
<Compile Include="Blocks\BlockInfo.BoundsBox.cs" />
<Compile Include="Blocks\BlockInfo.cs" />
<Compile Include="Blocks\BlockInfo.Culling.cs" />
<Compile Include="Blocks\BlockInfo.Atlas.cs" />

View File

@ -144,6 +144,7 @@ namespace ClassicalSharp {
fullBright = info.FullBright[tile];
isTranslucent = info.IsTranslucent[tile];
lightFlags = info.LightOffset[tile];
if( leftCount != 0 )
DrawLeftFace( leftCount );
@ -274,7 +275,9 @@ namespace ClassicalSharp {
chunkIndex++;
countIndex += TileSide.Sides;
int max = chunkSize - xx;
while( count < max && x < width && CanStretch( tile, chunkIndex, x, y, z, face ) ) {
bool stretchTile = info.CanStretch[tile * TileSide.Sides + face];
while( count < max && x < width && stretchTile && CanStretch( tile, chunkIndex, x, y, z, face ) ) {
counts[countIndex] = 0;
count++;
x++;
@ -290,7 +293,9 @@ namespace ClassicalSharp {
chunkIndex += extChunkSize;
countIndex += chunkSize * TileSide.Sides;
int max = chunkSize - zz;
while( count < max && z < length && CanStretch( tile, chunkIndex, x, y, z, face ) ) {
bool stretchTile = info.CanStretch[tile * TileSide.Sides + face];
while( count < max && z < length && stretchTile && CanStretch( tile, chunkIndex, x, y, z, face ) ) {
counts[countIndex] = 0;
count++;
z++;

View File

@ -10,6 +10,7 @@ namespace ClassicalSharp {
TerrainAtlas1D atlas;
int arraysCount = 0;
bool fullBright;
int lightFlags;
void TerrainAtlasChanged( object sender, EventArgs e ) {
int newArraysCount = game.TerrainAtlas1D.TexIds.Length;
@ -64,30 +65,25 @@ namespace ClassicalSharp {
bool CanStretch( byte initialTile, int chunkIndex, int x, int y, int z, int face ) {
byte tile = chunk[chunkIndex];
return tile == initialTile && info.CanStretch[tile * TileSide.Sides + face] &&
!info.IsFaceHidden( tile, GetNeighbour( chunkIndex, face ), face ) &&
( IsLit( X, Y, Z, face ) == IsLit( x, y, z, face ) );
return tile == initialTile && !info.IsFaceHidden( tile, GetNeighbour( chunkIndex, face ), face )
&& (fullBright || IsLit( X, Y, Z, face, initialTile ) == IsLit( x, y, z, face, tile ) );
}
bool IsLit( int x, int y, int z, int face ) {
bool IsLit( int x, int y, int z, int face, byte type ) {
int offset = (info.LightOffset[type] >> face) & 1;
switch( face ) {
case TileSide.Left:
return fullBright || x <= 0 || y > map.heightmap[(z * width) + (x - 1)];
return x < offset || y > map.heightmap[(z * width) + (x - offset)];
case TileSide.Right:
return fullBright || x >= maxX || y > map.heightmap[(z * width) + (x + 1)];
return x > (maxX - offset) || y > map.heightmap[(z * width) + (x + offset)];
case TileSide.Front:
return fullBright || z <= 0 || y > map.heightmap[((z - 1) * width) + x];
return z < offset || y > map.heightmap[((z - offset) * width) + x];
case TileSide.Back:
return fullBright || z >= maxZ || y > map.heightmap[((z + 1) * width) + x];
return z > (maxZ - offset) || y > map.heightmap[((z + offset) * width) + x];
case TileSide.Bottom:
return fullBright || y <= 0 || (y - 1) > map.heightmap[(z * width) + x];
return y <= 0 || (y - 1) > map.heightmap[(z * width) + x];
case TileSide.Top:
return fullBright || y >= maxY || y > map.heightmap[(z * width) + x];
return y >= maxY || y > map.heightmap[(z * width) + x];
}
return true;
}
@ -169,13 +165,14 @@ namespace ClassicalSharp {
int texId = info.textures[tile * TileSide.Sides + TileSide.Left];
int i = texId / elementsPerAtlas1D;
float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
int offset = (lightFlags >> TileSide.Left) & 1;
float u1 = minBB.Z, u2 = (maxBB.Z + (count - 1)) * 15.99f/16f;
float v1 = vOrigin + minBB.Y * invVerElementSize;
float v2 = vOrigin + maxBB.Y * invVerElementSize * 15.99f/16f;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
FastColour col = fullBright ? FastColour.White :
X > 0 ? (Y > map.heightmap[(Z * width) + (X - 1)] ? map.SunlightXSide : map.ShadowlightXSide) : map.SunlightXSide;
X >= offset ? (Y > map.heightmap[(Z * width) + (X - offset)] ? map.SunlightXSide : map.ShadowlightXSide) : map.SunlightXSide;
part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b( x1, y2, z2 + (count - 1), u2, v1, col );
part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b( x1, y2, z1, u1, v1, col );
@ -187,13 +184,14 @@ namespace ClassicalSharp {
int texId = info.textures[tile * TileSide.Sides + TileSide.Right];
int i = texId / elementsPerAtlas1D;
float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
int offset = (lightFlags >> TileSide.Right) & 1;
float u1 = minBB.Z, u2 = (maxBB.Z + (count - 1)) * 15.99f/16f;
float v1 = vOrigin + minBB.Y * invVerElementSize;
float v2 = vOrigin + maxBB.Y * invVerElementSize * 15.99f/16f;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
FastColour col = fullBright ? FastColour.White :
X < maxX ? (Y > map.heightmap[(Z * width) + (X + 1)] ? map.SunlightXSide : map.ShadowlightXSide) : map.SunlightXSide;
X <= (maxX - offset) ? (Y > map.heightmap[(Z * width) + (X + offset)] ? map.SunlightXSide : map.ShadowlightXSide) : map.SunlightXSide;
part.vertices[part.vIndex.right++] = new VertexPos3fTex2fCol4b( x2, y2, z1, u2, v1, col );
part.vertices[part.vIndex.right++] = new VertexPos3fTex2fCol4b( x2, y2, z2 + (count - 1), u1, v1, col );
@ -201,35 +199,18 @@ namespace ClassicalSharp {
part.vertices[part.vIndex.right++] = new VertexPos3fTex2fCol4b( x2, y1, z1, u2, v2, col );
}
void DrawBackFace( int count ) {
int texId = info.textures[tile * TileSide.Sides + TileSide.Back];
int i = texId / elementsPerAtlas1D;
float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
float u1 = minBB.X, u2 = (maxBB.X + (count - 1)) * 15.99f/16f;
float v1 = vOrigin + minBB.Y * invVerElementSize;
float v2 = vOrigin + maxBB.Y * invVerElementSize * 15.99f/16f;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
FastColour col = fullBright ? FastColour.White :
Z < maxZ ? (Y > map.heightmap[((Z + 1) * width) + X] ? map.SunlightZSide : map.ShadowlightZSide) : map.SunlightZSide;
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y2, z2, u2, v1, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x1, y2, z2, u1, v1, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x1, y1, z2, u1, v2, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y1, z2, u2, v2, col );
}
void DrawFrontFace( int count ) {
int texId = info.textures[tile * TileSide.Sides + TileSide.Front];
int i = texId / elementsPerAtlas1D;
float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
int offset = (lightFlags >> TileSide.Front) & 1;
float u1 = minBB.X, u2 = (maxBB.X + (count - 1)) * 15.99f/16f;
float v1 = vOrigin + minBB.Y * invVerElementSize;
float v2 = vOrigin + maxBB.Y * invVerElementSize * 15.99f/16f;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
FastColour col = fullBright ? FastColour.White :
Z > 0 ? (Y > map.heightmap[((Z - 1) * width) + X] ? map.SunlightZSide : map.ShadowlightZSide) : map.SunlightZSide;
Z >= offset ? (Y > map.heightmap[((Z - offset) * width) + X] ? map.SunlightZSide : map.ShadowlightZSide) : map.SunlightZSide;
part.vertices[part.vIndex.front++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y1, z1, u1, v2, col );
part.vertices[part.vIndex.front++] = new VertexPos3fTex2fCol4b( x1, y1, z1, u2, v2, col );
@ -237,6 +218,25 @@ namespace ClassicalSharp {
part.vertices[part.vIndex.front++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y2, z1, u1, v1, col );
}
void DrawBackFace( int count ) {
int texId = info.textures[tile * TileSide.Sides + TileSide.Back];
int i = texId / elementsPerAtlas1D;
float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
int offset = (lightFlags >> TileSide.Back) & 1;
float u1 = minBB.X, u2 = (maxBB.X + (count - 1)) * 15.99f/16f;
float v1 = vOrigin + minBB.Y * invVerElementSize;
float v2 = vOrigin + maxBB.Y * invVerElementSize * 15.99f/16f;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
FastColour col = fullBright ? FastColour.White :
Z <= (maxZ - offset) ? (Y > map.heightmap[((Z + offset) * width) + X] ? map.SunlightZSide : map.ShadowlightZSide) : map.SunlightZSide;
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y2, z2, u2, v1, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x1, y2, z2, u1, v1, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x1, y1, z2, u1, v2, col );
part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b( x2 + (count - 1), y1, z2, u2, v2, col );
}
void DrawBottomFace( int count ) {
int texId = info.textures[tile * TileSide.Sides + TileSide.Bottom];
int i = texId / elementsPerAtlas1D;