1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 21:49:41 +00:00

Restore WeaponAnimation

This commit is contained in:
scrawl 2015-05-31 01:07:43 +02:00
parent 62ce2cc123
commit a066b24303
14 changed files with 170 additions and 120 deletions

View file

@ -21,7 +21,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
actors objects renderingmanager animation sky npcanimation vismask 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 bulletdebugdraw globalmap characterpreview camera localmap
# occlusionquery water shadows # occlusionquery water shadows
# ripplesimulation refraction # ripplesimulation refraction

View file

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

View file

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

View file

@ -39,6 +39,31 @@ public:
EffectAnimationTime() : mTime(0) { } 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 class Animation
{ {
public: public:
@ -174,31 +199,6 @@ protected:
osg::Vec3f mAccumulate; 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 struct EffectParams
{ {
std::string mModelName; // Just here so we don't add the same effect twice 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 setAlpha(float alpha) {}
virtual void setPitchFactor(float factor) {} virtual void setPitchFactor(float factor) {}
virtual void attachArrow() {} virtual void attachArrow() {}
virtual void releaseArrow() {}
virtual void enableHeadAnimation(bool enable) {} virtual void enableHeadAnimation(bool enable) {}
// TODO: move outside of this class // TODO: move outside of this class
/// Makes this object glow, by placing a Light in its center. /// Makes this object glow, by placing a Light in its center.

View file

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

View file

@ -7,6 +7,7 @@
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/attach.hpp> #include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -52,7 +53,7 @@ CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const
updateParts(); updateParts();
} }
//mWeaponAnimationTime = Ogre::SharedPtr<WeaponAnimationTime>(new WeaponAnimationTime(this)); mWeaponAnimationTime = boost::shared_ptr<WeaponAnimationTime>(new WeaponAnimationTime(this));
} }
void CreatureWeaponAnimation::showWeapons(bool showWeapon) 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); MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt) if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow(); attachArrow();
//else else
// mAmmunition.setNull(); mAmmunition.reset();
} }
//else else
//mAmmunition.setNull(); mAmmunition.reset();
/* boost::shared_ptr<SceneUtil::ControllerSource> source;
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin());
for(;ctrl != scene->mControllers.end();++ctrl) if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
{ source = mWeaponAnimationTime;
if(ctrl->getSource().isNull()) else
{ source.reset(new NullAnimationTime);
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
ctrl->setSource(mWeaponAnimationTime); SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
else node->accept(assignVisitor);
ctrl->setSource(Ogre::SharedPtr<NullAnimationTime>(new NullAnimationTime()));
}
}
*/
} }
void CreatureWeaponAnimation::attachArrow() void CreatureWeaponAnimation::attachArrow()
{ {
//WeaponAnimation::attachArrow(mPtr); WeaponAnimation::attachArrow(mPtr);
} }
void CreatureWeaponAnimation::releaseArrow() 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) osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration)

View file

@ -22,7 +22,7 @@ namespace MWRender
// For creatures with weapons and shields // For creatures with weapons and shields
// Animation is already virtual anyway, so might as well make a separate class. // 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. // 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: public:
CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
@ -39,6 +39,12 @@ namespace MWRender
virtual void attachArrow(); virtual void attachArrow();
virtual void releaseArrow(); 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); virtual osg::Vec3f runAnimation(float duration);
@ -46,12 +52,6 @@ namespace MWRender
/// to indicate the facing orientation of the character. /// to indicate the facing orientation of the character.
//virtual void setPitchFactor(float factor) { mPitchFactor = factor; } //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: private:
PartHolderPtr mWeapon; PartHolderPtr mWeapon;
@ -59,7 +59,7 @@ namespace MWRender
bool mShowWeapons; bool mShowWeapons;
bool mShowCarriedLeft; bool mShowCarriedLeft;
//Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime; boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
}; };
} }

View file

@ -2,6 +2,9 @@
#include <osg/UserDataContainer> #include <osg/UserDataContainer>
#include <osg/MatrixTransform> // XXX
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
@ -9,6 +12,7 @@
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/attach.hpp> #include <components/sceneutil/attach.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/nifosg/nifloader.hpp> // TextKeyMapHolder #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; mNpc = mPtr.get<ESM::NPC>()->mBase;
mHeadAnimationTime = boost::shared_ptr<HeadAnimationTime>(new HeadAnimationTime(mPtr)); 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++) for(size_t i = 0;i < ESM::PRT_Count;i++)
{ {
@ -333,7 +337,7 @@ void NpcAnimation::updateNpcBase()
removeIndividualPart((ESM::PartReferenceType)i); removeIndividualPart((ESM::PartReferenceType)i);
updateParts(); updateParts();
//mWeaponAnimationTime->updateStartTime(); mWeaponAnimationTime->updateStartTime();
} }
void NpcAnimation::updateParts() void NpcAnimation::updateParts()
@ -585,7 +589,7 @@ void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset)
mFirstPersonOffset += 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> instance = mResourceSystem->getSceneManager()->createInstance(model);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename); 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) else if (type == ESM::PRT_Weapon)
// src = mWeaponAnimationTime; src = mWeaponAnimationTime;
else else
src.reset(new NullAnimationTime); src.reset(new NullAnimationTime);
@ -809,11 +813,11 @@ void NpcAnimation::showWeapons(bool showWeapon)
MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt) if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
attachArrow(); attachArrow();
//else else
//mAmmunition.setNull(); mAmmunition.reset();
} }
//else else
//mAmmunition.setNull(); mAmmunition.reset();
} }
} }
else else
@ -853,6 +857,31 @@ void NpcAnimation::releaseArrow()
WeaponAnimation::releaseArrow(mPtr); 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) void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound)
{ {
// During first auto equip, we don't play any sounds. // 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) void NpcAnimation::setWeaponGroup(const std::string &group)
{ {
//mWeaponAnimationTime-> mWeaponAnimationTime->setGroup(group);
} }
void NpcAnimation::equipmentChanged() void NpcAnimation::equipmentChanged()

View file

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

View file

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

View file

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

View file

@ -2757,7 +2757,7 @@ namespace MWWorld
} }
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile, 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 #if 0
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed); mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed);

View file

@ -574,7 +574,7 @@ namespace MWWorld
float speed, bool stack, const ESM::EffectList& effects, float speed, bool stack, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection); const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection);
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile, 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; virtual const std::vector<std::string>& getContentFiles() const;

View file

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