#include "orcharactersolver_hik.h"
#include "filterset2fbcharacter.h"
#ifdef _DEBUG
#include <humanik/hikdump.h>
#define MAX_PATH_LENGTH 2048
#endif
ORCONSTRAINTHIK__CLASS,
ORCONSTRAINTHIK__LABEL,
ORCONSTRAINTHIK__DESC,
"character_solver.tif" );
#ifdef _DEBUG
static void SaveHIKChar(
HIObject pObject,
bool pValue)
{
if(pValue)
{
FBFilePopup lFilePopup;
lFilePopup.Caption = "Save HIK Character";
lFilePopup.Filter = "*.hik";
lFilePopup.Path = "";
if(lFilePopup.Execute())
{
ORCharacterSolver_HIK* lCharacterSolver = FBCast<ORCharacterSolver_HIK>(pObject);
HIKCharacter *lHIKCharacter =
NULL;
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst;
}
else if(lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter != 0)
{
lHIKCharacter = lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter;
}
if(lHIKCharacter )
{
HIKSaveCharacter(lFilePopup.FullFilename, lHIKCharacter, &malloc, &free);
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0 &&
lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterSrc != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterSrc;
char sourceFileName[MAX_PATH_LENGTH];
strcpy(sourceFileName, lFilePopup.FullFilename);
strcat(sourceFileName, "_src");
HIKSaveCharacter(sourceFileName, lHIKCharacter, &malloc, &free);
}
}
}
}
}
static void SaveHIKState(
HIObject pObject,
bool pValue)
{
if(pValue)
{
FBFilePopup lFilePopup;
lFilePopup.Caption = "Save HIK State";
lFilePopup.Filter = "*.hiks";
lFilePopup.Path = "";
if(lFilePopup.Execute())
{
ORCharacterSolver_HIK* lCharacterSolver = FBCast<ORCharacterSolver_HIK>(pObject);
HIKCharacter *lHIKCharacter =
NULL;
HIKCharacterState *lHIKCharacterState =
NULL;
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst;
lHIKCharacterState = lCharacterSolver->GetState(0)->mState;
}
else if(lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter != 0)
{
lHIKCharacter = lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter;
lHIKCharacterState = lCharacterSolver->GetState(0)->mState;
}
if(lHIKCharacter && lHIKCharacterState)
{
HIKSaveCharacterState(lFilePopup.FullFilename,lHIKCharacter, lHIKCharacterState, HIKDataDescription::HIKGlobalSpace);
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0 &&
lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterSrc != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterSrc;
lHIKCharacterState = lCharacterSolver->GetState(0)->mSrcState;
char sourceFileName[MAX_PATH_LENGTH];
strcpy(sourceFileName, lFilePopup.FullFilename);
strcat(sourceFileName, "_src");
HIKSaveCharacterState(sourceFileName,lHIKCharacter, lHIKCharacterState, HIKDataDescription::HIKGlobalSpace);
}
}
}
}
}
static void SaveHIKEffectors(
HIObject pObject,
bool pValue)
{
if(pValue)
{
FBFilePopup lFilePopup;
lFilePopup.Caption = "Save HIK Effectors state";
lFilePopup.Filter = "*.hikes";
lFilePopup.Path = "";
if(lFilePopup.Execute())
{
ORCharacterSolver_HIK* lCharacterSolver = FBCast<ORCharacterSolver_HIK>(pObject);
HIKCharacter *lHIKCharacter =
NULL;
HIKEffectorSetState *lHIKCharacterEffectorState =
NULL;
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst;
lHIKCharacterEffectorState = lCharacterSolver->GetState(0)->mEffectorSetState;
}
else if(lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter != 0)
{
lHIKCharacter = lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter;
lHIKCharacterEffectorState = lCharacterSolver->GetState(0)->mEffectorSetState;
}
if(lHIKCharacter && lHIKCharacterEffectorState)
{
HIKSaveEffectorState(lFilePopup.FullFilename, lHIKCharacterEffectorState);
}
}
}
}
static void SaveHIKProperties(
HIObject pObject,
bool pValue)
{
if(pValue)
{
FBFilePopup lFilePopup;
lFilePopup.Caption = "Save HIK Properties state";
lFilePopup.Filter = "*.hikps";
lFilePopup.Path = "";
if(lFilePopup.Execute())
{
ORCharacterSolver_HIK* lCharacterSolver = FBCast<ORCharacterSolver_HIK>(pObject);
HIKCharacter *lHIKCharacter =
NULL;
HIKPropertySetState *lHIKCharacterPropertyState =
NULL;
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst;
lHIKCharacterPropertyState = lCharacterSolver->GetState(0)->mPropertySetState;
}
else if(lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter != 0)
{
lHIKCharacter = lCharacterSolver->mHIKControlRigHostEvaluator.mHIKCharacter;
lHIKCharacterPropertyState = lCharacterSolver->GetState(0)->mPropertySetState;
}
if(lHIKCharacter && lHIKCharacterPropertyState)
{
HIKSavePropertySetState(lFilePopup.FullFilename, lHIKCharacterPropertyState);
if(lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst != 0 &&
lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterSrc != 0)
{
lHIKCharacter = lCharacterSolver->mHIKCharacterHostEvaluator.mHIKCharacterDst;
lHIKCharacterPropertyState = lCharacterSolver->GetState(0)->mSrcPropertySetState;
char sourceFileName[MAX_PATH_LENGTH];
strcpy(sourceFileName, lFilePopup.FullFilename);
strcat(sourceFileName, "_src");
HIKSavePropertySetState(sourceFileName, lHIKCharacterPropertyState);
}
}
}
}
}
static void DumpHIK(const FBString &pFilepath, HIKCharacter *pCharacter, HIKCharacter *pCharacterSrc,
HIKCharacterState *pCharacterState, HIKCharacterState *pCharacterStateSrc,
HIKEffectorSetState *pEffectorSetState, HIKPropertySetState *pPropertySetState,
HIKPropertySetState *pPropertySetStateSrc)
{
FBString lFilename;
if (pCharacter)
{
lFilename = pFilepath + ".hik";
HIKSaveCharacter(lFilename, pCharacter, &malloc, &free);
}
if (pCharacterSrc)
{
lFilename = pFilepath + "_src.hik";
HIKSaveCharacter(lFilename, pCharacterSrc, &malloc, &free);
}
if (pCharacterState)
{
lFilename = pFilepath + ".hiks";
HIKSaveCharacterState(lFilename, pCharacter, pCharacterState, HIKDataDescription::HIKGlobalSpace);
}
if (pCharacterStateSrc)
{
lFilename = pFilepath + "_src.hiks";
HIKSaveCharacterState(lFilename, pCharacterSrc, pCharacterStateSrc, HIKDataDescription::HIKGlobalSpace);
}
if (pEffectorSetState)
{
lFilename = pFilepath + ".hikes";
HIKSaveEffectorState(lFilename, pEffectorSetState);
}
if (pPropertySetState)
{
lFilename = pFilepath + ".hikps";
HIKSavePropertySetState(lFilename, pPropertySetState);
}
if (pPropertySetStateSrc)
{
lFilename = pFilepath + "_src.hikps";
HIKSavePropertySetState(lFilename, pPropertySetStateSrc);
}
}
#define DefOverwriteHIKSolvingStepFunc(Step) \
static void OverwriteHIK##Step(HIObject pObject, bool pValue) \
{ \
ORCharacterSolver_HIK* lCharacterSolver = FBCast<ORCharacterSolver_HIK>(pObject);\
if (!lCharacterSolver) \
return; \
lCharacterSolver->ModifySolvingStep(pValue, HIK##Step); \
lCharacterSolver->Step.SetPropertyValue(pValue); \
} \
DefOverwriteHIKSolvingStepFunc(SolvingStepBodyPull)
DefOverwriteHIKSolvingStepFunc(SolvingStepContact)
DefOverwriteHIKSolvingStepFunc(SolvingStepContactApprox)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftShoulder)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightShoulder)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftArm)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightArm)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftLeg)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightLeg)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftHand)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightHand)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftFoot)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightFoot)
DefOverwriteHIKSolvingStepFunc(SolvingStepHead)
DefOverwriteHIKSolvingStepFunc(SolvingStepSpine)
DefOverwriteHIKSolvingStepFunc(SolvingStepHipsTranslation)
DefOverwriteHIKSolvingStepFunc(SolvingStepRollExtraction)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftArmSnS)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightArmSnS)
DefOverwriteHIKSolvingStepFunc(SolvingStepLeftLegSnS)
DefOverwriteHIKSolvingStepFunc(SolvingStepRightLegSnS)
DefOverwriteHIKSolvingStepFunc(SolvingStepModifiers)
DefOverwriteHIKSolvingStepFunc(SolvingStepAllParts)
#endif
static void LegSNSSet(
HIObject pObject,
bool pValue)
{
ORCharacterSolver_HIK* lConstraint = FBCast<ORCharacterSolver_HIK>(pObject);
int LegFilter = (HIKSolvingStepLeftLegSnS | HIKSolvingStepRightLegSnS);
lConstraint->ModifySolvingStep(pValue, LegFilter);
lConstraint->LegSNS.SetPropertyValue(pValue);
}
static void ArmSNSSet(
HIObject pObject,
bool pValue)
{
ORCharacterSolver_HIK* lConstraint = FBCast<ORCharacterSolver_HIK>(pObject);
int ArmFilter = (HIKSolvingStepLeftArmSnS | HIKSolvingStepRightArmSnS);
lConstraint->ModifySolvingStep(pValue, ArmFilter);
lConstraint->ArmSNS.SetPropertyValue(pValue);
}
static char* HIKLibraryVersionGet(
HIObject pObject)
{
return HUMANIK_VERSION_STRING ".1";
}
bool ORCharacterSolver_HIK::FBCreate()
{
mInternalPropertiesCount = PropertyList.GetCount();
mHIKCharacterSrc = NULL;
mHIKActorSrc = NULL;
mControlSetManipulator = NULL;
mEvaluationId = -1;
HIKHostPropertiesInit(mHIKCharacterHost);
HIKHostPropertiesInit(mHIKCharacterHostSrc);
FBPropertyPublish(this, HIKLibraryVersion, "HIK Library Version", HIKLibraryVersionGet, NULL);
ExtraCollarRatio.SetMinMax(0.,100.);
char namebuffer[50];
for(
int i = 0; i < 10; ++i)
{
sprintf(namebuffer,"Spine %i Min Length", i);
sprintf(namebuffer,"Spine %i Max Length", i);
SpineMinLength[
i].SetMinMax(0.0, 500.0);
SpineMaxLength[
i].SetMinMax(0.0, 500.0);
}
for(
int i = 0; i < 10; ++
i)
{
sprintf(namebuffer,"Neck %i Min Length", i);
sprintf(namebuffer,"Neck %i Max Length", i);
NeckMinLength[
i].SetMinMax(0.0, 500.0);
NeckMaxLength[
i].SetMinMax(0.0, 500.0);
}
HeadMinLength.SetMinMax(0.0, 500.0);
HeadMaxLength.SetMinMax(0.0, 500.0);
CollarStiffnessX.SetMinMax(-100.,100.);
CollarStiffnessY.SetMinMax(-100.,100.);
CollarStiffnessZ.SetMinMax(-100.,100.);
ReachLeftShoulder.SetMinMax(0, 100);
ReachRightShoulder.SetMinMax(0, 100);
FBPropertyPublish(
this, RealisticLeftKneeSolving,
"Realistic Left Knee Solving", NULL, NULL);
FBPropertyPublish(
this, RealisticRightKneeSolving,
"Realistic Right Knee Solving", NULL, NULL);
RealisticLeftKneeSolving.SetMinMax(0, 100);
RealisticRightKneeSolving.SetMinMax(0, 100);
TopSpineCorrection.SetMinMax(0, 100);
LowerSpineCorrection.SetMinMax(0, 100);
FBPropertyPublish(
this, StretchStartArmsAndLegs,
"StretchStartArmsAndLegs", NULL, NULL);
FBPropertyPublish(
this, StretchStopArmsAndLegs,
"StretchStopArmsAndLegs", NULL, NULL);
StretchStartArmsAndLegs.SetMinMax(0,100);
StretchStopArmsAndLegs.SetMinMax(100,200);
SnSScaleArmsAndLegs.SetMinMax(0,100);
SnSReachLeftWrist.SetMinMax(0,100);
SnSReachRightWrist.SetMinMax(0,100);
SnSReachLeftAnkle.SetMinMax(0,100);
SnSReachRightAnkle.SetMinMax(0,100);
SnSScaleSpine.SetMinMax(0,100);
SnSScaleSpineChildren.SetMinMax(0,100);
SnSReachChestEnd.SetMinMax(0,100);
SnSScaleNeck.SetMinMax(0,100);
SnSReachHead.SetMinMax(0,100);
ResetPropertiesToDefault();
#ifdef _DEBUG
FBPropertyPublish(
this, ActionSaveHIKCharacter,
"Save Characer (HIK)", NULL, SaveHIKChar);
FBPropertyPublish(
this, ActionSaveHIKState,
"Save State (HIKS)", NULL, SaveHIKState);
FBPropertyPublish(
this, ActionSaveHIKEffectors,
"Save Effectors (HIKES)", NULL, SaveHIKEffectors);
FBPropertyPublish(
this, ActionSaveHIKProperties,
"Save Properties (HIKPS)", NULL, SaveHIKProperties);
InitSolvingProperties();
#endif
mSolvingStepFilter = HIKSolvingStepAll;
mSolverPropertiesCount = PropertyList.GetCount();
return true;
}
void ORCharacterSolver_HIK::FBDestroy()
{
if(mHIKCharacter != NULL)
{
HIKCharacterDestroy(mHIKCharacter,&free);
}
if(mHIKCharacterSrc != NULL)
{
HIKCharacterDestroy(mHIKCharacterSrc,&free);
}
if(mHIKCharacterSrc != NULL)
{
HIKCharacterDestroy(mHIKCharacterSrc,&free);
}
if(mHIKActorSrc != NULL)
{
HIKCharacterDestroy(mHIKActorSrc,&free);
}
RemoveAllAnimationNodes();
}
void ORCharacterSolver_HIK::SetupAllAnimationNodes()
{
FBCharacter* lCharacter = TargetCharacter;
if(lCharacter != NULL && lCharacter->GetCharacterize())
{
FBComponent* lSource = Source;
FBCharacter* lCharacterSrc = dynamic_cast<FBCharacter*>(lSource);
FBControlSet* lControlRig = dynamic_cast<FBControlSet*>(lSource);
mActorSrc = dynamic_cast<FBActor*>(lSource);
if(mControlSetManipulator)
{
mControlSetManipulator->DeallocateState();
mControlSetManipulator->AllocateState(lCharacter);
}
SetupTargetCharacter(lCharacter);
SetupAutoProperties(lCharacter);
ResetSnSPropertiesVisibility(lCharacter);
if(lControlRig != NULL)
{
SetupInputControlRig( lControlRig, GetRigAlign() || GetDoubleSolve() );
}
else if(lCharacterSrc != NULL)
{
HIKCharacterHostFromFBCharacter(mHIKCharacterHostSrc, lCharacterSrc);
HIKCharacterFromFBCharacter(mHIKCharacterHostSrc, mHIKCharacterSrc, lCharacterSrc);
HIKHostPropertiesFromCharacter(mHIKCharacterHostSrc,lCharacterSrc);
RegisterExtraProperties(mHIKCharacterHostSrc);
mHIKCharacterHostEvaluator.Init(mHIKCharacter,&mHIKCharacterHost,mHIKCharacterSrc,&mHIKCharacterHostSrc,&malloc);
}
else if(mActorSrc != NULL)
{
HIKCharacterFromFBActor(mHIKActorSrc, mActorSrc);
mHIKCharacterHostEvaluator.Init(mHIKCharacter,&mHIKCharacterHost,mHIKActorSrc,NULL,&malloc);
}
else
{
mHIKCharacterHostEvaluator.Init(mHIKCharacter,&mHIKCharacterHost,NULL,NULL,&malloc);
}
if (lPlotToRig)
{
SetupInputControlRig( lCharacter->GetCurrentControlSet(
true),
true );
}
}
mHIKCharacterHostEvaluator.SetSolvingStep( mSolvingStepFilter );
mHIKControlRigHostEvaluator.SetSolvingStep( mSolvingStepFilter );
GetState(0);
GetState(1);
}
void ORCharacterSolver_HIK::ResetSnSPropertiesVisibility(FBCharacter* lCharacter)
{
for(
int i =0; i < 10; ++
i)
{
bool spineHidden = !(i == 0 || HIKGetNodeUse(mHIKCharacter, Spine1NodeId + (i-1)));
bool neckHidden = i == 0 || !HIKGetNodeUse(mHIKCharacter, Neck1NodeId + (i-1));
SyncVisibilitySolverPropertiesOnCharacters(&SpineMinLength[i]);
SyncVisibilitySolverPropertiesOnCharacters(&SpineMaxLength[i]);
SyncVisibilitySolverPropertiesOnCharacters(&NeckMinLength[i]);
SyncVisibilitySolverPropertiesOnCharacters(&NeckMaxLength[i]);
}
}
void ORCharacterSolver_HIK::SetupTargetCharacter(FBCharacter* pCharacter)
{
HIKCharacterHostFromFBCharacterSolver(mHIKCharacterHost, this, this, true);
HIKCharacterFromFBCharacterSolver(mHIKCharacterHost, mHIKCharacter, this);
HIKHostPropertiesFromCharacter(mHIKCharacterHost,pCharacter);
RegisterExtraProperties(mHIKCharacterHost);
}
void ORCharacterSolver_HIK::CreateExtraFKIfNeeded(FBCharacter* pCharacter, int pExtraBoneId, HIKEvaluationState* pStanceState)
{
OR_HIK_ASSERT(GetExtraBoneModelAt(pExtraBoneId) != NULL);
OR_HIK_ASSERT(lParentShoulderFK != NULL);
if(lParentShoulderFK)
{
FBModelMarker* lExtraFK = dynamic_cast<FBModelMarker*>(GetExtraFKModelAt(pExtraBoneId));
if(lExtraFK == NULL)
{
lExtraFK = new FBModelMarker(pExtraBoneId == LEFT_EXTRA_COLLAR ? "Left Shoulder Extra FK" : "Right Shoulder Extra FK");
SetExtraFKModelAt(lExtraFK, pExtraBoneId );
}
if(lExtraFK->Children.GetCount() == 0)
{
lExtraFK->Parent = lParentShoulderFK;
HIKNodeId lHIKId = ExtraIndexToHIKNodeId(pExtraBoneId);
ResetControRigModelTransformation(mHIKCharacter, pStanceState, lHIKId, lExtraFK);
for (int lIter = lParentShoulderFK->Children.GetCount()-1; lIter >= 0; lIter--)
{
FBModel* lChild = dynamic_cast<FBModel*>(lParentShoulderFK->Children.GetAt(lIter));
if(lChild != lExtraFK)
{
FBBodyNodeId lChildBodyNodeId = pCharacter->GetCtrlRigIndexByModel(lChild);
{
lParentShoulderFK->Children.RemoveAt(lIter);
lExtraFK->Children.Add(lChild);
lHIKId = FBBodyNodeIdToHIKNodeId(lChildBodyNodeId);
ResetControRigModelTransformation(mHIKCharacter, pStanceState, lHIKId, lChild);
}
}
}
FBEvaluateManager::TheOne().InvalidateDAG();
}
OR_HIK_ASSERT(lParentShoulderFK->Children.GetCount() == 1);
}
}
void ORCharacterSolver_HIK::SetupInputControlRig(FBControlSet* pControlRig, bool pConstraintRig )
{
FBCharacter* lCharacter = TargetCharacter;
HIKGetDefaultState(mHIKCharacter, lDisplayState->mState);
const int lExtraCount = GetExtraBoneCount();
for( int lExtraIndex=0; lExtraIndex < lExtraCount; lExtraIndex++)
{
FBModel* lExtraBone = GetExtraBoneModelAt(lExtraIndex);
if(lExtraBone)
{
CreateExtraFKIfNeeded(lCharacter, lExtraIndex, lDisplayState);
}
}
HIKControlRigHostFromFBCharacterSolver(mHIKControlRigHost, this, pControlRig, (pConstraintRig) ? this : NULL);
mHIKControlRigHostEvaluator.Init(mHIKCharacter,&mHIKCharacterHost,&mHIKControlRigHost, &malloc, pControlRig ? (pControlRig->ControlSetType ==
kFBControlSetTypeFKIK) :
true);
}
void ORCharacterSolver_HIK::SetupAutoProperties(FBCharacter* pCharacter)
{
for (int i = 0; i < HIKLastPropertyId; i++ )
{
if ( HIKGetPropertyInfoModeType(i) == HIKPropertyOffAutoUser || HIKGetPropertyInfoModeType(i) == HIKPropertyAutoUser )
{
AnimationNodeInCreate( 2000+i, mHIKCharacterHost.GetProperty(i).Get().mValueP );
}
}
}
void ORCharacterSolver_HIK::ModifySolvingStep(bool pEnable, int pStep)
{
if(pEnable)
mSolvingStepFilter |= pStep;
else
mSolvingStepFilter &= ~pStep;
mHIKCharacterHostEvaluator.SetSolvingStep( mSolvingStepFilter );
mHIKControlRigHostEvaluator.SetSolvingStep( mSolvingStepFilter );
}
void ORCharacterSolver_HIK::RemoveAllAnimationNodes()
{
if(mHIKCharacter != NULL)
{
HIKCharacterDestroy(mHIKCharacter,&free);
}
if(mHIKCharacterSrc != NULL)
{
HIKCharacterDestroy(mHIKCharacterSrc,&free);
}
if(mHIKActorSrc != NULL)
{
HIKCharacterDestroy(mHIKActorSrc,&free);
}
for(int lNodeIter = 0; lNodeIter < LastNodeId; lNodeIter++)
{
mHIKCharacterHost.GetNode(lNodeIter).Get().Clear();
mHIKCharacterHostSrc.GetNode(lNodeIter).Get().Clear();
mHIKControlRigHost.GetNode(lNodeIter).Get().Clear();
}
{
{
mHIKControlRigHost.GetEffector(lEffIter,lSetIter).Get().Clear();
}
}
mHIKControlRigHostEvaluator.Clear(&free);
mHIKCharacterHostEvaluator.Clear(&free);
ClearStates();
}
HIKEvaluationState* ORCharacterSolver_HIK::EvaluationStateCreator()
{
HIKEvaluationState* lNewState = new HIKEvaluationState();
if(mHIKActorSrc != NULL)
{
lNewState->Init(mHIKCharacter, mHIKActorSrc, &malloc);
}
else
{
lNewState->Init(mHIKCharacter, mHIKCharacterSrc, &malloc);
}
return lNewState;
}
bool ORCharacterSolver_HIK::AnimationNodeNotify(FBAnimationNode* pConnector,FBEvaluateInfo* pEvaluateInfo,FBConstraintInfo* pConstraintInfo)
{
if(pEvaluateInfo->GetRecursionLevel(this) > 0)
{
OR_HIK_ASSERT( pEvaluateInfo->GetRecursionLevel(this) == 1);
return false;
}
if(mHIKCharacterHost.GetNode(ReferenceNodeId).Valid())
{
if( mHIKCharacterHost.GetNode(ReferenceNodeId).Get().IsDestinationConn(pConnector) )
return false;
}
if(mHIKControlRigHostEvaluator.mHIKControlRigHost)
{
if(mHIKControlRigHostEvaluator.mHIKControlRigHost->GetNode(ReferenceNodeId).Valid())
{
if( mHIKControlRigHostEvaluator.mHIKControlRigHost->GetNode(ReferenceNodeId).Get().IsDestinationConn(pConnector) )
return false;
}
}
HIKEvaluationState* lCurrentState = GetState(pEvaluateInfo, this);
if(lCurrentState->mEvaluateId != pEvaluateInfo->GetEvaluationID())
{
lCurrentState->mEvaluateId = pEvaluateInfo->GetEvaluationID();
if(mHIKCharacterHostEvaluator.mHIKCharacterSrc != 0)
{
if(mHIKActorSrc != NULL)
{
mHIKCharacterHostEvaluator.ReadFromActor(pEvaluateInfo, lCurrentState, mActorSrc);
}
mHIKCharacterHostEvaluator.Read(pEvaluateInfo, lCurrentState);
mHIKCharacterHostEvaluator.SolveRetarget(lCurrentState);
if(TargetCharacter->IsPlottingActorToCtrlRig() && mHIKControlRigHostEvaluator.mHIKControlRigHost)
{
mHIKControlRigHostEvaluator.WriteRig(pEvaluateInfo, lCurrentState, true, true);
}
else
{
mHIKCharacterHostEvaluator.Write(pEvaluateInfo, lCurrentState);
}
if ( mHIKCharacterSrc )
{
RetargetExtensions( pEvaluateInfo );
}
}
{
FBCharacterMarkerSet* lMarkerSet = TargetCharacter->GetCharacterMarkerSet();
if(lMarkerSet && mHIKCharacterHostEvaluator.mHIKCharacterDst)
{
FBControlSetState* lFKState = TargetCharacter->GetControlSetEvaluationCache(pEvaluateInfo);
FBEffectorSetState* lIKState = TargetCharacter->GetEffectorEvaluationCache(pEvaluateInfo);
lMarkerSet->ReadCtrlSetAndEffectorState(lFKState,lIKState,pEvaluateInfo);
mHIKCharacterHostEvaluator.ReadFromFKIK(pEvaluateInfo, lCurrentState, lFKState, lIKState);
HIKSetPropertyValue(lCurrentState->mPropertySetState,HIKRealisticArmSolvingId,1.0f);
mHIKCharacterHostEvaluator.SolveIK(lCurrentState);
if(lPlotToRig && mHIKControlRigHostEvaluator.mHIKControlRigHost)
{
mHIKControlRigHostEvaluator.WriteRig(pEvaluateInfo, lCurrentState, true, true);
}
else
{
mHIKCharacterHostEvaluator.Write(pEvaluateInfo, lCurrentState);
}
}
}
else if(mHIKControlRigHostEvaluator.mHIKCharacter != 0)
{
if (lPlotToRig)
{
mHIKControlRigHostEvaluator.ReadSkeletonSolveOnRig(pEvaluateInfo,lCurrentState,TargetCharacter);
mHIKControlRigHostEvaluator.WriteRig(pEvaluateInfo,lCurrentState,true);
}
else
{
ControlRigInputEvaluateAndWrite(pEvaluateInfo, lCurrentState, GetRigAlign(), GetDoubleSolve(), true);
mHIKControlRigHostEvaluator.ApplyLock(lCurrentState, TargetCharacter->LockX, TargetCharacter->LockY, TargetCharacter->LockZ);
mHIKControlRigHostEvaluator.Write(pEvaluateInfo, lCurrentState);
}
}
else
{
mHIKCharacterHost.ReadReference(mHIKCharacter, lCurrentState->mState, pEvaluateInfo);
HIKGetNodeNormalizedStateTQSdv(mHIKCharacter, lCurrentState->mState, ReferenceNodeId, lGT.mValue, lGQ.mValue, lGS.mValue);
HIKGetDefaultState(mHIKCharacter, lCurrentState->mState);
HIKNodeStatePreMultTQSUpdv(mHIKCharacter, lCurrentState->mState, lGT.mValue, lGQ.mValue, lGS.mValue, false);
mHIKCharacterHost.WriteState(mHIKCharacter, lCurrentState->mState, pEvaluateInfo, false);
}
AnimationNodesOutDisableIfNotWritten(pEvaluateInfo);
}
int lHIKPropIndex = pConnector->Reference - 2000;
if ( lHIKPropIndex >= 0 && lHIKPropIndex < HIKLastPropertyId)
{
HIKPropertySetState * lPropState = lCurrentState->mPropertySetState;
if( HIKIsPropertyAuto(lPropState, lHIKPropIndex) )
{
double lValue = HIKGetPropertyValue( lPropState, lHIKPropIndex );
pConnector->WriteData(&lValue, pEvaluateInfo);
}
}
return true;
}
void ORCharacterSolver_HIK::ControlRigInputEvaluateAndWrite( FBEvaluateInfo* pEvaluateInfo, HIKEvaluationState* pState, const bool pRigAlign, const bool pDoubleSolve, const bool pWriteRig, const int pDisableSolvingStep )
{
if(pRigAlign || pDoubleSolve)
{
bool lRecursionDetected = false;
FBEvaluateInfo* lEvaluation = pDoubleSolve ? BackgroundEvaluateInfoRecursiveBegin(pEvaluateInfo) : BackgroundEvaluateInfoBegin(pEvaluateInfo);
{
mHIKControlRigHostEvaluator.Read(lEvaluation,pState, pDoubleSolve ? &lRecursionDetected : NULL, GetBlendAuxiliaryWithEffector());
}
BackgroundEvaluateInfoEnd(lEvaluation);
if(lRecursionDetected)
{
FBEvaluateInfo* lDoubleEvaluation = BackgroundEvaluateInfoRecursiveBegin(pEvaluateInfo, true);
{
mHIKControlRigHostEvaluator.SolveAndWriteControlRig(lDoubleEvaluation, pState, true, true);
mHIKControlRigHostEvaluator.Write(lDoubleEvaluation, pState);
ReadDoubleSolve(lDoubleEvaluation,pState);
}
BackgroundEvaluateInfoEnd(lDoubleEvaluation);
}
mHIKControlRigHostEvaluator.SolveAndWriteControlRig(pEvaluateInfo, pState, pWriteRig, false, pDisableSolvingStep);
}
else
{
mHIKControlRigHostEvaluator.Read(pEvaluateInfo, pState, NULL, GetBlendAuxiliaryWithEffector());
mHIKControlRigHostEvaluator.Solve(pState);
}
}
void ORCharacterSolver_HIK::ReadDoubleSolve( FBEvaluateInfo* pEvalInfo, HIKEvaluationState* pState )
{
BackgroundEvaluateInfoNotify(pEvalInfo, &ORCharacterSolver_HIK::BackgroundEvaluateInfoNotification, pState);
mHIKControlRigHostEvaluator.ReadRecursiveEffectors(pEvalInfo,pState);
BackgroundEvaluateInfoNotify(pEvalInfo, NULL);
}
void ORCharacterSolver_HIK::BackgroundEvaluateInfoNotification(const FBAnimationNode* pDst, const FBAnimationNode* pThisSrc, void* pCustomData)
{
const AnimationNode_Id lConnectorId = pCustomData ? (AnimationNode_Id)pThisSrc->Reference : AnimationNode_Id();
if(lConnectorId.IsValidEffectorId())
{
HIKEvaluationState* lCurrentState = (HIKEvaluationState*)pCustomData;
if(lCurrentState->mEvaluatedEffectorId >= 0 && lCurrentState->mEvaluatedEffectorId < LastEffectorId)
{
const int lEffectorId = lConnectorId.GetEffectorId();
if(lEffectorId != lCurrentState->mEvaluatedEffectorId)
{
const int lType = lConnectorId.GetType();
{
HIKSetTranslationActive( lCurrentState->mEffectorSetState, lEffectorId, 1.0f);
HIKSetPull( lCurrentState->mEffectorSetState, lEffectorId, 1.0f );
}
{
HIKSetRotationActive( lCurrentState->mEffectorSetState, lEffectorId, 1.0f);
HIKSetResist( lCurrentState->mEffectorSetState, lEffectorId, 1.0f );
}
}
}
}
}
FBCharacterManipulatorCtrlSet* ORCharacterSolver_HIK::CreateCharacterManipulatorCtrlSet(const char* pName)
{
mControlSetManipulator = new ORCharacterManipulatorCtrlSet(pName);
mControlSetManipulator->FBCreate();
return mControlSetManipulator;
}
int ORCharacterSolver_HIK::GetExtraFKCount()
{
return 2;
}
const char* ORCharacterSolver_HIK::GetExtraFKNameAt(int pIndex)
{
static const FBString gLeftExtraCollar_FK = FBString(HIKNodeNameFromNodeId(LeftCollarExtraNodeId)) + "_FK";
static const FBString gRightExtraCollar_FK = FBString(HIKNodeNameFromNodeId(RightCollarExtraNodeId)) + "_FK";
switch (pIndex)
{
case LEFT_EXTRA_COLLAR:
return gLeftExtraCollar_FK;
break;
case RIGHT_EXTRA_COLLAR:
return gRightExtraCollar_FK;
break;
}
}
FBBodyPartId ORCharacterSolver_HIK::GetExtraFKBodyPartAt(
int pIndex)
{
switch (pIndex)
{
case LEFT_EXTRA_COLLAR:
break;
case RIGHT_EXTRA_COLLAR:
break;
}
}
int ORCharacterSolver_HIK::GetExtraBoneCount()
{
return 2;
}
const char* ORCharacterSolver_HIK::GetExtraBoneNameAt(int pIndex)
{
switch (pIndex)
{
case LEFT_EXTRA_COLLAR:
return HIKNodeNameFromNodeId(LeftCollarExtraNodeId);
break;
case RIGHT_EXTRA_COLLAR:
return HIKNodeNameFromNodeId(RightCollarExtraNodeId);
break;
}
}
FBBodyPartId ORCharacterSolver_HIK::GetExtraBoneBodyPartAt(
int pIndex)
{
switch (pIndex)
{
case LEFT_EXTRA_COLLAR:
break;
case RIGHT_EXTRA_COLLAR:
break;
}
}
void ORCharacterSolver_HIK::RegisterExtraProperties(HIKCharacterHost<HIKHostNodeMB,HIKHostPropertyMB> &pHIKCharacterHost)
{
pHIKCharacterHost.GetProperty(HIKExtraCollarRatioId).Get().Init(NULL, &ExtraCollarRatio, 0,100.f, false);
pHIKCharacterHost.GetProperty(HIKCollarStiffnessX).Get().Init(NULL, &CollarStiffnessX, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKCollarStiffnessY).Get().Init(NULL, &CollarStiffnessY, 0,100.f, false);
pHIKCharacterHost.GetProperty(HIKCollarStiffnessZ).Get().Init(NULL, &CollarStiffnessZ, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKReachActorLeftShoulderId).Get().Init(NULL, &ReachLeftShoulder, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKReachActorRightShoulderId).Get().Init(NULL, &ReachRightShoulder, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKFingerPropagationId).Get().Init(&FingerSolvingPropagation, NULL, 0, 1.f, false);
pHIKCharacterHost.GetProperty(HIKRealisticLeftKneeSolvingId).Get().Init(NULL, &RealisticLeftKneeSolving, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKRealisticRightKneeSolvingId).Get().Init(NULL, &RealisticRightKneeSolving, 0, 100.f, false);
pHIKCharacterHost.GetProperty(HIKRealisticArmSolvingId).Get().Init(NULL,&RealisticArmSolving,0,1.f,false);
pHIKCharacterHost.GetProperty(HIKTopSpineCorrectionId).Get().Init(NULL,&TopSpineCorrection,0,100,false);
pHIKCharacterHost.GetProperty(HIKLowerSpineCorrectionId).Get().Init(NULL,&LowerSpineCorrection,0,100,false);
pHIKCharacterHost.GetProperty(HIKStretchStartArmsAndLegs).Get().Init(NULL, &StretchStartArmsAndLegs,0,100,false);
pHIKCharacterHost.GetProperty(HIKStretchStopArmsAndLegs).Get().Init(NULL, &StretchStopArmsAndLegs,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSScaleArmsAndLegs).Get().Init(NULL, &SnSScaleArmsAndLegs,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachLeftWrist).Get().Init(NULL, &SnSReachLeftWrist,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachRightWrist).Get().Init(NULL, &SnSReachRightWrist,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachLeftAnkle).Get().Init(NULL, &SnSReachLeftAnkle,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachRightAnkle).Get().Init(NULL, &SnSReachRightAnkle,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSScaleSpine).Get().Init(NULL, &SnSScaleSpine,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSScaleSpineChildren).Get().Init(NULL, &SnSScaleSpineChildren,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachChestEnd).Get().Init(NULL, &SnSReachChestEnd,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSScaleNeck).Get().Init(NULL, &SnSScaleNeck,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSReachHead).Get().Init(NULL, &SnSReachHead,0,100,false);
for(
int i = 0; i < 10; ++
i)
{
pHIKCharacterHost.GetSpineMinLength(i).Get().Init(NULL, &SpineMinLength[i],0,100,false);
pHIKCharacterHost.GetSpineMaxLength(i).Get().Init(NULL, &SpineMaxLength[i],0,100,false);
pHIKCharacterHost.GetNeckMinLength(i).Get().Init(NULL, &NeckMinLength[i],0,100,false);
pHIKCharacterHost.GetNeckMaxLength(i).Get().Init(NULL, &NeckMaxLength[i],0,100,false);
}
pHIKCharacterHost.GetHeadMinLength().Get().Init(NULL, &HeadMinLength,0,100,false);
pHIKCharacterHost.GetHeadMaxLength().Get().Init(NULL, &HeadMaxLength,0,100,false);
pHIKCharacterHost.GetProperty(HIKSnSSmoothReach).Get().Init(NULL, &SnSSmoothReach,0,1.0f,false);
}
void ORCharacterSolver_HIK::ResetExtraProperties()
{
RemoveAnimations();
ResetPropertiesToDefault();
}
void ORCharacterSolver_HIK::ResetPropertiesToDefault()
{
Weight = 100;
ExtraCollarRatio = 50;
for(
int i = 0; i < 10; ++
i)
{
SpineMaxLength[
i] = 110.0;
SpineMinLength[
i] = 90.0;
NeckMaxLength[
i] = 110.0;
}
HeadMaxLength = 110.0;
HeadMinLength = 90.0;
CollarStiffnessX = 0;
CollarStiffnessY = 0;
CollarStiffnessZ = 0;
ReachLeftShoulder = 0;
ReachRightShoulder = 0;
FingerSolvingPropagation = false;
RealisticLeftKneeSolving = 0;
RealisticRightKneeSolving = 0;
RealisticArmSolving = false;
LegSNS = false;
ArmSNS = false;
StretchStartArmsAndLegs = HIKGetPropertyInfoDefaultValue(HIKStretchStartArmsAndLegs) * 100;
StretchStopArmsAndLegs = HIKGetPropertyInfoDefaultValue(HIKStretchStopArmsAndLegs) * 100;
SnSScaleArmsAndLegs = HIKGetPropertyInfoDefaultValue(HIKSnSScaleArmsAndLegs) * 100;
SnSReachLeftWrist = HIKGetPropertyInfoDefaultValue(HIKSnSReachLeftWrist) * 100;
SnSReachRightWrist = HIKGetPropertyInfoDefaultValue(HIKSnSReachRightWrist) * 100;
SnSReachLeftAnkle = HIKGetPropertyInfoDefaultValue(HIKSnSReachLeftAnkle) * 100;
SnSReachRightAnkle = HIKGetPropertyInfoDefaultValue(HIKSnSReachRightAnkle) * 100;
SnSScaleSpine = HIKGetPropertyInfoDefaultValue(HIKSnSScaleSpine) * 100;
SnSScaleSpineChildren = HIKGetPropertyInfoDefaultValue(HIKSnSScaleSpineChildren) * 100;
SnSReachChestEnd = HIKGetPropertyInfoDefaultValue(HIKSnSReachChestEnd) * 100;
TopSpineCorrection = HIKGetPropertyInfoDefaultValue(HIKTopSpineCorrectionId) * 100;
LowerSpineCorrection = HIKGetPropertyInfoDefaultValue(HIKLowerSpineCorrectionId) * 100;
SnSScaleNeck = HIKGetPropertyInfoDefaultValue(HIKSnSScaleNeck) * 100;
SnSReachHead = HIKGetPropertyInfoDefaultValue(HIKSnSReachHead) * 100;
SnSSmoothReach = true;
}
void ORCharacterSolver_HIK::RemoveAnimations()
{
FBUndoManager lUndoManager;
const int lPropertyCount = mSolverPropertiesCount < PropertyList.GetCount() ? mSolverPropertiesCount : PropertyList.GetCount();
for( int lPropID = mInternalPropertiesCount; lPropID < lPropertyCount; ++lPropID )
{
FBProperty* lProp = PropertyList[lPropID];
{
if( lUndoManager.TransactionIsOpen() )
lUndoManager.TransactionAddProperty(lProp);
if( lProp->IsAnimatable() )
{
FBPropertyAnimatable* lEvalProp = (FBPropertyAnimatable*) lProp;
if(lEvalProp)
lEvalProp->SetAnimated(false);
}
}
}
if( lUndoManager.TransactionIsOpen() )
lUndoManager.TransactionAddProperty( &Weight );
Weight.SetAnimated(false);
}
void ORCharacterSolver_HIK::RetargetExtensions( FBEvaluateInfo* pEvalInfo )
{
int lCharacterExtensionCount = TargetCharacter->CharacterExtensions.GetCount();
for(int i = 0; i < lCharacterExtensionCount; i++)
{
FBCharacterExtension* lCharacterExtension = (FBCharacterExtension*)TargetCharacter->CharacterExtensions.GetAt(i);
lCharacterExtension->RetargetAnimation( pEvalInfo );
}
}
void ORCharacterSolver_HIK::FilterBodyParts(HIKEvaluationState* pPasteState, HIKEvaluationState* pCurrentState)
{
TargetCharacter->GetActiveBodyPart(lActiveBodyPart);
int lNodeIdDesc[LastNodeId + 1];
HIKDataDescription lDescription = {
HIKDataDescription::HIKLocalSpace,
sizeof(KHIKNodeState),
lNodeIdDesc
};
HIKFillCharacterDescription(mHIKCharacter, lNodeIdDesc);
HIKGetCharacterStateTransformTQS( mHIKCharacter, pCurrentState->mState, &lDescription, pCurrentState->mDataSet);
HIKGetCharacterStateTransformTQS( mHIKCharacter, pPasteState->mState, &lDescription, pPasteState->mDataSet);
{
HIKNodeId lHIKNodeId = FBBodyNodeIdToHIKNodeId((
FBBodyNodeId)lNodeCounter);
{
CopyNormalizedState(pPasteState->mDataSet, pCurrentState->mDataSet, lHIKNodeId);
}
}
const int lExtraBoneCount = GetExtraBoneCount();
for(int lExtraIndex = 0; lExtraIndex < lExtraBoneCount; lExtraIndex++)
{
HIKNodeId lHIKNodeId = ExtraIndexToHIKNodeId(lExtraIndex);
if(HIKGetNodeUse(mHIKCharacter, lHIKNodeId) && GetExtraBoneModelAt(lExtraIndex) && lActiveBodyPart[GetExtraBoneBodyPartAt(lExtraIndex)] == false)
{
CopyNormalizedState(pPasteState->mDataSet, pCurrentState->mDataSet, lHIKNodeId);
}
}
HIKSetCharacterStateTransformTQS(mHIKCharacter, pPasteState->mState, &lDescription, pPasteState->mDataSet);
}
void ORCharacterSolver_HIK::SolverPasteCharacterPose( HIKCharacter* pHIKCharacter,
HIKEvaluationState* pPasteState, HIKEvaluationState* pCurrentState,
HIKCharacter* pHIKFromCharacter, HIKEvaluationState* pFromState,
FBCharacterPose* pPose, FBCharacterPoseOptions& pCharacterPoseOptions,
FBMatrix& pHipsOffsetGX, FBEvaluateInfo* pPasteEvaluateInfo)
{
HIKPasteState( pHIKCharacter, pPasteState->mState, pCurrentState->mState,
pHIKFromCharacter, pFromState->mState,
pCurrentState->mPropertySetState, pFromState->mPropertySetState,
(double*)pHipsOffsetGX );
{
FilterBodyParts(pPasteState, pCurrentState);
}
HIKEffectorSetFromCharacter(pHIKCharacter, pPasteState->mEffectorSetState, pPasteState->mState, pCurrentState->mPropertySetState);
mHIKControlRigHostEvaluator.WriteRigCandidate(pPasteEvaluateInfo, pPasteState, true);
mHIKControlRigHostEvaluator.WriteCandidate(pPasteEvaluateInfo, pPasteState);
DoPasteCharacterExtension(pPose, pCharacterPoseOptions, pPasteState, pPasteEvaluateInfo);
}
void ORCharacterSolver_HIK::CharacterPasteState( FBCharacter* pFromCharacter, FBCharacterPose* pPose, FBCharacterPoseOptions& pCharacterPoseOptions )
{
if(mHIKControlRigHostEvaluator.mHIKCharacter == 0) return;
HIKCharacter* lHIKFromCharacter =
NULL;
HIKEvaluationState lFromState;
PastePoseToTempHikCharacter( pFromCharacter, pPose, pCharacterPoseOptions, lHIKFromCharacter, &lFromState );
const bool lMatchRotation = pCharacterPoseOptions.GetFlag(
kFBCharacterPoseMatchR ) && pCharacterPoseOptions.mModelToMatch !=
NULL;
FBMatrix lHipsOffset_GX;
FBMatrix lMatchModel_GX;
FBMatrix lMatchModel_PoseGX;
if(pCharacterPoseOptions.mModelToMatch)
{
}
FBEvaluateInfo* lEvaluation = BackgroundEvaluateInfoBegin(
FBGetDisplayInfo(),
true);
HIKEvaluationState* lPasteState = GetState(lEvaluation, this);
HIKSetPropertyValue(lCurrentState->mPropertySetState, HIKSnSSmoothReach, 0.0f);
HIKSetPropertyValue(lCurrentState->mPropertySetState, HIKPullIterationCount, 30.0f);
HIKSetPropertyMode(lCurrentState->mPropertySetState, HIKMirrorId, 0.0f);
SolverPasteCharacterPose( mHIKCharacter, lPasteState, lCurrentState, lHIKFromCharacter, &lFromState, pPose, pCharacterPoseOptions, lHipsOffset_GX, lEvaluation );
if(lMatchRotation)
{
OR_HIK_ASSERT(pCharacterPoseOptions.mModelToMatch);
BackgroundEvaluateInfoEnd(lEvaluation);
pCharacterPoseOptions.mModelToMatch->GetMatrix(lMatchModel_PoseGX,
kModelTransformation,
true, lEvaluation);
GetRotationOffset( lMatchModel_GX, lMatchModel_PoseGX, pCharacterPoseOptions, lHipsOffset_GX );
BackgroundEvaluateInfoEnd(lEvaluation);
SolverPasteCharacterPose( mHIKCharacter, lPasteState, lCurrentState, lHIKFromCharacter, &lFromState, pPose, pCharacterPoseOptions, lHipsOffset_GX, lEvaluation );
}
if(lMatchTranslation)
{
OR_HIK_ASSERT(pCharacterPoseOptions.mModelToMatch);
BackgroundEvaluateInfoEnd(lEvaluation);
pCharacterPoseOptions.mModelToMatch->GetMatrix(lMatchModel_PoseGX,
kModelTransformation,
true, lEvaluation);
GetTranslationOffset( lMatchModel_GX, lMatchModel_PoseGX, pCharacterPoseOptions, lHipsOffset_GX );
BackgroundEvaluateInfoEnd(lEvaluation);
SolverPasteCharacterPose( mHIKCharacter, lPasteState, lCurrentState, lHIKFromCharacter, &lFromState, pPose, pCharacterPoseOptions, lHipsOffset_GX, lEvaluation );
}
BackgroundEvaluateInfoEnd(lEvaluation);
}
void ORCharacterSolver_HIK::DoPasteCharacterExtension(FBCharacterPose* pPose, FBCharacterPoseOptions& pCharacterPoseOptions, HIKEvaluationState* pCurrentState, FBEvaluateInfo* pPasteEvaluateInfo)
{
FBCharacter* lToCharacter = TargetCharacter;
int lCharacterExtensionCount = lToCharacter->CharacterExtensions.GetCount();
for(int i = 0; i < lCharacterExtensionCount; i++)
{
FBCharacterExtension* lCharacterExtension = (FBCharacterExtension*)lToCharacter->CharacterExtensions.GetAt(i);
{
if( lCharacterExtension != NULL && !lCharacterExtension->IsElementSelected() )
continue;
}
FBObjectPose* lCharacterExtPose =
NULL;
if(lCharacterExtension != NULL)
{
lCharacterExtPose = pPose->GetCharacterExtensionPose(lCharacterExtension->Label);
}
if(lCharacterExtension && lCharacterExtPose)
{
FBObjectPoseOptions* lObjectPoseOptions = new FBObjectPoseOptions();
{
}
{
{
}
else
{
}
}
FBModel* lReferenceModel = lCharacterExtension->ReferenceModel != NULL ? lCharacterExtension->ReferenceModel : lToCharacter->GetModel(
kFBHipsNodeId );
if(lReferenceModel)
{
lReferenceModel->GetMatrix(lObjectPoseOptions->mReferenceGRM,
kModelRotation,
true, pPasteEvaluateInfo);
lReferenceModel->GetMatrix(lObjectPoseOptions->mReferenceGSM,
kModelScaling,
true, pPasteEvaluateInfo);
}
else
{
lObjectPoseOptions->mReferenceGT.Init();
lObjectPoseOptions->mReferenceGRM.Identity();
lObjectPoseOptions->mReferenceGSM.Identity();
}
lCharacterExtension->GetMirrorExtension() &&
pPose->GetCharacterExtensionPose(lCharacterExtension->GetMirrorExtension()->Label))
{
FBVector4<double> lMirrorPlaneEquation;
pPose->GetMirrorPlaneEquation(lMirrorPlaneEquation, *lToCharacter, pCharacterPoseOptions);
FBObjectPose lMirrorExtensionPose(FBComponentGetLongName(lCharacterExtPose));
FBCharacterExtension* lSrcCharacterExtension = lCharacterExtension->GetMirrorExtension();
OR_HIK_ASSERT(lSrcCharacterExtension);
FBObjectPose* lSrcExtensionPose = pPose->GetCharacterExtensionPose(lSrcCharacterExtension->Label);
OR_HIK_ASSERT(lSrcExtensionPose);
int lObjectIter = 0;
for( lObjectIter = 0; lObjectIter < lCharacterExtension->GetSubObjectCount(); lObjectIter++ )
{
FBModel* lObject = (FBModel*)(lCharacterExtension->GetSubObject(lObjectIter));
if( lObject )
{
FBString lObjectLabel;
lCharacterExtension->GetLabelNameWithExtensionObject(lObjectLabel,lObject,true);
FBObjectPose::RetargetPose
(
lMirrorExtensionPose,
*lSrcExtensionPose,
lObjectLabel,
lObjectLabel
);
FBObjectPose* lSrcStancePose = lSrcCharacterExtension->GetStancePose();
FBObjectPose* lDstStancePose = lCharacterExtension->GetStancePose();
if( lSrcStancePose && lDstStancePose )
{
FBObjectPose::MirrorRetargetPose
(
lMirrorExtensionPose,
*lSrcExtensionPose,
*lDstStancePose,
*lSrcStancePose,
lMirrorPlaneEquation,
lObjectLabel,
lObjectLabel
);
}
lMirrorExtensionPose.PasteTransform( (char*)lObjectLabel, *lObject, *lObjectPoseOptions, pPasteEvaluateInfo );
}
}
}
else
{
int lObjectIter = 0;
for( lObjectIter = 0; lObjectIter < lCharacterExtension->GetSubObjectCount(); lObjectIter++ )
{
FBModel* lObject = (FBModel*)(lCharacterExtension->GetSubObject(lObjectIter));
if( lObject )
{
FBString lObjectLabel;
lCharacterExtension->GetLabelNameWithExtensionObject(lObjectLabel,lObject,true);
lCharacterExtPose->PasteTransform( (char*)lObjectLabel, *lObject, *lObjectPoseOptions, pPasteEvaluateInfo );
}
}
}
}
}
}
void ORCharacterSolver_HIK::GetRotationOffset( const FBMatrix& pMatchModel_GX, const FBMatrix& pMatchMode_PoseTRSM, const FBCharacterPoseOptions& pCharacterPoseOptions, FBMatrix& pHipsOffsetGX )
{
FBMatrix lOffsetRM;
{
FBMatrix lRM;
}
}
void ORCharacterSolver_HIK::GetTranslationOffset( const FBMatrix& pMatchModel_GX, const FBMatrix& pMatchMode_PoseTRSM, const FBCharacterPoseOptions& pCharacterPoseOptions, FBMatrix& pHipsOffsetGX )
{
FBSub( lOffsetT, lMatch_GT, lPastedVector );
{
lOffsetT[0] = 0.0;
}
{
lOffsetT[1] = 0.0;
}
{
lOffsetT[2] = 0.0;
}
pHipsOffsetGX(3,0) = lOffsetT[0];
pHipsOffsetGX(3,1) = lOffsetT[1];
pHipsOffsetGX(3,2) = lOffsetT[2];
pHipsOffsetGX(3,3) = lOffsetT[3];
}
void ORCharacterSolver_HIK::PastePoseToTempHikCharacter( FBCharacter* pFromCharacter, FBCharacterPose* pPose, FBCharacterPoseOptions& pCharacterPoseOptions,
HIKCharacter*& pHIKFromCharacter, HIKEvaluationState* pTempState )
{
FBCharacter* lToCharacter = TargetCharacter;
UndoSetup(lToCharacter);
HIKCharacterHost<HIKHostNodeMB,HIKHostPropertyMB> lHIKFromCharacterHost;
HIKHostPropertiesInit(lHIKFromCharacterHost);
HIKCharacterHostFromFBCharacterPose(lHIKFromCharacterHost, pFromCharacter, pPose);
HIKCharacterFromFBCharacterPose(lHIKFromCharacterHost, pHIKFromCharacter, pFromCharacter, pPose);
HIKHostPropertiesFromCharacter(lHIKFromCharacterHost, pFromCharacter);
RegisterExtraProperties(lHIKFromCharacterHost);
pTempState->Init(pHIKFromCharacter, NULL, &malloc);
lHIKFromCharacterHost.ReadFromPose(pHIKFromCharacter,
FBGetDisplayInfo(), pTempState->mState, pPose);
lHIKFromCharacterHost.ReadCharacterAndPropertiesForSolve(pHIKFromCharacter, pTempState->mPropertySetState,
FBGetDisplayInfo());
{
FBMatrix lMirrorPlaneMatrix;
pPose->GetMirrorPlaneEquation(lMirrorPlaneMatrix, *lToCharacter, pCharacterPoseOptions);
HIKMirrorState( pHIKFromCharacter, pTempState->mState, pTempState->mState, pHIKFromCharacter, lMirrorPlaneEquationQ.mValue);
}
}
bool ORCharacterSolver_HIK::FbxStore( FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat )
{
return true;
}
bool ORCharacterSolver_HIK::FbxRetrieve( FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat )
{
return true;
}
void ORCharacterSolver_HIK::FreezeSuggested()
{
FBConstraint::FreezeSuggested();
if( ReferenceGet( 0,0 ) )
{
FreezeSRT( (FBModel*)ReferenceGet( 0, 0), true, true, true );
}
}
static FBPlug* FindDstPropertyWithOwner(FBPlug* pPlug, FBPlug* pOwner)
{
OR_HIK_ASSERT(pPlug && pOwner);
const int lDstCount = pPlug->GetDstCount();
for(int lDstIndex = 0; lDstIndex < lDstCount; lDstIndex++)
{
FBPlug* lDstPlug = pPlug->GetDst(lDstIndex);
if(lDstPlug->GetOwner() == pOwner &&
FBIS(lDstPlug, FBProperty))
{
return lDstPlug;
}
}
}
void ORCharacterSolver_HIK::AddSolverPropertiesToCharacter(FBCharacter* pDstCharacter)
{
if(FBUndoManager().ActiveOperation()) return;
const int lPropertyCount = mSolverPropertiesCount < PropertyList.GetCount() ? mSolverPropertiesCount : PropertyList.GetCount();
for(int i = mInternalPropertiesCount; i < lPropertyCount; i++)
{
FBProperty* lProp = PropertyList[
i];
if(lProp->GetPropertyFlag(kFBPropertyFlagNotSavable) == false)
{
if(FindDstPropertyWithOwner(lProp, pDstCharacter) ==
NULL)
{
pDstCharacter->PropertyAddReferenceProperty(lProp);
}
}
}
}
void ORCharacterSolver_HIK::RemoveSolverPropertiesFromCharacter(FBCharacter* pDstCharacter)
{
const int lPropertyCount = mSolverPropertiesCount < PropertyList.GetCount() ? mSolverPropertiesCount : PropertyList.GetCount();
for(int i = mInternalPropertiesCount; i < lPropertyCount; i++)
{
FBProperty* lProp = PropertyList[
i];
if(lProp->GetPropertyFlag(kFBPropertyFlagNotSavable) == false)
{
FBProperty* lRefProp = (FBProperty*)FindDstPropertyWithOwner(lProp, pDstCharacter);
if(lRefProp)
{
pDstCharacter->PropertyRemove(lRefProp);
}
}
}
}
void ORCharacterSolver_HIK::RenameSolverPropertiesOnCharacters()
{
FBString lNewName;
const int lPropertyCount = mSolverPropertiesCount < PropertyList.GetCount() ? mSolverPropertiesCount : PropertyList.GetCount();
for(int i = mInternalPropertiesCount; i < lPropertyCount; i++)
{
FBProperty* lSourceProp = PropertyList[
i];
if(lSourceProp->GetPropertyFlag(kFBPropertyFlagNotSavable) == false)
{
const int lDstCount = lSourceProp->GetDstCount();
for(int lDstIndex = 0; lDstIndex < lDstCount; lDstIndex++)
{
FBPlug* lDstPlug = lSourceProp->GetDst(lDstIndex);
if(
FBIS(lDstPlug->GetOwner(), FBCharacter) &&
FBIS(lDstPlug, FBProperty))
{
FBProperty* lRefProperty = (FBProperty*)lDstPlug;
if(lRefProperty->IsReferenceProperty())
{
lNewName = (
const char*)this->
Name;
lNewName += ".";
lNewName += lSourceProp->GetName();
lRefProperty->SetName((const char*)lNewName);
}
}
}
}
}
}
void ORCharacterSolver_HIK::SyncVisibilitySolverPropertiesOnCharacters(FBProperty* pSourceProperty, FBProperty* pRefProperty)
{
if(pRefProperty)
{
OR_HIK_ASSERT(pRefProperty->IsReferenceProperty() && pRefProperty->GetSrcCount() > 0);
pRefProperty->ModifyPropertyFlag(kFBPropertyFlagNotSavable, true);
}
else
{
const int lDstCount = pSourceProperty->GetDstCount();
for(int lDstIndex = 0; lDstIndex < lDstCount; lDstIndex++)
{
FBPlug* lDstPlug = pSourceProperty->GetDst(lDstIndex);
if(
FBIS(lDstPlug->GetOwner(), FBCharacter) &&
FBIS(lDstPlug, FBProperty))
{
FBProperty* lRefProperty = (FBProperty*)lDstPlug;
if(lRefProperty->IsReferenceProperty())
{
lRefProperty->ModifyPropertyFlag(kFBPropertyFlagNotSavable, true);
}
}
}
}
}
{
if(pThis ==
this &&
FBIS(pPlug, FBCharacter))
{
switch (pAction)
{
{
AddSolverPropertiesToCharacter((FBCharacter*)pPlug);
}
break;
{
RemoveSolverPropertiesFromCharacter((FBCharacter*)pPlug);
}
break;
}
}
else if(pAction ==
kFBConnectedDst && pThis->GetOwner() ==
this &&
FBIS(pThis, FBProperty) &&
FBIS(pPlug, FBProperty) )
{
FBProperty* lThisProperty = (FBProperty*)pThis;
FBProperty* lRefProperty = (FBProperty*)pPlug;
if(lRefProperty->IsReferenceProperty())
{
SyncVisibilitySolverPropertiesOnCharacters(lThisProperty, lRefProperty);
}
}
return __FBParentClass::PlugNotify(pAction, pThis, pIndex, pPlug, pConnectionType, pNewPlug);
}
bool ORCharacterSolver_HIK::PlugStateNotify(
FBConnectionAction pAction,FBPlug* pThis,
void* pData,
void* pDataOld,
int pDataSize)
{
if(pThis == this)
{
switch (pAction)
{
{
RenameSolverPropertiesOnCharacters();
}
break;
}
}
return __FBParentClass::PlugStateNotify(pAction, pThis, pData, pDataOld, pDataSize);
}
static void AddPropertyViewForSolverAndCharacter(const char* pPropertyName, const char* pHierarchy, bool pAddToCharacter, bool pIsFolder=false)
{
FBPropertyViewManager::TheOne().AddPropertyView(ORCONSTRAINTHIK__CLASSNAME, pPropertyName, pHierarchy);
if(pAddToCharacter)
{
if(!pIsFolder)
{
FBString lPropertyNameWithAnyPrefix = FBString("*.") + pPropertyName;
FBPropertyViewManager::TheOne().AddPropertyView("KCharacter", (const char*)lPropertyNameWithAnyPrefix, pHierarchy);
}
}
}
void ORCharacterSolver_HIK::AddPropertiesToPropertyViewManager()
{
char lNameBuffer[50];
AddPropertyViewForSolverAndCharacter("HIK Library Version", "", false);
AddPropertyViewForSolverAndCharacter("Weight", "", false);
AddPropertyViewForSolverAndCharacter("Solving", "", true, true);
AddPropertyViewForSolverAndCharacter("Realistic Left Knee Solving", "Solving", true);
AddPropertyViewForSolverAndCharacter("Realistic Right Knee Solving", "Solving", true);
AddPropertyViewForSolverAndCharacter("Realistic Arm Solving", "Solving", true);
AddPropertyViewForSolverAndCharacter("Extra Collar Ratio", "Solving", true);
AddPropertyViewForSolverAndCharacter("Retargeting", "", true, true);
AddPropertyViewForSolverAndCharacter("Finger Propagation", "Retargeting", true);
AddPropertyViewForSolverAndCharacter("Top Spine Correction", "Retargeting", true);
AddPropertyViewForSolverAndCharacter("Lower Spine Correction", "Retargeting", true);
AddPropertyViewForSolverAndCharacter("Reach", "", true, true);
AddPropertyViewForSolverAndCharacter("Reach Left Shoulder", "Reach", true);
AddPropertyViewForSolverAndCharacter("Reach Right Shoulder", "Reach", true);
AddPropertyViewForSolverAndCharacter("Stretch", "", true, true);
AddPropertyViewForSolverAndCharacter("Stretch Neck", "Stretch", true);
AddPropertyViewForSolverAndCharacter("Stretch Spine", "Stretch", true);
AddPropertyViewForSolverAndCharacter("Stretch Damping", "Stretch", true);
for(
int i = 0; i < 10; ++
i)
{
sprintf(lNameBuffer,"Spine %i Min Length", i);
AddPropertyViewForSolverAndCharacter(lNameBuffer, "Stretch", true);
sprintf(lNameBuffer,"Spine %i Max Length", i);
AddPropertyViewForSolverAndCharacter(lNameBuffer, "Stretch", true);
}
for(
int i = 0; i < 10; ++
i)
{
sprintf(lNameBuffer,"Neck %i Min Length", i);
AddPropertyViewForSolverAndCharacter(lNameBuffer, "Stretch", true);
sprintf(lNameBuffer,"Neck %i Max Length", i);
AddPropertyViewForSolverAndCharacter(lNameBuffer, "Stretch", true);
}
AddPropertyViewForSolverAndCharacter("Head Min Length", "Stretch", true);
AddPropertyViewForSolverAndCharacter("Head Max Length", "Stretch", true);
AddPropertyViewForSolverAndCharacter("Stiffness", "", true, true);
AddPropertyViewForSolverAndCharacter("Collar Stiffness X", "Stiffness", true);
AddPropertyViewForSolverAndCharacter("Collar Stiffness Y", "Stiffness", true);
AddPropertyViewForSolverAndCharacter("Collar Stiffness Z", "Stiffness", true);
AddPropertyViewForSolverAndCharacter("Scale (deprecated)", "", true, true);
AddPropertyViewForSolverAndCharacter("Leg SNS", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("Arm SNS", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("StretchStartArmsAndLegs", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("StretchStopArmsAndLegs", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSScaleArmsAndLegs", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachLeftWrist", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachRightWrist", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachLeftAnkle", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachRightAnkle", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSScaleSpine", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSScaleSpineChildren", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSScaleNeck", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachChestEnd", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSReachHead", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSSpineFreedom", "Scale (deprecated)", true);
AddPropertyViewForSolverAndCharacter("SnSNeckFreedom", "Scale (deprecated)", true);
#ifdef _DEBUG
AddPropertyViewForSolverAndCharacter("SolvingStep", "", true, true);
#define AddSolvingStepPropertyView(Step) \
AddPropertyViewForSolverAndCharacter(#Step, "SolvingStep", true); \
AddSolvingStepPropertyView(SolvingStepBodyPull)
AddSolvingStepPropertyView(SolvingStepContact)
AddSolvingStepPropertyView(SolvingStepContactApprox)
AddSolvingStepPropertyView(SolvingStepLeftShoulder)
AddSolvingStepPropertyView(SolvingStepRightShoulder)
AddSolvingStepPropertyView(SolvingStepLeftArm)
AddSolvingStepPropertyView(SolvingStepRightArm)
AddSolvingStepPropertyView(SolvingStepLeftLeg)
AddSolvingStepPropertyView(SolvingStepRightLeg)
AddSolvingStepPropertyView(SolvingStepLeftHand)
AddSolvingStepPropertyView(SolvingStepRightHand)
AddSolvingStepPropertyView(SolvingStepLeftFoot)
AddSolvingStepPropertyView(SolvingStepRightFoot)
AddSolvingStepPropertyView(SolvingStepHead)
AddSolvingStepPropertyView(SolvingStepSpine)
AddSolvingStepPropertyView(SolvingStepHipsTranslation)
AddSolvingStepPropertyView(SolvingStepRollExtraction)
AddSolvingStepPropertyView(SolvingStepLeftArmSnS)
AddSolvingStepPropertyView(SolvingStepRightArmSnS)
AddSolvingStepPropertyView(SolvingStepLeftLegSnS)
AddSolvingStepPropertyView(SolvingStepRightLegSnS)
AddSolvingStepPropertyView(SolvingStepModifiers)
AddSolvingStepPropertyView(SolvingStepAllParts)
#endif
}
#ifdef _DEBUG
#define InitSolvingStep(Step) \
FBPropertyPublish(this, Step, #Step, NULL, OverwriteHIK##Step); \
Step = true; \
void ORCharacterSolver_HIK::InitSolvingProperties()
{
InitSolvingStep(SolvingStepBodyPull)
InitSolvingStep(SolvingStepContact)
InitSolvingStep(SolvingStepContactApprox)
InitSolvingStep(SolvingStepLeftShoulder)
InitSolvingStep(SolvingStepRightShoulder)
InitSolvingStep(SolvingStepLeftArm)
InitSolvingStep(SolvingStepRightArm)
InitSolvingStep(SolvingStepLeftLeg)
InitSolvingStep(SolvingStepRightLeg)
InitSolvingStep(SolvingStepLeftHand)
InitSolvingStep(SolvingStepRightHand)
InitSolvingStep(SolvingStepLeftFoot)
InitSolvingStep(SolvingStepRightFoot)
InitSolvingStep(SolvingStepHead)
InitSolvingStep(SolvingStepSpine)
InitSolvingStep(SolvingStepHipsTranslation)
InitSolvingStep(SolvingStepRollExtraction)
InitSolvingStep(SolvingStepLeftArmSnS)
InitSolvingStep(SolvingStepRightArmSnS)
InitSolvingStep(SolvingStepLeftLegSnS)
InitSolvingStep(SolvingStepRightLegSnS)
InitSolvingStep(SolvingStepModifiers)
InitSolvingStep(SolvingStepAllParts)
}
#endif