You can implement your own solver for a customized IK solve instead of using the internal solver or HIK 2014 solver. You can read from the markers again to guide the solver. The following sample shows how to retarget the goal FK state into the skeleton.
void ORCharacterSolver_Custom::SetupAllAnimationNodes()
{
FBCharacter* lCharacter = TargetCharacter;
if(lCharacter != NULL && lCharacter->GetCharacterize() && AnimationNodeInGet())
{
if(TargetCharacter->InputType == kFBCharacterInputMoCap)
{
FBCharacterMarkerSet* lMarkerSet = TargetCharacter->GetCharacterMarkerSet();
if(lMarkerSet)
{
for(int lBodyNodeId = kFBHipsNodeId; lBodyNodeId < kFBLastNodeId; lBodyNodeId++)
{
if(lBodyNodeId != kFBReferenceNodeId)
{
mNodes[lBodyNodeId].Setup(lCharacter->GetModel((FBBodyNodeId)lBodyNodeId), this, lBodyNodeId);
}
}
}
}
}
}
void ORCharacterSolver_Custom::RemoveAllAnimationNodes()
{
// All animation nodes are cleared by the system.
ClearNodes();
}
bool ORCharacterSolver_Custom::AnimationNodeNotify(FBAnimationNode* pConnector,
FBEvaluateInfo* pEvaluateInfo,FBConstraintInfo* pConstraintInfo)
{
//Get the state for this evaluation.
if(mEvaluateId != pEvaluateInfo->GetEvaluationID())
{
mEvaluateId = pEvaluateInfo->GetEvaluationID();
//The character marker set.
if(TargetCharacter->InputType == kFBCharacterInputMoCap)
{
// Simple logic that retargets the goal state into the skeleton.
FBCharacterMarkerSet* lMarkerSet = TargetCharacter->GetCharacterMarkerSet();
if(lMarkerSet)
{
FBControlSetState* lFKState = TargetCharacter->GetControlSetEvaluationCache(pEvaluateInfo);
FBEffectorSetState* lIKState = TargetCharacter->GetEffectorEvaluationCache(pEvaluateInfo);
lMarkerSet->ReadCtrlSetAndEffectorState(lFKState,lIKState,pEvaluateInfo);
// Plotting directly to the control rig is not implemented (check the HIK sample for implementation details)
//const bool lPlotToRig = (TargetCharacter->InputType == kFBCharacterOutputMarkerSet ||
//TargetCharacter->IsPlottingActorToCtrlRig());
FBMatrix lGX;
FBMatrix lCtr2Skeleton;
FBRVector lROffset;
for(int lBodyNodeId = kFBHipsNodeId; lBodyNodeId < kFBLastNodeId; lBodyNodeId++)
{
// Get the global matrix for the body node in the control rig space.
lFKState->GetNodeMatrix((FBBodyNodeId)lBodyNodeId, lGX);
// Conversion from the control rig to the skeleton space.
TargetCharacter->GetROffset((FBBodyNodeId)lBodyNodeId, &lROffset);
FBRotationToMatrix(lCtr2Skeleton, lROffset);
FBMatrixMult(lGX, lGX, lCtr2Skeleton);
// Write the "solve" to the skeleton
mNodes[lBodyNodeId].Write(lGX, pEvaluateInfo, (lBodyNodeId == kFBHipsNodeId));
}
}
}
AnimationNodesOutDisableIfNotWritten(pEvaluateInfo);
}
return true;
}
struct AnimationNodeMapping
{
FBModel* mModel;
FBAnimationNode* mT;
FBAnimationNode* mR;
FBAnimationNode* mS;
AnimationNodeMapping()
{
Clear();
}
~AnimationNodeMapping()
{
Clear();
}
void Clear()
{
mModel = NULL;
mT = mR = mS = NULL;
}
bool Valid() {return mModel != NULL;}
void Setup(FBModel* pModel, FBConstraint* pConstraint, int pIndex=0);
void Write(FBMatrix& pMatrix, FBEvaluateInfo* pEvaluateInfo, bool pWriteT=false, bool pWriteR=true, bool pWriteS=false);
};
void ORCharacterSolver_Custom::AnimationNodeMapping::Setup(FBModel* pModel, FBConstraint* pConstraint, int pIndex)
{
mModel = pModel;
if(mModel)
{
mT = pConstraint->AnimationNodeInCreate(pIndex, mModel, ANIMATIONNODE_TYPE_TRANSLATION);
mR = pConstraint->AnimationNodeInCreate(pIndex, mModel, ANIMATIONNODE_TYPE_ROTATION);
mS = pConstraint->AnimationNodeInCreate(pIndex, mModel, ANIMATIONNODE_TYPE_SCALING);
}
}
void ORCharacterSolver_Custom::AnimationNodeMapping::Write( FBMatrix& pMatrix, FBEvaluateInfo* pEvaluateInfo,
bool pWriteT, bool pWriteR, bool pWriteS )
{
if(Valid())
{
FBTVector lT;
FBRVector lR;
FBSVector lS;
FBMatrixToTRS(lT, lR, lS, pMatrix);
if(pWriteT && mT) mT->WriteData(lT.mValue,pEvaluateInfo);
if(pWriteR && mR) mR->WriteData(lR.mValue,pEvaluateInfo);
if(pWriteS && mS) mS->WriteData(lS.mValue,pEvaluateInfo);
}
}
struct Node
{
FBBodyNodeId mStartNode;
FBBodyNodeId mEndNode;
FBAnimationNode* mReadT;
FBAnimationNode* mWriteT;
double mLength;
Node(FBBodyNodeId pNodeA, FBBodyNodeId pNodeB)
{
mStartNode = pNodeA;
mEndNode = pNodeB;
Clear();
}
~Node()
{
Clear();
}
void ReferenceAdd(FBCharacter* pCharacter, FBConstraint* pConstraint, int pGroup);
void Setup(FBCharacter* pCharacter, FBConstraint* pConstraint, int pIndex);
void Clear()
{
mReadT = NULL;
mWriteT = NULL;
mLength = 1e10;
}
void Solve(FBCharacter* pCharacter, FBConstraint* pConstraint, FBEvaluateInfo* pEvaluateInfo);
};
You can refer to the full CustomMarkerSolver sample at http://area.autodesk.com/downloads/plugins/sample_plug_ins_for_the_flexible_mocap_workflow.