You can adjust or override the extraction to prevent locking of the elbows/knees. You can refer to the constraintextraction sample at http://area.autodesk.com/downloads/plugins/sample_plug_ins_for_the_flexible_mocap_workflow.
The sample shows how to read the original extraction and decide whether to override the extraction.
void ORConstraintExtraction::SetupAllAnimationNodes() { if(Character.GetSrcCount() > 0) { FBCharacter* lCharacter = (FBCharacter*)Character.GetSrc(0); FBCharacterMarkerSet* lMarkerSet = lCharacter ? lCharacter->GetCharacterMarkerSet():NULL; if(lMarkerSet) { for(int i = 0; i < mNodes.GetCount(); i++) { mNodes[i]->Setup(lCharacter, this, i); } } } } void ORConstraintExtraction::Node::Setup(FBCharacter* pCharacter, FBConstraint* pConstraint, int pIndex) { FBModel* lStartGoalModel = pCharacter->GetGoalModel(mStartNode); FBModel* lEndGoalModel = pCharacter->GetGoalModel(mEndNode); if(lStartGoalModel && lEndGoalModel) { FBTVector lT_A,lT_B,lV; // Get the characterization stance pose to calculate the maximum length. pCharacter->GetTOffset(mStartNode, &lT_A); pCharacter->GetTOffset(mEndNode, &lT_B); FBSub(lV, lT_B, lT_A); // Calculate the maximum allowed length per body part. mLength = FBLength(lV); mReadT = lEndGoalModel->Translation.GetAnimationNode(); // Create the input connector to end the effector translation (global data) mWriteT = pConstraint->AnimationNodeInCreate (pIndex+1, lEndGoalModel, ANIMATIONNODE_TYPE_TRANSLATION); } } void ORConstraintExtraction::Node::Solve(FBCharacter* pCharacter, FBConstraint* pConstraint, FBEvaluateInfo* pEvaluateInfo) { if(mReadT == NULL || mWriteT == NULL) return; FBModel* lStart = pCharacter->GetGoalModel(mStartNode); FBModel* lEnd = pCharacter->GetGoalModel(mEndNode); if(lStart && lEnd) { FBTVector lT_A,lT_B,lV; lStart->GetVector(*(FBVector3d*)(lT_A.mValue), kModelTranslation, true, pEvaluateInfo); // Read from the connector directly, knowing that data over there is always // written globally by the Character Marker Set solver. mReadT->ReadData(lT_B.mValue, pEvaluateInfo); FBSub(lV, lT_B, lT_A); double lCurrentLength = FBLength(lV); // Very simple test that can be expanded to more sophisticated logic. if(lCurrentLength > mLength) { FBMult(lV,lV,mLength/lCurrentLength); FBAdd(lT_B, lT_A, lV); // Write the clamp global translation. mWriteT->WriteData(lT_B.mValue, pEvaluateInfo); } } } bool ORConstraintExtraction::AnimationNodeNotify(FBAnimationNode* pConnector, FBEvaluateInfo* pEvaluateInfo,FBConstraintInfo* pConstraintInfo) { // If any character is connected (Just in case, as it is used blindly afterwards) if(Character.GetSrcCount() > 0) { FBCharacter* lCharacter = (FBCharacter*)Character.GetSrc(0); // Solve all the constraints. for(int i = 0; i < mNodes.GetCount(); i++) { mNodes[i]->Solve(lCharacter, this, pEvaluateInfo); } } // Disable all the animation nodes that you did not write to. // This optimization stops the evaluation engine // from calling AnimationNodeNotify again in the same evaluation ID AnimationNodesOutDisableIfNotWritten(pEvaluateInfo); return true; }