diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e6dca6ca..5fd73a4e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ Bug #4979: AiTravel maximum range depends on "actors processing range" setting Bug #4980: Drowning mechanics is applied for actors indifferently from distance to player Bug #4984: "Friendly hits" feature should be used only for player's followers + Bug #4989: Object dimension-dependent VFX scaling behavior is inconsistent Bug #4990: Dead bodies prevent you from hitting Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 22cdeb2df..1e4ac96bc 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -1085,41 +1086,18 @@ namespace MWMechanics std::string texture = effect->mParticle; - float scale = 1.0f; osg::Vec3f pos (mCaster.getRefData().getPosition().asVec3()); - if (animation && mCaster.getClass().isNpc()) - { - // For NPC we should take race height as scaling factor - const ESM::NPC *npc = mCaster.get()->mBase; - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); - - const ESM::Race *race = - esmStore.get().find(npc->mRace); - - scale = npc->isMale() ? race->mData.mHeight.mMale : race->mData.mHeight.mFemale; - } - else - { - osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(mCaster); - - // TODO: take a size of particle or NPC with height and weight = 1.0 as scale = 1.0 - float scaleX = halfExtents.x() * 2 / 60.f; - float scaleY = halfExtents.y() * 2 / 60.f; - float scaleZ = halfExtents.z() * 2 / 120.f; - - scale = std::max({ scaleX, scaleY, scaleZ }); - } - - // If the caster has no animation, add the effect directly to the effectManager if (animation) { - animation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex, false, "", texture, scale); + animation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex, false, "", texture); } else { - // We should set scale for effect manager manually + // If the caster has no animation, add the effect directly to the effectManager + // We should scale it manually + osg::Vec3f bounds (MWBase::Environment::get().getWorld()->getHalfExtents(mCaster) * 2.f / Constants::UnitsPerFoot); + float scale = std::max({ bounds.x()/3.f, bounds.y()/3.f, bounds.z()/6.f }); float meshScale = !mCaster.getClass().isActor() ? mCaster.getCellRef().getScale() : 1.0f; MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + castStatic->mModel, effect->mParticle, pos, scale * meshScale); } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 96b377b10..1e8eb9f8e 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1631,7 +1631,7 @@ namespace MWRender SceneUtil::addLight(parent, esmLight, Mask_ParticleSystem, Mask_Lighting, exterior); } - void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, const std::string& texture, float scale) + void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, const std::string& texture) { if (!mObjectRoot.get()) return; @@ -1663,7 +1663,12 @@ namespace MWRender } osg::ref_ptr trans = new osg::PositionAttitudeTransform; - trans->setScale(osg::Vec3f(scale, scale, scale)); + if (!mPtr.getClass().isNpc()) + { + osg::Vec3f bounds (MWBase::Environment::get().getWorld()->getHalfExtents(mPtr) * 2.f / Constants::UnitsPerFoot); + float scale = std::max({ bounds.x()/3.f, bounds.y()/3.f, bounds.z()/6.f }); + trans->setScale(osg::Vec3f(scale, scale, scale)); + } parentNode->addChild(trans); osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(model, trans); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index f638a4db7..9b9092146 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -365,7 +365,7 @@ public: * @param texture override the texture specified in the model's materials - if empty, do not override * @note Will not add an effect twice. */ - void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", const std::string& texture = "", float scale = 1.0f); + void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", const std::string& texture = ""); void removeEffect (int effectId); void removeEffects (); void getLoopingEffects (std::vector& out) const;