Use relative animation time only for bows and crossbows (bug #3778)

pull/541/head
Andrei Kortunov 6 years ago
parent a381a1aff4
commit 4c21776b94

@ -6,6 +6,7 @@
Bug #3623: Fix HiDPI on Windows Bug #3623: Fix HiDPI on Windows
Bug #3733: Normal maps are inverted on mirrored UVs Bug #3733: Normal maps are inverted on mirrored UVs
Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable
Bug #3778: [Mod] Improved Thrown Weapon Projectiles - weapons have wrong transformation during throw animation
Bug #4329: Removed birthsign abilities are restored after reloading the save Bug #4329: Removed birthsign abilities are restored after reloading the save
Bug #4383: Bow model obscures crosshair when arrow is drawn Bug #4383: Bow model obscures crosshair when arrow is drawn
Bug #4384: Resist Normal Weapons only checks ammunition for ranged weapons Bug #4384: Resist Normal Weapons only checks ammunition for ranged weapons

@ -917,7 +917,10 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
if(mWeaponType != WeapType_None && mWeaponType != WeapType_Spell && mWeaponType != WeapType_HandToHand) if(mWeaponType != WeapType_None && mWeaponType != WeapType_Spell && mWeaponType != WeapType_HandToHand)
{ {
mAnimation->showWeapons(true); mAnimation->showWeapons(true);
mAnimation->setWeaponGroup(mCurrentWeapon); // Note: controllers for ranged weapon should use time for beginning of animation to play shooting properly,
// for other weapons they should use absolute time. Some mods rely on this behaviour (to rotate throwing projectiles, for example)
bool useRelativeDuration = mWeaponType == WeapType_BowAndArrow || mWeaponType == WeapType_Crossbow;
mAnimation->setWeaponGroup(mCurrentWeapon, useRelativeDuration);
} }
mAnimation->showCarriedLeft(updateCarriedLeftVisible(mWeaponType)); mAnimation->showCarriedLeft(updateCarriedLeftVisible(mWeaponType));
@ -1375,7 +1378,10 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype));
getWeaponGroup(weaptype, weapgroup); getWeaponGroup(weaptype, weapgroup);
mAnimation->setWeaponGroup(weapgroup); // Note: controllers for ranged weapon should use time for beginning of animation to play shooting properly,
// for other weapons they should use absolute time. Some mods rely on this behaviour (to rotate throwing projectiles, for example)
bool useRelativeDuration = weaptype == WeapType_BowAndArrow || weaptype == WeapType_Crossbow;
mAnimation->setWeaponGroup(weapgroup, useRelativeDuration);
if (!isStillWeapon) if (!isStillWeapon)
{ {

@ -457,7 +457,7 @@ public:
virtual void showWeapons(bool showWeapon) {} virtual void showWeapons(bool showWeapon) {}
virtual void showCarriedLeft(bool show) {} virtual void showCarriedLeft(bool show) {}
virtual void setWeaponGroup(const std::string& group) {} virtual void setWeaponGroup(const std::string& group, bool relativeDuration) {}
virtual void setVampire(bool vampire) {} virtual void setVampire(bool vampire) {}
/// A value < 1 makes the animation translucent, 1.f = fully opaque /// A value < 1 makes the animation translucent, 1.f = fully opaque
void setAlpha(float alpha); void setAlpha(float alpha);

@ -44,7 +44,7 @@ namespace MWRender
virtual osg::Node* getWeaponNode(); virtual osg::Node* getWeaponNode();
virtual Resource::ResourceSystem* getResourceSystem(); virtual Resource::ResourceSystem* getResourceSystem();
virtual void showWeapon(bool show) { showWeapons(show); } virtual void showWeapon(bool show) { showWeapons(show); }
virtual void setWeaponGroup(const std::string& group) { mWeaponAnimationTime->setGroup(group); } virtual void setWeaponGroup(const std::string& group, bool relativeDuration) { mWeaponAnimationTime->setGroup(group, relativeDuration); }
virtual void addControllers(); virtual void addControllers();

@ -1030,9 +1030,9 @@ void NpcAnimation::enableHeadAnimation(bool enable)
mHeadAnimationTime->setEnabled(enable); mHeadAnimationTime->setEnabled(enable);
} }
void NpcAnimation::setWeaponGroup(const std::string &group) void NpcAnimation::setWeaponGroup(const std::string &group, bool relativeDuration)
{ {
mWeaponAnimationTime->setGroup(group); mWeaponAnimationTime->setGroup(group, relativeDuration);
} }
void NpcAnimation::equipmentChanged() void NpcAnimation::equipmentChanged()

