Reset joint positions after detaching a rigged model

meow-7.2.2
prep linden 2010-10-05 14:14:37 -04:00
parent 7be98bc20f
commit 70b2ace131
6 changed files with 85 additions and 4 deletions

View File

@ -239,6 +239,17 @@ void LLJoint::setPosition( const LLVector3& pos )
}
}
//--------------------------------------------------------------------
// setPosition()
//--------------------------------------------------------------------
void LLJoint::setDefaultFromCurrentXform( void )
{
mDefaultXform = mXform;
touch(MATRIX_DIRTY | POSITION_DIRTY);
}
//--------------------------------------------------------------------
// storeCurrentXform()
//--------------------------------------------------------------------
@ -254,6 +265,14 @@ void LLJoint::restoreOldXform( void )
{
mXform = mOldXform;
}
//--------------------------------------------------------------------
// restoreOldXform()
//--------------------------------------------------------------------
void LLJoint::restoreToDefaultXform( void )
{
mXform = mDefaultXform;
setPosition( mXform.getPosition() );
}
//--------------------------------------------------------------------
// getWorldPosition()

View File

@ -87,6 +87,7 @@ protected:
// explicit transformation members
LLXformMatrix mXform;
LLXformMatrix mOldXform;
LLXformMatrix mDefaultXform;
public:
U32 mDirtyFlags;
@ -137,7 +138,9 @@ public:
// get/set local position
const LLVector3& getPosition();
void setPosition( const LLVector3& pos );
void setDefaultPosition( const LLVector3& pos );
// get/set world position
LLVector3 getWorldPosition();
LLVector3 getLastWorldPosition();
@ -181,6 +184,9 @@ public:
void setJointNum(S32 joint_num) { mJointNum = joint_num; }
void restoreOldXform( void );
void restoreToDefaultXform( void );
void setDefaultFromCurrentXform( void );
void storeCurrentXform( const LLVector3& pos );
};
#endif // LL_LLJOINT_H

View File

@ -1631,7 +1631,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
joint->setDefaultFromCurrentXform();
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
@ -4784,6 +4785,38 @@ void LLVOAvatar::resetJointPositions( void )
mSkeleton[i].restoreOldXform();
}
}
//-----------------------------------------------------------------------------
// resetJointPositionsToDefault
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsToDefault( void )
{
const LLVector3& avPos = getCharacterPosition();
//Reposition the pelvis
LLJoint* pPelvis = mRoot.findJoint("mPelvis");
if ( pPelvis )
{
pPelvis->setPosition( avPos + pPelvis->getPosition() );
}
else
{
llwarns<<"Can't get pelvis joint."<<llendl;
return;
}
//Subsequent joints are relative to pelvis
for( S32 i = 0; i < (S32)mNumJoints; ++i )
{
LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
//restore joints to default positions, however skip over the pelvis
if ( pJoint && pPelvis != pJoint )
{
pJoint->restoreToDefaultXform();
}
}
}
//-----------------------------------------------------------------------------
// getCharacterPosition()
//-----------------------------------------------------------------------------

View File

@ -171,6 +171,7 @@ public:
virtual LLJoint* getRootJoint() { return &mRoot; }
void resetJointPositions( void );
void resetJointPositionsToDefault( void );
virtual const char* getAnimationPrefix() { return "avatar"; }
virtual const LLUUID& getID();

View File

@ -62,6 +62,8 @@
#include "llviewerstats.h"
#include "llviewerregion.h"
#include "llappearancemgr.h"
#include "llmeshrepository.h"
#include "llvovolume.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@ -655,6 +657,10 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
return LLVOAvatar::getJoint(name);
}
void LLVOAvatarSelf::resetJointPositions( void )
{
return LLVOAvatar::resetJointPositionsToDefault();
}
// virtual
BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
{
@ -1119,8 +1125,22 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
{
const LLUUID attachment_id = viewer_object->getAttachmentItemID();
if (LLVOAvatar::detachObject(viewer_object))
if ( LLVOAvatar::detachObject(viewer_object) )
{
//If a VO has a skin that we'll reset the joint positions to their default
if ( viewer_object->mDrawable )
{
LLVOVolume* pVObj = viewer_object->mDrawable->getVOVolume();
if ( pVObj )
{
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() );
if ( pSkinData )
{
resetJointPositions();
}
}
}
// the simulator should automatically handle permission revocation
stopMotionFromSource(attachment_id);

View File

@ -83,7 +83,9 @@ public:
/*virtual*/ void stopMotionFromSource(const LLUUID& source_id);
/*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name);
void resetJointPositions( void );
/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );