Restore WeaponAnimation

pull/638/head
scrawl 10 years ago
parent 62ce2cc123
commit a066b24303

@ -21,7 +21,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation sky npcanimation vismask
creatureanimation effectmanager util renderinginterface pathgrid rendermode
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap
# occlusionquery water shadows
# ripplesimulation refraction

@ -22,6 +22,7 @@ namespace Ogre
namespace osg
{
class Vec3f;
class Quat;
}
namespace Loading
@ -486,7 +487,7 @@ namespace MWBase
float speed, bool stack, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection) = 0;
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
const Ogre::Vector3& worldPos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed) = 0;
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed) = 0;
virtual const std::vector<std::string>& getContentFiles() const = 0;

@ -812,7 +812,7 @@ void CharacterController::handleTextKey(const std::string &groupname, const std:
else if (evt.compare(off, len, "shoot attach") == 0)
mAnimation->attachArrow();
else if (evt.compare(off, len, "shoot release") == 0)
{;}//mAnimation->releaseArrow();
mAnimation->releaseArrow();
else if (evt.compare(off, len, "shoot follow attach") == 0)
mAnimation->attachArrow();

@ -39,6 +39,31 @@ public:
EffectAnimationTime() : mTime(0) { }
};
/// @brief Detaches the node from its parent when the object goes out of scope.
class PartHolder
{
public:
PartHolder(osg::ref_ptr<osg::Node> node)
: mNode(node)
{
}
~PartHolder()
{
if (mNode->getNumParents())
mNode->getParent(0)->removeChild(mNode);
}
osg::ref_ptr<osg::Node> getNode()
{
return mNode;
}
private:
osg::ref_ptr<osg::Node> mNode;
};
typedef boost::shared_ptr<PartHolder> PartHolderPtr;
class Animation
{
public:
@ -174,31 +199,6 @@ protected:
osg::Vec3f mAccumulate;
/// @brief Detaches the node from its parent when the object goes out of scope.
class PartHolder
{
public:
PartHolder(osg::ref_ptr<osg::Node> node)
: mNode(node)
{
}
~PartHolder()
{
if (mNode->getNumParents())
mNode->getParent(0)->removeChild(mNode);
}
osg::ref_ptr<osg::Node> getNode()
{
return mNode;
}
private:
osg::ref_ptr<osg::Node> mNode;
};
typedef boost::shared_ptr<PartHolder> PartHolderPtr;
struct EffectParams
{
std::string mModelName; // Just here so we don't add the same effect twice
@ -378,6 +378,7 @@ public:
virtual void setAlpha(float alpha) {}
virtual void setPitchFactor(float factor) {}
virtual void attachArrow() {}
virtual void releaseArrow() {}
virtual void enableHeadAnimation(bool enable) {}
// TODO: move outside of this class
/// Makes this object glow, by placing a Light in its center.

@ -361,7 +361,7 @@ namespace MWRender
if(isFirstPerson())
{
mAnimation->setViewMode(NpcAnimation::VM_FirstPerson);
mTrackingNode = mAnimation->getNode("Head");
mTrackingNode = mAnimation->getNode("Camera");
}
else
{

@ -7,6 +7,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp>
#include "../mwbase/world.hpp"
@ -52,7 +53,7 @@ CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const
updateParts();
}
//mWeaponAnimationTime = Ogre::SharedPtr<WeaponAnimationTime>(new WeaponAnimationTime(this));
mWeaponAnimationTime = boost::shared_ptr<WeaponAnimationTime>(new WeaponAnimationTime(this));
}
void CreatureWeaponAnimation::showWeapons(bool showWeapon)
@ -122,35 +123,52 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow();
//else
// mAmmunition.setNull();
else
mAmmunition.reset();
}
//else
//mAmmunition.setNull();
else
mAmmunition.reset();
/*
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin());
for(;ctrl != scene->mControllers.end();++ctrl)
{
if(ctrl->getSource().isNull())
{
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
ctrl->setSource(mWeaponAnimationTime);
else
ctrl->setSource(Ogre::SharedPtr<NullAnimationTime>(new NullAnimationTime()));
}
}
*/
boost::shared_ptr<SceneUtil::ControllerSource> source;
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
source = mWeaponAnimationTime;
else
source.reset(new NullAnimationTime);
SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
node->accept(assignVisitor);
}
void CreatureWeaponAnimation::attachArrow()
{
//WeaponAnimation::attachArrow(mPtr);
WeaponAnimation::attachArrow(mPtr);
}
void CreatureWeaponAnimation::releaseArrow()
{
//WeaponAnimation::releaseArrow(mPtr);
WeaponAnimation::releaseArrow(mPtr);
}
osg::Group *CreatureWeaponAnimation::getArrowBone()
{
if (!mWeapon)
return NULL;
SceneUtil::FindByNameVisitor findVisitor ("ArrowBone");
mWeapon->getNode()->accept(findVisitor);
return findVisitor.mFoundNode;
}
osg::Node *CreatureWeaponAnimation::getWeaponNode()
{
return mWeapon ? mWeapon->getNode().get() : NULL;
}
Resource::ResourceSystem *CreatureWeaponAnimation::getResourceSystem()
{
return mResourceSystem;
}
osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration)

@ -22,7 +22,7 @@ namespace MWRender
// For creatures with weapons and shields
// Animation is already virtual anyway, so might as well make a separate class.
// Most creatures don't need weapons/shields, so this will save some memory.
class CreatureWeaponAnimation : public Animation/*, public WeaponAnimation*/, public MWWorld::InventoryStoreListener
class CreatureWeaponAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
{
public:
CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
@ -39,6 +39,12 @@ namespace MWRender
virtual void attachArrow();
virtual void releaseArrow();
// WeaponAnimation
virtual osg::Group* getArrowBone();
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 osg::Vec3f runAnimation(float duration);
@ -46,12 +52,6 @@ namespace MWRender
/// to indicate the facing orientation of the character.
//virtual void setPitchFactor(float factor) { mPitchFactor = factor; }
//virtual void setWeaponGroup(const std::string& group) { mWeaponAnimationTime->setGroup(group); }
// WeaponAnimation
//virtual NifOgre::ObjectScenePtr getWeapon() { return mWeapon; }
//virtual void showWeapon(bool show) { showWeapons(show); }
//virtual void configureAddedObject(NifOgre::ObjectScenePtr object, MWWorld::Ptr ptr, int slot);
private:
PartHolderPtr mWeapon;
@ -59,7 +59,7 @@ namespace MWRender
bool mShowWeapons;
bool mShowCarriedLeft;
//Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
};
}

