浏览代码

Modularizing

Josh Yelon 20 年之前
父节点
当前提交
af19a37b44
共有 2 个文件被更改,包括 732 次插入0 次删除
  1. 704 0
      pandatool/src/mayaeggimport/mayaEggLoader.cxx
  2. 28 0
      pandatool/src/mayaeggimport/mayaEggLoader.h

+ 704 - 0
pandatool/src/mayaeggimport/mayaEggLoader.cxx

@@ -0,0 +1,704 @@
+// Filename: mayaEggImport.cxx
+// Created by:  jyelon (20Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+//
+// This file contains the code for class MayaEggLoader.  This class
+// does the actual work of copying an EggData tree into the maya scene.
+//
+////////////////////////////////////////////////////////////////////
+
+
+#include "pandatoolbase.h"
+#include "notifyCategoryProxy.h"
+
+#include "eggData.h"
+#include "eggVertexPool.h"
+#include "eggVertex.h"
+#include "eggPolygon.h"
+#include "eggPrimitive.h"
+#include "eggGroupNode.h"
+#include "eggPolysetMaker.h"
+#include "eggBin.h"
+
+#include "mayaEggLoader.h"
+
+class MayaEggMesh;
+class MayaEggJoint;
+class MayaEggTex;
+
+NotifyCategoryDeclNoExport(mayaloader);
+NotifyCategoryDef(mayaloader, "");
+
+class MayaEggLoader
+{
+public:
+  bool ConvertEggData(EggData *data,    bool merge, bool model, bool anim);
+  bool ConvertEggFile(const char *name, bool merge, bool model, bool anim);
+  
+public:
+  void         TraverseEggNode(EggNode *node, EggGroup *context);
+  MayaEggMesh  *GetMesh(EggVertexPool *pool);
+  MayaEggJoint *FindJoint(EggGroup *joint);
+  MayaEggJoint *MakeJoint(EggGroup *joint, EggGroup *context);
+  MayaEggTex   *GetTex(const string &fn);
+  void         CreateSkinModifier(MayaEggMesh *M);
+
+  typedef phash_map<EggVertexPool *, MayaEggMesh *> MeshTable;
+  typedef second_of_pair_iterator<MeshTable::const_iterator> MeshIterator;
+  typedef phash_map<EggGroup *, MayaEggJoint *> JointTable;
+  typedef second_of_pair_iterator<JointTable::const_iterator> JointIterator;
+  typedef phash_map<string, MayaEggTex *> TexTable;
+  typedef second_of_pair_iterator<TexTable::const_iterator> TexIterator;
+
+  MeshTable        _mesh_tab;
+  JointTable       _joint_tab;
+  TexTable         _tex_tab;
+  int              _next_tex;
+  CoordinateSystem _coord_sys;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// MayaEggTex
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class MayaEggTex
+{
+public:
+  string     _path;
+  int        _id;
+  //  StdMat    *_mat;
+  //  BitmapTex *_bmt;
+};
+
+MayaEggTex *MayaEggLoader::GetTex(const string &fn)
+{
+  if (_tex_tab.count(fn))
+    return _tex_tab[fn];
+
+  //  BitmapTex *bmt = NewDefaultBitmapTex();
+  //  bmt->SetMapName((TCHAR*)(fn.c_str()));
+  //  StdMat *mat = NewDefaultStdMat();
+  //  mat->SetSubTexmap(ID_DI, bmt);
+  //  mat->SetTexmapAmt(ID_DI, 1.0, 0);
+  //  mat->EnableMap(ID_DI, TRUE);
+  //  mat->SetActiveTexmap(bmt);
+  //  GetCOREInterface()->ActivateTexture(bmt, mat);
+  
+  MayaEggTex *res = new MayaEggTex;
+  res->_path = fn;
+  res->_id = _next_tex ++;
+  //  res->_bmt = bmt;
+  //  res->_mat = mat;
+
+  _tex_tab[fn] = res;
+  return res;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// MayaEggJoint
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class MayaEggJoint
+{
+public:
+  LMatrix4d      _trans;
+  LVector3d      _endpos;
+  LVector3d      _perp;
+  double         _thickness;
+  //  bool           _inskin;
+  //  SimpleObject2 *_bone;
+  //  INode         *_node;
+  EggGroup      *_egg_joint;
+  MayaEggJoint   *_parent;
+  vector <MayaEggJoint *> _children;
+
+public:
+  LVector3d GetXV(void) { return _trans.get_row3(0); }
+  LVector3d GetYV(void) { return _trans.get_row3(1); }
+  LVector3d GetZV(void) { return _trans.get_row3(2); }
+  LVector3d GetPos(void) { return _trans.get_row3(3); }
+  MayaEggJoint *ChooseBestChild(LVector3d dir);
+  void ChooseEndPos(double thickness);
+  void CreateMayaBone(CoordinateSystem sys);
+};
+
+MayaEggJoint *MayaEggLoader::FindJoint(EggGroup *joint)
+{
+  if (joint==0) return 0;
+  return _joint_tab[joint];
+}
+
+MayaEggJoint *MayaEggLoader::MakeJoint(EggGroup *joint, EggGroup *context)
+{
+  MayaEggJoint *parent = FindJoint(context);
+  MayaEggJoint *result = new MayaEggJoint;
+  LMatrix4d t = joint->get_transform();
+  if (parent) {
+    result->_trans = t * parent->_trans;
+  } else {
+    result->_trans = t;
+  }
+  result->_endpos = LVector3d(0,0,0);
+  result->_perp = LVector3d(0,0,0);
+  result->_thickness = 0.0;
+  //  result->_inskin = false;
+  //  result->_bone = 0;
+  //  result->_node = 0;
+  result->_egg_joint = joint;
+  result->_parent = parent;
+  if (parent) parent->_children.push_back(result);
+  _joint_tab[joint] = result;
+  return result;
+}
+
+MayaEggJoint *MayaEggJoint::ChooseBestChild(LVector3d dir)
+{
+  if (dir.length() < 0.001) return 0;
+  dir.normalize();
+  double firstbest = -1000;
+  MayaEggJoint *firstchild = 0;
+  LVector3d firstpos = GetPos();
+  double secondbest = 0;
+  for (unsigned int i=0; i<_children.size(); i++) {
+    MayaEggJoint *child = _children[i];
+    LVector3d tryfwd = child->GetPos() - GetPos();
+    if ((child->GetPos() != firstpos) && (tryfwd.length() > 0.001)) {
+      LVector3d trydir = tryfwd;
+      trydir.normalize();
+      double quality = trydir.dot(dir);
+      if (quality > firstbest) {
+        secondbest = firstbest;
+        firstbest = quality;
+        firstpos = child->GetPos();
+        firstchild = child;
+      } else if (quality > secondbest) {
+        secondbest = quality;
+      }
+    }
+  }
+  if (firstbest > secondbest + 0.1)
+    return firstchild;
+  return 0;
+}
+
+void MayaEggJoint::ChooseEndPos(double thickness)
+{
+  LVector3d parentpos(0,0,0);
+  LVector3d parentendpos(0,0,1);
+  if (_parent) {
+    parentpos = _parent->GetPos();
+    parentendpos = _parent->_endpos;
+  }
+  LVector3d fwd = GetPos() - parentpos;
+  if (fwd.length() < 0.001) {
+    fwd = parentendpos - parentpos;
+  }
+  fwd.normalize();
+  MayaEggJoint *child = ChooseBestChild(fwd);
+  if (child == 0) {
+    _endpos = fwd * thickness * 0.8 + GetPos();
+    _thickness = thickness * 0.8;
+  } else {
+    _endpos = child->GetPos();
+    _thickness = (_endpos - GetPos()).length();
+    if (_thickness > thickness) _thickness = thickness;
+  }
+  LVector3d orient = _endpos - GetPos();
+  orient.normalize();
+  LVector3d altaxis = orient.cross(LVector3d(0,-1,0));
+  if (altaxis.length() < 0.001) altaxis = orient.cross(LVector3d(0,0,1));
+  _perp = altaxis.cross(orient);
+  _perp.normalize();
+}
+
+void MayaEggJoint::CreateMayaBone(CoordinateSystem sys)
+{
+  //  Point3 xv(ConvertCoordSys(sys, GetXV()));
+  //  Point3 yv(ConvertCoordSys(sys, GetYV()));
+  //  Point3 zv(ConvertCoordSys(sys, GetZV()));
+  //  Point3 pos(ConvertCoordSys(sys, GetPos()));
+  //  Point3 endpos(ConvertCoordSys(sys, _endpos));
+  //  Point3 tzv(ConvertCoordSys(sys, _perp));
+  //  
+  //  Point3 fwd = endpos - pos;
+  //  double len = fwd.Length();
+  //  Point3 txv = fwd * ((float)(1.0/len));
+  //  Point3 tyv = tzv ^ txv;
+  //  Point3 row1 = Point3(txv % xv, txv % yv, txv % zv);
+  //  Point3 row2 = Point3(tyv % xv, tyv % yv, tyv % zv);
+  //  Point3 row3 = Point3(tzv % xv, tzv % yv, tzv % zv);
+  //  Matrix3 oomat(row1,row2,row3,Point3(0,0,0));
+  //  Quat ooquat(oomat);
+  //  _bone = (SimpleObject2*)CreateInstance(GEOMOBJECT_CLASS_ID, BONE_OBJ_CLASSID);
+  //  _node = GetCOREInterface()->CreateObjectNode(_bone);
+  //  _node->SetNodeTM(0, Matrix3(xv, yv, zv, pos));
+  //  IParamBlock2 *blk = _bone->pblock2;
+  //  for (int i=0; i<blk->NumParams(); i++) {
+  //    TSTR n = blk->GetLocalName(i);
+  //    if      (strcmp(n, "Length")==0) blk->SetValue(i,0,(float)len); 
+  //    else if (strcmp(n, "Width")==0)  blk->SetValue(i,0,(float)_thickness);
+  //    else if (strcmp(n, "Height")==0) blk->SetValue(i,0,(float)_thickness);
+  //  }
+  //  Point3 boneColor = GetUIColor(COLOR_BONES);
+  //  _node->SetWireColor(RGB(int(boneColor.x*255.0f), int(boneColor.y*255.0f), int(boneColor.z*255.0f) ));
+  //  _node->SetBoneNodeOnOff(TRUE, 0);
+  //  _node->SetRenderable(FALSE);
+  //  _node->SetName((TCHAR*)(_egg_joint->get_name().c_str()));
+  //  _node->SetObjOffsetRot(ooquat);
+  //  if (_parent) {
+  //    _node->Detach(0, 1);
+  //    _parent->_node->AttachChild(_node, 1);
+  //  }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// MayaEggMesh
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef pair<double, EggGroup *> MayaEggWeight;
+
+struct MayaEggVertex
+{
+  Vertexd               _pos;
+  Normald               _normal;
+  vector<MayaEggWeight> _weights;
+  int                   _index;
+};
+
+struct MEV_Compare: public stl_hash_compare<MayaEggVertex>
+{
+  size_t operator()(const MayaEggVertex &key) const
+  {
+    return key._pos.add_hash(key._normal.get_hash());
+  }
+  bool operator()(const MayaEggVertex &k1, const MayaEggVertex &k2) const
+  {
+    int n = k1._pos.compare_to(k2._pos);
+    if (n < 0) return true;
+    if (n > 0) return false;
+    n = k1._normal.compare_to(k2._normal);
+    if (n < 0) return true;
+    if (n > 0) return false;
+    n = k1._weights.size() - k2._weights.size();
+    if (n < 0) return true;
+    if (n > 0) return false;
+    for (unsigned int i=0; i<k1._weights.size(); i++) {
+      double d = k1._weights[i].first - k2._weights[i].first;
+      if (d < 0) return true;
+      if (d > 0) return false;
+      EggGroup *g1 = k1._weights[i].second;
+      EggGroup *g2 = k2._weights[i].second;
+      if (g1 < g2) return true;
+      if (g1 > g2) return false;
+    }
+    return false;
+  }
+};
+
+typedef phash_set<MayaEggVertex, MEV_Compare> VertTable;
+typedef phash_map<TexCoordd, int>            TVertTable;
+typedef phash_map<Colorf, int>               CVertTable;
+
+class MayaEggMesh
+{
+public:
+  
+  string           _name;
+  //  TriObject       *_obj;
+  //  Mesh            *_mesh;
+  //  INode           *_node;
+  //  IDerivedObject  *_dobj;
+  //  Modifier        *_skin_mod;
+  //  ISkin           *_iskin;
+  //  ISkinImportData *_iskin_import;
+  int              _vert_count;
+  int              _tvert_count;
+  int              _cvert_count;
+  int              _face_count;
+  
+  VertTable  _vert_tab;
+  TVertTable _tvert_tab;
+  CVertTable _cvert_tab;
+  
+  int GetVert(EggVertex *vert, EggGroup *context, CoordinateSystem sys);
+  int GetTVert(TexCoordd uv);
+  int GetCVert(Colorf col);
+  int AddFace(int v0, int v1, int v2, int tv0, int tv1, int tv2, int cv0, int cv1, int cv2, int tex);
+  EggGroup *GetControlJoint(void);
+};
+
+#define CTRLJOINT_DEFORM ((EggGroup*)((char*)(-1)))
+
+int MayaEggMesh::GetVert(EggVertex *vert, EggGroup *context, CoordinateSystem sys)
+{
+  MayaEggVertex vtx;
+  vtx._pos = vert->get_pos3();
+  vtx._normal = vert->get_normal();
+  vtx._index = 0;
+
+  EggVertex::GroupRef::const_iterator gri;
+  for (gri = vert->gref_begin(); gri != vert->gref_end(); ++gri) {
+    EggGroup *egg_joint = (*gri);
+    double membership = egg_joint->get_vertex_membership(vert);
+    vtx._weights.push_back(MayaEggWeight(membership, egg_joint));
+  }
+  if (vtx._weights.size()==0) {
+    if (context != 0)
+      vtx._weights.push_back(MayaEggWeight(1.0, context));
+  }
+  
+  VertTable::const_iterator vti = _vert_tab.find(vtx);
+  if (vti != _vert_tab.end())
+    return vti->_index;
+  
+  //  if (_vert_count == _mesh->numVerts) {
+  //    int nsize = _vert_count*2 + 100;
+  //    _mesh->setNumVerts(nsize, _vert_count?TRUE:FALSE);
+  //  }
+  //  vtx._index = _vert_count++;
+  //  _vert_tab.insert(vtx);
+  //  _mesh->setVert(vtx._index, ConvertCoordSys(sys, vtx._pos));
+  return vtx._index;
+}
+
+int MayaEggMesh::GetTVert(TexCoordd uv)
+{
+  if (_tvert_tab.count(uv))
+    return _tvert_tab[uv];
+  //  if (_tvert_count == _mesh->numTVerts) {
+  //    int nsize = _tvert_count*2 + 100;
+  //    _mesh->setNumTVerts(nsize, _tvert_count?TRUE:FALSE);
+  //  }
+  int idx = _tvert_count++;
+  //  _mesh->setTVert(idx, uv.get_x(), uv.get_y(), 0.0);
+  _tvert_tab[uv] = idx;
+  return idx;
+}
+
+int MayaEggMesh::GetCVert(Colorf col)
+{
+  if (_cvert_tab.count(col))
+    return _cvert_tab[col];
+  //  if (_cvert_count == _mesh->numCVerts) {
+  //    int nsize = _cvert_count*2 + 100;
+  //    _mesh->setNumVertCol(nsize, _cvert_count?TRUE:FALSE);
+  //  }
+  int idx = _cvert_count++;
+  //  _mesh->vertCol[idx] = Point3(col.get_x(), col.get_y(), col.get_z());
+  _cvert_tab[col] = idx;
+  return idx;
+}
+
+MayaEggMesh *MayaEggLoader::GetMesh(EggVertexPool *pool)
+{
+  MayaEggMesh *result = _mesh_tab[pool];
+  if (result == 0) {
+    string name = pool->get_name();
+    int nsize = name.size();
+    if ((nsize > 6) && (name.rfind(".verts")==(nsize-6)))
+      name.resize(nsize-6);
+    result = new MayaEggMesh;
+    result->_name = name;
+    //    result->_obj  = CreateNewTriObject();
+    //    result->_mesh = &result->_obj->GetMesh();
+    //    result->_mesh->setMapSupport(0, TRUE);
+    //    result->_node = GetCOREInterface()->CreateObjectNode(result->_obj);
+    //    result->_dobj = 0;
+    //    result->_skin_mod = 0;
+    //    result->_iskin = 0;
+    //    result->_iskin_import = 0;
+    result->_vert_count = 0;
+    result->_tvert_count = 0;
+    result->_cvert_count = 0;
+    result->_face_count = 0;
+    //    result->_node->SetName((TCHAR*)(name.c_str()));
+    _mesh_tab[pool] = result;
+  }
+  return result;
+}
+
+int MayaEggMesh::AddFace(int v0, int v1, int v2, int tv0, int tv1, int tv2, int cv0, int cv1, int cv2, int tex)
+{
+  static int dump = 0;
+  //  if (_face_count == _mesh->numFaces) {
+  //    int nsize = _face_count*2 + 100;
+  //    BOOL keep = _mesh->numFaces ? TRUE:FALSE;
+  //    _mesh->setNumFaces(nsize, keep);
+  //    _mesh->setNumTVFaces(nsize, keep, _face_count);
+  //    _mesh->setNumVCFaces(nsize, keep, _face_count);
+  //  }
+  int idx = _face_count++;
+  //  _mesh->faces[idx].setVerts(v0,v1,v2);
+  //  _mesh->faces[idx].smGroup = 1;
+  //  _mesh->faces[idx].flags = EDGE_ALL | HAS_TVERTS;
+  //  _mesh->faces[idx].setMatID(tex);
+  //  _mesh->tvFace[idx].setTVerts(tv0,tv1,tv2);
+  //  _mesh->vcFace[idx].setTVerts(cv0,cv1,cv2);
+  return idx;
+}
+
+EggGroup *MayaEggMesh::GetControlJoint(void)
+{
+  EggGroup *result;
+  VertTable::const_iterator vert = _vert_tab.begin();
+  if (vert == _vert_tab.end()) return 0;
+  switch (vert->_weights.size()) {
+  case 0: 
+    for (++vert; vert != _vert_tab.end(); ++vert)
+      if (vert->_weights.size() != 0)
+        return CTRLJOINT_DEFORM;
+    return 0;
+  case 1:
+    result = vert->_weights[0].second;
+    for (++vert; vert != _vert_tab.end(); ++vert)
+      if ((vert->_weights.size() != 1) || (vert->_weights[0].second != result))
+        return CTRLJOINT_DEFORM;
+    return result;
+  default:
+    return CTRLJOINT_DEFORM;
+  }
+}
+
+void MayaEggLoader::CreateSkinModifier(MayaEggMesh *M)
+{
+  //  vector <MayaEggJoint *> joints;
+  //
+  //  M->_dobj = CreateDerivedObject(M->_obj);
+  //  M->_node->SetObjectRef(M->_dobj);
+  //  M->_skin_mod = (Modifier*)CreateInstance(OSM_CLASS_ID, SKIN_CLASSID);
+  //  M->_iskin = (ISkin*)M->_skin_mod->GetInterface(I_SKIN);
+  //  M->_iskin_import = (ISkinImportData*)M->_skin_mod->GetInterface(I_SKINIMPORTDATA);
+  //  M->_dobj->SetAFlag(A_LOCK_TARGET);
+  //  M->_dobj->AddModifier(M->_skin_mod);
+  //  M->_dobj->ClearAFlag(A_LOCK_TARGET);
+  //  GetCOREInterface()->ForceCompleteRedraw();
+  //
+  //  VertTable::const_iterator vert;
+  //  for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
+  //    for (int i=0; i<vert->_weights.size(); i++) {
+  //      double strength = vert->_weights[i].first;
+  //      MayaEggJoint *joint = FindJoint(vert->_weights[i].second);
+  //      if (!joint->_inskin) {
+  //        joint->_inskin = true;
+  //        joints.push_back(joint);
+  //      }
+  //    }
+  //  }
+  //  for (int i=0; i<joints.size(); i++) {
+  //    BOOL last = (i == (joints.size()-1)) ? TRUE : FALSE;
+  //    M->_iskin_import->AddBoneEx(joints[i]->_node, last);
+  //    joints[i]->_inskin = false;
+  //  }
+  //
+  //  GetCOREInterface()->SetCommandPanelTaskMode(TASK_MODE_MODIFY);
+  //  GetCOREInterface()->SelectNode(M->_node);
+  //  GetCOREInterface()->ForceCompleteRedraw();
+  //
+  //  for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
+  //    Tab<INode*> mayaJoints;
+  //    Tab<float> mayaWeights;
+  //    mayaJoints.ZeroCount();
+  //    mayaWeights.ZeroCount();
+  //    for (int i=0; i<vert->_weights.size(); i++) {
+  //      float strength = (float)(vert->_weights[i].first);
+  //      MayaEggJoint *joint = FindJoint(vert->_weights[i].second);
+  //      mayaWeights.Append(1,&strength);
+  //      mayaJoints.Append(1,&(joint->_node));
+  //    }
+  //    M->_iskin_import->AddWeights(M->_node, vert->_index, mayaJoints, mayaWeights);
+  //  }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// TraverseEggData
+//
+// We have an EggData in memory, and now we're going to copy that
+// over into the maya scene graph.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void MayaEggLoader::TraverseEggNode(EggNode *node, EggGroup *context)
+{
+  vector<int> vertIndices;
+  vector<int> tvertIndices;
+  vector<int> cvertIndices;
+  
+  if (node->is_of_type(EggPolygon::get_class_type())) {
+    EggPolygon *poly = DCAST(EggPolygon, node);
+
+    int texid;
+    LMatrix3d uvtrans = LMatrix3d::ident_mat();
+    if (poly->has_texture()) {
+      EggTexture *tex = poly->get_texture(0);
+      texid = GetTex(tex->get_fullpath().to_os_specific())->_id;
+      if (tex->has_transform())
+        uvtrans = tex->get_transform();
+    } else {
+      texid = GetTex("")->_id;
+    }
+    
+    EggPolygon::const_iterator ci;
+    MayaEggMesh *mesh = GetMesh(poly->get_pool());
+    vertIndices.clear();
+    tvertIndices.clear();
+    cvertIndices.clear();
+    for (ci = poly->begin(); ci != poly->end(); ++ci) {
+      EggVertex *vtx = (*ci);
+      EggVertexPool *pool = poly->get_pool();
+      TexCoordd uv = vtx->get_uv();
+      vertIndices.push_back(mesh->GetVert(vtx, context, _coord_sys));
+      tvertIndices.push_back(mesh->GetTVert(uv * uvtrans));
+      cvertIndices.push_back(mesh->GetCVert(vtx->get_color()));
+    }
+    for (unsigned int i=1; i<vertIndices.size()-1; i++)
+      mesh->AddFace(vertIndices[0], vertIndices[i], vertIndices[i+1],
+                    tvertIndices[0], tvertIndices[i], tvertIndices[i+1],
+                    cvertIndices[0], cvertIndices[i], cvertIndices[i+1],
+                    texid);
+  } else if (node->is_of_type(EggGroupNode::get_class_type())) {
+    EggGroupNode *group = DCAST(EggGroupNode, node);
+    if (node->is_of_type(EggGroup::get_class_type())) {
+      EggGroup *group = DCAST(EggGroup, node);
+      if (group->is_joint()) {
+        MakeJoint(group, context);
+        context = group;
+      }
+    }
+    EggGroupNode::const_iterator ci;
+    for (ci = group->begin(); ci != group->end(); ++ci) {
+      TraverseEggNode(*ci, context);
+    }
+  }
+}
+
+bool MayaEggLoader::ConvertEggData(EggData *data, bool merge, bool model, bool anim)
+{
+  if (!merge) {
+    mayaloader_cat.error() << "Currently, only 'merge' mode is implemented.\n";
+    return false;
+  }
+  
+  if ((anim) || (!model)) {
+    mayaloader_cat.error() << "Currently, only model-loading is implemented.\n";
+    return false;
+  }
+
+  MeshIterator ci;
+  JointIterator ji;
+  TexIterator ti;
+
+  //  SuspendAnimate();
+  //  SuspendSetKeyMode();
+  //  AnimateOff();
+  _next_tex = 0;
+  _coord_sys = data->get_coordinate_system();
+  
+  TraverseEggNode(data, NULL);
+
+  for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
+    MayaEggMesh *mesh = (*ci);
+    //    mesh->_mesh->setNumVerts(mesh->_vert_count, TRUE);
+    //    mesh->_mesh->setNumTVerts(mesh->_tvert_count, TRUE);
+    //    mesh->_mesh->setNumVertCol(mesh->_cvert_count, TRUE);
+    //    mesh->_mesh->setNumFaces(mesh->_face_count, TRUE);
+    //    mesh->_mesh->setNumTVFaces(mesh->_face_count, TRUE, mesh->_face_count);
+    //    mesh->_mesh->setNumVCFaces(mesh->_face_count, TRUE, mesh->_face_count);
+    //    mesh->_mesh->InvalidateTopologyCache();
+    //    mesh->_mesh->InvalidateGeomCache();
+    //    mesh->_mesh->buildNormals();
+  }
+  
+  double thickness = 0.0;
+  for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
+    double dfo = ((*ji)->GetPos()).length();
+    if (dfo > thickness) thickness = dfo;
+  }
+  thickness = thickness * 0.025;
+  for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
+    MayaEggJoint *joint = *ji;
+    joint->ChooseEndPos(thickness);
+    joint->CreateMayaBone(_coord_sys);
+  }
+  
+  for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
+    MayaEggMesh *mesh = (*ci);
+    EggGroup *joint = mesh->GetControlJoint();
+    if (joint) CreateSkinModifier(mesh);
+  }
+  
+  if (_next_tex) {
+    //    TSTR name;
+    //    MultiMtl *mtl = NewDefaultMultiMtl();
+    //    mtl->SetNumSubMtls(_next_tex);
+    //    for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
+    //      MayaEggTex *tex = *ti;
+    //      mtl->SetSubMtlAndName(tex->_id, tex->_mat, name);
+    //    }
+    //    for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
+    //      MayaEggMesh *mesh = *ci;
+    //      mesh->_node->SetMtl(mtl);
+    //    }
+  }
+
+  for (ci = _mesh_tab.begin();  ci != _mesh_tab.end();  ++ci) delete *ci;
+  for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) delete *ji;
+  for (ti = _tex_tab.begin();   ti != _tex_tab.end();   ++ti) delete *ti;
+  
+  //  ResumeSetKeyMode();
+  //  ResumeAnimate();
+  
+  mayaloader_cat.info() << "Egg import successful\n";
+  return true;
+}
+
+bool MayaEggLoader::ConvertEggFile(const char *name, bool merge, bool model, bool anim)
+{
+  EggData data;
+  Filename datafn = Filename::from_os_specific(name);
+  if (!data.read(datafn)) {
+    mayaloader_cat.error() << "Cannot read Egg file for import\n";
+    return false;
+  }
+  return ConvertEggData(&data, merge, model, anim);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The two global functions that form the API of this module.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool MayaLoadEggData(EggData *data, bool merge, bool model, bool anim)
+{
+  MayaEggLoader loader;
+  return loader.ConvertEggData(data, merge, model, anim);
+}
+
+bool MayaLoadEggFile(const char *name, bool merge, bool model, bool anim)
+{
+  MayaEggLoader loader;
+  return loader.ConvertEggFile(name, merge, model, anim);
+}
+

+ 28 - 0
pandatool/src/mayaeggimport/mayaEggLoader.h

@@ -0,0 +1,28 @@
+// Filename: mayaEggLoader.h
+// Created by:  jyelon (20jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2005, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MAYAEGGLOADER_H
+#define MAYAEGGLOADER_H
+
+class EggData;
+
+bool MayaLoadEggData(EggData *data,    bool merge, bool model, bool anim);
+bool MayaLoadEggFile(const char *name, bool merge, bool model, bool anim);
+
+#endif
+