3ds Max Exporter------Mesh

154 篇文章 8 订阅
 

3ds Max Exporter------Mesh

标签: classextensionfilenullstringfloat
  2659人阅读  评论(0)  收藏  举报
  分类:
 

Prepare:
1. 3D Studio MAX Plugin AppWizard can be found in the directory /3dsmax5/maxsdk/Help/SDKAPWZ
2. Copy SDKAPWZ.awx file into Visual Studio directory, e.g. C:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin/IDE
3. Run Visual C++ and click new. The appwizard will appear in the list of options.click "File Export", type exporter in the Plugin category, find the paths that you want to use and then the appwizard creates the skeleton code .

Plug-in Requirements:
int ExtCount() : Returns the number of file extensions that the exporter provides (for our example, we provide 1)
const TCHAR Ext(int n) : Returns the 3-letter file extension string for the given extension index (0-based).
const TCHAR LongDesc() : Provides the long description of the file export format.
const TCHAR ShortDesc() : Provides the short description of the file export format, shown in the file export dialog drop-down.
const TCHAR AuthorName() : Provides the string that describes the author and/or company of the exporter plugin.
const TCHAR CopyrightMessage() : Provides the string that shows the copyright for the given exporter and/or exporter format.
const TCHAR OtherMessage1() : not used
const TCHAR OtherMessage2() : not used
unsigned int Version() : Somewhat redundant, but returns a version number for the exporter.
void ShowAbout() : Shows an about box, accessible by the user from the main MAX export dialog.
int DoExport() : The actual export method. BOOL SupportsOptions() : Returns TRUE if the exporter supports some custom export options. Currently, only one option (export selected versus export entire scene) exists.