@ -2,6 +2,9 @@
#include <osg/UserDataContainer>
#include <osg/MatrixTransform> // XXX
#include <components/misc/rng.hpp>
#include <components/misc/resourcehelpers.hpp>
@ -9,6 +12,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/nifosg/nifloader.hpp> // TextKeyMapHolder
@ -203,7 +207,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> par
mNpc = mPtr.get<ESM::NPC>()->mBase;
mHeadAnimationTime = boost::shared_ptr<HeadAnimationTime>(new HeadAnimationTime(mPtr));
//mWeaponAnimationTime = Ogre::SharedPtr<WeaponAnimationTime>(new WeaponAnimationTime(this));
mWeaponAnimationTime = boost::shared_ptr<WeaponAnimationTime>(new WeaponAnimationTime(this));
for(size_t i = 0;i < ESM::PRT_Count;i++)
{
@ -333,7 +337,7 @@ void NpcAnimation::updateNpcBase()
removeIndividualPart((ESM::PartReferenceType)i);
updateParts();
//mWeaponAnimationTime->updateStartTime();
mWeaponAnimationTime->updateStartTime();
}
void NpcAnimation::updateParts()
@ -585,7 +589,7 @@ void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset)
mFirstPersonOffset += offset;
}*/
Animation::PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor)
PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor)
{
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->createInstance(model);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename);
@ -729,8 +733,8 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
}
}
}
//else if (type == ESM::PRT_Weapon)
// src = mWeaponAnimationTime;
else if (type == ESM::PRT_Weapon)
src = mWeaponAnimationTime;
else
src.reset(new NullAnimationTime);
@ -809,11 +813,11 @@ void NpcAnimation::showWeapons(bool showWeapon)
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow();
//else
//mAmmunition.setNull();
else
mAmmunition.reset();
}
//else
//mAmmunition.setNull();
else
mAmmunition.reset();
}
}
else
@ -853,6 +857,31 @@ void NpcAnimation::releaseArrow()
WeaponAnimation::releaseArrow(mPtr);
}
osg::Group* NpcAnimation::getArrowBone()
{
PartHolderPtr part = mObjectParts[ESM::PRT_Weapon];
if (!part)
return NULL;
SceneUtil::FindByNameVisitor findVisitor ("ArrowBone");
part->getNode()->accept(findVisitor);
return findVisitor.mFoundNode;
}
osg::Node* NpcAnimation::getWeaponNode()
{
PartHolderPtr part = mObjectParts[ESM::PRT_Weapon];
if (!part)
return NULL;
return part->getNode();
}
Resource::ResourceSystem* NpcAnimation::getResourceSystem()
{
return mResourceSystem;
}
void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound)
{
// During first auto equip, we don't play any sounds.
@ -897,7 +926,7 @@ void NpcAnimation::enableHeadAnimation(bool enable)
void NpcAnimation::setWeaponGroup(const std::string &group)
{
//mWeaponAnimationTime->
mWeaponAnimationTime->setGroup(group);
}
void NpcAnimation::equipmentChanged()

@ -95,7 +95,7 @@ private:
//Ogre::Vector3 mFirstPersonOffset;
boost::shared_ptr<HeadAnimationTime> mHeadAnimationTime;
//Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
float mAlpha;
bool mSoundsDisabled;
@ -157,6 +157,10 @@ public:
virtual void attachArrow();
virtual void releaseArrow();
virtual osg::Group* getArrowBone();
virtual osg::Node* getWeaponNode();
virtual Resource::ResourceSystem* getResourceSystem();
// WeaponAnimation
//virtual NifOgre::ObjectScenePtr getWeapon() { return mObjectParts[ESM::PRT_Weapon]; }
virtual void showWeapon(bool show) { showWeapons(show); }

@ -1,9 +1,7 @@
#include "weaponanimation.hpp"
#include <OgreEntity.h>
#include <OgreBone.h>
#include <OgreSceneNode.h>
#include <OgreSkeletonInstance.h>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
@ -21,10 +19,11 @@
namespace MWRender
{
float WeaponAnimationTime::getValue() const
float WeaponAnimationTime::getValue(osg::NodeVisitor*)
{
if (mWeaponGroup.empty())
return 0;
float current = mAnimation->getCurrentTime(mWeaponGroup);
if (current == -1)
return 0;
@ -42,6 +41,11 @@ void WeaponAnimationTime::updateStartTime()
setGroup(mWeaponGroup);
}
WeaponAnimation::WeaponAnimation()
: mPitchFactor(0)
{
}
void WeaponAnimation::attachArrow(MWWorld::Ptr actor)
{
MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor);
@ -63,8 +67,8 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor)
}
else if (weaponType == ESM::Weapon::MarksmanBow || weaponType == ESM::Weapon::MarksmanCrossbow)
{
NifOgre::ObjectScenePtr weapon = getWeapon();
if (!weapon.get())
osg::Group* parent = getArrowBone();
if (!parent)
return;
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
@ -72,12 +76,9 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor)
return;
std::string model = ammo->getClass().getModel(*ammo);
if (!weapon->mSkelBase)
throw std::runtime_error("Need a skeleton to attach the arrow to");
osg::ref_ptr<osg::Node> arrow = getResourceSystem()->getSceneManager()->createInstance(model, parent);
const std::string bonename = "ArrowBone";
mAmmunition = NifOgre::Loader::createObjects(weapon->mSkelBase, bonename, bonename, weapon->mSkelBase->getParentSceneNode(), model);
configureAddedObject(mAmmunition, *ammo, MWWorld::InventoryStore::Slot_Ammunition);
mAmmunition = PartHolderPtr(new PartHolder(arrow));
}
}
@ -91,8 +92,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
return;
// The orientation of the launched projectile. Always the same as the actor orientation, even if the ArrowBone's orientation dictates otherwise.
Ogre::Quaternion orient = Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
* osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -102,18 +103,13 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
if (weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanThrown)
{
// Thrown weapons get detached now
NifOgre::ObjectScenePtr objects = getWeapon();
Ogre::Vector3 launchPos(0,0,0);
if (objects->mSkelBase)
{
launchPos = objects->mSkelBase->getParentNode()->_getDerivedPosition();
}
else if (objects->mEntities.size())
{
objects->mEntities[0]->getParentNode()->needUpdate(true);
launchPos = objects->mEntities[0]->getParentNode()->_getDerivedPosition();
}
osg::Node* weaponNode = getWeaponNode();
if (!weaponNode)
return;
osg::MatrixList mats = weaponNode->getWorldMatrices();
if (mats.empty())
return;
osg::Vec3f launchPos = mats[0].getTrans();
float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat();
float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat();
@ -133,19 +129,14 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
if (ammo == inv.end())
return;
if (!mAmmunition.get())
if (!mAmmunition)
return;
Ogre::Vector3 launchPos(0,0,0);
if (mAmmunition->mSkelBase)
{
launchPos = mAmmunition->mSkelBase->getParentNode()->_getDerivedPosition();
}
else if (mAmmunition->mEntities.size())
{
mAmmunition->mEntities[0]->getParentNode()->needUpdate(true);
launchPos = mAmmunition->mEntities[0]->getParentNode()->_getDerivedPosition();
}
osg::ref_ptr<osg::Node> ammoNode = mAmmunition->getNode();
osg::MatrixList mats = ammoNode->getWorldMatrices();
if (mats.empty())
return;
osg::Vec3f launchPos = mats[0].getTrans();
float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat();
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
@ -154,10 +145,11 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
MWBase::Environment::get().getWorld()->launchProjectile(actor, *ammo, launchPos, orient, *weapon, speed);
inv.remove(*ammo, 1, actor);
mAmmunition.setNull();
mAmmunition.reset();
}
}
/*
void WeaponAnimation::pitchSkeleton(float xrot, Ogre::SkeletonInstance* skel)
{
if (mPitchFactor == 0)
@ -179,5 +171,6 @@ void WeaponAnimation::pitchSkeleton(float xrot, Ogre::SkeletonInstance* skel)
node = skel->getBone("Bip01 Spine1");
node->pitch(Ogre::Radian(-pitch/2), Ogre::Node::TS_WORLD);
}
*/
}

