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

pull/2226/head
Andrei Kortunov 5 years ago
parent a381a1aff4
commit 4c21776b94

@ -6,6 +6,7 @@
Bug #3623: Fix HiDPI on Windows
Bug #3733: Normal maps are inverted on mirrored UVs
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 #4383: Bow model obscures crosshair when arrow is drawn
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)
{
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));
@ -1375,7 +1378,10 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype));
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)
{

@ -457,7 +457,7 @@ public:
virtual void showWeapons(bool showWeapon) {}
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) {}
/// A value < 1 makes the animation translucent, 1.f = fully opaque
void setAlpha(float alpha);

@ -44,7 +44,7 @@ namespace MWRender
virtual osg::Node* getWeaponNode();
virtual Resource::ResourceSystem* getResourceSystem();
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();

@ -1030,9 +1030,9 @@ void NpcAnimation::enableHeadAnimation(bool 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()

@ -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
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);

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

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

@ -3,7 +3,6 @@
#include <iomanip>
#include <osg/PositionAttitudeTransform>
#include <osg/ComputeBoundsVisitor>
#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::ComputeBoundsVisitor> 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)
{
@ -465,24 +458,14 @@ namespace MWWorld
osg::Vec3f pos(it->mNode->getPosition());
osg::Vec3f newPos = pos + it->mVelocity * duration;
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
// rotation does not work well for throwing projectiles - their roll angle will depend on shooting direction.
if (!it->mThrown)
{
osg::Quat orient;
orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity);
it->mNode->setAttitude(orient);
}
it->mNode->setAttitude(orient);
it->mNode->setPosition(newPos);
update(*it, duration);

Loading…
Cancel
Save