Export Functions:
//
test if is a mesh node
BOOL IsMesh(INode* pNode)
{
      if(pNode==NULL)
          return FALSE;
     if(!pNode->IsRootNode())
     {
          ObjectState obs=pNode->EvalWorldState(0);
          if(obs.obj)
          {
                //GEOMOBJECT_CLASS_ID is include EDITTRIOBJ_CLASS_ID
                //EDITTRIOBJ_CLASS_ID is EditMesh type id
               //if(obs.obj->SuperClassID()==GEOMOBJECT_CLASS_ID)
                 if(obs.obj->ClassID()==Class_ID(EDITTRIOBJ_CLASS_ID,0))
                        return TRUE;
          }
     }
     return FALSE;
}
//test if is a bone or biped controller
BOOL IsBone(INode* pNode)
{
 if(pNode==NULL)
  return FALSE;
 ObjectState obs=pNode->EvalWorldState(0);
 if(obs.obj==NULL)
  return FALSE;
 if(obs.obj->ClassID()==BONE_OBJ_CLASSID)   //bone class id
  return TRUE;
 if(obs.obj->ClassID()==Class_ID(BONE_CLASS_ID, 0)) //include with Helper
  return TRUE;
 if(obs.obj->ClassID()==Class_ID(DUMMY_CLASS_ID, 0)) //include with Helper
  return FALSE;
 Control* ctrl=pNode->GetTMController();
 if(ctrl->ClassID() == BIPSLAVE_CONTROL_CLASS_ID ||  //others biped parts
  ctrl->ClassID() == BIPBODY_CONTROL_CLASS_ID   //biped root 
 ) 
  return TRUE;
 return FALSE;
}
//Export mesh
BOOL ExportMesh(INode* pNode,FILE* out)
{
 if((!pNode)||(!IsMesh(pNode)))
  return FALSE;
 Mesh_hdr meshHdr;
 memset(&meshHdr,0,sizeof(Mesh_hdr));
 
 Matrix3 tm=pNode->GetObjectTM(0);
 ObjectState os=pNode->EvalWorldState(0);
 if(os.obj)
 {
  Object *obj = os.obj;
  if (obj && obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) 
  { 
            TriObject * tri = NULL;
            tri = (TriObject *) obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
            if (tri) {
     Mesh mesh = tri->GetMesh();
      long startPos = ftell(out);
     fseek(out, sizeof(Mesh_hdr), SEEK_CUR);
     mesh.buildBoundingBox();
     Box3 b=mesh.getBoundingBox();
     ......
    meshHdr.vertCnt=mesh.getNumVerts();
     meshHdr.vertOfS=ftell(out);
     for(int i=0;i<meshHdr.vertCnt;i++)
     {
      Point3 pnt=mesh.getVert(i)*tm;
      MAXtoGL(pnt);
      fwrite(&pnt.x, sizeof(float), 3, out);
     }
     mesh.buildNormals();
     meshHdr.normCnt=mesh.getNumVerts();
     meshHdr.normOfS=ftell(out);
     for(i=0;i<meshHdr.normCnt;i++)
     {
      Point3 norm=Normalize(mesh.getNormal(i));
      MAXtoGL(norm);
      fwrite(&norm.x,sizeof(float),3,out);
     }
     meshHdr.textureCnt=mesh.getNumTVerts();
     Texture_hdr* tp=NULL;
    //texture verts map to mesh verts
     if(meshHdr.textureCnt>0)
     {
      meshHdr.textureCnt=meshHdr.vertCnt;
      tp=new Texture_hdr[meshHdr.textureCnt];
      memset(tp,0,sizeof(Texture_hdr)*meshHdr.textureCnt);
     }
     meshHdr.faceCnt=mesh.getNumFaces();
     meshHdr.faceOfS=ftell(out);
     for(i=0;i<meshHdr.faceCnt;i++)
     {
      Face_hdr fHdr;
      memset(&fHdr,0,sizeof(Face_hdr));
      fHdr.vert[0]=mesh.faces[i].v[0];
      fHdr.vert[1]=mesh.faces[i].v[1];
      fHdr.vert[2]=mesh.faces[i].v[2];
      if(tp)
      {
       for(int j=0;j<3;j++)
        if((tp[fHdr.vert[j]].u==0)&&(tp[fHdr.vert[j]].v==0))
        {
         tp[fHdr.vert[j]].u=mesh.tVerts[mesh.tvFace[i].getTVert(j)].x;
         tp[fHdr.vert[j]].v=mesh.tVerts[mesh.tvFace[i].getTVert(j)].y;
        }
      }
      fwrite(&fHdr,sizeof(Face_hdr),1,out);

     }
     meshHdr.textureOfS=ftell(out);
     if(tp)
     {
      fwrite(tp,sizeof(Texture_hdr),meshHdr.textureCnt,out);
     }
    //all texture vert is follow:
     /*
     meshHdr.textureCnt=mesh.getNumTVerts();
     meshHdr.textureOfS=ftell(out);
     for(i=0;i<meshHdr.textureCnt;i++)
     {
      Texture_hdr tHdr;
      memset(&tHdr,0,sizeof(Texture_hdr));
      tHdr.u=mesh.tVerts[i].x;
      tHdr.v=mesh.tVerts[i].y;
      fwrite(&tHdr,sizeof(Texture_hdr),1,out);
     }
     */
     meshHdr.materialOfs=ftell(out);
     Mtl* mtl=pNode->GetMtl();//just only one or zero
     if(mtl)
     {
      
      if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) //standard material
      { 
        StdMat* std = (StdMat *)mtl;
        if(std)
        {
         Material_hdr mHdr;
         Color tmpCl;
         memset(&mHdr,0,sizeof(Material_hdr));
         long mtlStart=ftell(out);
         fseek(out,sizeof(Material_hdr),SEEK_CUR);
         meshHdr.materialCnt=1;
         tmpCl=std->GetAmbient(0);
         .............
         tmpCl=std->GetDiffuse(0);
        .............
         tmpCl=std->GetSpecular(0);
        .............
         mHdr.shininess=std->GetShininess(0);
         mHdr.opacity=std->GetOpacity(0);

         Texmap *tmap = std->GetSubTexmap(ID_DI);//diffuce channel
         if(tmap)
         {
           if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) 
          {
          BitmapTex *bmt = (BitmapTex*) tmap; //bitmap inform
          ...............
          }
         }
         long mtlEnd=ftell(out);
         fseek(out,mtlStart,SEEK_SET);
         fwrite(&mHdr,sizeof(Material_hdr),1,out);
         fseek(out,mtlEnd,SEEK_SET);
       }
      }
      else if(mtl->ClassID() == Class_ID(MULTI_CLASS_ID,0))
      {
       Material_hdr pmHdr;
       long pmtlStart=ftell(out);
       fseek(out,sizeof(Material_hdr),SEEK_CUR);
       pmHdr.subCnt=mtl->NumSubMtls();
       pmHdr.subOfs=ftell(out);
       for(int j=0;j<pmHdr.subCnt;j++)
       {
        Mtl* sMtl=mtl->GetSubMtl(j);
        ..........................
         }
        }
     }
      long endPos = ftell(out);
     fseek(out, startPos, SEEK_SET);
     fwrite(&meshHdr, sizeof(Mesh_hdr), 1, out);
     fseek(out, endPos, SEEK_SET);
     for(int n=0;n<pNode->NumberOfChildren();n++)
     {
      ExportMesh(pNode->GetChildNode(n),pCnt,out,fp);
     }
    }
  }
 }
 return TRUE;
}
//other way to get mesh
// dummy view used internally by WriteMesh
class NullView : public View {
public:
 Point2 ViewToScreen(Point3 p)
 { 
  return Point2(p.x,p.y); 
 }

 NullView() {
  worldToView.IdentityMatrix();
  screenW=800.0f; screenH = 600.0f;
 }

};

static NullView nullView;
int needDelete;
Mesh &mesh=*(((GeomObject*)os.obj)->GetRenderMesh(0,pNode,nullView,needDelete));


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值