constraints/CharacterSolver/HIK2013Solver/hikhost.h

constraints/CharacterSolver/HIK2013Solver/hikhost.h
/***************************************************************************************
Autodesk(R) Open Reality(R) Samples
(C) 2012 Autodesk, Inc. and/or its licensors
All rights reserved.
AUTODESK SOFTWARE LICENSE AGREEMENT
Autodesk, Inc. licenses this Software to you only upon the condition that
you accept all of the terms contained in the Software License Agreement ("Agreement")
that is embedded in or that is delivered with this Software. By selecting
the "I ACCEPT" button at the end of the Agreement or by copying, installing,
uploading, accessing or using all or any portion of the Software you agree
to enter into the Agreement. A contract is then formed between Autodesk and
either you personally, if you acquire the Software for yourself, or the company
or other legal entity for which you are acquiring the software.
AUTODESK, INC., MAKES NO WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE REGARDING THESE MATERIALS, AND MAKES SUCH MATERIALS AVAILABLE SOLELY ON AN
"AS-IS" BASIS.
IN NO EVENT SHALL AUTODESK, INC., BE LIABLE TO ANYONE FOR SPECIAL, COLLATERAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING OUT OF PURCHASE
OR USE OF THESE MATERIALS. THE SOLE AND EXCLUSIVE LIABILITY TO AUTODESK, INC.,
REGARDLESS OF THE FORM OF ACTION, SHALL NOT EXCEED THE PURCHASE PRICE OF THE
MATERIALS DESCRIBED HEREIN.
Autodesk, Inc., reserves the right to revise and improve its products as it sees fit.
Autodesk and Open Reality are registered trademarks or trademarks of Autodesk, Inc.,
in the U.S.A. and/or other countries. All other brand names, product names, or
trademarks belong to their respective holders.
GOVERNMENT USE
Use, duplication, or disclosure by the U.S. Government is subject to restrictions as
set forth in FAR 12.212 (Commercial Computer Software-Restricted Rights) and
DFAR 227.7202 (Rights in Technical Data and Computer Software), as applicable.
Manufacturer is Autodesk, Inc., 10 Duke Street, Montreal, Quebec, Canada, H3C 2L7.
***************************************************************************************/
#ifndef __HIKHOST__H_
#define __HIKHOST__H_
#include <humanik/humanik.h>
#include <humanik/hikproperty.h>
#include <humanik/hikutils.h>
// HIK Key
#include <autodeskmwkey.h>
#include "hikdebug.h"
template <bool x> struct KStaticAssertionFailure;
template <> struct KStaticAssertionFailure<true> { enum { value = 1 }; };
template<int x> struct KStaticAssertionTest {};
#define K_STATIC_ASSERT( B ) \
typedef ::KStaticAssertionTest<sizeof( KStaticAssertionFailure< (bool)( B ) > )>\
KStaticAssertionTypedef##__LINE__
const int HIKLastEffectorSetId = 15;
class KHIKNodeState
{
#if defined(_MSC_VER)
typedef float __declspec(align(16)) FloatArray[4];
#elif defined(__GNUC__)
typedef float __attribute__ ((aligned(16))) FloatArray[4];
#endif
public:
FloatArray mTfv;
FloatArray mQfv;
FloatArray mSfv;
};
template<typename HostNode> class HIKHostNode;
template<typename HostProperty> class HIKHostProperty;
template<typename HostNode> class HIKHost;
template<typename HostNode,typename HostProperty> class HIKCharacterHost;
template<typename HostNode> class HIKControlRigHost;
template<typename HostNode,typename HostProperty> class HIKControlRigHostEvaluator;
template<typename HostNode,typename HostProperty> class HIKCharacterHostEvaluator;
template<typename HostNode> class HIKHostNode
{
HostNode mNode;
public:
HostNode& Get() { return mNode; }
bool Valid();
void ReadXForm(double *pXFrom,void *pUserData);
void WriteXForm(double *pXFrom,void *pUserData);
void WriteXFormCandidate(double *pXFrom,void *pUserData);
double ReadReachT(void *pUserData);
double ReadReachR(void *pUserData);
void ReadIKPivot(double *pIkPivot,void *pUserData);
bool GetIKSync();
void GetVector(FBVector3d &retVector,FBModelTransformationType pWhat,bool pGlobalInfo,void *pUserData);
bool GetUseLimits();
int GetRotationOrder();
void GetPreQ(double *pPreQ);
void GetPostQ(double *pPostQ);
int GetMinXYZ(double *pXYZ);
int GetMaxXYZ(double *pXYZ);
};
template<typename HostProperty> class HIKHostProperty
{
HostProperty mProperty;
public:
HostProperty& Get() { return mProperty; }
int ReadMode(void *pUserData);
double ReadValue(void *pUserData);
};
template<typename HostNode> class HIKHost
{
HIKHostNode<HostNode> mNodeArray[LastNodeId];
public:
HIKHostNode<HostNode>& GetNode(int pNodeId) { return mNodeArray[pNodeId]; }
void ReadState(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, void *pUserData, bool pNormalized)
{
double lXForm[16];
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
mNodeArray[lNodeIter].ReadXForm(lXForm,pUserData);
if(pNormalized)
{
HIKSetNodeNormalizedStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
else
{
HIKSetNodeStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
}
}
}
void WriteState(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, void *pUserData, bool pNormalized)
{
double lXForm[16];
// we don't write the reference, we want to be able to offset the Animation
for(int lNodeIter = HipsNodeId; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
HIKGetNodeNormalizedStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
else
{
HIKGetNodeStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
mNodeArray[lNodeIter].WriteXForm(lXForm,pUserData);
}
}
}
void WriteStateCandidate(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, void *pUserData, bool pNormalized)
{
double lXForm[16];
// we don't write the reference, we want to be able to offset the Animation
for(int lNodeIter = HipsNodeId; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
HIKGetNodeNormalizedStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
else
{
HIKGetNodeStatedv(pHIKCharacter, pState,lNodeIter,lXForm);
}
mNodeArray[lNodeIter].WriteXFormCandidate(lXForm,pUserData);
}
}
}
};
template<typename HostNode,typename HostProperty> class HIKCharacterHost : public HIKHost<HostNode>
{
HIKHostProperty<HostProperty> mPropertyArray[HIKLastPropertyId];
HIKHostNode<HostNode> mFloorArray[HIKLastFloorId];
public:
HIKHostProperty<HostProperty>& GetProperty(int pPropertyId) { return mPropertyArray[pPropertyId]; }
HIKHostNode<HostNode>& GetFloorNode(int pFloorId) { return mFloorArray[pFloorId]; }
bool IsRollPropertyToInverse(int pPropertyIndex)
{
// based on FbxCharacter::SetValuesFromLegacyLoad() and the fact that all RollEx are reversed
if( pPropertyIndex == HIKLeftLegRollId || pPropertyIndex == HIKRightLegRollId ||
pPropertyIndex == HIKLeftForeArmRollId || pPropertyIndex == HIKRightForeArmRollId ||
pPropertyIndex == HIKLeftUpLegRollExId || pPropertyIndex == HIKRightUpLegRollExId ||
pPropertyIndex == HIKLeftLegRollExId || pPropertyIndex == HIKRightLegRollExId ||
pPropertyIndex == HIKLeftArmRollExId || pPropertyIndex == HIKRightArmRollExId ||
pPropertyIndex == HIKLeftForeArmRollExId || pPropertyIndex == HIKRightForeArmRollExId )
{
return true;
}
return false;
}
void ReadReference(HIKCharacter *pHIKCharacter, HIKCharacterState *pCharacterState, void *pUserData)
{
double lGX[16];
GetNode(ReferenceNodeId).ReadXForm(lGX,pUserData);
HIKSetNodeStatedv(pHIKCharacter, pCharacterState, ReferenceNodeId, lGX);
}
void ReadPropertySetState(HIKPropertySetState *pPropertyState,void *pUserData)
{
for(int lPropertyIter = 0; lPropertyIter < HIKLastPropertyId; lPropertyIter++)
{
int pMode = mPropertyArray[lPropertyIter].ReadMode(pUserData);
float pValue = float(mPropertyArray[lPropertyIter].ReadValue(pUserData));
//inverse the roll value
if(IsRollPropertyToInverse(lPropertyIter))
{
pValue = 1. - pValue;
}
HIKSetPropertyMode(pPropertyState,lPropertyIter,pMode);
HIKSetPropertyValue(pPropertyState,lPropertyIter,pValue);
}
}
void ReadFloorState(HIKEffectorSetState *pEffectorSetState,void *pUserData)
{
double lXForm[16];
for(int lFloorIter = 0; lFloorIter < HIKLastFloorId; lFloorIter++)
{
GetFloorNode(lFloorIter).ReadXForm(lXForm,pUserData);
HIKSetEffectorFloorStatedv(pEffectorSetState,lFloorIter,lXForm);
}
}
bool IsParentDirect( int pNodeId )
{
if ( GetNode(pNodeId).Valid() )
{
FBModel *lModel = GetNode(pNodeId).Get().mNode;
FBModel *lParent = lModel->Parent;
if (lParent)
{
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
if ( GetNode(lNodeIter).Valid() )
{
lModel = GetNode(lNodeIter).Get().mNode;
if ( lModel == lParent )
return true;
}
}
}
}
return false;
}
HIKCharacter *CharacterCreate(HIKMalloc pMalloc)
{
HIKCharacterDefinition lHIKDef;
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
lHIKDef.mUsedNodes[lNodeIter] = HIKNodeNotUsed;
if(GetNode(lNodeIter).Valid())
{
lHIKDef.mUsedNodes[lNodeIter] |= HIKNodeUsed;
if(GetNode(lNodeIter).GetUseLimits())
{
lHIKDef.mUsedNodes[lNodeIter] |= HIKNodeLimits;
}
// if(!GetNode(lNodeIter).GetParentDirect())
if( !IsParentDirect(lNodeIter) )
{
lHIKDef.mUsedNodes[lNodeIter] |= HIKNodeParentOffset;
}
}
}
HIKCharacter *lHIKCharacter = HIKCharacterCreate(&lHIKDef, pMalloc, AutodeskCustomerString, AutodeskCustomerKey);
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
TransfertRotationsAndLimits(lHIKCharacter, lNodeIter);
}
return lHIKCharacter;
}
void TransfertRotationsAndLimits(HIKCharacter *pHIKCharacter, int pNodeIter)
{
if(GetNode(pNodeIter).Valid())
{
if(GetNode(pNodeIter).GetUseLimits())
{
double lPreQ[4];
double lPostQ[4];
double lMaxXYZ[4];
double lMinXYZ[4];
int lOrder = GetNode(pNodeIter).GetRotationOrder();
int lMinActiveMask = GetNode(pNodeIter).GetMinXYZ(lMinXYZ);
int lMaxActiveMask = GetNode(pNodeIter).GetMaxXYZ(lMaxXYZ);
GetNode(pNodeIter).GetPreQ(lPreQ);
GetNode(pNodeIter).GetPostQ(lPostQ);
HIKSetMinXYZRotationdv(pHIKCharacter,pNodeIter,lMinXYZ,lMinActiveMask);
HIKSetMaxXYZRotationdv(pHIKCharacter,pNodeIter,lMaxXYZ,lMaxActiveMask);
HIKSetRotationOrder(pHIKCharacter,pNodeIter, HIKRotationOrder(lOrder));
HIKSetPreQdv(pHIKCharacter,pNodeIter,lPreQ);
HIKSetPostQdv(pHIKCharacter,pNodeIter,lPostQ);
}
}
}
};
template<typename HostNode> class HIKControlRigHost : public HIKHost<HostNode>
{
HIKHostNode<HostNode> mEffectorArray[LastEffectorId][HIKLastEffectorSetId];
public:
HIKHostNode<HostNode>& GetEffector(int pEffectorId,int pEffectorSetId) { return mEffectorArray[pEffectorId][pEffectorSetId]; }
void ReadEffectorState(HIKEffectorSetState *pEffectorSetState,void *pUserData, bool pFKIK)
{
double lXFormArray[HIKLastEffectorSetId][16];
double lIKPivotArray[HIKLastEffectorSetId][4];
double lReachTArray[HIKLastEffectorSetId];
double lReachRArray[HIKLastEffectorSetId];
for(int lEffectorIter = 0; lEffectorIter < LastEffectorId; lEffectorIter++)
{
for(int lSetIter = 0; lSetIter < HIKLastEffectorSetId; lSetIter++)
{
mEffectorArray[lEffectorIter][lSetIter].ReadXForm(lXFormArray[lSetIter],pUserData);
mEffectorArray[lEffectorIter][lSetIter].ReadIKPivot(lIKPivotArray[lSetIter],pUserData);
lReachTArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachT(pUserData) : 1;
lReachRArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachR(pUserData) : 1;
}
HIKBlendEffectorPivotsdv(pEffectorSetState,lEffectorIter,lXFormArray,lIKPivotArray,lReachTArray,lReachRArray,HIKLastEffectorSetId);
}
}
void WriteEffectorState(HIKEffectorSetState *pEffectorSetState, void * pUserData, int pSetIndex)
{
int lIter = 0;
for(lIter = 0; lIter < LastEffectorId; lIter++)
{
if(pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
FBTVector lIKPivot;
HIKGetEffectorStateTQSdv(pEffectorSetState, lIter, lT.mValue, lQ.mValue, lS.mValue);
mEffectorArray[lIter][pSetIndex].ReadIKPivot(lIKPivot.mValue,pUserData);
if( lIKPivot.mValue[0] != 0.0 ||
lIKPivot.mValue[1] != 0.0 ||
lIKPivot.mValue[2] != 0.0)
{
FBSVector lPivotGSVector;
mEffectorArray[lIter][pSetIndex].GetVector(lPivotGSVector, kModelScaling, true, pUserData);
lIKPivot.mValue[0] *= lPivotGSVector.mValue[0];
lIKPivot.mValue[1] *= lPivotGSVector.mValue[1];
lIKPivot.mValue[2] *= lPivotGSVector.mValue[2];
FBMatrix lGRM;
FBRotationToMatrix(lGRM, lR);
FBVectorMatrixMult(lIKPivot,lGRM,lIKPivot);
FBSub(lIKPivot,lT,lIKPivot);
}
else
{
lIKPivot = lT;
}
FBMatrix lMat;
FBSVector l3dS(lS.mValue[0], lS.mValue[1], lS.mValue[2]);
FBTRSToMatrix(lMat, lIKPivot, lR, l3dS);
mEffectorArray[lIter][pSetIndex].WriteXForm(lMat, pUserData);
}
}
}
void WriteEffectorStateCandidate(HIKEffectorSetState *pEffectorSetState, void * pUserData, int pSetIndex)
{
int lIter = 0;
for(lIter = 0; lIter < LastEffectorId; lIter++)
{
if(pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
FBTVector lIKPivot;
HIKGetEffectorStateTQSdv(pEffectorSetState, lIter, lT.mValue, lQ.mValue, lS.mValue);
mEffectorArray[lIter][pSetIndex].ReadIKPivot(lIKPivot.mValue,pUserData);
if( lIKPivot.mValue[0] != 0.0 ||
lIKPivot.mValue[1] != 0.0 ||
lIKPivot.mValue[2] != 0.0)
{
FBSVector lPivotGSVector;
mEffectorArray[lIter][pSetIndex].GetVector(lPivotGSVector, kModelScaling, true, pUserData);
lIKPivot.mValue[0] *= lPivotGSVector.mValue[0];
lIKPivot.mValue[1] *= lPivotGSVector.mValue[1];
lIKPivot.mValue[2] *= lPivotGSVector.mValue[2];
FBMatrix lGRM;
FBRotationToMatrix(lGRM, lR);
FBVectorMatrixMult(lIKPivot,lGRM,lIKPivot);
FBSub(lIKPivot,lT,lIKPivot);
}
else
{
lIKPivot = lT;
}
FBMatrix lMat;
FBSVector l3dS(lS.mValue[0], lS.mValue[1], lS.mValue[2]);
FBTRSToMatrix(lMat, lIKPivot, lR, l3dS);
mEffectorArray[lIter][pSetIndex].WriteXFormCandidate(lMat, pUserData);
}
}
}
void WriteEffectors(HIKEffectorSetState *pEffectorSetState, void * pUserData, bool pCandidate)
{
if(pCandidate)
{
for(int lSetIter = 0; lSetIter < FBLastEffectorSetIndex; lSetIter++)
{
WriteEffectorStateCandidate(pEffectorSetState,pUserData,lSetIter);
}
}
else
{
for(int lSetIter = 0; lSetIter < FBLastEffectorSetIndex; lSetIter++)
{
WriteEffectorState(pEffectorSetState,pUserData,lSetIter);
}
}
}
};
struct HIKEvaluationState
{
HIKEvaluationState()
{
//character part
mStateDst = NULL;
mStateSrc = NULL;
mEffectorSetState = NULL;
mDstPropertySetState = NULL;
mSrcPropertySetState = NULL;
mEvaluateId = -1;
//control rig part
mCRState = NULL;
mCREffectorSetState = NULL;
mCRPropertySetState = NULL;
}
virtual ~HIKEvaluationState()
{
Clear(&free);
}
void Init(HIKCharacter *pHIKCharacterDst, HIKCharacter *pHIKCharacterSrc, bool pInitCR, HIKMalloc pMalloc)
{
mStateDst = HIKCharacterStateCreate(pHIKCharacterDst,pMalloc);
mStateSrc = (pHIKCharacterSrc) ? HIKCharacterStateCreate(pHIKCharacterSrc,pMalloc) : NULL;
mEffectorSetState = HIKEffectorSetStateCreate(pMalloc);
mDstPropertySetState = HIKPropertySetStateCreate(pMalloc);
mSrcPropertySetState = HIKPropertySetStateCreate(pMalloc);
if(pInitCR)
{
mCRState = HIKCharacterStateCreate(pHIKCharacterDst,pMalloc);
mCREffectorSetState = HIKEffectorSetStateCreate(pMalloc);
mCRPropertySetState = HIKPropertySetStateCreate(pMalloc);
}
}
void Clear(HIKFree pFree)
{
if(mStateDst != 0)
{
HIKCharacterStateDestroy(mStateDst,pFree);
mStateDst = 0;
}
if(mStateSrc != 0)
{
HIKCharacterStateDestroy(mStateSrc,pFree);
mStateSrc = 0;
}
if(mEffectorSetState != 0)
{
HIKEffectorSetStateDestroy(mEffectorSetState,pFree);
mEffectorSetState = 0;
}
if(mDstPropertySetState != 0)
{
HIKPropertySetStateDestroy(mDstPropertySetState,pFree);
mDstPropertySetState = 0;
}
if(mSrcPropertySetState != 0)
{
HIKPropertySetStateDestroy(mSrcPropertySetState,pFree);
mSrcPropertySetState = 0;
}
if(mCRState != 0)
{
HIKCharacterStateDestroy(mCRState,pFree);
mCRState = 0;
}
if(mCREffectorSetState != 0)
{
HIKEffectorSetStateDestroy(mCREffectorSetState,pFree);
mCREffectorSetState = 0;
}
if(mCRPropertySetState != 0)
{
HIKPropertySetStateDestroy(mCRPropertySetState,pFree);
mCRPropertySetState = 0;
}
mEvaluateId = -1;
}
//character part
HIKCharacterState* mStateDst;
HIKCharacterState* mStateSrc;
HIKEffectorSetState* mEffectorSetState;
HIKPropertySetState* mDstPropertySetState;
HIKPropertySetState* mSrcPropertySetState;
//control rig part
HIKCharacterState* mCRState;
HIKEffectorSetState* mCREffectorSetState;
HIKPropertySetState* mCRPropertySetState;
//last evaluation id - used to block recursive calls.
int mEvaluateId;
};
class MultiState
{
HIKEvaluationState** mMultiState;
int mStateCount;
public:
MultiState()
{
mMultiState = NULL;
mStateCount = 0;
}
virtual ~MultiState()
{
ClearStates();
}
void ClearStates()
{
//not locked, but should not be needed.
for (int Count=0; Count<mStateCount; Count++)
{
K_SAFE_DELETE_PTR(mMultiState[Count]);
}
mStateCount = 0;
K_SAFE_FREE_PTR(mMultiState);
}
HIKEvaluationState* GetState(FBEvaluateInfo* pEvaluateInfo)
{
int lIndex = pEvaluateInfo->GetDeviceID() == 0 ? 1 : 0;
return GetState(lIndex);
}
HIKEvaluationState* GetState(int pIndex)
{
if(pIndex >= mStateCount)
{
static FBFastLock sLock;
sLock.Lock();
{
if(pIndex >= mStateCount)
{
int NewCount = pIndex + 1;
mMultiState = (HIKEvaluationState**)realloc( mMultiState,NewCount*sizeof(HIKEvaluationState*) );
for (int Count=mStateCount; Count<NewCount; Count++)
{
mMultiState[Count] = EvaluationStateCreator();
}
mStateCount = NewCount;
}
}
sLock.Unlock();
}
return mMultiState[pIndex];
}
virtual HIKEvaluationState* EvaluationStateCreator() = 0;
};
template<typename HostNode,typename HostProperty> class HIKControlRigHostEvaluator
{
public:
HIKCharacter *mHIKCharacter;
HIKCharacterHost<HostNode,HostProperty> *mHIKCharacterHost;
HIKControlRigHost<HostNode> *mHIKControlRigHost;
int mSolvingStep;
HIKControlRigHostEvaluator()
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
mSolvingStep = HIKSolvingStepAll;
}
void SetSolvingStep( int pSolvingState )
{
mSolvingStep = pSolvingState;
}
void Init(HIKCharacter *pHIKCharacter,HIKCharacterHost<HostNode,HostProperty> *pHIKCharacterHost,HIKControlRigHost<HostNode> *pHIKControlRigHost,HIKMalloc pMalloc)
{
mHIKCharacter = pHIKCharacter;
mHIKCharacterHost = pHIKCharacterHost;
mHIKControlRigHost = pHIKControlRigHost;
}
void Clear(HIKFree pFree)
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
}
void Read(void *pUserData, bool pFKIK, HIKEvaluationState* pState)
{
if(pFKIK)
mHIKControlRigHost->ReadState(mHIKCharacter, pState->mCRState,pUserData,true);
else
HIKGetRelaxPose(mHIKCharacter, pState->mCRState);
mHIKControlRigHost->ReadEffectorState(pState->mCREffectorSetState,pUserData,pFKIK);
mHIKCharacterHost->ReadPropertySetState(pState->mCRPropertySetState,pUserData);
mHIKCharacterHost->ReadFloorState(pState->mCREffectorSetState,pUserData);
TransfertPropertiesPullResistToEffectorSet(pState);
}
void Solve(HIKEvaluationState* pState)
{
HIKSetIKSolvingStep(pState->mCREffectorSetState, mSolvingStep);
HIKSolveForEffectorSet(mHIKCharacter,pState->mCRState,pState->mCREffectorSetState, pState->mCRPropertySetState);
}
void Write(void *pUserData, HIKEvaluationState* pState, bool pRigAlign=false)
{
mHIKCharacterHost->WriteState(mHIKCharacter, pState->mCRState,pUserData,false);
if(pRigAlign)
{
EffectorStateFromControlSet(pState);
mHIKControlRigHost->WriteEffectors(pState->mCREffectorSetState, pUserData, false);
mHIKControlRigHost->WriteState(mHIKCharacter, pState->mCRState, pUserData, true);
}
}
void WriteCandidate(void *pUserData, HIKEvaluationState* pState)
{
mHIKCharacterHost->WriteStateCandidate(mHIKCharacter, pState->mCRState,pUserData,false);
}
void WriteRigCandidate(void *pUserData, HIKEvaluationState* pState)
{
mHIKControlRigHost->WriteEffectors(pState->mCREffectorSetState, pUserData, true);
mHIKControlRigHost->WriteStateCandidate(mHIKCharacter, pState->mCRState, pUserData, true);
}
void Evaluate(void *pUserData, HIKEvaluationState* pState)
{
if(mHIKCharacter != 0)
{
Read(pUserData,pState);
Solve(pState);
Write(pUserData,pState);
}
}
void EffectorStateFromControlSet(HIKEvaluationState* pState)
{
HIKEffectorSetFromCharacter(mHIKCharacter, pState->mCREffectorSetState, pState->mCRState, pState->mCRPropertySetState);
}
void TransfertPropertiesPullResistToEffectorSet(HIKEvaluationState* pState)
{
HIKSetEffectorPullResistFromPropertyState(pState->mCREffectorSetState, pState->mCRPropertySetState);
}
void ReadSkeletonSolveOnRig(void *pUserData, HIKEvaluationState* pState)
{
// Read Skeleton and Settings
mHIKCharacterHost->ReadState( mHIKCharacter, pState->mCRState, pUserData, false);
mHIKCharacterHost->ReadPropertySetState( pState->mCRPropertySetState, pUserData);
mHIKCharacterHost->ReadFloorState( pState->mCREffectorSetState, pUserData);
TransfertPropertiesPullResistToEffectorSet(pState);
// solver back on Rig
EffectorStateFromControlSet(pState);
}
};
template<typename HostNode,typename HostProperty> class HIKCharacterHostEvaluator
{
public:
HIKCharacter *mHIKCharacterDst;
HIKCharacterHost<HostNode,HostProperty> *mHIKCharacterHostDst;
HIKCharacter *mHIKCharacterSrc;
HIKCharacterHost<HostNode,HostProperty> *mHIKCharacterHostSrc;
int mSolvingStep;
HIKCharacterHostEvaluator()
{
mHIKCharacterDst = 0;
mHIKCharacterHostDst = 0;
mHIKCharacterSrc = 0;
mHIKCharacterHostSrc = 0;
mSolvingStep = HIKSolvingStepAll;
}
void SetSolvingStep( int pSolvingState )
{
mSolvingStep = pSolvingState;
}
void Init(HIKCharacter *pHIKCharacterDst,HIKCharacterHost<HostNode,HostProperty> *pHIKCharacterHostDst,HIKCharacter *pHIKCharacterSrc,HIKCharacterHost<HostNode,HostProperty> *pHIKCharacterHostSrc,HIKMalloc pMalloc)
{
mHIKCharacterDst = pHIKCharacterDst;
mHIKCharacterHostDst = pHIKCharacterHostDst;
mHIKCharacterSrc = pHIKCharacterSrc;
mHIKCharacterHostSrc = pHIKCharacterHostSrc;
}
void Clear(HIKFree pFree)
{
mHIKCharacterDst = 0;
mHIKCharacterHostDst = 0;
mHIKCharacterSrc = 0;
mHIKCharacterHostSrc = 0;
}
void Read(void *pUserData, HIKEvaluationState* pState)
{
if(mHIKCharacterHostSrc != NULL)
{
mHIKCharacterHostSrc->ReadState(mHIKCharacterSrc, pState->mStateSrc,pUserData,false);
mHIKCharacterHostSrc->ReadPropertySetState(pState->mSrcPropertySetState,pUserData);
}
mHIKCharacterHostDst->ReadPropertySetState(pState->mDstPropertySetState,pUserData);
mHIKCharacterHostDst->ReadFloorState(pState->mEffectorSetState,pUserData);
mHIKCharacterHostDst->ReadReference(mHIKCharacterDst, pState->mStateDst, pUserData);
}
void Solve(HIKEvaluationState* pState)
{
HIKSetIKSolvingStep(pState->mEffectorSetState, mSolvingStep);
HIKSolveForCharacter(mHIKCharacterDst,pState->mStateDst,mHIKCharacterSrc,pState->mStateSrc,pState->mEffectorSetState, pState->mDstPropertySetState, pState->mSrcPropertySetState);
}
void Write(void *pUserData, HIKEvaluationState* pState, bool pNormalized = false)
{
mHIKCharacterHostDst->WriteState(mHIKCharacterDst, pState->mStateDst,pUserData,pNormalized);
}
void Evaluate(void *pUserData, HIKEvaluationState* pState)
{
if(mHIKCharacterDst != 0)
{
Read(pUserData, pState);
Solve(pState);
Write(pUserData, pState);
}
}
};
#endif