unigine animation 移除动画位移 anim

适用于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);
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值