From 99bd040d2fb10925b2a89e27896a31f7869bbbf2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 7 Jan 2016 09:54:40 +1100 Subject: [PATCH] Fix DefineBlock/DefineBlockExt packets taking a disproportionate amount of time to process. --- ClassicalSharp/Blocks/BlockInfo.Culling.cs | 86 +++++++++++-------- ClassicalSharp/Blocks/BlockInfo.cs | 5 +- .../Network/NetworkProcessor.CPE.cs | 6 +- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/ClassicalSharp/Blocks/BlockInfo.Culling.cs b/ClassicalSharp/Blocks/BlockInfo.Culling.cs index 319ea1f2e..ce7121dc5 100644 --- a/ClassicalSharp/Blocks/BlockInfo.Culling.cs +++ b/ClassicalSharp/Blocks/BlockInfo.Culling.cs @@ -12,52 +12,66 @@ namespace ClassicalSharp { public bool[] IsAir = new bool[BlocksCount]; - internal void CheckOpaque() { - for( int tile = 1; tile < BlocksCount; tile++ ) { - if( MinBB[tile] != Vector3.Zero || MaxBB[tile] != Vector3.One ) { - IsOpaque[tile] = false; - IsTransparent[tile] = true; - } - } - } - internal void SetupCullingCache() { IsAir[0] = true; - CheckOpaque(); - for( int i = 0; i < CanStretch.Length; i++ ) - CanStretch[i] = true; + for( int tile = 1; tile < BlocksCount; tile++ ) + CheckOpaque( tile ); + for( int tile = 0; tile < CanStretch.Length; tile++ ) + CanStretch[tile] = true; for( int tileI = 1; tileI < BlocksCount; tileI++ ) { for( int neighbourI = 1; neighbourI < BlocksCount; neighbourI++ ) { byte tile = (byte)tileI, neighbour = (byte)neighbourI; - bool hidden = IsHidden( tile, neighbour ); - if( tile == neighbour && !CullWithNeighbours[tile] ) - hidden = false; - Vector3 tMin = MinBB[tile], tMax = MaxBB[tile]; - Vector3 nMin = MinBB[neighbour], nMax = MaxBB[neighbour]; - - if( IsSprite[tile] ) { - SetHidden( tile, neighbour, TileSide.Left, hidden ); - SetHidden( tile, neighbour, TileSide.Right, hidden ); - SetHidden( tile, neighbour, TileSide.Front, hidden ); - SetHidden( tile, neighbour, TileSide.Back, hidden ); - SetHidden( tile, neighbour, TileSide.Bottom, hidden && nMax.Y == 1 ); - SetHidden( tile, neighbour, TileSide.Top, hidden && tMax.Y == 1 ); - } else { - SetXStretch( tile, tMin.X == 0 && tMax.X == 1 ); - SetZStretch( tile, tMin.Z == 0 && tMax.Z == 1 ); - - SetHidden( tile, neighbour, TileSide.Left, hidden && nMax.X == 1 && tMin.X == 0 ); - SetHidden( tile, neighbour, TileSide.Right, hidden && nMin.X == 0 && tMax.X == 1 ); - SetHidden( tile, neighbour, TileSide.Front, hidden && nMax.Z == 1 && tMin.Z == 0 ); - SetHidden( tile, neighbour, TileSide.Back, hidden && nMin.Z == 0 && tMax.Z == 1 ); - SetHidden( tile, neighbour, TileSide.Bottom, hidden && nMax.Y == 1 && tMin.Y == 0 ); - SetHidden( tile, neighbour, TileSide.Top, hidden && nMin.Y == 0 && tMax.Y == 1 ); - } + UpdateCulling( tile, neighbour ); } } } + internal void SetupCullingCache( byte tile ) { + IsAir[0] = true; + CheckOpaque( tile ); + CanStretch[tile] = true; + + for( int other = 1; other < BlocksCount; other++ ) { + UpdateCulling( tile, (byte)other ); + UpdateCulling( (byte)other, tile ); + } + } + + void CheckOpaque( int tile ) { + if( MinBB[tile] != Vector3.Zero || MaxBB[tile] != Vector3.One ) { + IsOpaque[tile] = false; + IsTransparent[tile] = true; + } + } + + void UpdateCulling( byte tile, byte neighbour ) { + bool hidden = IsHidden( tile, neighbour ); + if( tile == neighbour && !CullWithNeighbours[tile] ) + hidden = false; + Vector3 tMin = MinBB[tile], tMax = MaxBB[tile]; + Vector3 nMin = MinBB[neighbour], nMax = MaxBB[neighbour]; + + if( IsSprite[tile] ) { + SetHidden( tile, neighbour, TileSide.Left, hidden ); + SetHidden( tile, neighbour, TileSide.Right, hidden ); + SetHidden( tile, neighbour, TileSide.Front, hidden ); + SetHidden( tile, neighbour, TileSide.Back, hidden ); + SetHidden( tile, neighbour, TileSide.Bottom, hidden && nMax.Y == 1 ); + SetHidden( tile, neighbour, TileSide.Top, hidden && tMax.Y == 1 ); + } else { + SetXStretch( tile, tMin.X == 0 && tMax.X == 1 ); + SetZStretch( tile, tMin.Z == 0 && tMax.Z == 1 ); + + SetHidden( tile, neighbour, TileSide.Left, hidden && nMax.X == 1 && tMin.X == 0 ); + SetHidden( tile, neighbour, TileSide.Right, hidden && nMin.X == 0 && tMax.X == 1 ); + SetHidden( tile, neighbour, TileSide.Front, hidden && nMax.Z == 1 && tMin.Z == 0 ); + SetHidden( tile, neighbour, TileSide.Back, hidden && nMin.Z == 0 && tMax.Z == 1 ); + SetHidden( tile, neighbour, TileSide.Bottom, hidden && nMax.Y == 1 && tMin.Y == 0 ); + SetHidden( tile, neighbour, TileSide.Top, hidden && nMin.Y == 0 && tMax.Y == 1 ); + } + } + bool IsHidden( byte tile, byte block ) { return ((tile == block || (IsOpaque[block] && !IsLiquid[block])) && !IsSprite[tile]) || diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs index a5a616759..656e9a84b 100644 --- a/ClassicalSharp/Blocks/BlockInfo.cs +++ b/ClassicalSharp/Blocks/BlockInfo.cs @@ -163,7 +163,7 @@ namespace ClassicalSharp { FullBright[(int)id] = emits; } - public void ResetBlockInfo( byte id ) { + public void ResetBlockInfo( byte id, bool updateCulling ) { IsTransparent[id] = false; IsTranslucent[id] = false; IsOpaque[id] = true; @@ -180,7 +180,8 @@ namespace ClassicalSharp { CollideType[id] = BlockCollideType.Solid; SpeedMultiplier[id] = 1; SetAll( 0, (Block)id ); - SetupCullingCache(); + if( updateCulling ) + SetupCullingCache( id ); MinBB[id] = Vector3.Zero; MaxBB[id] = Vector3.One; StepSounds[id] = SoundType.None; diff --git a/ClassicalSharp/Network/NetworkProcessor.CPE.cs b/ClassicalSharp/Network/NetworkProcessor.CPE.cs index e8dbbc8b2..6eddb0c95 100644 --- a/ClassicalSharp/Network/NetworkProcessor.CPE.cs +++ b/ClassicalSharp/Network/NetworkProcessor.CPE.cs @@ -410,7 +410,7 @@ namespace ClassicalSharp { } void HandleCpeRemoveBlockDefinition() { - game.BlockInfo.ResetBlockInfo( reader.ReadUInt8() ); + game.BlockInfo.ResetBlockInfo( reader.ReadUInt8(), true ); game.BlockInfo.InitLightOffsets(); } @@ -434,7 +434,7 @@ namespace ClassicalSharp { byte HandleCpeDefineBlockCommonStart() { byte block = reader.ReadUInt8(); BlockInfo info = game.BlockInfo; - info.ResetBlockInfo( block ); + info.ResetBlockInfo( block, false ); info.Name[block] = reader.ReadAsciiString(); info.CollideType[block] = (BlockCollideType)reader.ReadUInt8(); @@ -478,7 +478,7 @@ namespace ClassicalSharp { info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f; info.FogColour[block] = new FastColour( reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() ); - info.SetupCullingCache(); + info.SetupCullingCache( block ); info.InitLightOffsets(); }