@ -1,15 +1,15 @@
#ifndef OPENMW_MWRENDER_WEAPONANIMATION_H
#define OPENMW_MWRENDER_WEAPONANIMATION_H
#include <components/sceneutil/controller.hpp>
#include "../mwworld/ptr.hpp"
#include "animation.hpp"
namespace MWRender
{
class Animation;
/*
class WeaponAnimationTime : public Ogre::ControllerValue<Ogre::Real>
class WeaponAnimationTime : public SceneUtil::ControllerSource
{
private:
Animation* mAnimation;
@ -20,27 +20,29 @@ namespace MWRender
void setGroup(const std::string& group);
void updateStartTime();
virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value)
{ }
virtual float getValue(osg::NodeVisitor* nv);
};
*/
/// Handles attach & release of projectiles for ranged weapons
class WeaponAnimation
{
public:
WeaponAnimation() : mPitchFactor(0) {}
WeaponAnimation();
virtual ~WeaponAnimation() {}
/// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op.
void attachArrow(MWWorld::Ptr actor) {}
void attachArrow(MWWorld::Ptr actor);
/// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op.
void releaseArrow(MWWorld::Ptr actor) {}
void releaseArrow(MWWorld::Ptr actor);
protected:
//NifOgre::ObjectScenePtr mAmmunition;
PartHolderPtr mAmmunition;
virtual osg::Group* getArrowBone() = 0;
virtual osg::Node* getWeaponNode() = 0;
virtual Resource::ResourceSystem* getResourceSystem() = 0;
//virtual NifOgre::ObjectScenePtr getWeapon() = 0;
virtual void showWeapon(bool show) = 0;

@ -2757,7 +2757,7 @@ namespace MWWorld
}
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
const Ogre::Vector3& worldPos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed)
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed)
{
#if 0
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed);

@ -574,7 +574,7 @@ namespace MWWorld
float speed, bool stack, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection);
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
const Ogre::Vector3& worldPos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed);
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed);
virtual const std::vector<std::string>& getContentFiles() const;

@ -38,6 +38,8 @@ enum RangeType
struct Position
{
float pos[3];
// In radians
float rot[3];
osg::Vec3f asVec3() const

Loading…
Cancel
Save