From 7ad054b08715c5ee57b6362718c18c3758796d28 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 6 Feb 2021 21:32:54 +0000 Subject: Explodinator performance optimisations Thanks @lixfel (#4246) --- src/BlockInfo.cpp | 121 -------------------------------------- src/BlockInfo.h | 8 --- src/Physics/Explodinator.cpp | 137 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 133 insertions(+), 133 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 76ca420e2..f5bbe97e3 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -408,127 +408,6 @@ bool IsBlockMaterialRock(BLOCKTYPE a_BlockType) //////////////////////////////////////////////////////////////////////////////// // cBlockInfo: -float cBlockInfo::GetExplosionAbsorption(const BLOCKTYPE Block) -{ - switch (Block) - { - case E_BLOCK_BEDROCK: - case E_BLOCK_COMMAND_BLOCK: - case E_BLOCK_END_GATEWAY: - case E_BLOCK_END_PORTAL: - case E_BLOCK_END_PORTAL_FRAME: return 3600000; - case E_BLOCK_ANVIL: - case E_BLOCK_ENCHANTMENT_TABLE: - case E_BLOCK_OBSIDIAN: return 1200; - case E_BLOCK_ENDER_CHEST: return 600; - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: return 100; - case E_BLOCK_DRAGON_EGG: - case E_BLOCK_END_STONE: - case E_BLOCK_END_BRICKS: return 9; - case E_BLOCK_STONE: - case E_BLOCK_BLOCK_OF_COAL: - case E_BLOCK_DIAMOND_BLOCK: - case E_BLOCK_EMERALD_BLOCK: - case E_BLOCK_GOLD_BLOCK: - case E_BLOCK_IRON_BLOCK: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_BRICK: - case E_BLOCK_BRICK_STAIRS: - case E_BLOCK_COBBLESTONE: - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_IRON_BARS: - case E_BLOCK_JUKEBOX: - case E_BLOCK_MOSSY_COBBLESTONE: - case E_BLOCK_NETHER_BRICK: - case E_BLOCK_NETHER_BRICK_FENCE: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_PRISMARINE_BLOCK: - case E_BLOCK_STONE_BRICKS: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_COBBLESTONE_WALL: return 6; - case E_BLOCK_IRON_DOOR: - case E_BLOCK_IRON_TRAPDOOR: - case E_BLOCK_MOB_SPAWNER: return 5; - case E_BLOCK_HOPPER: return 4.8f; - case E_BLOCK_TERRACOTTA: return 4.2f; - case E_BLOCK_COBWEB: return 4; - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: - case E_BLOCK_FURNACE: - case E_BLOCK_OBSERVER: return 3.5f; - case E_BLOCK_BEACON: - case E_BLOCK_COAL_ORE: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DIAMOND_ORE: - case E_BLOCK_EMERALD_ORE: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_IRON_ORE: - case E_BLOCK_LAPIS_BLOCK: - case E_BLOCK_LAPIS_ORE: - case E_BLOCK_NETHER_QUARTZ_ORE: - case E_BLOCK_PLANKS: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_FENCE: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_WOODEN_SLAB: - case E_BLOCK_WOODEN_STAIRS: - case E_BLOCK_TRAPDOOR: return 3; - case E_BLOCK_CHEST: - case E_BLOCK_WORKBENCH: - case E_BLOCK_TRAPPED_CHEST: return 2.5f; - case E_BLOCK_BONE_BLOCK: - case E_BLOCK_CAULDRON: - case E_BLOCK_LOG: return 2; - case E_BLOCK_CONCRETE: return 1.8f; - case E_BLOCK_BOOKCASE: return 1.5f; - case E_BLOCK_STANDING_BANNER: - case E_BLOCK_WALL_BANNER: - case E_BLOCK_JACK_O_LANTERN: - case E_BLOCK_MELON: - case E_BLOCK_HEAD: - case E_BLOCK_NETHER_WART_BLOCK: - case E_BLOCK_PUMPKIN: - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: return 1; - case E_BLOCK_QUARTZ_BLOCK: - case E_BLOCK_QUARTZ_STAIRS: - case E_BLOCK_RED_SANDSTONE: - case E_BLOCK_RED_SANDSTONE_STAIRS: - case E_BLOCK_SANDSTONE: - case E_BLOCK_SANDSTONE_STAIRS: - case E_BLOCK_WOOL: return 0.8f; - case E_BLOCK_SILVERFISH_EGG: return 0.75f; - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_POWERED_RAIL: - case E_BLOCK_RAIL: return 0.7f; - case E_BLOCK_GRASS_PATH: - case E_BLOCK_CLAY: - case E_BLOCK_FARMLAND: - case E_BLOCK_GRASS: - case E_BLOCK_GRAVEL: - case E_BLOCK_SPONGE: return 0.6f; - case E_BLOCK_BREWING_STAND: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_WOODEN_BUTTON: - case E_BLOCK_CAKE: - case E_BLOCK_CONCRETE_POWDER: - case E_BLOCK_DIRT: - case E_BLOCK_FROSTED_ICE: - case E_BLOCK_HAY_BALE: - case E_BLOCK_ICE: return 0.5f; - default: return 0; - } -} - - - - - NIBBLETYPE cBlockInfo::GetLightValue(const BLOCKTYPE Block) { // Emissive blocks: diff --git a/src/BlockInfo.h b/src/BlockInfo.h index d40ea21ac..fe5421690 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -12,14 +12,6 @@ class cBlockInfo { public: - // tolua_end - - /** Returns how much of an explosion Destruction Lazor's (tm) intensity the given block attenuates. - See Physics\Explodinator.cpp for details of explosion block destruction. */ - static float GetExplosionAbsorption(BLOCKTYPE Block); - - // tolua_begin - /** How much light do the blocks emit on their own? */ static NIBBLETYPE GetLightValue(BLOCKTYPE Block); diff --git a/src/Physics/Explodinator.cpp b/src/Physics/Explodinator.cpp index 4b0190ac8..862952fb9 100644 --- a/src/Physics/Explodinator.cpp +++ b/src/Physics/Explodinator.cpp @@ -39,12 +39,141 @@ namespace Explodinator }; } + /** Returns how much of an explosion Destruction Lazor's (tm) intensity the given block attenuates. + Values are scaled as 0.3 * (0.3 + Wiki) since some compilers miss the constant folding optimisation. + Wiki values are https://minecraft.gamepedia.com/Explosion#Blast_resistance as of 2021-02-06. */ + static float GetExplosionAbsorption(const BLOCKTYPE Block) + { + switch (Block) + { + case E_BLOCK_BEDROCK: + case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_END_GATEWAY: + case E_BLOCK_END_PORTAL: + case E_BLOCK_END_PORTAL_FRAME: return 1080000.09f; + case E_BLOCK_ANVIL: + case E_BLOCK_ENCHANTMENT_TABLE: + case E_BLOCK_OBSIDIAN: return 360.09f; + case E_BLOCK_ENDER_CHEST: return 180.09f; + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: return 30.09f; + case E_BLOCK_DRAGON_EGG: + case E_BLOCK_END_STONE: + case E_BLOCK_END_BRICKS: return 2.79f; + case E_BLOCK_STONE: + case E_BLOCK_BLOCK_OF_COAL: + case E_BLOCK_DIAMOND_BLOCK: + case E_BLOCK_EMERALD_BLOCK: + case E_BLOCK_GOLD_BLOCK: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_BRICK: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_IRON_BARS: + case E_BLOCK_JUKEBOX: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHER_BRICK_FENCE: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_PRISMARINE_BLOCK: + case E_BLOCK_STONE_BRICKS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_COBBLESTONE_WALL: return 1.89f; + case E_BLOCK_IRON_DOOR: + case E_BLOCK_IRON_TRAPDOOR: + case E_BLOCK_MOB_SPAWNER: return 1.59f; + case E_BLOCK_HOPPER: return 1.53f; + case E_BLOCK_TERRACOTTA: return 1.35f; + case E_BLOCK_COBWEB: return 1.29f; + case E_BLOCK_DISPENSER: + case E_BLOCK_DROPPER: + case E_BLOCK_FURNACE: + case E_BLOCK_OBSERVER: return 1.14f; + case E_BLOCK_BEACON: + case E_BLOCK_COAL_ORE: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_IRON_ORE: + case E_BLOCK_LAPIS_BLOCK: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_NETHER_QUARTZ_ORE: + case E_BLOCK_PLANKS: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_FENCE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_WOODEN_SLAB: + case E_BLOCK_WOODEN_STAIRS: + case E_BLOCK_TRAPDOOR: return 0.99f; + case E_BLOCK_CHEST: + case E_BLOCK_WORKBENCH: + case E_BLOCK_TRAPPED_CHEST: return 0.84f; + case E_BLOCK_BONE_BLOCK: + case E_BLOCK_CAULDRON: + case E_BLOCK_LOG: return 0.69f; // nIcE + case E_BLOCK_CONCRETE: return 0.63f; + case E_BLOCK_BOOKCASE: return 0.54f; + case E_BLOCK_STANDING_BANNER: + case E_BLOCK_WALL_BANNER: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_MELON: + case E_BLOCK_HEAD: + case E_BLOCK_NETHER_WART_BLOCK: + case E_BLOCK_PUMPKIN: + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: return 0.39f; + case E_BLOCK_QUARTZ_BLOCK: + case E_BLOCK_QUARTZ_STAIRS: + case E_BLOCK_RED_SANDSTONE: + case E_BLOCK_RED_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_WOOL: return 0.33f; + case E_BLOCK_SILVERFISH_EGG: return 0.315f; + case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_RAIL: return 0.3f; + case E_BLOCK_GRASS_PATH: + case E_BLOCK_CLAY: + case E_BLOCK_FARMLAND: + case E_BLOCK_GRASS: + case E_BLOCK_GRAVEL: + case E_BLOCK_SPONGE: return 0.27f; + case E_BLOCK_BREWING_STAND: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_WOODEN_BUTTON: + case E_BLOCK_CAKE: + case E_BLOCK_CONCRETE_POWDER: + case E_BLOCK_DIRT: + case E_BLOCK_FROSTED_ICE: + case E_BLOCK_HAY_BALE: + case E_BLOCK_ICE: return 0.24f; + default: return 0.09f; + } + } + /** Calculates the approximate percentage of an Entity's bounding box that is exposed to an explosion centred at Position. */ - static float CalculateEntityExposure(cChunk & a_Chunk, const cEntity & a_Entity, const Vector3f a_Position, const int a_SquareRadius) + static float CalculateEntityExposure(const cChunk & a_Chunk, const cEntity & a_Entity, const Vector3f a_Position, const int a_SquareRadius) { + class LineOfSightCallbacks final : public cLineBlockTracer::cCallbacks + { + virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override + { + return a_BlockType != E_BLOCK_AIR; + } + } Callback; + const Vector3d Position = a_Position; unsigned Unobstructed = 0, Total = 0; const auto Box = a_Entity.GetBoundingBox(); + cLineBlockTracer Tracer(*a_Chunk.GetWorld(), Callback); for (double X = Box.GetMinX(); X < Box.GetMaxX(); X += BoundingBoxStepUnit) { @@ -60,7 +189,7 @@ namespace Explodinator continue; } - if (cLineBlockTracer::LineOfSightTrace(*a_Chunk.GetWorld(), a_Position, Destination, cLineBlockTracer::eLineOfSight::losAir)) + if (Tracer.Trace(a_Position, Destination)) { Unobstructed++; } @@ -73,7 +202,7 @@ namespace Explodinator } /** Applies distance-based damage and knockback to all entities within the explosion's effect range. */ - static void DamageEntities(cChunk & a_Chunk, const Vector3f a_Position, const int a_Power) + static void DamageEntities(const cChunk & a_Chunk, const Vector3f a_Position, const int a_Power) { const auto Radius = a_Power * 2; const auto SquareRadius = Radius * Radius; @@ -225,7 +354,7 @@ namespace Explodinator break; } - a_Intensity -= 0.3f * (0.3f + cBlockInfo::GetExplosionAbsorption(Neighbour->GetBlock(Position))); + a_Intensity -= GetExplosionAbsorption(Neighbour->GetBlock(Position)); if (a_Intensity <= 0) { // The ray is exhausted: -- cgit v1.2.3