very minorly optimise BlockInfo.CalcCulling

This commit is contained in:
UnknownShadow200 2018-03-14 22:06:03 +11:00
parent cee8a9aa63
commit 865b72db72
6 changed files with 51 additions and 66 deletions

View File

@ -102,8 +102,10 @@ namespace ClassicalSharp {
#if USE16_BIT
public const BlockID MaxDefinedBlock = 0x3FF;
public const int Shift = 10;
#else
public const BlockID MaxDefinedBlock = 0xFF;
public const int Shift = 8;
#endif
public const int Count = MaxDefinedBlock + 1;

View File

@ -18,10 +18,8 @@ namespace ClassicalSharp {
public static byte[] CanStretch = new byte[Block.Count];
internal static void UpdateCulling() {
for (int block = 0; block < Block.Count; block++)
CanStretch[block] = 0x3F;
for (int block = 0; block < Block.Count; block++) {
CalcStretch((BlockID)block);
for (int neighbour = 0; neighbour < Block.Count; neighbour++) {
CalcCulling((BlockID)block, (BlockID)neighbour);
}
@ -29,21 +27,36 @@ namespace ClassicalSharp {
}
internal static void UpdateCulling(BlockID block) {
CanStretch[block] = 0x3F;
CalcStretch(block);
for (int other = 0; other < Block.Count; other++) {
CalcCulling(block, (BlockID)other);
CalcCulling((BlockID)other, block);
}
}
static void CalcStretch(BlockID block) {
// faces which can be stretched on X axis
if (MinBB[block].X == 0 && MaxBB[block].X == 1) {
CanStretch[block] |= 0x3C;
} else {
CanStretch[block] &= 0xC3; // ~0x3C
}
// faces which can be stretched on Z axis
if (MinBB[block].Z == 0 && MaxBB[block].Z == 1) {
CanStretch[block] |= 0x03;
} else {
CanStretch[block] &= 0xFC; // ~0x03
}
}
static void CalcCulling(BlockID block, BlockID other) {
Vector3 bMin = MinBB[block], bMax = MaxBB[block];
Vector3 oMin = MinBB[other], oMax = MaxBB[other];
if (IsLiquid[block]) bMax.Y -= 1.5f/16;
if (IsLiquid[other]) oMax.Y -= 1.5f/16;
hidden[block * Block.Count + other] = 0; // set all faces 'not hidden'
hidden[(block << Block.Shift) | other] = 0; // set all faces 'not hidden'
if (Draw[block] == DrawType.Sprite) {
SetHidden(block, other, Side.Left, true);
SetHidden(block, other, Side.Right, true);
@ -52,8 +65,6 @@ namespace ClassicalSharp {
SetHidden(block, other, Side.Bottom, oMax.Y == 1);
SetHidden(block, other, Side.Top, bMax.Y == 1);
} else {
SetXStretch(block, bMin.X == 0 && bMax.X == 1);
SetZStretch(block, bMin.Z == 0 && bMax.Z == 1);
bool bothLiquid = IsLiquid[block] && IsLiquid[other];
SetHidden(block, other, Side.Left, oMax.X == 1 && bMin.X == 0);
@ -85,37 +96,20 @@ namespace ClassicalSharp {
// e.g. for water / ice, don't need to draw water.
byte bType = Collide[block], oType = Collide[other];
bool canSkip = (bType == CollideType.Solid && oType == CollideType.Solid)
|| bType != CollideType.Solid;
bool canSkip = (bType == CollideType.Solid && oType == CollideType.Solid) || bType != CollideType.Solid;
return canSkip;
}
static void SetHidden(BlockID block, BlockID other, int side, bool value) {
value = IsHidden(block, other) && FaceOccluded(block, other, side) && value;
int bit = value ? 1 : 0;
hidden[block * Block.Count + other] |= (byte)(bit << side);
hidden[(block << Block.Shift) | other] |= (byte)(bit << side);
}
/// <summary> Returns whether the face at the given face of the block
/// should be drawn with the neighbour 'other' present on the other side of the face. </summary>
public static bool IsFaceHidden(BlockID block, BlockID other, int tileSide) {
#if USE16_BIT
return (hidden[(block << 10) | other] & (1 << tileSide)) != 0;
#else
return (hidden[(block << 8) | other] & (1 << tileSide)) != 0;
#endif
}
static void SetXStretch(BlockID block, bool stretch) {
const byte mask = 0x3C;
CanStretch[block] &= 0xC3; // ~0x3C
CanStretch[block] |= (stretch ? mask : (byte)0);
}
static void SetZStretch(BlockID block, bool stretch) {
const byte mask = 0x03;
CanStretch[block] &= 0xFC; // ~0x03
CanStretch[block] |= (stretch ? mask : (byte)0);
return (hidden[(block << Block.Shift) | other] & (1 << tileSide)) != 0;
}
}
}

View File

@ -202,11 +202,7 @@ namespace ClassicalSharp {
X = x; Y = y; Z = z;
fullBright = BlockInfo.FullBright[b];
#if USE16_BIT
int tileIdx = b << 10;
#else
int tileIdx = b << 8;
#endif
int tileIdx = b << Block.Shift;
// All of these function calls are inlined as they can be called tens of millions to hundreds of millions of times.
if (counts[index] == 0 ||

View File

@ -360,15 +360,20 @@ void Block_RecalculateBB(BlockID block) {
}
void Block_SetXStretch(BlockID block, bool stretch) {
void Block_CalcStretch(BlockID block) {
/* faces which can be stretched on X axis */
if (Block_MinBB[block].X == 0.0f && Block_MaxBB[block].X == 1.0f) {
Block_CanStretch[block] |= 0x3C;
} else {
Block_CanStretch[block] &= 0xC3; /* ~0x3C */
Block_CanStretch[block] |= (stretch ? 0x3C : (UInt8)0);
}
}
void Block_SetZStretch(BlockID block, bool stretch) {
/* faces which can be stretched on Z axis */
if (Block_MinBB[block].Z == 0.0f && Block_MaxBB[block].Z == 1.0f) {
Block_CanStretch[block] |= 0x03;
} else {
Block_CanStretch[block] &= 0xFC; /* ~0x03 */
Block_CanStretch[block] |= (stretch ? 0x03 : (UInt8)0);
}
}
void Block_CalcCulling(BlockID block, BlockID other) {
@ -377,7 +382,7 @@ void Block_CalcCulling(BlockID block, BlockID other) {
if (Block_IsLiquid[block]) bMax.Y -= 1.5f / 16.0f;
if (Block_IsLiquid[other]) oMax.Y -= 1.5f / 16.0f;
Block_Hidden[block * BLOCK_COUNT + other] = 0; /* set all faces 'not hidden' */
Block_Hidden[(block << BLOCK_SHIFT) | other] = 0; /* set all faces 'not hidden' */
if (Block_Draw[block] == DRAW_SPRITE) {
Block_SetHidden(block, other, FACE_XMIN, true);
Block_SetHidden(block, other, FACE_XMAX, true);
@ -386,8 +391,6 @@ void Block_CalcCulling(BlockID block, BlockID other) {
Block_SetHidden(block, other, FACE_YMIN, oMax.Y == 1.0f);
Block_SetHidden(block, other, FACE_YMAX, bMax.Y == 1.0f);
} else {
Block_SetXStretch(block, bMin.X == 0 && bMax.X == 1.0f);
Block_SetZStretch(block, bMin.Z == 0 && bMax.Z == 1.0f);
bool bothLiquid = Block_IsLiquid[block] && Block_IsLiquid[other];
Block_SetHidden(block, other, FACE_XMIN, oMax.X == 1.0f && bMin.X == 0.0f);
@ -404,10 +407,8 @@ void Block_CalcCulling(BlockID block, BlockID other) {
void Block_UpdateCullingAll(void) {
Int32 block, neighbour;
for (block = BLOCK_AIR; block < BLOCK_COUNT; block++)
Block_CanStretch[block] = 0x3F;
for (block = BLOCK_AIR; block < BLOCK_COUNT; block++) {
Block_CalcStretch((BlockID)block);
for (neighbour = BLOCK_AIR; neighbour < BLOCK_COUNT; neighbour++) {
Block_CalcCulling((BlockID)block, (BlockID)neighbour);
}
@ -415,8 +416,7 @@ void Block_UpdateCullingAll(void) {
}
void Block_UpdateCulling(BlockID block) {
Block_CanStretch[block] = 0x3F;
Block_CalcStretch(block);
Int32 other;
for (other = BLOCK_AIR; other < BLOCK_COUNT; other++) {
Block_CalcCulling(block, (BlockID)other);
@ -442,22 +442,17 @@ bool Block_IsHidden(BlockID block, BlockID other) {
/* e.g. for water / ice, don't need to draw water. */
UInt8 bType = Block_Collide[block], oType = Block_Collide[other];
bool canSkip = (bType == COLLIDE_SOLID && oType == COLLIDE_SOLID)
|| bType != COLLIDE_SOLID;
bool canSkip = (bType == COLLIDE_SOLID && oType == COLLIDE_SOLID) || bType != COLLIDE_SOLID;
return canSkip;
}
void Block_SetHidden(BlockID block, BlockID other, Face face, bool value) {
value = Block_IsHidden(block, other) && Block_FaceOccluded(block, other, face) && value;
Block_Hidden[block * BLOCK_COUNT + other] |= (UInt8)(value << face);
Block_Hidden[(block << BLOCK_SHIFT) | other] |= (UInt8)(value << face);
}
bool Block_IsFaceHidden(BlockID block, BlockID other, Face face) {
#if USE16_BIT
return (hidden[(block << 12) | other] & (1 << face)) != 0;
#else
return (Block_Hidden[(block << 8) | other] & (1 << face)) != 0;
#endif
return (Block_Hidden[(block << BLOCK_SHIFT) | other] & (1 << face)) != 0;
}

View File

@ -84,9 +84,11 @@
#define BLOCK_CPE_COUNT (BLOCK_MAX_CPE + 1)
#if USE16_BIT
#define BLOCK_MAX_DEFINED 0xFFF
#define BLOCK_MAX_DEFINED 0x3FF
#define BLOCK_SHIFT 10
#else
#define BLOCK_MAX_DEFINED 0xFF
#define BLOCK_SHIFT 8
#endif
#define BLOCK_RAW_NAMES "Air Stone Grass Dirt Cobblestone Wood Sapling Bedrock Water StillWater Lava"\

View File

@ -153,11 +153,7 @@ void Builder_Stretch(Int32 x1, Int32 y1, Int32 z1) {
Builder_X = x; Builder_Y = y; Builder_Z = z;
Builder_FullBright = Block_FullBright[b];
#if USE16_BIT
Int32 tileIdx = b << 12;
#else
Int32 tileIdx = b << 8;
#endif
Int32 tileIdx = b << BLOCK_SHIFT;
/* All of these function calls are inlined as they can be called tens of millions to hundreds of millions of times. */
if (Builder_Counts[index] == 0 ||