From de42aa9d03842bc1c84acd76985a36261afd339d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 00:32:22 +0100 Subject: [PATCH 1/6] Make thrown projectiles rotate --- apps/openmw/mwworld/projectilemanager.cpp | 17 ++++++++++++++++- apps/openmw/mwworld/projectilemanager.hpp | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index ede8c34c4..1d53c1909 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -316,6 +316,8 @@ namespace MWWorld state.mIdArrow = projectile.getCellRef().getRefId(); state.mCasterHandle = actor; state.mAttackStrength = attackStrength; + state.mThrown = projectile.get()->mBase->mData.mType == ESM::Weapon::MarksmanThrown; + state.mTime = 0.0; MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId()); MWWorld::Ptr ptr = ref.getPtr(); @@ -453,12 +455,25 @@ namespace MWWorld // gravity constant - must be way lower than the gravity affecting actors, since we're not // simulating aerodynamics at all it->mVelocity -= osg::Vec3f(0, 0, 627.2f * 0.1f) * duration; + it->mTime += duration; osg::Vec3f pos(it->mNode->getPosition()); osg::Vec3f newPos = pos + it->mVelocity * duration; osg::Quat orient; - orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity); + + orient.set( + osg::Matrixd::rotate(it->mThrown ? -1 * it->mTime : 0.0,osg::Vec3f(0,0,1)) * + osg::Matrixd::rotate(osg::PI / 2.0,osg::Vec3f(0,1,0)) * + osg::Matrixd::rotate(-1 * osg::PI / 2.0,osg::Vec3f(1,0,0)) * + osg::Matrixd::inverse( + osg::Matrixd::lookAt( + osg::Vec3f(0,0,0), + it->mVelocity, + osg::Vec3f(0,0,1)) + ) + ); + it->mNode->setAttitude(orient); it->mNode->setPosition(newPos); diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index 0dfbf6080..1e0de4dbe 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -112,6 +112,8 @@ namespace MWWorld osg::Vec3f mVelocity; float mAttackStrength; + float mTime; + bool mThrown; }; std::vector mMagicBolts; From 2b9a0a77328d69b215cf4ad0fb51f28944407b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 12:11:26 +0100 Subject: [PATCH 2/6] Save new projectile state --- apps/openmw/mwworld/projectilemanager.cpp | 5 +++++ components/esm/projectilestate.cpp | 8 ++++++++ components/esm/projectilestate.hpp | 2 ++ 3 files changed, 15 insertions(+) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 1d53c1909..1c080aec1 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -567,6 +567,9 @@ namespace MWWorld state.mVelocity = it->mVelocity; state.mAttackStrength = it->mAttackStrength; + state.mThrown = it->mThrown; + state.mTime = it->mTime; + state.save(writer); writer.endRecord(ESM::REC_PROJ); @@ -604,6 +607,8 @@ namespace MWWorld state.mVelocity = esm.mVelocity; state.mIdArrow = esm.mId; state.mAttackStrength = esm.mAttackStrength; + state.mThrown = esm.mThrown; + state.mTime = esm.mTime; std::string model; try diff --git a/components/esm/projectilestate.cpp b/components/esm/projectilestate.cpp index 8ade9d5b2..1c8a10bcb 100644 --- a/components/esm/projectilestate.cpp +++ b/components/esm/projectilestate.cpp @@ -52,6 +52,8 @@ namespace ESM esm.writeHNString ("BOW_", mBowId); esm.writeHNT ("VEL_", mVelocity); esm.writeHNT ("STR_", mAttackStrength); + esm.writeHNT ("THR_", mThrown); + esm.writeHNT ("TIM_", mTime); } void ProjectileState::load(ESMReader &esm) @@ -63,6 +65,12 @@ namespace ESM mAttackStrength = 1.f; esm.getHNOT(mAttackStrength, "STR_"); + + mThrown = false; + esm.getHNOT (mThrown, "THR_"); + + mTime = 0.f; + esm.getHNOT (mTime, "TIM_"); } } diff --git a/components/esm/projectilestate.hpp b/components/esm/projectilestate.hpp index 67ec89bb6..625d34b6a 100644 --- a/components/esm/projectilestate.hpp +++ b/components/esm/projectilestate.hpp @@ -42,6 +42,8 @@ namespace ESM std::string mBowId; Vector3 mVelocity; float mAttackStrength; + float mTime; + bool mThrown; void load (ESMReader &esm); void save (ESMWriter &esm) const; From 3dbcda6686deb5fd31d0a1992eb36884b4b369ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 15:14:15 +0100 Subject: [PATCH 3/6] Make use of mEffectAnimationTime for projectile rotation --- apps/openmw/mwworld/projectilemanager.cpp | 6 +----- apps/openmw/mwworld/projectilemanager.hpp | 1 - components/esm/projectilestate.cpp | 4 ---- components/esm/projectilestate.hpp | 1 - 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 1c080aec1..d38931700 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -317,7 +317,6 @@ namespace MWWorld state.mCasterHandle = actor; state.mAttackStrength = attackStrength; state.mThrown = projectile.get()->mBase->mData.mType == ESM::Weapon::MarksmanThrown; - state.mTime = 0.0; MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId()); MWWorld::Ptr ptr = ref.getPtr(); @@ -455,7 +454,6 @@ namespace MWWorld // gravity constant - must be way lower than the gravity affecting actors, since we're not // simulating aerodynamics at all it->mVelocity -= osg::Vec3f(0, 0, 627.2f * 0.1f) * duration; - it->mTime += duration; osg::Vec3f pos(it->mNode->getPosition()); osg::Vec3f newPos = pos + it->mVelocity * duration; @@ -463,7 +461,7 @@ namespace MWWorld osg::Quat orient; orient.set( - osg::Matrixd::rotate(it->mThrown ? -1 * it->mTime : 0.0,osg::Vec3f(0,0,1)) * + osg::Matrixd::rotate(it->mThrown ? -1 * it->mEffectAnimationTime->getTime() * 10.0 : 0.0,osg::Vec3f(0,0,1)) * osg::Matrixd::rotate(osg::PI / 2.0,osg::Vec3f(0,1,0)) * osg::Matrixd::rotate(-1 * osg::PI / 2.0,osg::Vec3f(1,0,0)) * osg::Matrixd::inverse( @@ -568,7 +566,6 @@ namespace MWWorld state.mAttackStrength = it->mAttackStrength; state.mThrown = it->mThrown; - state.mTime = it->mTime; state.save(writer); @@ -608,7 +605,6 @@ namespace MWWorld state.mIdArrow = esm.mId; state.mAttackStrength = esm.mAttackStrength; state.mThrown = esm.mThrown; - state.mTime = esm.mTime; std::string model; try diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index 1e0de4dbe..ba2fe7a74 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -112,7 +112,6 @@ namespace MWWorld osg::Vec3f mVelocity; float mAttackStrength; - float mTime; bool mThrown; }; diff --git a/components/esm/projectilestate.cpp b/components/esm/projectilestate.cpp index 1c8a10bcb..7b6c419f2 100644 --- a/components/esm/projectilestate.cpp +++ b/components/esm/projectilestate.cpp @@ -53,7 +53,6 @@ namespace ESM esm.writeHNT ("VEL_", mVelocity); esm.writeHNT ("STR_", mAttackStrength); esm.writeHNT ("THR_", mThrown); - esm.writeHNT ("TIM_", mTime); } void ProjectileState::load(ESMReader &esm) @@ -68,9 +67,6 @@ namespace ESM mThrown = false; esm.getHNOT (mThrown, "THR_"); - - mTime = 0.f; - esm.getHNOT (mTime, "TIM_"); } } diff --git a/components/esm/projectilestate.hpp b/components/esm/projectilestate.hpp index 625d34b6a..c89bb7683 100644 --- a/components/esm/projectilestate.hpp +++ b/components/esm/projectilestate.hpp @@ -42,7 +42,6 @@ namespace ESM std::string mBowId; Vector3 mVelocity; float mAttackStrength; - float mTime; bool mThrown; void load (ESMReader &esm); From 38bda3bd710a7cabb8168d1c9785c561d1ad4aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 18:00:10 +0100 Subject: [PATCH 4/6] Do not save thrown state for projectiles --- apps/openmw/mwworld/projectilemanager.cpp | 4 +--- components/esm/projectilestate.cpp | 4 ---- components/esm/projectilestate.hpp | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index d38931700..707e8b193 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -565,8 +565,6 @@ namespace MWWorld state.mVelocity = it->mVelocity; state.mAttackStrength = it->mAttackStrength; - state.mThrown = it->mThrown; - state.save(writer); writer.endRecord(ESM::REC_PROJ); @@ -604,7 +602,6 @@ namespace MWWorld state.mVelocity = esm.mVelocity; state.mIdArrow = esm.mId; state.mAttackStrength = esm.mAttackStrength; - state.mThrown = esm.mThrown; std::string model; try @@ -612,6 +609,7 @@ namespace MWWorld MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), esm.mId); MWWorld::Ptr ptr = ref.getPtr(); model = ptr.getClass().getModel(ptr); + state.mThrown = ptr.get()->mBase->mData.mType == ESM::Weapon::MarksmanThrown; } catch(...) { diff --git a/components/esm/projectilestate.cpp b/components/esm/projectilestate.cpp index 7b6c419f2..8ade9d5b2 100644 --- a/components/esm/projectilestate.cpp +++ b/components/esm/projectilestate.cpp @@ -52,7 +52,6 @@ namespace ESM esm.writeHNString ("BOW_", mBowId); esm.writeHNT ("VEL_", mVelocity); esm.writeHNT ("STR_", mAttackStrength); - esm.writeHNT ("THR_", mThrown); } void ProjectileState::load(ESMReader &esm) @@ -64,9 +63,6 @@ namespace ESM mAttackStrength = 1.f; esm.getHNOT(mAttackStrength, "STR_"); - - mThrown = false; - esm.getHNOT (mThrown, "THR_"); } } diff --git a/components/esm/projectilestate.hpp b/components/esm/projectilestate.hpp index c89bb7683..67ec89bb6 100644 --- a/components/esm/projectilestate.hpp +++ b/components/esm/projectilestate.hpp @@ -42,7 +42,6 @@ namespace ESM std::string mBowId; Vector3 mVelocity; float mAttackStrength; - bool mThrown; void load (ESMReader &esm); void save (ESMWriter &esm) const; From d0a299caabc3feef0d8009189d0ec25fa51b89f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 20:02:12 +0100 Subject: [PATCH 5/6] Rotate thrown projectiles around the bb center --- apps/openmw/mwworld/projectilemanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 707e8b193..73b8d4d49 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -202,6 +203,12 @@ namespace MWWorld osg::ref_ptr projectile = mResourceSystem->getSceneManager()->getInstance(model, attachTo); + osg::ref_ptr boundVisitor = new osg::ComputeBoundsVisitor(); + projectile->accept(*boundVisitor.get()); + osg::BoundingBox bb = boundVisitor->getBoundingBox(); + + state.mNode->setPivotPoint(bb.center()); + if (state.mIdMagic.size() > 1) for (size_t iter = 1; iter != state.mIdMagic.size(); ++iter) { From 4373fea21e008375b974447f48c84844ac690bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 23 Nov 2017 20:27:22 +0100 Subject: [PATCH 6/6] Correct projectile rotation --- apps/openmw/mwworld/projectilemanager.cpp | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 73b8d4d49..a4a22ea4a 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -386,7 +386,6 @@ namespace MWWorld static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get() .find("fTargetSpellMaxSpeed")->getFloat(); float speed = fTargetSpellMaxSpeed * it->mSpeed; - osg::Vec3f direction = orient * osg::Vec3f(0,1,0); direction.normalize(); osg::Vec3f pos(it->mNode->getPosition()); @@ -466,18 +465,21 @@ namespace MWWorld osg::Vec3f newPos = pos + it->mVelocity * duration; osg::Quat orient; - - orient.set( - osg::Matrixd::rotate(it->mThrown ? -1 * it->mEffectAnimationTime->getTime() * 10.0 : 0.0,osg::Vec3f(0,0,1)) * - osg::Matrixd::rotate(osg::PI / 2.0,osg::Vec3f(0,1,0)) * - osg::Matrixd::rotate(-1 * osg::PI / 2.0,osg::Vec3f(1,0,0)) * - osg::Matrixd::inverse( - osg::Matrixd::lookAt( - osg::Vec3f(0,0,0), - it->mVelocity, - osg::Vec3f(0,0,1)) - ) - ); + + if (it->mThrown) + orient.set( + osg::Matrixd::rotate(it->mEffectAnimationTime->getTime() * -10.0,osg::Vec3f(0,0,1)) * + osg::Matrixd::rotate(osg::PI / 2.0,osg::Vec3f(0,1,0)) * + osg::Matrixd::rotate(-1 * osg::PI / 2.0,osg::Vec3f(1,0,0)) * + osg::Matrixd::inverse( + osg::Matrixd::lookAt( + osg::Vec3f(0,0,0), + it->mVelocity, + osg::Vec3f(0,0,1)) + ) + ); + else + orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity); it->mNode->setAttitude(orient); it->mNode->setPosition(newPos);