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;