?? ogremayaskeleton.cpp
字號:
// --------------------------------------------------------------------------
bool SkeletonGenerator::_querySkeleton() {
cout << "\nSkeletonGenerator::_querySkeleton\n";
jointList.clear();
MItDag kDagIt(MItDag::kDepthFirst, MFn::kJoint);
MDagPath kRootPath;
MStatus kStatus;
kDagIt.getPath(kRootPath);
// check if valid path
if(!kRootPath.isValid()) {
cout << "\tcan not find parent joint\n";
return false;
}
else {
cout << "\tfound parent joint \""<<kRootPath.partialPathName().asChar()<<"\"\n";
}
/*
// is this really necessary?
// check for skeleton root joint
{
MFnIkJoint kJointFn( kRootPath.node() );
MObject kParentObj = kJointFn.parent(0);
// root joint can not have parent joint
if(!kParentObj.hasFn( MFn::kJoint)) {
cout << "\tParent joint found: \"" << kJointFn.partialPathName().asChar() << "\"\n";
}
else {
MFnDagNode kDagNodeFn(kParentObj);
cout << "\troot joint can not have joint as parent, PATH:\""<<kDagNodeFn.partialPathName().asChar()<<"\"\n";
return 0;
}
}
*/
//Setup skeleton
cout << "\tsetup skeleton\n";
int uiNumJoints = 0;
for( ; !kDagIt.isDone(); kDagIt.next(), ++uiNumJoints ) {
MDagPath kDagPath;
kDagIt.getPath( kDagPath );
MFnIkJoint kJointFn( kDagPath.node() );
SkeletonJoint *pkJoint = new SkeletonJoint;
jointList.push_back( pkJoint );
pkJoint->dagPath = kDagPath;
pkJoint->name = kJointFn.partialPathName().asChar();
pkJoint->index = uiNumJoints;
unsigned int uiNumParents = kJointFn.parentCount();
// can only have one parent
if( uiNumParents != 1 ) {
cout << "\t[ERROR] joint has " << uiNumParents << " parents (only 1 allowed)" << '\n';
return 0;
}
MObject kParentObj = kJointFn.parent(0);
if(kParentObj.hasFn(MFn::kJoint)) {
MFnIkJoint kParentJointFn(kParentObj);
pkJoint->parentName = kParentJointFn.partialPathName().asChar();
pkJoint->hasParent = true;
}
else {
// we've found root here -> mark
root = pkJoint;
pkJoint->parentName = "";
pkJoint->hasParent = false;
}
//Get bindpose world matrix for joint
MPlug kBindMatrixPlug = kJointFn.findPlug("bindPose");
MObject kBindMatrixObject;
kStatus = kBindMatrixPlug.getValue(kBindMatrixObject);
if( kStatus != MStatus::kSuccess ) {
cout << "\t[ERROR] unable to get bind matrix plug object\n";
return 0;
}
MFnMatrixData kMatrixDataFn( kBindMatrixObject );
MMatrix kBindMatrix = kMatrixDataFn.matrix( &kStatus );
if( kStatus != MStatus::kSuccess ) {
cout << "\t[ERROR] unable to get bind matrix data from plug object\n";
return 0;
}
pkJoint->worldMatrix = kBindMatrix;
pkJoint->invWorldMatrix = kBindMatrix.inverse();
}
// if numJoints == 0, we only have single root bone in skeleton
if(!uiNumJoints) {
return true;
}
//Calculate relative position and rotation data
cout << "\tcalculate relative position and rotation data\n";
SkeletonJointList::iterator jointIt = jointList.begin();
SkeletonJointList::iterator jointEnd = jointList.end();
for(;jointIt!=jointEnd; ++jointIt) {
SkeletonJoint* j = *jointIt;
// search for parent node
if(j->hasParent) {
SkeletonJointList::iterator parentJointIt = jointList.begin();
SkeletonJointList::iterator parentJointEnd = jointList.end();
for( ; parentJointIt != parentJointEnd; ++parentJointIt )
if( (*parentJointIt)->name == (*jointIt)->parentName ) {
(*jointIt)->parent = *parentJointIt;
break;
}
}
if(j->hasParent)
j->localMatrix = j->worldMatrix * j->parent->invWorldMatrix;
else
j->localMatrix = j->worldMatrix;
j->invLocalMatrix = j->localMatrix.inverse();
j->relPos.x = j->localMatrix(3,0);
j->relPos.y = j->localMatrix(3,1);
j->relPos.z = j->localMatrix(3,2);
j->relRot = j->localMatrix;
}
// ===== Done
return true;
}
bool SkeletonGenerator::_querySkeletonAnim() {
cout << "\nSkeletonGenerator::_querySkeletonAnim\n";
animations.clear();
MTime kTimeMin = MAnimControl::minTime();
MTime kTimeMax = MAnimControl::maxTime();
MTime kTimeTotal = kTimeMax - kTimeMin;
float fLength = (float)kTimeTotal.as(MTime::kSeconds);
int iTimeMin = (int)kTimeMin.value();
int iTimeMax = (int)kTimeMax.value();
int iFrames = (iTimeMax-iTimeMin)+1;
float secondsPerFrame = fLength / (float)iFrames;
MAnimControl kAnimControl;
cout << "\tanimation start: " << iTimeMin << " end: " << iTimeMax << '\n';
if( iFrames <= 1 )
return false;
Options::KeyframeRangeMap& m = OPTIONS.animations;
Options::KeyframeRangeMap::iterator it = m.begin();
Options::KeyframeRangeMap::iterator end = m.end();
for(;it!=end; ++it) {
string animationName = (*it).first;
int from = (*it).second.from;
int to = (*it).second.to;
int step = (*it).second.step;
int frameCount = to - from + 1;
if(from < iTimeMin || to > iTimeMax || !(frameCount>0)) {
cout << "\t[ERROR] Illegal Animation Range\n";
continue;
}
Animation& anim = animations[animationName];
anim.time = (float)(frameCount)*secondsPerFrame;
SkeletonJointList::iterator ppkJoint = jointList.begin();
SkeletonJointList::iterator ppkJointEnd = jointList.end();
for( ; ppkJoint != ppkJointEnd; ++ppkJoint ) {
MTime kFrame = kTimeMin + (from - 1);
for(int iFrame=0; iFrame<frameCount; iFrame+=step, kFrame+=step) {
kAnimControl.setCurrentTime( kFrame );
MVector kTranslation;
MQuaternion kRotation;
MMatrix kIncMat = (*ppkJoint)->dagPath.inclusiveMatrix();
MMatrix kExcMat = (*ppkJoint)->dagPath.exclusiveMatrix();
MMatrix kExcInvMat = (*ppkJoint)->dagPath.exclusiveMatrixInverse();
if((*ppkJoint)->hasParent) {
MMatrix kLocalMat = kIncMat * kExcInvMat * (*ppkJoint)->invLocalMatrix;
kRotation = kLocalMat;
kTranslation.x = (float)kLocalMat(3, 0);
kTranslation.y = (float)kLocalMat(3, 1);
kTranslation.z = (float)kLocalMat(3, 2);
}
else {
// root has to be handled differently
// cause when exporting root bone to ogre
// we remove all maya parents
kRotation = kIncMat * (*ppkJoint)->invLocalMatrix;
kTranslation.x = (float)(kIncMat(3, 0) - kExcMat(3, 0));
kTranslation.y = (float)(kIncMat(3, 1) - kExcMat(3, 1));
kTranslation.z = (float)(kIncMat(3, 2) - kExcMat(3, 2));
}
float timePos =
(float)iFrame * secondsPerFrame;
anim.keyframes[(*ppkJoint)->name].push_back(
Keyframe(timePos, kTranslation, kRotation)
);
}
}
}
return true;
}
} // namespace OgreMaya
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -