#ifndef __HIKHOST__H_
#define __HIKHOST__H_
#include <humanik/humanik.h>
#include <humanik/hikproperty.h>
#include <humanik/hikutils.h>
#include <autodeskmwkey.h>
#include "hikdebug.h"
#include "filterset2fbcharacter.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__
#ifdef _DEBUG
#define OR_HIK_ASSERT( pCondition ) assert( pCondition );
#else
#define OR_HIK_ASSERT( pCondition );
#endif
#ifndef _WIN32
#ifdef __MACH__
#define _aligned_malloc(size, alignment) malloc(size) // No alignement is necessary on OSX, it is automatically 16 bytes.
#else
#define _aligned_malloc(size, alignment) memalign(alignment, size)
#endif
#define _aligned_free(p) free(p)
#endif
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;
};
enum{ eNoRecursion = 0, eRecursiveT = 1 << 0, eRecursiveR = 1 << 1, eRecursiveS = 1 << 2 };
struct HIKEvaluationState
{
HIKEvaluationState()
{
mSrcEffectorSetState =
NULL;
mSrcPropertySetState =
NULL;
mEffectorSetState =
NULL;
mPropertySetState =
NULL;
mDirtyFlag = true;
mEvaluateId = -1;
}
virtual ~HIKEvaluationState()
{
Clear(&free);
}
void Init(HIKCharacter *pHIKCharacterDst, HIKCharacter *pHIKCharacterSrc, HIKMalloc pMalloc)
{
mSrcState = (pHIKCharacterSrc) ? HIKCharacterStateCreate(pHIKCharacterSrc,pMalloc) :
NULL;
mSrcEffectorSetState = HIKEffectorSetStateCreate(pMalloc);
mSrcPropertySetState = HIKPropertySetStateCreate(pMalloc);
mState = HIKCharacterStateCreate(pHIKCharacterDst,pMalloc);
mEffectorSetState = HIKEffectorSetStateCreate(pMalloc);
mPropertySetState = HIKPropertySetStateCreate(pMalloc);
mDataSet = (KHIKNodeState*)_aligned_malloc( sizeof(KHIKNodeState) * LastNodeId, 16);
}
void Clear(HIKFree pFree)
{
if(mSrcState != 0)
{
HIKCharacterStateDestroy(mSrcState,pFree);
mSrcState = 0;
}
if(mSrcEffectorSetState != 0)
{
HIKEffectorSetStateDestroy(mSrcEffectorSetState,pFree);
mSrcEffectorSetState = 0;
}
if(mSrcPropertySetState != 0)
{
HIKPropertySetStateDestroy(mSrcPropertySetState,pFree);
mSrcPropertySetState = 0;
}
if(mState != 0)
{
HIKCharacterStateDestroy(mState,pFree);
mState = 0;
}
if(mEffectorSetState != 0)
{
HIKEffectorSetStateDestroy(mEffectorSetState,pFree);
mEffectorSetState = 0;
}
if(mPropertySetState != 0)
{
HIKPropertySetStateDestroy(mPropertySetState,pFree);
mPropertySetState = 0;
}
if(mDataSet != 0)
{
_aligned_free(mDataSet);
mDataSet = 0;
}
mEvaluateId = -1;
mDirtyFlag = true;
}
HIKCharacterState* mSrcState;
HIKEffectorSetState* mSrcEffectorSetState;
HIKPropertySetState* mSrcPropertySetState;
HIKCharacterState* mState;
HIKEffectorSetState* mEffectorSetState;
HIKPropertySetState* mPropertySetState;
KHIKNodeState* mDataSet;
int mEvaluateId;
bool mDirtyFlag;
int mEvaluatedEffectorId;
int mRecursiveFlag[LastEffectorId];
};
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, FBBox* pCaller)
{
int lIndex = pEvaluateInfo->GetBufferID(pCaller);
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> 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, FBEvaluateInfo* pEvalInfo);
void WriteXForm(double *pXFrom, FBEvaluateInfo* pEvalInfo);
void WriteXFormCandidate(double *pXFrom, FBEvaluateInfo* pEvalInfo);
int IsEvaluationRecursiveTQS(FBEvaluateInfo* pEvalInfo);
double ReadReachT( FBEvaluateInfo* pEvalInfo );
double ReadReachR( FBEvaluateInfo* pEvalInfo );
void ReadIKPivot(double *pIkPivot, FBEvaluateInfo* pEvalInfo);
bool GetIKSync();
bool GetUseTranslationLimits();
bool GetUseRotationLimits();
int GetRotationOrder();
void GetPreQ(double *pPreQ);
void GetPostQ(double *pPostQ);
int GetRotationMinXYZ(double *pXYZ);
int GetRotationMaxXYZ(double *pXYZ);
int GetTranslationMinXYZ(double *pXYZ);
int GetTranslationMaxXYZ(double *pXYZ);
};
template<typename HostProperty> class HIKHostProperty
{
HostProperty mProperty;
public:
HostProperty& Get() { return mProperty; }
int ReadMode( FBEvaluateInfo* pEvalInfo );
double ReadValue( FBEvaluateInfo* pEvalInfo );
};
template<typename HostNode> class HIKHost
{
HIKHostNode<HostNode> mNodeArray[LastNodeId];
public:
HIKHostNode<HostNode>& GetNode(int pNodeId) { return mNodeArray[pNodeId]; }
void ReadState(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, FBEvaluateInfo* pEvalInfo, bool pNormalized)
{
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
mNodeArray[lNodeIter].ReadTQS(lT, lQ, lS, pEvalInfo);
if(pNormalized)
{
HIKSetNodeNormalizedStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
else
{
HIKSetNodeStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
}
}
}
void WriteState(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, FBEvaluateInfo* pEvalInfo, bool pNormalized)
{
for(int lNodeIter = HipsNodeId; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
HIKGetNodeNormalizedStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
else
{
HIKGetNodeStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
mNodeArray[lNodeIter].WriteTQS(lT, lQ, lS,pEvalInfo);
}
}
}
void WriteStateCandidate(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, FBEvaluateInfo* pEvalInfo, bool pNormalized)
{
for(int lNodeIter = HipsNodeId; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
HIKGetNodeNormalizedStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
else
{
HIKGetNodeStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
mNodeArray[lNodeIter].WriteCandidateTQS(lT, lQ, lS,pEvalInfo);
}
}
}
void SetStateCandidate(HIKCharacter *pHIKCharacter, HIKCharacterState *pState, FBEvaluateInfo* pEvalInfo, bool pNormalized)
{
for(int lNodeIter = HipsNodeId; lNodeIter < LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
HIKGetNodeNormalizedStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
else
{
HIKGetNodeStateTQSdv(pHIKCharacter, pState,lNodeIter,lT.mValue, lQ.mValue, lS.mValue);
}
mNodeArray[lNodeIter].SetCandidateTQS(lT, lQ, lS,pEvalInfo);
}
}
}
};
template<typename HostNode,typename HostProperty> class HIKCharacterHost : public HIKHost<HostNode>
{
HIKHostProperty<HostProperty> mPropertyArray[HIKLastPropertyId];
HIKHostProperty<HostProperty> mSpineMinLength[10];
HIKHostProperty<HostProperty> mSpineMaxLength[10];
HIKHostProperty<HostProperty> mNeckMinLength[10];
HIKHostProperty<HostProperty> mNeckMaxLength[10];
HIKHostProperty<HostProperty> mHeadMinLength;
HIKHostProperty<HostProperty> mHeadMaxLength;
HIKHostNode<HostNode> mFloorArray[HIKLastFloorId];
public:
HIKHostProperty<HostProperty>& GetProperty(int pPropertyId) { return mPropertyArray[pPropertyId]; }
HIKHostNode<HostNode>& GetFloorNode(int pFloorId) { return mFloorArray[pFloorId]; }
HIKHostProperty<HostProperty>& GetSpineMinLength(int spineId) { return mSpineMinLength[spineId]; }
HIKHostProperty<HostProperty>& GetSpineMaxLength(int spineId) { return mSpineMaxLength[spineId]; }
HIKHostProperty<HostProperty>& GetNeckMinLength(int neckId) { return mNeckMinLength[neckId]; }
HIKHostProperty<HostProperty>& GetNeckMaxLength(int neckId) { return mNeckMaxLength[neckId]; }
HIKHostProperty<HostProperty>& GetHeadMinLength() { return mHeadMinLength; }
HIKHostProperty<HostProperty>& GetHeadMaxLength() { return mHeadMaxLength; }
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 ReadPropertySetState(HIKPropertySetState *pPropertyState, FBEvaluateInfo* pEvalInfo)
{
for(int lPropertyIter = 0; lPropertyIter < HIKLastPropertyId; lPropertyIter++)
{
int pMode = mPropertyArray[lPropertyIter].ReadMode(pEvalInfo);
HIKSetPropertyMode(pPropertyState,lPropertyIter,pMode);
if( HIKIsPropertyAuto(pPropertyState, lPropertyIter) == false )
{
float pValue = float(mPropertyArray[lPropertyIter].ReadValue(pEvalInfo));
if(IsRollPropertyToInverse(lPropertyIter))
{
pValue = 1. - pValue;
}
HIKSetPropertyValue(pPropertyState, lPropertyIter, pValue);
}
}
}
void ReadLengthLimits(HIKCharacter *pCharcter, FBEvaluateInfo* pEvalInfo)
{
for(
int i = 0;
i < 10;
i++)
{
float minL = GetSpineMinLength(
i).ReadValue(pEvalInfo);
float maxL = GetSpineMaxLength(
i).ReadValue(pEvalInfo);
int nodeid = WaistNodeId;
if(
i != 0) nodeid = Spine1NodeId + (
i-1);
if(HIKGetNodeUse(pCharcter, nodeid))
{
HIKSetTranslationLimitsf(pCharcter, nodeid, minL, maxL,true);
}
minL = GetNeckMinLength(
i).ReadValue(pEvalInfo);
maxL = GetNeckMaxLength(
i).ReadValue(pEvalInfo);
nodeid = NeckNodeId;
if(
i != 0) nodeid = Neck1NodeId + (
i-1);
if(HIKGetNodeUse(pCharcter, nodeid))
{
HIKSetTranslationLimitsf(pCharcter, nodeid, minL, maxL,true);
}
}
float minL = GetHeadMinLength().ReadValue(pEvalInfo);
float maxL = GetHeadMaxLength().ReadValue(pEvalInfo);
HIKSetTranslationLimitsf(pCharcter, HeadNodeId, minL, maxL,true);
}
void TransfertRotationsAndLimits(HIKCharacter *pHIKCharacter, int pNodeIter, bool updatePrePost = false)
{
if(GetNode(pNodeIter).Valid())
{
if(GetNode(pNodeIter).GetUseRotationLimits())
{
double lPreQ[4];
double lPostQ[4];
double lMaxXYZ[4];
double lMinXYZ[4];
int lOrder = GetNode(pNodeIter).GetRotationOrder();
int lMinActiveMask = GetNode(pNodeIter).GetRotationMinXYZ(lMinXYZ);
int lMaxActiveMask = GetNode(pNodeIter).GetRotationMaxXYZ(lMaxXYZ);
GetNode(pNodeIter).GetPreQ(lPreQ);
GetNode(pNodeIter).GetPostQ(lPostQ);
HIKSetMinXYZRotationdv(pHIKCharacter,pNodeIter,lMinXYZ,lMinActiveMask);
HIKSetMaxXYZRotationdv(pHIKCharacter,pNodeIter,lMaxXYZ,lMaxActiveMask);
HIKSetRotationOrder(pHIKCharacter,pNodeIter, HIKRotationOrder(lOrder));
if(updatePrePost)
{
HIKSetPreQdv(pHIKCharacter,pNodeIter,lPreQ);
HIKSetPostQdv(pHIKCharacter,pNodeIter,lPostQ);
}
}
}
}
void ReadCharacterAndPropertiesForSolve(HIKCharacter *pHIKCharacter, HIKPropertySetState *pPropertyState, FBEvaluateInfo* pEvalInfo)
{
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
TransfertRotationsAndLimits(pHIKCharacter, lNodeIter);
}
ReadLengthLimits(pHIKCharacter, pEvalInfo);
ReadPropertySetState(pPropertyState,pEvalInfo);
HIKSetPropertyValue( pPropertyState , HIKChestTOffsetXId , - HIKGetPropertyValue(pPropertyState, HIKChestTOffsetXId) );
HIKSetPropertyValue( pPropertyState , HIKChestTOffsetYId , - HIKGetPropertyValue(pPropertyState, HIKChestTOffsetYId) );
HIKSetPropertyValue( pPropertyState , HIKChestTOffsetZId , - HIKGetPropertyValue(pPropertyState, HIKChestTOffsetZId) );
HIKSetPropertyValue( pPropertyState , HIKHipsTOffsetXId , - HIKGetPropertyValue(pPropertyState, HIKHipsTOffsetXId) );
HIKSetPropertyValue( pPropertyState , HIKHipsTOffsetYId , - HIKGetPropertyValue(pPropertyState, HIKHipsTOffsetYId) );
HIKSetPropertyValue( pPropertyState , HIKHipsTOffsetZId , - HIKGetPropertyValue(pPropertyState, HIKHipsTOffsetZId) );
}
void ReadReference(HIKCharacter *pHIKCharacter, HIKCharacterState *pCharacterState, FBEvaluateInfo* pEvalInfo)
{
double lGX[16];
GetNode(ReferenceNodeId).ReadXForm(lGX,pEvalInfo);
HIKSetNodeStatedv(pHIKCharacter, pCharacterState, ReferenceNodeId, lGX);
}
void ReadFloorState(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo)
{
double lXForm[16];
for(int lFloorIter = 0; lFloorIter < HIKLastFloorId; lFloorIter++)
{
GetFloorNode(lFloorIter).ReadXForm(lXForm,pEvalInfo);
HIKSetEffectorFloorStatedv(pEffectorSetState,lFloorIter,lXForm);
}
}
void ReadNormalizedFromState(FBControlSetState* pSrcState, HIKCharacter *pHIKCharacter, HIKCharacterState *pState, FBEvaluateInfo* pEvalInfo)
{
FBMatrix lXForm;
{
pSrcState->GetNodeMatrix((
FBBodyNodeId)lBodyNodeId, lXForm);
int lHIKNode = gFBBodyNodeToHIKNodeId[lBodyNodeId];
HIKSetNodeNormalizedStatedv(pHIKCharacter, pState,lHIKNode,lXForm);
}
}
void ReadEffectorsFromState(FBEffectorSetState* pSrcState, HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo)
{
FBMatrix lXForm;
double lReachT, lReachR;
for(int lEffectorIter = 0; lEffectorIter < LastEffectorId; lEffectorIter++)
{
pSrcState->GetEffectorMatrix((
FBEffectorId)lEffectorIter, lXForm);
pSrcState->GetReach((
FBEffectorId)lEffectorIter,lReachT,lReachR);
HIKBlendEffectorPivotsdv(pEffectorSetState, lEffectorIter, (double (*)[16])lXForm.GetData(), &lIKPivot.mValue, &lReachT, &lReachR, 1);
}
}
void ReadFromPose(HIKCharacter *pHIKCharacter, FBEvaluateInfo* pEvalInfo, HIKCharacterState* pState, FBCharacterPose* pPose)
{
{
int lHIKId = FBBodyNodeIdToHIKNodeId((
FBBodyNodeId)lBodyNodeId);
FBMatrix lMatrix = pPose->GetNodeMatrixGlobal(lBodyNodeId);
HIKSetNodeStatedv(pHIKCharacter, pState, lHIKId, (double*)lMatrix);
}
const int lExtraCount = pPose->GetExtraBoneCount();
for(
int i = 0;
i < lExtraCount;
i++)
{
int lHIKId = ExtraIndexToHIKNodeId(
i);
if(lHIKId != LastNodeId)
{
lT.mValue[3] = lS.mValue[3] = 1;
HIKSetNodeStateTQSdv(pHIKCharacter, pState, lHIKId, lT.mValue, lQ.mValue, lS.mValue);
}
}
}
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;
lHIKDef.mUsedNodes[lNodeIter] |= HIKNodeLimits;
if( !IsParentDirect(lNodeIter) )
{
lHIKDef.mUsedNodes[lNodeIter] |= HIKNodeParentOffset;
}
}
}
HIKCharacter *lHIKCharacter = HIKCharacterCreate(&lHIKDef, pMalloc, AutodeskCustomerString);
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
TransfertRotationsAndLimits(lHIKCharacter, lNodeIter, true);
}
return lHIKCharacter;
}
};
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, FBEvaluateInfo* pEvalInfo, bool pFKIK, bool pBlendAuxiliaryWithEffector)
{
double lIKPivotArray[HIKLastEffectorSetId][4];
double lReachTArray[HIKLastEffectorSetId];
double lReachRArray[HIKLastEffectorSetId];
for(int lEffectorIter = 0; lEffectorIter < LastEffectorId; lEffectorIter++)
{
for(int lSetIter = 0; lSetIter < HIKLastEffectorSetId; lSetIter++)
{
lReachTArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachT(pEvalInfo) : 1;
lReachRArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachR(pEvalInfo) : 1;
if ( (lReachTArray[lSetIter] > 0 || lReachRArray[lSetIter] > 0) && ( lSetIter > 0 ? pBlendAuxiliaryWithEffector : true ) )
{
mEffectorArray[lEffectorIter][lSetIter].ReadTQS(lTArray[lSetIter],lQArray[lSetIter],lSArray[lSetIter],pEvalInfo);
mEffectorArray[lEffectorIter][lSetIter].ReadIKPivot(lIKPivotArray[lSetIter],pEvalInfo);
}
else
{
lTArray[lSetIter].Init();
lQArray[lSetIter].Init();
lSArray[lSetIter].mValue[0]=lSArray[lSetIter].mValue[1]=lSArray[lSetIter].mValue[2]=lSArray[lSetIter].mValue[3]=lQArray[lSetIter].mValue[3]=1.0;
memset(lIKPivotArray[lSetIter],0,sizeof(double)*4);
lReachTArray[lSetIter] = 0.0;
lReachRArray[lSetIter] = 0.0;
}
}
HIKBlendEffectorPivotsTQSdv(pEffectorSetState,lEffectorIter,&lTArray[0].mValue,&lQArray[0].mValue,&lSArray[0].mValue,lIKPivotArray,lReachTArray,lReachRArray,HIKLastEffectorSetId);
}
}
void ReadEffectorState(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, bool pFKIK, bool &pDetectedRecursivity, int* pEffectorsRecursiveFlag, bool pBlendAuxiliaryWithEffector)
{
pDetectedRecursivity = false;
double lIKPivotArray[HIKLastEffectorSetId][4];
double lReachTArray[HIKLastEffectorSetId];
double lReachRArray[HIKLastEffectorSetId];
for(int lEffectorIter = 0; lEffectorIter < LastEffectorId; lEffectorIter++)
{
pEffectorsRecursiveFlag[lEffectorIter] = eNoRecursion;
for(int lSetIter = 0; lSetIter < HIKLastEffectorSetId; lSetIter++)
{
lReachTArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachT(pEvalInfo) : 1;
lReachRArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachR(pEvalInfo) : 1;
if ( (lReachTArray[lSetIter] > 0 || lReachRArray[lSetIter] > 0) && ( lSetIter > 0 ? pBlendAuxiliaryWithEffector : true ) )
{
mEffectorArray[lEffectorIter][lSetIter].ReadTQS(lTArray[lSetIter],lQArray[lSetIter],lSArray[lSetIter],pEvalInfo);
pEffectorsRecursiveFlag[lEffectorIter] |= mEffectorArray[lEffectorIter][lSetIter].IsEvaluationRecursiveTQS(pEvalInfo);
if(pEffectorsRecursiveFlag[lEffectorIter] != eNoRecursion) pDetectedRecursivity = true;
mEffectorArray[lEffectorIter][lSetIter].ReadIKPivot(lIKPivotArray[lSetIter],pEvalInfo);
}
else
{
lTArray[lSetIter].Init();
lQArray[lSetIter].Init();
lSArray[lSetIter].mValue[0]=lSArray[lSetIter].mValue[1]=lSArray[lSetIter].mValue[2]=lSArray[lSetIter].mValue[3]=lQArray[lSetIter].mValue[3]=1.0;
memset(lIKPivotArray[lSetIter],0,sizeof(double)*4);
lReachTArray[lSetIter] = 0.0;
lReachRArray[lSetIter] = 0.0;
}
}
HIKBlendEffectorPivotsTQSdv(pEffectorSetState,lEffectorIter,&lTArray[0].mValue,&lQArray[0].mValue,&lSArray[0].mValue,lIKPivotArray,lReachTArray,lReachRArray,HIKLastEffectorSetId);
}
}
void ReadRecursiveEffectorState(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, bool pFKIK, int* pEffectorsRecursiveFlag, int &pReadIndex)
{
double lIKPivotArray[HIKLastEffectorSetId][4];
double lReachTArray[HIKLastEffectorSetId];
double lReachRArray[HIKLastEffectorSetId];
for(int lEffectorIter = 0; lEffectorIter < LastEffectorId; lEffectorIter++)
{
if(pEffectorsRecursiveFlag[lEffectorIter] != eNoRecursion)
{
pReadIndex = lEffectorIter;
for(int lSetIter = 0; lSetIter < HIKLastEffectorSetId; lSetIter++)
{
mEffectorArray[lEffectorIter][lSetIter].ReadTQS(lTArray[lSetIter],lQArray[lSetIter],lSArray[lSetIter],pEvalInfo);
mEffectorArray[lEffectorIter][lSetIter].ReadIKPivot(lIKPivotArray[lSetIter],pEvalInfo);
lReachTArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachT(pEvalInfo) : 1;
lReachRArray[lSetIter] = pFKIK || lSetIter > 0 ? mEffectorArray[lEffectorIter][lSetIter].ReadReachR(pEvalInfo) : 1;
}
HIKBlendEffectorPivotsTQSdv(pEffectorSetState,lEffectorIter,&lTArray[0].mValue,&lQArray[0].mValue,&lSArray[0].mValue,lIKPivotArray,lReachTArray,lReachRArray,HIKLastEffectorSetId);
}
}
}
void WriteEffectorsState(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo,
bool pWriteAll=
false,
int* pEffectorsRecursiveFlag=
NULL)
{
{
WriteEffectorState(pEffectorSetState, pEvalInfo, lSetIter, pWriteAll, pEffectorsRecursiveFlag);
}
}
void WriteEffectorsStateCandidate(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, bool pWriteAll=false)
{
{
WriteEffectorStateCandidate(pEffectorSetState, pEvalInfo, lSetIter, pWriteAll);
}
}
void SetEffectorStateCandidate(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, bool pWriteAll=false)
{
{
SetEffectorStateCandidate(pEffectorSetState, pEvalInfo, lSetIter, pWriteAll);
}
}
private:
void WriteEffectorState(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo,
int pSetIndex,
bool pWriteAll=
false,
int* pEffectorsRecursiveFlag=
NULL)
{
int lIter = 0;
for(lIter = 0; lIter < LastEffectorId; lIter++)
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
HIKGetEffectorStateTQSdv(pEffectorSetState, lIter, lT.mValue, lQ.mValue, lS.mValue);
mEffectorArray[lIter][pSetIndex].ReadIKPivot(lIKPivot.mValue,pEvalInfo);
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, pEvalInfo);
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;
}
if(pEffectorsRecursiveFlag ==
NULL)
{
mEffectorArray[lIter][pSetIndex].WriteTQS(lIKPivot, lQ, lS, pEvalInfo);
}
else
{
mEffectorArray[lIter][pSetIndex].WriteTQSIfNotRecursive(lIKPivot, lQ, lS, pEvalInfo, pEffectorsRecursiveFlag[lIter]);
}
}
}
}
void WriteEffectorStateCandidate(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, int pSetIndex, bool pWriteAll=false)
{
int lIter = 0;
for(lIter = 0; lIter < LastEffectorId; lIter++)
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
HIKGetEffectorStateTQSdv(pEffectorSetState, lIter, lT.mValue, lQ.mValue, lS.mValue);
mEffectorArray[lIter][pSetIndex].ReadIKPivot(lIKPivot.mValue,pEvalInfo);
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, pEvalInfo);
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;
}
mEffectorArray[lIter][pSetIndex].WriteCandidateTQS(lIKPivot, lQ, lS, pEvalInfo);
}
}
}
void SetEffectorStateCandidate(HIKEffectorSetState *pEffectorSetState, FBEvaluateInfo* pEvalInfo, int pSetIndex, bool pWriteAll=false)
{
int lIter = 0;
for(lIter = 0; lIter < LastEffectorId; lIter++)
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
HIKGetEffectorStateTQSdv(pEffectorSetState, lIter, lT.mValue, lQ.mValue, lS.mValue);
mEffectorArray[lIter][pSetIndex].ReadIKPivot(lIKPivot.mValue,pEvalInfo);
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, pEvalInfo);
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;
}
mEffectorArray[lIter][pSetIndex].SetCandidateTQS(lIKPivot, lQ, lS, pEvalInfo);
}
}
}
};
template<typename HostNode,typename HostProperty> class HIKControlRigHostEvaluator
{
public:
HIKCharacter* mHIKCharacter;
HIKCharacterHost<HostNode,HostProperty>* mHIKCharacterHost;
HIKControlRigHost<HostNode>* mHIKControlRigHost;
int mSolvingStep;
bool mFKIK;
HIKControlRigHostEvaluator()
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
mSolvingStep = HIKSolvingStepAll;
mFKIK = true;
}
void SetSolvingStep( int pSolvingState )
{
mSolvingStep = pSolvingState;
}
void Init(HIKCharacter *pHIKCharacter,HIKCharacterHost<HostNode,HostProperty> *pHIKCharacterHost,HIKControlRigHost<HostNode> *pHIKControlRigHost,HIKMalloc pMalloc, bool pFKIK)
{
mHIKCharacter = pHIKCharacter;
mHIKCharacterHost = pHIKCharacterHost;
mHIKControlRigHost = pHIKControlRigHost;
mFKIK = pFKIK;
}
void Clear(HIKFree pFree)
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
}
static void SetPropertiesDisabledInControlRigSolve(HIKPropertySetState *pPropertyState)
{
HIKSetPropertyValue(pPropertyState,HIKSnSSmoothReach,0.0f);
HIKSetPropertyMode(pPropertyState,HIKMirrorId,0);
HIKSetPropertyValue(pPropertyState,HIKHipsTOffsetXId,0.0f);
HIKSetPropertyValue(pPropertyState,HIKHipsTOffsetYId,0.0f);
HIKSetPropertyValue(pPropertyState,HIKHipsTOffsetZId,0.0f);
HIKSetPropertyValue(pPropertyState,HIKChestTOffsetXId,0.0f);
HIKSetPropertyValue(pPropertyState,HIKChestTOffsetYId,0.0f);
HIKSetPropertyValue(pPropertyState,HIKChestTOffsetZId,0.0f);
}
void Read( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState,
bool* pDetectedIKRecursiveEvaluation=
NULL,
bool pBlendAuxiliaryWithEffector =
true )
{
if(pDetectedIKRecursiveEvaluation)
{
mHIKControlRigHost->ReadEffectorState(pState->mEffectorSetState,pEvalInfo,mFKIK,*pDetectedIKRecursiveEvaluation,pState->mRecursiveFlag, pBlendAuxiliaryWithEffector);
}
else
{
mHIKControlRigHost->ReadEffectorState(pState->mEffectorSetState,pEvalInfo,mFKIK, pBlendAuxiliaryWithEffector);
}
if(mFKIK)
mHIKControlRigHost->ReadState(mHIKCharacter, pState->mState,pEvalInfo,true);
else
HIKGetRelaxPose(mHIKCharacter, pState->mState);
mHIKCharacterHost->ReadCharacterAndPropertiesForSolve(mHIKCharacter,pState->mPropertySetState,pEvalInfo);
mHIKCharacterHost->ReadFloorState(pState->mEffectorSetState,pEvalInfo);
HIKSetEffectorPullResistFromPropertyState(pState->mEffectorSetState, pState->mPropertySetState);
SetPropertiesDisabledInControlRigSolve(pState->mPropertySetState);
}
void ReadRecursiveEffectors( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState )
{
mHIKControlRigHost->ReadRecursiveEffectorState(pState->mEffectorSetState,pEvalInfo,mFKIK,pState->mRecursiveFlag,pState->mEvaluatedEffectorId);
}
void ReadSkeletonSolveOnRig( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, FBCharacter* pCharacter )
{
mHIKCharacterHost->ReadState( mHIKCharacter, pState->mState, pEvalInfo, false);
mHIKCharacterHost->ReadCharacterAndPropertiesForSolve(mHIKCharacter,pState->mPropertySetState,pEvalInfo);
mHIKCharacterHost->ReadFloorState( pState->mEffectorSetState, pEvalInfo);
HIKSetEffectorPullResistFromPropertyState(pState->mEffectorSetState, pState->mPropertySetState);
HIKSetPropertyValue(pState->mPropertySetState,HIKSnSSmoothReach,0.0f);
int lMode = HIKGetPropertyMode(pState->mPropertySetState, HIKMirrorId);
if (lMode == 1)
{
HIKMirrorState( mHIKCharacter, pState->mState, pState->mState, mHIKCharacter, lMirrorQ.mValue);
pCharacter->MirrorCharacterExtensions(pEvalInfo);
}
EffectorStateFromControlSet(pState);
}
void Solve(HIKEvaluationState* pState, const int pDisableSolvingSteps=0)
{
HIKSetIKSolvingStep(pState->mEffectorSetState, (mSolvingStep & ~pDisableSolvingSteps));
HIKSolveForEffectorSet(mHIKCharacter,pState->mState,pState->mEffectorSetState, pState->mPropertySetState);
}
void SolveAndWriteControlRig(FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, bool pWriteRig, bool pDoubleSolve=false, const int pDisableSolvingSteps=0)
{
if(pDoubleSolve)
{
for(int lEffectorId = 0; lEffectorId < LastEffectorId; lEffectorId++)
{
if((pState->mRecursiveFlag[lEffectorId] & eRecursiveT) > 0)
{
HIKSetPull( pState->mEffectorSetState, lEffectorId, 0.0f );
}
if((pState->mRecursiveFlag[lEffectorId] & eRecursiveR) > 0)
{
HIKSetResist( pState->mEffectorSetState, lEffectorId, 0.0f );
}
}
}
if(HIKGetPropertyValue(pState->mPropertySetState, HIKRollExtractionMode) == 0)
{
Solve(pState, pDisableSolvingSteps);
if(pWriteRig)
{
WriteRig(pEvalInfo, pState, false, true, 0, pDoubleSolve);
}
}
else
{
HIKCharacterState* lCharacterState = pState->mState;
HIKEffectorSetState* lEffectorSetState = pState->mEffectorSetState;
HIKEffectorSetState* lTempEffectorSet = pState->mSrcEffectorSetState;
const HIKPropertySetState* lPropertyState = pState->mPropertySetState;
HIKSetIKSolvingStep(lEffectorSetState, (mSolvingStep & ~pDisableSolvingSteps));
HIKSolveForEffectorSetBegin(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetFloorContactApprox(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetBodyPull(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetArmsAndLegs(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetFingersAndToes(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetHeadAndNeck(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetFloorContact(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
HIKSolveForEffectorSetHipsTranslation(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
if(pWriteRig)
{
WriteRig(pEvalInfo, pState, false, true, lTempEffectorSet, pDoubleSolve);
}
HIKSolveForEffectorSetRollExtraction(mHIKCharacter,lCharacterState,lEffectorSetState,lPropertyState);
if(pDoubleSolve)
HIKEffectorStateCopy(lEffectorSetState, lTempEffectorSet);
}
if(pDoubleSolve)
{
HIKSetEffectorPullResistFromPropertyState(pState->mEffectorSetState, pState->mPropertySetState);
}
}
void Write( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState )
{
mHIKCharacterHost->WriteState(mHIKCharacter, pState->mState,pEvalInfo,false);
}
void WriteCandidate( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState )
{
mHIKCharacterHost->WriteStateCandidate(mHIKCharacter, pState->mState,pEvalInfo,false);
}
void WriteRig(FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState,
bool pWriteAll=
false,
bool pSnapEffectorsToRig=
true, HIKEffectorSetState* pEffectorSetToUse=
NULL,
bool pDoubleSolve=
false)
{
if(pEffectorSetToUse ==
NULL)
{
pEffectorSetToUse = pState->mEffectorSetState;
}
if(pSnapEffectorsToRig)
{
SetPropertiesDisabledInControlRigSolve(pState->mPropertySetState);
HIKEffectorSetFromCharacter(mHIKCharacter, pEffectorSetToUse, pState->mState, pState->mPropertySetState);
}
mHIKControlRigHost->WriteState(mHIKCharacter, pState->mState, pEvalInfo, true);
mHIKControlRigHost->WriteEffectorsState(pEffectorSetToUse, pEvalInfo, pWriteAll, pDoubleSolve ? pState->mRecursiveFlag :
NULL);
}
void WriteRigCandidate( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, bool pSetGlobalPropertyCandidate = false )
{
if(pSetGlobalPropertyCandidate)
{
mHIKControlRigHost->SetStateCandidate(mHIKCharacter, pState->mState, pEvalInfo, true);
mHIKControlRigHost->SetEffectorStateCandidate(pState->mEffectorSetState, pEvalInfo);
}
else
{
mHIKControlRigHost->WriteStateCandidate(mHIKCharacter, pState->mState, pEvalInfo, true);
mHIKControlRigHost->WriteEffectorsStateCandidate(pState->mEffectorSetState, pEvalInfo);
}
}
void ApplyLock(HIKEvaluationState* pState, bool pLockX, bool pLockY, bool pLockZ)
{
if(pLockX || pLockY || pLockZ)
{
FBMatrix lHipsGX, lHipsLX;
FBMatrix lRefGX;
HIKGetNodeStatedv(mHIKCharacter, pState->mState, ReferenceNodeId, lRefGX);
HIKGetNodeStatedv(mHIKCharacter, pState->mState, HipsNodeId, lHipsGX);
if(pLockX) lOffsetT[0] = lHipsDefaultGT[0] - lHipsLX(3, 0);
if(pLockY) lOffsetT[1] = lHipsDefaultGT[1] - lHipsLX(3, 1);
if(pLockZ) lOffsetT[2] = lHipsDefaultGT[2] - lHipsLX(3, 2);
HIKNodeStatePreMultTQSUpdv(mHIKCharacter, pState->mState, lOffsetT,
FBQuaternion(0,0,0,1),
FBVector4d(1,1,1,1),
false);
}
}
void EffectorStateFromControlSet(HIKEvaluationState* pState)
{
HIKEffectorSetFromCharacter(mHIKCharacter, pState->mEffectorSetState, pState->mState, pState->mPropertySetState);
}
};
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( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState )
{
if(mHIKCharacterHostSrc !=
NULL)
{
mHIKCharacterHostSrc->ReadState(mHIKCharacterSrc, pState->mSrcState,pEvalInfo,false);
mHIKCharacterHostSrc->ReadCharacterAndPropertiesForSolve(mHIKCharacterSrc,pState->mSrcPropertySetState,pEvalInfo);
}
mHIKCharacterHostDst->ReadCharacterAndPropertiesForSolve(mHIKCharacterDst,pState->mPropertySetState,pEvalInfo);
mHIKCharacterHostDst->ReadFloorState(pState->mEffectorSetState,pEvalInfo);
mHIKCharacterHostDst->ReadReference(mHIKCharacterDst, pState->mState, pEvalInfo);
}
void ReadFromActor( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, FBActor* pActor )
{
pActor->UpdateValues(pEvalInfo);
FBMatrix lGX;
FBSVector lGS;
FBSkeletonState* lSkeletonState = pActor->GetCurrentSkeletonState();
{
HIKSetNodeStatedv(mHIKCharacterSrc, pState->mSrcState, gActor2HIK[lActorIter], (double*)lGX);
}
for(int lPIter = 0; lPIter < HIKLastPropertyId; lPIter++)
{
HIKSetPropertyMode(pState->mSrcPropertySetState,lPIter,HIKGetPropertyInfoDefaultMode(lPIter));
if(lPIter == HIKFootBottomToAnkleId)
{
FBSVector lGS;
HIKSetPropertyValue(pState->mSrcPropertySetState,lPIter,7.5f*lGS[1]);
}
else
{
HIKSetPropertyValue(pState->mSrcPropertySetState,lPIter,HIKGetPropertyInfoDefaultValue(lPIter));
}
}
}
void ReadFromFKIK( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, FBControlSetState* pFKState, FBEffectorSetState* pIKState )
{
mHIKCharacterHostDst->ReadCharacterAndPropertiesForSolve(mHIKCharacterDst,pState->mPropertySetState,pEvalInfo);
mHIKCharacterHostDst->ReadFloorState(pState->mEffectorSetState,pEvalInfo);
mHIKCharacterHostDst->ReadNormalizedFromState(pFKState, mHIKCharacterDst, pState->mState, pEvalInfo);
mHIKCharacterHostDst->ReadEffectorsFromState(pIKState, pState->mEffectorSetState, pEvalInfo);
HIKSetEffectorPullResistFromPropertyState(pState->mEffectorSetState, pState->mPropertySetState);
}
void SolveRetarget(HIKEvaluationState* pState)
{
HIKSetIKSolvingStep(pState->mEffectorSetState, mSolvingStep);
HIKSolveForCharacter(mHIKCharacterDst,pState->mState,mHIKCharacterSrc,pState->mSrcState,pState->mEffectorSetState, pState->mPropertySetState, pState->mSrcPropertySetState);
}
void SolveIK(HIKEvaluationState* pState)
{
HIKSetIKSolvingStep(pState->mEffectorSetState, mSolvingStep);
HIKSolveForEffectorSet(mHIKCharacterDst, pState->mState, pState->mEffectorSetState, pState->mPropertySetState);
}
void Write( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, bool pNormalized = false )
{
mHIKCharacterHostDst->WriteState(mHIKCharacterDst, pState->mState,pEvalInfo,pNormalized);
}
};
#endif