@ -117,7 +117,7 @@ public:
/// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands /// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands
virtual void setAccurateAiming(bool enabled); virtual void setAccurateAiming(bool enabled);
virtual void setWeaponGroup(const std::string& group); virtual void setWeaponGroup(const std::string& group, bool relativeDuration);
virtual osg::Vec3f runAnimation(float timepassed); virtual osg::Vec3f runAnimation(float timepassed);

@ -33,15 +33,20 @@ float WeaponAnimationTime::getValue(osg::NodeVisitor*)
return current - mStartTime; return current - mStartTime;
} }
void WeaponAnimationTime::setGroup(const std::string &group) void WeaponAnimationTime::setGroup(const std::string &group, bool relativeTime)
{ {
mWeaponGroup = group; mWeaponGroup = group;
mRelativeTime = relativeTime;
if (mRelativeTime)
mStartTime = mAnimation->getStartTime(mWeaponGroup); mStartTime = mAnimation->getStartTime(mWeaponGroup);
else
mStartTime = 0;
} }
void WeaponAnimationTime::updateStartTime() void WeaponAnimationTime::updateStartTime()
{ {
setGroup(mWeaponGroup); setGroup(mWeaponGroup, mRelativeTime);
} }
WeaponAnimation::WeaponAnimation() WeaponAnimation::WeaponAnimation()

@ -17,9 +17,10 @@ namespace MWRender
Animation* mAnimation; Animation* mAnimation;
std::string mWeaponGroup; std::string mWeaponGroup;
float mStartTime; float mStartTime;
bool mRelativeTime;
public: public:
WeaponAnimationTime(Animation* animation) : mAnimation(animation), mStartTime(0) {} WeaponAnimationTime(Animation* animation) : mAnimation(animation), mStartTime(0), mRelativeTime(false) {}
void setGroup(const std::string& group); void setGroup(const std::string& group, bool relativeTime);
void updateStartTime(); void updateStartTime();
virtual float getValue(osg::NodeVisitor* nv); virtual float getValue(osg::NodeVisitor* nv);

@ -3,7 +3,6 @@
#include <iomanip> #include <iomanip>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include <osg/ComputeBoundsVisitor>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
@ -204,12 +203,6 @@ namespace MWWorld
osg::ref_ptr<osg::Node> projectile = mResourceSystem->getSceneManager()->getInstance(model, attachTo); osg::ref_ptr<osg::Node> projectile = mResourceSystem->getSceneManager()->getInstance(model, attachTo);
osg::ref_ptr<osg::ComputeBoundsVisitor> boundVisitor = new osg::ComputeBoundsVisitor();
projectile->accept(*boundVisitor.get());
osg::BoundingBox bb = boundVisitor->getBoundingBox();
state.mNode->setPivotPoint(bb.center());
if (state.mIdMagic.size() > 1) if (state.mIdMagic.size() > 1)
for (size_t iter = 1; iter != state.mIdMagic.size(); ++iter) for (size_t iter = 1; iter != state.mIdMagic.size(); ++iter)
{ {
@ -465,24 +458,14 @@ namespace MWWorld
osg::Vec3f pos(it->mNode->getPosition()); osg::Vec3f pos(it->mNode->getPosition());
osg::Vec3f newPos = pos + it->mVelocity * duration; osg::Vec3f newPos = pos + it->mVelocity * duration;
// rotation does not work well for throwing projectiles - their roll angle will depend on shooting direction.
if (!it->mThrown)
{
osg::Quat orient; osg::Quat orient;
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); orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity);
it->mNode->setAttitude(orient); it->mNode->setAttitude(orient);
}
it->mNode->setPosition(newPos); it->mNode->setPosition(newPos);
update(*it, duration); update(*it, duration);

Loading…
Cancel
Save