mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 11:56:39 +00:00 
			
		
		
		
	Restore ranged weapon aiming
This commit is contained in:
		
							parent
							
								
									71bafcb52b
								
							
						
					
					
						commit
						ed4863ad7d
					
				
					 8 changed files with 170 additions and 94 deletions
				
			
		| 
						 | 
					@ -20,7 +20,7 @@ set(GAME_HEADER
 | 
				
			||||||
source_group(game FILES ${GAME} ${GAME_HEADER})
 | 
					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 rotatecontroller sky npcanimation vismask
 | 
				
			||||||
    creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
 | 
					    creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
 | 
				
			||||||
    bulletdebugdraw globalmap characterpreview camera localmap
 | 
					    bulletdebugdraw globalmap characterpreview camera localmap
 | 
				
			||||||
#    occlusionquery water shadows
 | 
					#    occlusionquery water shadows
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,14 +171,16 @@ Resource::ResourceSystem *CreatureWeaponAnimation::getResourceSystem()
 | 
				
			||||||
    return mResourceSystem;
 | 
					    return mResourceSystem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CreatureWeaponAnimation::addControllers()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration)
 | 
					osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    osg::Vec3f ret = Animation::runAnimation(duration);
 | 
					    osg::Vec3f ret = Animation::runAnimation(duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]);
 | 
				
			||||||
    if (mSkelBase)
 | 
					 | 
				
			||||||
        pitchSkeleton(mPtr.getRefData().getPosition().rot[0], mSkelBase->getSkeleton());
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,11 +46,13 @@ namespace MWRender
 | 
				
			||||||
        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) { mWeaponAnimationTime->setGroup(group); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void addControllers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual osg::Vec3f runAnimation(float duration);
 | 
					        virtual osg::Vec3f runAnimation(float duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// A relative factor (0-1) that decides if and how much the skeleton should be pitched
 | 
					        /// A relative factor (0-1) that decides if and how much the skeleton should be pitched
 | 
				
			||||||
        /// 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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
#include "../mwbase/soundmanager.hpp"
 | 
					#include "../mwbase/soundmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "camera.hpp"
 | 
					#include "camera.hpp"
 | 
				
			||||||
 | 
					#include "rotatecontroller.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -72,64 +73,6 @@ std::string getVampireHead(const std::string& race, bool female)
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @note Assumes that the node being rotated has its "original" orientation set every frame by a different controller.
 | 
					 | 
				
			||||||
/// The rotation is then applied on top of that orientation.
 | 
					 | 
				
			||||||
/// @note Must be set on a MatrixTransform.
 | 
					 | 
				
			||||||
class RotateController : public osg::NodeCallback
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    RotateController(osg::Node* relativeTo)
 | 
					 | 
				
			||||||
        : mEnabled(true)
 | 
					 | 
				
			||||||
        , mRelativeTo(relativeTo)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void setEnabled(bool enabled)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        mEnabled = enabled;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void setRotate(const osg::Quat& rotate)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        mRotate = rotate;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (!mEnabled)
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
 | 
					 | 
				
			||||||
        osg::Matrix matrix = transform->getMatrix();
 | 
					 | 
				
			||||||
        osg::Quat worldOrient = getWorldOrientation(node);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        osg::Quat orient = worldOrient * mRotate * worldOrient.inverse() * matrix.getRotate();
 | 
					 | 
				
			||||||
        matrix.setRotate(orient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        transform->setMatrix(matrix);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        traverse(node,nv);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    osg::Quat getWorldOrientation(osg::Node* node)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // this could be optimized later, we just need the world orientation, not the full matrix
 | 
					 | 
				
			||||||
        osg::MatrixList worldMats = node->getWorldMatrices(mRelativeTo);
 | 
					 | 
				
			||||||
        osg::Quat worldOrient;
 | 
					 | 
				
			||||||
        if (!worldMats.empty())
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            osg::Matrixf worldMat = worldMats[0];
 | 
					 | 
				
			||||||
            worldOrient = worldMat.getRotate();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return worldOrient;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
protected:
 | 
					 | 
				
			||||||
    bool mEnabled;
 | 
					 | 
				
			||||||
    osg::Quat mRotate;
 | 
					 | 
				
			||||||
    osg::ref_ptr<osg::Node> mRelativeTo;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Subclass RotateController to add a Z-offset for sneaking in first person mode.
 | 
					/// Subclass RotateController to add a Z-offset for sneaking in first person mode.
 | 
				
			||||||
/// @note We use inheritance instead of adding another controller, so that we do not have to compute the worldOrient twice.
 | 
					/// @note We use inheritance instead of adding another controller, so that we do not have to compute the worldOrient twice.
 | 
				
			||||||
/// @note Must be set on a MatrixTransform.
 | 
					/// @note Must be set on a MatrixTransform.
 | 
				
			||||||
| 
						 | 
					@ -710,17 +653,7 @@ osg::Vec3f NpcAnimation::runAnimation(float timepassed)
 | 
				
			||||||
            mHeadController->setRotate(osg::Quat(mHeadPitchRadians, osg::Vec3f(1,0,0)) * osg::Quat(mHeadYawRadians, osg::Vec3f(0,0,1)));
 | 
					            mHeadController->setRotate(osg::Quat(mHeadPitchRadians, osg::Vec3f(1,0,0)) * osg::Quat(mHeadYawRadians, osg::Vec3f(0,0,1)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]);
 | 
				
			||||||
    if (mSkelBase)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
 | 
					 | 
				
			||||||
        if(mViewMode != VM_FirstPerson)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // In third person mode we may still need pitch for ranged weapon targeting
 | 
					 | 
				
			||||||
            pitchSkeleton(mPtr.getRefData().getPosition().rot[0], baseinst);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -906,6 +839,8 @@ void NpcAnimation::addControllers()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mFirstPersonNeckController = NULL;
 | 
					    mFirstPersonNeckController = NULL;
 | 
				
			||||||
    mHeadController = NULL;
 | 
					    mHeadController = NULL;
 | 
				
			||||||
 | 
					    WeaponAnimation::deleteControllers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (mViewMode == VM_FirstPerson)
 | 
					    if (mViewMode == VM_FirstPerson)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        NodeMap::iterator found = mNodeMap.find("bip01 neck");
 | 
					        NodeMap::iterator found = mNodeMap.find("bip01 neck");
 | 
				
			||||||
| 
						 | 
					@ -927,6 +862,8 @@ void NpcAnimation::addControllers()
 | 
				
			||||||
            node->addUpdateCallback(mHeadController);
 | 
					            node->addUpdateCallback(mHeadController);
 | 
				
			||||||
            mActiveControllers.insert(std::make_pair(node, mHeadController));
 | 
					            mActiveControllers.insert(std::make_pair(node, mHeadController));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										57
									
								
								apps/openmw/mwrender/rotatecontroller.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								apps/openmw/mwrender/rotatecontroller.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,57 @@
 | 
				
			||||||
 | 
					#include "rotatecontroller.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/MatrixTransform>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RotateController::RotateController(osg::Node *relativeTo)
 | 
				
			||||||
 | 
					    : mEnabled(true)
 | 
				
			||||||
 | 
					    , mRelativeTo(relativeTo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RotateController::setEnabled(bool enabled)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mEnabled = enabled;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RotateController::setRotate(const osg::Quat &rotate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    mRotate = rotate;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RotateController::operator()(osg::Node *node, osg::NodeVisitor *nv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!mEnabled)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        traverse(node, nv);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
 | 
				
			||||||
 | 
					    osg::Matrix matrix = transform->getMatrix();
 | 
				
			||||||
 | 
					    osg::Quat worldOrient = getWorldOrientation(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::Quat orient = worldOrient * mRotate * worldOrient.inverse() * matrix.getRotate();
 | 
				
			||||||
 | 
					    matrix.setRotate(orient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    transform->setMatrix(matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    traverse(node,nv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osg::Quat RotateController::getWorldOrientation(osg::Node *node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // this could be optimized later, we just need the world orientation, not the full matrix
 | 
				
			||||||
 | 
					    osg::MatrixList worldMats = node->getWorldMatrices(mRelativeTo);
 | 
				
			||||||
 | 
					    osg::Quat worldOrient;
 | 
				
			||||||
 | 
					    if (!worldMats.empty())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        osg::Matrixf worldMat = worldMats[0];
 | 
				
			||||||
 | 
					        worldOrient = worldMat.getRotate();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return worldOrient;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								apps/openmw/mwrender/rotatecontroller.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								apps/openmw/mwrender/rotatecontroller.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					#ifndef OPENMW_MWRENDER_ROTATECONTROLLER_H
 | 
				
			||||||
 | 
					#define OPENMW_MWRENDER_ROTATECONTROLLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/NodeCallback>
 | 
				
			||||||
 | 
					#include <osg/Quat>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MWRender
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Applies a rotation in \a relativeTo's space.
 | 
				
			||||||
 | 
					/// @note Assumes that the node being rotated has its "original" orientation set every frame by a different controller.
 | 
				
			||||||
 | 
					/// The rotation is then applied on top of that orientation.
 | 
				
			||||||
 | 
					/// @note Must be set on a MatrixTransform.
 | 
				
			||||||
 | 
					class RotateController : public osg::NodeCallback
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    RotateController(osg::Node* relativeTo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setEnabled(bool enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setRotate(const osg::Quat& rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    osg::Quat getWorldOrientation(osg::Node* node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool mEnabled;
 | 
				
			||||||
 | 
					    osg::Quat mRotate;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Node> mRelativeTo;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
#include "weaponanimation.hpp"
 | 
					#include "weaponanimation.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/MatrixTransform>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <components/resource/resourcesystem.hpp>
 | 
					#include <components/resource/resourcesystem.hpp>
 | 
				
			||||||
#include <components/resource/scenemanager.hpp>
 | 
					#include <components/resource/scenemanager.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +17,7 @@
 | 
				
			||||||
#include "../mwmechanics/combat.hpp"
 | 
					#include "../mwmechanics/combat.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "animation.hpp"
 | 
					#include "animation.hpp"
 | 
				
			||||||
 | 
					#include "rotatecontroller.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -46,6 +49,11 @@ WeaponAnimation::WeaponAnimation()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WeaponAnimation::~WeaponAnimation()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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);
 | 
				
			||||||
| 
						 | 
					@ -149,28 +157,49 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					void WeaponAnimation::addControllers(const std::map<std::string, osg::ref_ptr<osg::MatrixTransform> >& nodes,
 | 
				
			||||||
void WeaponAnimation::pitchSkeleton(float xrot, Ogre::SkeletonInstance* skel)
 | 
					                                     std::multimap<osg::ref_ptr<osg::Node>, osg::ref_ptr<osg::NodeCallback> > &map, osg::Node* objectRoot)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (mPitchFactor == 0)
 | 
					    for (int i=0; i<2; ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mSpineControllers[i] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::map<std::string, osg::ref_ptr<osg::MatrixTransform> >::const_iterator found = nodes.find(i == 0 ? "bip01 spine1" : "bip01 spine2");
 | 
				
			||||||
 | 
					        if (found != nodes.end())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            osg::Node* node = found->second;
 | 
				
			||||||
 | 
					            mSpineControllers[i] = new RotateController(objectRoot);
 | 
				
			||||||
 | 
					            node->addUpdateCallback(mSpineControllers[i]);
 | 
				
			||||||
 | 
					            map.insert(std::make_pair(node, mSpineControllers[i]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WeaponAnimation::deleteControllers()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (int i=0; i<2; ++i)
 | 
				
			||||||
 | 
					        mSpineControllers[i] = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WeaponAnimation::configureControllers(float characterPitchRadians)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!mSpineControllers[0])
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float pitch = xrot * mPitchFactor;
 | 
					    if (mPitchFactor == 0.f || characterPitchRadians == 0.f)
 | 
				
			||||||
    Ogre::Node *node;
 | 
					    {
 | 
				
			||||||
 | 
					        for (int i=0; i<2; ++i)
 | 
				
			||||||
    // In spherearcher.nif, we have spine, not Spine. Not sure if all bone names should be case insensitive?
 | 
					            mSpineControllers[i]->setEnabled(false);
 | 
				
			||||||
    if (skel->hasBone("Bip01 spine2"))
 | 
					        return;
 | 
				
			||||||
        node = skel->getBone("Bip01 spine2");
 | 
					    }
 | 
				
			||||||
    else
 | 
					
 | 
				
			||||||
        node = skel->getBone("Bip01 Spine2");
 | 
					    float pitch = characterPitchRadians * mPitchFactor;
 | 
				
			||||||
    node->pitch(Ogre::Radian(-pitch/2), Ogre::Node::TS_WORLD);
 | 
					    osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0));
 | 
				
			||||||
 | 
					    for (int i=0; i<2; ++i)
 | 
				
			||||||
    if (skel->hasBone("Bip01 spine1")) // in spherearcher.nif
 | 
					    {
 | 
				
			||||||
        node = skel->getBone("Bip01 spine1");
 | 
					        mSpineControllers[i]->setRotate(rotate);
 | 
				
			||||||
    else
 | 
					        mSpineControllers[i]->setEnabled(true);
 | 
				
			||||||
        node = skel->getBone("Bip01 Spine1");
 | 
					    }
 | 
				
			||||||
    node->pitch(Ogre::Radian(-pitch/2), Ogre::Node::TS_WORLD);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,8 @@
 | 
				
			||||||
namespace MWRender
 | 
					namespace MWRender
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class RotateController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class WeaponAnimationTime : public SceneUtil::ControllerSource
 | 
					    class WeaponAnimationTime : public SceneUtil::ControllerSource
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
| 
						 | 
					@ -28,7 +30,7 @@ namespace MWRender
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        WeaponAnimation();
 | 
					        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);
 | 
				
			||||||
| 
						 | 
					@ -36,9 +38,20 @@ namespace MWRender
 | 
				
			||||||
        /// @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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Add WeaponAnimation-related controllers to \a nodes and store the added controllers in \a map.
 | 
				
			||||||
 | 
					        void addControllers(const std::map<std::string, osg::ref_ptr<osg::MatrixTransform> >& nodes,
 | 
				
			||||||
 | 
					                std::multimap<osg::ref_ptr<osg::Node>, osg::ref_ptr<osg::NodeCallback> >& map, osg::Node* objectRoot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void deleteControllers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Configure controllers, should be called every animation frame.
 | 
				
			||||||
 | 
					        void configureControllers(float characterPitchRadians);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
        PartHolderPtr mAmmunition;
 | 
					        PartHolderPtr mAmmunition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        osg::ref_ptr<RotateController> mSpineControllers[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual osg::Group* getArrowBone() = 0;
 | 
					        virtual osg::Group* getArrowBone() = 0;
 | 
				
			||||||
        virtual osg::Node* getWeaponNode() = 0;
 | 
					        virtual osg::Node* getWeaponNode() = 0;
 | 
				
			||||||
        virtual Resource::ResourceSystem* getResourceSystem() = 0;
 | 
					        virtual Resource::ResourceSystem* getResourceSystem() = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue