mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 21:49:55 +00:00
Merge pull request #2226 from akortunov/projectilefix
Use relative animation time only for bows and crossbows
This commit is contained in:
commit
e3bde5ec91
9 changed files with 31 additions and 35 deletions
|
@ -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;
|
||||||
mStartTime = mAnimation->getStartTime(mWeaponGroup);
|
mRelativeTime = relativeTime;
|
||||||
|
|
||||||
|
if (mRelativeTime)
|
||||||
|
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;
|
||||||
|
|
||||||
osg::Quat orient;
|
// rotation does not work well for throwing projectiles - their roll angle will depend on shooting direction.
|
||||||
|
if (!it->mThrown)
|
||||||
if (it->mThrown)
|
{
|
||||||
orient.set(
|
osg::Quat orient;
|
||||||
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…
Reference in a new issue