#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;
HIKNodeId ExtraIndexToHIKNodeId(
int pExtraIndex);
class KHIKNodeState
{
#if defined(_MSC_VER)
typedef float __declspec(align(16)) FloatArray[4];
#elif defined(__GNUC__)
#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);
}
{
mDataSet = (KHIKNodeState*)_aligned_malloc(
sizeof(KHIKNodeState) *
LastNodeId, 16);
}
{
if(mSrcState != 0)
{
mSrcState = 0;
}
if(mSrcEffectorSetState != 0)
{
mSrcEffectorSetState = 0;
}
if(mSrcPropertySetState != 0)
{
mSrcPropertySetState = 0;
}
if(mState != 0)
{
mState = 0;
}
if(mEffectorSetState != 0)
{
mEffectorSetState = 0;
}
if(mPropertySetState != 0)
{
mPropertySetState = 0;
}
if(mDataSet != 0)
{
_aligned_free(mDataSet);
mDataSet = 0;
}
mEvaluateId = -1;
mDirtyFlag = true;
}
KHIKNodeState* mDataSet;
int mEvaluateId;
bool mDirtyFlag;
int mEvaluatedEffectorId;
};
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
{
public:
HIKHostNode<HostNode>& GetNode(int pNodeId) { return mNodeArray[pNodeId]; }
{
for(
int lNodeIter = 0; lNodeIter <
LastNodeId; lNodeIter++)
{
if(mNodeArray[lNodeIter].Valid())
{
mNodeArray[lNodeIter].ReadTQS(lT, lQ, lS, pEvalInfo);
if(pNormalized)
{
}
else
{
}
}
}
}
{
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
}
else
{
}
mNodeArray[lNodeIter].WriteTQS(lT, lQ, lS,pEvalInfo);
}
}
}
{
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
}
else
{
}
mNodeArray[lNodeIter].WriteCandidateTQS(lT, lQ, lS,pEvalInfo);
}
}
}
{
{
if(mNodeArray[lNodeIter].Valid())
{
if(pNormalized)
{
}
else
{
}
mNodeArray[lNodeIter].SetCandidateTQS(lT, lQ, lS,pEvalInfo);
}
}
}
};
template<typename HostNode,typename HostProperty> class HIKCharacterHost : public HIKHost<HostNode>
{
HIKHostProperty<HostProperty> mSpineMinLength[10];
HIKHostProperty<HostProperty> mSpineMaxLength[10];
HIKHostProperty<HostProperty> mNeckMinLength[10];
HIKHostProperty<HostProperty> mNeckMaxLength[10];
HIKHostProperty<HostProperty> mHeadMinLength;
HIKHostProperty<HostProperty> mHeadMaxLength;
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)
{
{
return true;
}
return false;
}
{
{
int pMode = mPropertyArray[lPropertyIter].ReadMode(pEvalInfo);
{
float pValue = float(mPropertyArray[lPropertyIter].ReadValue(pEvalInfo));
if(IsRollPropertyToInverse(lPropertyIter))
{
}
}
}
}
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);
{
}
minL = GetNeckMinLength(
i).ReadValue(pEvalInfo);
maxL = GetNeckMaxLength(
i).ReadValue(pEvalInfo);
{
}
}
float minL = GetHeadMinLength().ReadValue(pEvalInfo);
float maxL = GetHeadMaxLength().ReadValue(pEvalInfo);
}
void TransfertRotationsAndLimits(
HIKCharacter *pHIKCharacter,
int pNodeIter,
bool updatePrePost =
false)
{
if(this->GetNode(pNodeIter).Valid())
{
if(this->GetNode(pNodeIter).GetUseRotationLimits())
{
double lPreQ[4];
double lPostQ[4];
double lMaxXYZ[4];
double lMinXYZ[4];
int lOrder = this->GetNode(pNodeIter).GetRotationOrder();
int lMinActiveMask = this->GetNode(pNodeIter).GetRotationMinXYZ(lMinXYZ);
int lMaxActiveMask = this->GetNode(pNodeIter).GetRotationMaxXYZ(lMaxXYZ);
this->GetNode(pNodeIter).GetPreQ(lPreQ);
this->GetNode(pNodeIter).GetPostQ(lPostQ);
if(updatePrePost)
{
}
}
}
}
{
for(
int lNodeIter = 0; lNodeIter <
LastNodeId; lNodeIter++)
{
TransfertRotationsAndLimits(pHIKCharacter, lNodeIter);
}
ReadLengthLimits(pHIKCharacter, pEvalInfo);
ReadPropertySetState(pPropertyState,pEvalInfo);
}
{
double lGX[16];
}
{
double lXForm[16];
{
GetFloorNode(lFloorIter).ReadXForm(lXForm,pEvalInfo);
}
}
{
FBMatrix lXForm;
{
pSrcState->GetNodeMatrix((
FBBodyNodeId)lBodyNodeId, lXForm);
int lHIKNode = gFBBodyNodeToHIKNodeId[lBodyNodeId];
}
}
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);
}
}
{
{
int lHIKId = FBBodyNodeIdToHIKNodeId((
FBBodyNodeId)lBodyNodeId);
FBMatrix lMatrix = pPose->GetNodeMatrixGlobal(lBodyNodeId);
}
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;
}
}
}
bool IsParentDirect( int pNodeId )
{
if ( this->GetNode(pNodeId).Valid() )
{
FBModel *lModel = this->GetNode(pNodeId).Get().mNode;
FBModel *lParent = lModel->Parent;
if (lParent)
{
for(
int lNodeIter = 0; lNodeIter <
LastNodeId; lNodeIter++)
{
if ( this->GetNode(lNodeIter).Valid() )
{
lModel = this->GetNode(lNodeIter).Get().mNode;
if ( lModel == lParent )
return true;
}
}
}
}
return false;
}
{
for(
int lNodeIter = 0; lNodeIter <
LastNodeId; lNodeIter++)
{
if(this->GetNode(lNodeIter).Valid())
{
if( !IsParentDirect(lNodeIter) )
{
}
}
}
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;
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
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;
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
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;
{
if(pWriteAll || pSetIndex == 0 || mEffectorArray[lIter][pSetIndex].GetIKSync())
{
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:
HIKCharacterHost<HostNode,HostProperty>* mHIKCharacterHost;
HIKControlRigHost<HostNode>* mHIKControlRigHost;
int mSolvingStep;
bool mFKIK;
HIKControlRigHostEvaluator()
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
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;
}
{
mHIKCharacter = 0;
mHIKCharacterHost = 0;
mHIKControlRigHost = 0;
}
{
}
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
mHIKCharacterHost->ReadCharacterAndPropertiesForSolve(mHIKCharacter,pState->mPropertySetState,pEvalInfo);
mHIKCharacterHost->ReadFloorState(pState->mEffectorSetState,pEvalInfo);
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);
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)
{
}
void SolveAndWriteControlRig(FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState, bool pWriteRig, bool pDoubleSolve=false, const int pDisableSolvingSteps=0)
{
if(pDoubleSolve)
{
{
if((pState->mRecursiveFlag[lEffectorId] & eRecursiveT) > 0)
{
HIKSetPull( pState->mEffectorSetState, lEffectorId, 0.0f );
}
if((pState->mRecursiveFlag[lEffectorId] & eRecursiveR) > 0)
{
HIKSetResist( pState->mEffectorSetState, lEffectorId, 0.0f );
}
}
}
{
Solve(pState, pDisableSolvingSteps);
if(pWriteRig)
{
WriteRig(pEvalInfo, pState, false, true, 0, pDoubleSolve);
}
}
else
{
if(pWriteRig)
{
WriteRig(pEvalInfo, pState, false, true, lTempEffectorSet, pDoubleSolve);
}
if(pDoubleSolve)
HIKEffectorStateCopy(lEffectorSetState, lTempEffectorSet);
}
if(pDoubleSolve)
{
}
}
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);
}
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;
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)
{
}
};
template<typename HostNode,typename HostProperty> class HIKCharacterHostEvaluator
{
public:
HIKCharacterHost<HostNode,HostProperty> *mHIKCharacterHostDst;
HIKCharacterHost<HostNode,HostProperty> *mHIKCharacterHostSrc;
int mSolvingStep;
HIKCharacterHostEvaluator()
{
mHIKCharacterDst = 0;
mHIKCharacterHostDst = 0;
mHIKCharacterSrc = 0;
mHIKCharacterHostSrc = 0;
}
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;
}
{
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);
}
{
{
}
else
{
}
}
}
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);
}
void SolveRetarget(HIKEvaluationState* pState)
{
HIKSolveForCharacter(mHIKCharacterDst,pState->mState,mHIKCharacterSrc,pState->mSrcState,pState->mEffectorSetState, pState->mPropertySetState, pState->mSrcPropertySetState);
}
void SolveIK(HIKEvaluationState* pState)
{
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