mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-31 10:20:13 +00:00
Update the object position as the animation moves
This commit is contained in:
parent
7ba09ff025
commit
5b3a20ef69
@ -7,6 +7,9 @@
|
|||||||
#include <OgreSubMesh.h>
|
#include <OgreSubMesh.h>
|
||||||
#include <OgreSceneManager.h>
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -16,8 +19,14 @@ Animation::Animation(const MWWorld::Ptr &ptr)
|
|||||||
, mTime(0.0f)
|
, mTime(0.0f)
|
||||||
, mAnimState(NULL)
|
, mAnimState(NULL)
|
||||||
, mSkipFrame(false)
|
, mSkipFrame(false)
|
||||||
|
, mAccumRoot(NULL)
|
||||||
, mNonAccumRoot(NULL)
|
, mNonAccumRoot(NULL)
|
||||||
|
, mLastPosition(0.0f)
|
||||||
{
|
{
|
||||||
|
mCurGroup.mStart = mCurGroup.mLoopStart = 0.0f;
|
||||||
|
mCurGroup.mLoopStop = mCurGroup.mStop = 0.0f;
|
||||||
|
mNextGroup.mStart = mNextGroup.mLoopStart = 0.0f;
|
||||||
|
mNextGroup.mLoopStop = mNextGroup.mStop = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Animation::~Animation()
|
Animation::~Animation()
|
||||||
@ -52,9 +61,10 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
|
|||||||
mAnimState = state;
|
mAnimState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::SkeletonInstance *skelinst = mEntityList.mSkelBase->getSkeleton();
|
||||||
// Would be nice if Ogre::SkeletonInstance allowed access to the 'master' Ogre::SkeletonPtr.
|
// Would be nice if Ogre::SkeletonInstance allowed access to the 'master' Ogre::SkeletonPtr.
|
||||||
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
|
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
|
||||||
Ogre::SkeletonPtr skel = skelMgr.getByName(mEntityList.mSkelBase->getSkeleton()->getName());
|
Ogre::SkeletonPtr skel = skelMgr.getByName(skelinst->getName());
|
||||||
Ogre::Skeleton::BoneIterator iter = skel->getBoneIterator();
|
Ogre::Skeleton::BoneIterator iter = skel->getBoneIterator();
|
||||||
while(iter.hasMoreElements())
|
while(iter.hasMoreElements())
|
||||||
{
|
{
|
||||||
@ -63,7 +73,10 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
|
|||||||
if(!data.isEmpty())
|
if(!data.isEmpty())
|
||||||
{
|
{
|
||||||
mTextKeys = Ogre::any_cast<NifOgre::TextKeyMap>(data);
|
mTextKeys = Ogre::any_cast<NifOgre::TextKeyMap>(data);
|
||||||
mNonAccumRoot = mEntityList.mSkelBase->getSkeleton()->getBone(bone->getHandle());
|
mAccumRoot = skelinst->getRootBone();
|
||||||
|
mAccumRoot->setManuallyControlled(true);
|
||||||
|
mNonAccumRoot = skelinst->getBone(bone->getHandle());
|
||||||
|
mLastPosition = mNonAccumRoot->getPosition();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,6 +84,43 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Animation::updatePosition(float time)
|
||||||
|
{
|
||||||
|
mAnimState->setTimePosition(time);
|
||||||
|
if(mNonAccumRoot)
|
||||||
|
{
|
||||||
|
/* Update the animation and get the non-accumulation root's difference from the
|
||||||
|
* last update. */
|
||||||
|
mEntityList.mSkelBase->getSkeleton()->setAnimationState(*mAnimState->getParent());
|
||||||
|
Ogre::Vector3 posdiff = mNonAccumRoot->getPosition() - mLastPosition;
|
||||||
|
|
||||||
|
/* Translate the accumulation root back to compensate for the move. */
|
||||||
|
mAccumRoot->translate(-posdiff);
|
||||||
|
mLastPosition += posdiff;
|
||||||
|
|
||||||
|
/* Finally, move the object based on how much the non-accumulation root moved. */
|
||||||
|
Ogre::Vector3 newpos(mPtr.getRefData().getPosition().pos);
|
||||||
|
newpos += mInsert->getOrientation() * posdiff;
|
||||||
|
|
||||||
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
world->moveObject(mPtr, newpos.x, newpos.y, newpos.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::resetPosition(float time)
|
||||||
|
{
|
||||||
|
mAnimState->setTimePosition(time);
|
||||||
|
if(mNonAccumRoot)
|
||||||
|
{
|
||||||
|
mEntityList.mSkelBase->getSkeleton()->setAnimationState(*mAnimState->getParent());
|
||||||
|
mLastPosition = mNonAccumRoot->getPosition();
|
||||||
|
/* FIXME: This should be set to -mLastPosition, but without proper collision the
|
||||||
|
* model gets placed halfway into the ground. */
|
||||||
|
mAccumRoot->setPosition(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct checklow {
|
struct checklow {
|
||||||
bool operator()(const char &a, const char &b) const
|
bool operator()(const char &a, const char &b) const
|
||||||
{
|
{
|
||||||
@ -145,6 +195,7 @@ void Animation::playGroup(std::string groupname, int mode, int loops)
|
|||||||
mCurGroup = times;
|
mCurGroup = times;
|
||||||
mNextGroup = GroupTimes();
|
mNextGroup = GroupTimes();
|
||||||
mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart);
|
mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart);
|
||||||
|
resetPosition(mTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,29 +206,36 @@ void Animation::skipAnim()
|
|||||||
|
|
||||||
void Animation::runAnimation(float timepassed)
|
void Animation::runAnimation(float timepassed)
|
||||||
{
|
{
|
||||||
if(mCurGroup.mLoops > 0 && !mSkipFrame)
|
if(mAnimState && !mSkipFrame)
|
||||||
{
|
{
|
||||||
mTime += timepassed;
|
mTime += timepassed;
|
||||||
|
recheck:
|
||||||
if(mTime >= mCurGroup.mLoopStop)
|
if(mTime >= mCurGroup.mLoopStop)
|
||||||
{
|
{
|
||||||
if(mCurGroup.mLoops > 1)
|
if(mCurGroup.mLoops > 1)
|
||||||
{
|
{
|
||||||
mCurGroup.mLoops--;
|
mCurGroup.mLoops--;
|
||||||
|
updatePosition(mCurGroup.mLoopStop);
|
||||||
mTime = mTime - mCurGroup.mLoopStop + mCurGroup.mLoopStart;
|
mTime = mTime - mCurGroup.mLoopStop + mCurGroup.mLoopStart;
|
||||||
|
resetPosition(mCurGroup.mLoopStart);
|
||||||
|
goto recheck;
|
||||||
}
|
}
|
||||||
else if(mTime >= mCurGroup.mStop)
|
else if(mTime >= mCurGroup.mStop)
|
||||||
{
|
{
|
||||||
if(mNextGroup.mLoops > 0)
|
if(mNextGroup.mLoops > 0)
|
||||||
|
{
|
||||||
|
updatePosition(mCurGroup.mStop);
|
||||||
mTime = mTime - mCurGroup.mStop + mNextGroup.mStart;
|
mTime = mTime - mCurGroup.mStop + mNextGroup.mStart;
|
||||||
else
|
resetPosition(mNextGroup.mStart);
|
||||||
mTime = mCurGroup.mStop;
|
mCurGroup = mNextGroup;
|
||||||
mCurGroup = mNextGroup;
|
mNextGroup = GroupTimes();
|
||||||
mNextGroup = GroupTimes();
|
goto recheck;
|
||||||
|
}
|
||||||
|
mTime = mCurGroup.mStop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mAnimState)
|
updatePosition(mTime);
|
||||||
mAnimState->setTimePosition(mTime);
|
|
||||||
}
|
}
|
||||||
mSkipFrame = false;
|
mSkipFrame = false;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,16 @@ protected:
|
|||||||
|
|
||||||
NifOgre::EntityList mEntityList;
|
NifOgre::EntityList mEntityList;
|
||||||
NifOgre::TextKeyMap mTextKeys;
|
NifOgre::TextKeyMap mTextKeys;
|
||||||
Ogre::Node *mNonAccumRoot;
|
Ogre::Bone *mAccumRoot;
|
||||||
|
Ogre::Bone *mNonAccumRoot;
|
||||||
|
Ogre::Vector3 mLastPosition;
|
||||||
|
|
||||||
|
/* Updates the animation to the specified time, and moves the mPtr object
|
||||||
|
* based on the change since the last update or reset. */
|
||||||
|
void updatePosition(float time);
|
||||||
|
/* Updates the animation to the specified time, without moving the mPtr
|
||||||
|
* object. */
|
||||||
|
void resetPosition(float time);
|
||||||
|
|
||||||
bool findGroupTimes(const std::string &groupname, GroupTimes *times);
|
bool findGroupTimes(const std::string &groupname, GroupTimes *times);
|
||||||
|
|
||||||
|
@ -138,7 +138,6 @@ namespace MWRender
|
|||||||
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
|
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview);
|
||||||
|
|
||||||
mAnimation->playGroup ("inventoryhandtohand", 0, 1);
|
mAnimation->playGroup ("inventoryhandtohand", 0, 1);
|
||||||
mAnimation->runAnimation (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user