现在的位置: 首页 > 综合 > 正文

3dsmax表情动画的导出

2013年09月07日 ⁄ 综合 ⁄ 共 3203字 ⁄ 字号 评论关闭

作者 任晓宇

1 基本概念

      1Morpher Modifier

   3dsmax中,使用Morpher Modifier可以改变mesh, patch, NURBS model的形状,同时支持Material morphing,通常用来实现复杂的表情动画。

   Mesh添加Morpher Modifier:选择一个mesh->Modify面板->Modifier List->Morpher

     

      2Channel

   每个channel对应一个不同的Mesh,代表一种表情。

  

      通过指定在不同关健帧时每个channel的权重,来实现不同表情的组合过渡。

2 准备工作

      3dsmax6 sdk并没有暴露访问morpher modifier的接口,但是我们可以在3dsmax6/maxsdk/samples/modifiers/morpher/wm3.h中找到它的定义和ClassID

  #define MR3_CLASS_ID           Class_ID(0x17bb6854, 0xa5cba2a3)

  

  class MorphR3 : public Modifier, TimeChangeCallback

  {

  

  };

          

 将此文件include到你的工程中就可以访问morpher modifier接口了。注意,把下面两行代码注释才可以联接通过:  

       

       //static GetMorphMod theModPickmode;

       

       //static GetMorphNode thePickMode;

 

3 实现代码

   1得到morpher modifier

       

      Modifier *wxFindMorpherModifier(INode *pINode)

      {

      #if MAX_RELEASE >= 4000

             // get the object reference of the node

             Object *pObject;

             pObject = pINode->GetObjectRef();

             if(pObject == 0) return 0;

  

             // loop through all derived objects

             while(pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID)

             {

                    IDerivedObject *pDerivedObject;

                    pDerivedObject = static_cast<IDerivedObject *>(pObject);

  

                    // loop through all modifiers

                    int stackId;

                    for(stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++)

                    {

                           // get the modifier

                           Modifier *pModifier;

                           pModifier = pDerivedObject->GetModifier(stackId);

  

                           // check if we found the morpher modifier

                           if(pModifier->ClassID() == MR3_CLASS_ID) return pModifier;

                    }

  

                    // continue with next derived object

                    pObject = pDerivedObject->GetObjRef();

             }

      #endif

  

             return 0;

      }

 

    2,得到每个channel相对于原始Mesh的变化顶点和偏移量:

        

MorphR3*pMorpherModifier = static_cast<MorphR3*>( wxFindMorpherModifier(pNode));

if(pMorpherModifier != NULL )

{

intiNumPoses = (int)pMorpherModifier->chanBank.size();

for(int i = 0; i<iNumPoses; ++i )

{

morphChannel&currChannel =pMorpherModifier->chanBank[i];

if( !currChannel.mActive || !currChannel.mActiveOverride ||!currChannel.cblock || !currChannel.mNumPoints )

{

continue;

}

wxPose pose;

//表情的名称

memcpy( pose.chName, currChannel.mName, sizeof(char)*64);

wxPose::wxOffsetVertex offsetVertex;

//遍历所有顶点

for( int iVertexID = 0; iVertexID<currChannel.mNumPoints;++iVertexID )

{

//判断是否有偏移

if(currChannel.mDeltas[iVertexID] == Point3(0,0,0) )

continue;

//保存顶点ID和偏移量

offsetVertex.index =iVertexID;

offsetVertex.pos =currChannel.mPoints[iVertexID] - m_aVertexArray[iVertexID].vPos;

 pose.m_VertexOffsetMap.push_back(offsetVertex);

}

   3得到channel的关健帧信息

                                         // 权重的变化范围

                    float fRange = currChannel.mSpinmax - currChannel.mSpinmin;

                    Control *Controller = currChannel.cblock->GetController(0);

                    IKeyControl *pIKeyControl = GetKeyControlInterface(Controller);

                    // 关健帧数目

                    int iNumKeys = pIKeyControl->GetNumKeys();

                    for( int j = 0; j < iNumKeys; ++j )

                    {

                           IBezFloatKey FKey;

                           pIKeyControl->GetKey( j, &FKey);

抱歉!评论已关闭.