#ifndef __HIKHOST__H_
#define __HIKHOST__H_
#include <humanik/humanik.h>
#include <humanik/hikproperty.h>
#include <humanik/hikutils.h>
#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();
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];
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];
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)
{
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));
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( !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())
{
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;
FBSub(lIKPivot,lT,lIKPivot);
}
else
{
lIKPivot = lT;
}
FBMatrix lMat;
FBSVector l3dS(lS.mValue[0], lS.mValue[1], lS.mValue[2]);
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())
{
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;
FBSub(lIKPivot,lT,lIKPivot);
}
else
{
lIKPivot = lT;
}
FBMatrix lMat;
FBSVector l3dS(lS.mValue[0], lS.mValue[1], lS.mValue[2]);
mEffectorArray[lIter][pSetIndex].WriteXFormCandidate(lMat, pUserData);
}
}
}
void WriteEffectors(HIKEffectorSetState *pEffectorSetState, void * pUserData, bool pCandidate)
{
if(pCandidate)
{
{
WriteEffectorStateCandidate(pEffectorSetState,pUserData,lSetIter);
}
}
else
{
{
WriteEffectorState(pEffectorSetState,pUserData,lSetIter);
}
}
}
};
struct HIKEvaluationState
{
HIKEvaluationState()
{
mEffectorSetState =
NULL;
mDstPropertySetState =
NULL;
mSrcPropertySetState =
NULL;
mEvaluateId = -1;
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;
}
HIKCharacterState* mStateDst;
HIKCharacterState* mStateSrc;
HIKEffectorSetState* mEffectorSetState;
HIKPropertySetState* mDstPropertySetState;
HIKPropertySetState* mSrcPropertySetState;
HIKCharacterState* mCRState;
HIKEffectorSetState* mCREffectorSetState;
HIKPropertySetState* mCRPropertySetState;
int mEvaluateId;
};
class MultiState
{
HIKEvaluationState** mMultiState;
int mStateCount;
public:
MultiState()
{
mStateCount = 0;
}
virtual ~MultiState()
{
ClearStates();
}
void ClearStates()
{
for (int Count=0; Count<mStateCount; Count++)
{
}
mStateCount = 0;
}
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)
{
mHIKCharacterHost->ReadState( mHIKCharacter, pState->mCRState, pUserData, false);
mHIKCharacterHost->ReadPropertySetState( pState->mCRPropertySetState, pUserData);
mHIKCharacterHost->ReadFloorState( pState->mCREffectorSetState, pUserData);
TransfertPropertiesPullResistToEffectorSet(pState);
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