mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-23 04:34:58 -04:00
97 lines
2.9 KiB
C#
97 lines
2.9 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
#if OCCLUSION
|
|
using System;
|
|
using ClassicalSharp.GraphicsAPI;
|
|
|
|
namespace ClassicalSharp {
|
|
|
|
public partial class ChunkMeshBuilder {
|
|
|
|
unsafe int ComputeOcclusion() {
|
|
int* didFlags = stackalloc int[chunkSize2];
|
|
OpenTK.MemUtils.memset( (IntPtr)didFlags, 0x00, 0, chunkSize2 * sizeof( int ) );
|
|
int* stack = stackalloc int[chunkSize3 * 4];
|
|
|
|
int i = 0;
|
|
bool solidX = true, solidY = true, solidZ = true;
|
|
for( int y = 0; y < 16; y++ ) {
|
|
for( int z = 0; z < 16; z++ ) {
|
|
int flagIndex = (y << 4) | z;
|
|
int chunkIndex = (y + 1) * extChunkSize2 + (z + 1) * extChunkSize + (0 + 1);
|
|
for( int x = 0; x < 16; x++ ) {
|
|
byte block = chunk[chunkIndex];
|
|
if( info.IsOpaque[block] ) {
|
|
didFlags[flagIndex] |= (1 << x);
|
|
} else if( (didFlags[flagIndex] & (1 << x)) == 0 ) {
|
|
FloodFill( didFlags, stack, i, ref solidX, ref solidY, ref solidZ );
|
|
}
|
|
|
|
i++;
|
|
chunkIndex++;
|
|
}
|
|
}
|
|
}
|
|
return (solidX ? 0x1 : 0) | (solidZ ? 0x2 : 0) | (solidY ? 0x4 : 0);
|
|
}
|
|
|
|
unsafe void FloodFill( int* didFlags, int* stack, int startIndex,
|
|
ref bool solidX, ref bool solidY, ref bool solidZ ) {
|
|
int index = 0;
|
|
stack[index++] = startIndex;
|
|
bool tX0 = false, tX1 = false, tY0 = false,
|
|
tY1 = false, tZ0 = false, tZ1 = false;
|
|
|
|
while( index > 0 ) {
|
|
int bIndex = stack[--index];
|
|
int x = (bIndex & 0xF);
|
|
int z = ((bIndex >> 4) & 0xF);
|
|
int y = ((bIndex >> 8) & 0xF);
|
|
int flagIndex = (y << 4) | z;
|
|
didFlags[flagIndex] |= (1 << x);
|
|
|
|
int chunkIndex = (y + 1) * extChunkSize2 + (z + 1) * extChunkSize + (x + 1);
|
|
byte block = chunk[chunkIndex];
|
|
if( !info.IsOpaque[block] ) {
|
|
if( x == 0 )
|
|
tX0 = true;
|
|
else if( (didFlags[flagIndex] & (1 << (x - 1))) == 0 )
|
|
stack[index++] = bIndex - 1;
|
|
|
|
if( x == 15 )
|
|
tX1 = true;
|
|
else if( (didFlags[flagIndex] & (1 << (x + 1))) == 0 )
|
|
stack[index++] = bIndex + 1;
|
|
|
|
if( z == 0 )
|
|
tZ0 = true;
|
|
else if( (didFlags[flagIndex - 1] & (1 << x)) == 0 )
|
|
stack[index++] = bIndex - 16;
|
|
|
|
if( z == 15 )
|
|
tZ1 = true;
|
|
else if( (didFlags[flagIndex + 1] & (1 << x)) == 0 )
|
|
stack[index++] = bIndex + 16;
|
|
}
|
|
|
|
if( !info.IsOpaqueY[block] ) {
|
|
if( y == 0 )
|
|
tY0 = true;
|
|
else if( (didFlags[flagIndex - 16] & (1 << x)) == 0
|
|
&& !info.IsOpaqueY[chunk[chunkIndex - extChunkSize2]] )
|
|
stack[index++] = bIndex - 256;
|
|
|
|
if( y == 15 )
|
|
tY1 = true;
|
|
else if( (didFlags[flagIndex + 16] & (1 << x)) == 0
|
|
&& !info.IsOpaqueY[chunk[chunkIndex + extChunkSize2]] )
|
|
stack[index++] = bIndex + 256;
|
|
}
|
|
}
|
|
|
|
if( tX0 && tX1 ) solidX = false;
|
|
if( tY0 && tY1 ) solidY = false;
|
|
if( tZ0 && tZ1 ) solidZ = false;
|
|
}
|
|
}
|
|
}
|
|
#endif |