适用于unigine 所有版本,动画相关的操作最好结合sdk bin中的resourceEditor来查看。
步骤是
1、先找出所有根骨骼,因为制作原因可能会有多根根骨骼。
2、选择一根根骨骼作为参考,用于每帧提取其位移,并将这个位移用于所有骨骼的位移进行抵消。一般选取腰间的骨骼。
void AnimManager::removeAnimTranslate(const char* mainBoneName, const char* inpath, const char* outpath, const char* animName)
{
MeshPtr animOut = Unigine::Mesh::create();
MeshPtr anim = Unigine::Mesh::create();
int ret = anim->load(inpath);
int size = anim->getNumBones();
Vector<short> bones;
Vector<short> noParentBones;
int mainBoneId;
int leftHand;
for (int i = 0; i < anim->getNumBones(); i++)
{
const char* name = anim->getBoneName(i);
if (strcmp(name, mainBoneName) == 0) //we choose a main bone that considered as translation reference bone .as there may be lots of no-parent bone (each no parent bone have it's own translation),all no-parent bone can reference to the choosed main bone
{
mainBoneId = i;
}
else
{
if (anim->getBoneParent(i) == -1) //all
{
noParentBones.append(i);
}
if (strcmp(name, "LeftHand") == 0)
{
leftHand = i;
}
}
animOut->addBone(name, anim->getBoneParent(i));
animOut->setBoneTransform(i, anim->getBoneTransform(i));
bones.append(i);
}
int animationId = animOut->addAnimation(animName);
animOut->setAnimationBones(animationId, bones);
int frameNum = anim->getNumAnimationFrames(0);
animOut->setNumAnimationFrames(animationId, frameNum);
Vector<Math::mat4> mats;
bool firstFrame = true;
Math::vec3 t;
for (int i = 0; i < frameNum; i++) {
mats.clear();
anim->getAnimationFrame(0, i, mats);
if (firstFrame)
{
t = mats[mainBoneId].getTranslate();
Log::message("t: %f,%f,%f\n", t.x, t.y, t.z);
firstFrame = false;
}
else
{
//Math::vec3 t;
//t = mats[mainBoneId].getTranslate();
Math::vec3 temp = mats[mainBoneId].getTranslate() - t;
Math::vec3 tt1 = mats[mainBoneId].getTranslate();
Log::message("main %f,%f,%f\n", tt1.x, tt1.y, tt1.z);
//Math::vec3 temp
Math::quat r = mats[mainBoneId].getRotate();
Math::vec3 s = mats[mainBoneId].getScale();
mats[mainBoneId] = Math::translate(t)*Math::rotate(r)*Math::scale(s); //the new transform of mainbone
tt1 = mats[mainBoneId].getTranslate();
Log::message("nmain %f,%f,%f\n", tt1.x, tt1.y, tt1.z);
for (int j = 0; j < noParentBones.size(); j++)
{
Math::vec3 tt = mats[noParentBones[j]].getTranslate();
if (noParentBones[j] == leftHand)
Log::message("pre %f,%f,%f\n", tt.x, tt.y, tt.z);
//mats[noParentBones[j]] *= translate(temp);
r = mats[noParentBones[j]].getRotate();
s = mats[noParentBones[j]].getScale();
tt = mats[noParentBones[j]].getTranslate() - temp;
mats[noParentBones[j]] = Math::translate(tt)*Math::rotate(r)*Math::scale(s);
//tt = mats[noParentBones[j]].getTranslate();
if(noParentBones[j] == leftHand)
Log::message("aft %f,%f,%f\n",tt.x,tt.y,tt.z);
}
}
animOut->setAnimationFrame(animationId, i, mats);
}
animOut->save(outpath);
}