From a339ca77b271d55207a19297f8832e50133e5a7e Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 12 Jan 2025 14:46:56 -0800 Subject: [PATCH] Update entity colliders on faded raised platforms. --- .../src/Entities/EntityChunkManager.cpp | 35 +++++++++++++++++++ .../src/Entities/EntityChunkManager.h | 1 + OpenTESArena/src/Entities/EntityInstance.cpp | 5 +++ OpenTESArena/src/Entities/EntityInstance.h | 3 ++ 4 files changed, 44 insertions(+) diff --git a/OpenTESArena/src/Entities/EntityChunkManager.cpp b/OpenTESArena/src/Entities/EntityChunkManager.cpp index 853c4dd3a..d14d7fc35 100644 --- a/OpenTESArena/src/Entities/EntityChunkManager.cpp +++ b/OpenTESArena/src/Entities/EntityChunkManager.cpp @@ -1000,6 +1000,40 @@ void EntityChunkManager::updateCreatureSounds(double dt, EntityChunk &entityChun } } +void EntityChunkManager::updateFadedElevatedPlatforms(EntityChunk &entityChunk, const VoxelChunk &voxelChunk, double ceilingScale, JPH::PhysicsSystem &physicsSystem) +{ + for (const VoxelFadeAnimationInstance &fadeAnimInst : voxelChunk.getFadeAnimInsts()) + { + if (fadeAnimInst.isDoneFading()) + { + for (int i = static_cast(entityChunk.entityIDs.size()) - 1; i >= 0; i--) + { + const EntityInstanceID entityInstID = entityChunk.entityIDs[i]; + const EntityInstance &entityInst = this->entities.get(entityInstID); + const CoordDouble2 &entityCoord = this->positions.get(entityInst.positionID); + const VoxelInt2 entityVoxel = VoxelUtils::pointToVoxel(entityCoord.point); + + const bool matchesFadedVoxel = (entityVoxel.x == fadeAnimInst.x) && (entityVoxel.y == fadeAnimInst.z); + + // @todo: we don't know if this was a raised platform because the voxel shape has already changed this frame, so just assume yes for "can be elevated" entities + if (matchesFadedVoxel && entityInst.canUseElevatedPlatforms()) + { + JPH::BodyInterface &bodyInterface = physicsSystem.GetBodyInterface(); + const JPH::BodyID entityPhysicsBodyID = entityInst.physicsBodyID; + const JPH::RVec3 oldEntityPhysicsPosition = bodyInterface.GetPosition(entityPhysicsBodyID); + const JPH::ShapeRefC entityPhysicsShape = bodyInterface.GetShape(entityPhysicsBodyID); + const JPH::AABox entityColliderBBox = entityPhysicsShape->GetLocalBounds(); + const float entityColliderHeight = entityColliderBBox.GetSize().GetY(); + const double newEntityFeetY = ceilingScale; + const double newEntityPhysicsCenterY = newEntityFeetY + (entityColliderHeight * 0.50); + const JPH::RVec3 newEntityPhysicsPosition(oldEntityPhysicsPosition.GetX(), newEntityPhysicsCenterY, oldEntityPhysicsPosition.GetZ()); + bodyInterface.SetPosition(entityPhysicsBodyID, newEntityPhysicsPosition, JPH::EActivation::Activate); + } + } + } + } +} + void EntityChunkManager::update(double dt, BufferView activeChunkPositions, BufferView newChunkPositions, BufferView freedChunkPositions, const Player &player, const LevelDefinition *activeLevelDef, const LevelInfoDefinition *activeLevelInfoDef, @@ -1080,6 +1114,7 @@ void EntityChunkManager::update(double dt, BufferView activeChu } this->updateCreatureSounds(dt, entityChunk, playerCoord, ceilingScale, random, audioManager); + this->updateFadedElevatedPlatforms(entityChunk, voxelChunk, ceilingScale, physicsSystem); } } diff --git a/OpenTESArena/src/Entities/EntityChunkManager.h b/OpenTESArena/src/Entities/EntityChunkManager.h index 6da9effd1..af99959ff 100644 --- a/OpenTESArena/src/Entities/EntityChunkManager.h +++ b/OpenTESArena/src/Entities/EntityChunkManager.h @@ -92,6 +92,7 @@ class EntityChunkManager final : public SpecializedChunkManager std::string getCreatureSoundFilename(const EntityDefID defID) const; void updateCreatureSounds(double dt, EntityChunk &entityChunk, const CoordDouble3 &playerCoord, double ceilingScale, Random &random, AudioManager &audioManager); + void updateFadedElevatedPlatforms(EntityChunk &entityChunk, const VoxelChunk &voxelChunk, double ceilingScale, JPH::PhysicsSystem &physicsSystem); public: const EntityDefinition &getEntityDef(EntityDefID defID) const; const EntityInstance &getEntity(EntityInstanceID id) const; diff --git a/OpenTESArena/src/Entities/EntityInstance.cpp b/OpenTESArena/src/Entities/EntityInstance.cpp index 03a73c668..0ee68e2e2 100644 --- a/OpenTESArena/src/Entities/EntityInstance.cpp +++ b/OpenTESArena/src/Entities/EntityInstance.cpp @@ -24,6 +24,11 @@ bool EntityInstance::isDynamic() const return this->directionID >= 0; } +bool EntityInstance::canUseElevatedPlatforms() const +{ + return !this->isDynamic(); +} + bool EntityInstance::isCitizen() const { return this->citizenDirectionIndexID >= 0; diff --git a/OpenTESArena/src/Entities/EntityInstance.h b/OpenTESArena/src/Entities/EntityInstance.h index 4a9f8970e..15d1b7e14 100644 --- a/OpenTESArena/src/Entities/EntityInstance.h +++ b/OpenTESArena/src/Entities/EntityInstance.h @@ -38,6 +38,9 @@ struct EntityInstance // Whether the entity is capable of moving + looking. bool isDynamic() const; + // Whether the entity can be placed on raised platforms. + bool canUseElevatedPlatforms() const; + bool isCitizen() const; bool hasInventory() const;