打印本文 打印本文 关闭窗口 关闭窗口
3ds Max Exporter------Skin Bone Animation
作者:武汉SEO闵涛  文章来源:敏韬网  点击数2034  更新时间:2009/4/25 0:44:42  文章录入:mintao  责任编辑:mintao

//Frist processing bone weights
BOOL ProcessingBoneWeights(INode* pNode,INode* pRoot,BoneData* BD)
{
 if((!pNode)||(!IsMesh(pNode)))
  return FALSE;
 Modifier* pmf=GetPhysiqueMod(pNode);
 if(pmf)
  GetPhysiqueWeights(pNode, pRoot, pmf, BD);
 else
 { 
  pmf = GetSkinMod(pNode);
  if (pmf)
   GetSkinWeights(pNode,pMeshIdx,pRoot, pmf, BD);
  }
 int num=pNode->NumberOfChildren();
 for(int n=0;n<num;n++)
 {
  ProcessingBoneWeights(pNode->GetChildNode(n),pRoot,BD);
 }
 return TRUE;
}
//here just take with Physique and Skin Modify .... 
static Modifier* GetPhysiqueMod(INode* pNode)
{
 Object* pObj=pNode->GetObjectRef();
 if(!pObj)
  return NULL;
 while(pObj->SuperClassID()==GEN_DERIVOB_CLASS_ID)
 {
  IDerivedObject* pDerivedObj = static_cast<IDerivedObject*>(pObj);
  int  modStackIndex=0;
  while(modStackIndex<pDerivedObj->NumModifiers())
  {
   Modifier* mod=pDerivedObj->GetModifier(modStackIndex);
   if(mod->ClassID()==Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
    return mod;
   modStackIndex++;
  }
  pObj=pDerivedObj->GetObjRef();
 }
 return NULL;
}
static Modifier* GetSkinMod(INode* pNode)
{
 Object* pObj=pNode->GetObjectRef();
 if(!pObj)
  return NULL;
 while(pObj->SuperClassID()==GEN_DERIVOB_CLASS_ID)
 {
  IDerivedObject* pDerivedObj = static_cast<IDerivedObject*>(pObj);
  int  modStackIndex=0;
  while(modStackIndex<pDerivedObj->NumModifiers())
  {
   Modifier* mod=pDerivedObj->GetModifier(modStackIndex);
   if(mod->ClassID()==SKIN_CLASSID)
    return mod;
   modStackIndex++;
  }
  pObj=pDerivedObj->GetObjRef();
 }
 return NULL;
}
// Get an index from a node pointer
int GetBoneIndex(INode *pRoot, INode *pNode)
{
 if(!IsBone(pNode))
  return -1;

 int boneCount = 0;
 return RecursiveGetBoneIndex(pRoot, pNode, boneCount);
}
//if there is more than one mesh ,we will use pMeshIdx  
BOOL GetSkinWeights(INode* pNode,int* pMeshIdx,INode* pRoot,Modifier* pMod,BoneData* BD)
{
 ISkin* skin = (ISkin*)pMod->GetInterface(I_SKIN);
 if(skin)
 {
  ISkinContextData* skincontext = skin->GetContextInterface(pNode);
  if(skincontext)
  {
   int numVert=skincontext->GetNumPoints();
   for(int i=0;i<numVert;i++)
   {
    int numBones=skincontext->GetNumAssignedBones(i);
    for(int j=0;j<numBones;j++)
    {
     INode* bone=skin->GetBone(skincontext->GetAssignedBone(i,j));//do not use j,but use GetAssignedBone(i,j)
     int boneIdx;
     if(bone)
     { 
      boneIdx=GetBoneIndex(pRoot, bone);
      if(boneIdx==-1)
       continue;
     }
     else
      continue;
      
     BoneWeight_hdr wData;
     wData.meshIdx=*pMeshIdx;
     wData.vertIdx=i;
     wData.weight=skincontext->GetBoneWeight(i,j);
     bool notfound = true;  
     for(int v=0;notfound&&v<BD[boneIdx].weightVect.size();v++)
     {
      if(BD[boneIdx].weightVect[v].vertIdx==wData.vertIdx&&BD[boneIdx].weightVect[v].meshIdx==wData.meshIdx)
      {
       BD[boneIdx].weightVect[v].weight += wData.weight;
       notfound = false;
      }
     }
     if(notfound)
     {
      BD[boneIdx].weightVect.push_back(wData);
      BD[boneIdx].boneHdr.vertexCnt=BD[boneIdx].weightVect.size();
     } 
    }
   }
    
  }
  pMod->ReleaseInterface(I_SKIN, skin);
 }
 return TRUE;
}
BOOL GetPhysiqueWeights(INode *pNode, int* pMeshIdx,INode *pRoot, Modifier *pMod, BoneData *BD)
{
 IPhysiqueExport* phyInterface=(IPhysiqueExport*)pMod->GetInterface(I_PHYINTERFACE);
 if(phyInterface)
 {
  // create a ModContext Export Interface for the specific node of the Physique Modifier
  IPhyContextExport *modContextInt = (IPhyContextExport*)phyInterface->GetContextInterface(pNode);
  // needed by vertex interface (only Rigid one supported for now)
  modContextInt->ConvertToRigid(TRUE);
  // more than a single bone per vertex
  modContextInt->AllowBlending(TRUE);
  if(modContextInt)
  {
   int totalVtx=modContextInt->GetNumberVertices();
   for(int i=0;i<totalVtx;i++)
   {
    IPhyVertexExport* vtxInterface=(IPhyVertexExport*)modContextInt->GetVertexInterface(i);
    if(vtxInterface)
    {
     int vertType=vtxInterface->GetVertexType();
     if(vertType==RIGID_TYPE)
     {
      INode* boneNode=((IPhyRigidVertex*)vtxInterface)->GetNode();
      int boneIdx=GetBoneIndex(pRoot, boneNode);
      BoneWeight_hdr wData;
      wData.meshIdx=*pMeshIdx;
      wData.vertIdx=i;
      wData.weight=1.0f;
      BD[boneIdx].weightVect.push_back(wData);
      BD[boneIdx].boneHdr.vertexCnt=BD[boneIdx].weightVect.size();
     } 
     else if(vertType==RIGID_BLENDED_TYPE)
     {
      IPhyBlendedRigidVertex *vtxBlendedInt = (IPhyBlendedRigidVertex*)vtxInterface;
      for(int j=0;j<vtxBlendedInt->GetNumberNodes();j++)
      {
       INode* boneNode=vtxBlendedInt->GetNode(j);
       int boneIdx=GetBoneIndex(pRoot, boneNode);
       BoneWeight_hdr wData;
       wData.meshIdx=*pMeshIdx;
      

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口