From 80efd7c2531239d34b6d2312900511b08c232f24 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Fri, 26 Aug 2005 21:08:47 +0000 Subject: [PATCH] *** empty log message *** --- pandatool/src/maxegg/maxEggLoader.cxx | 736 ++++++++++++++++++++++++++ pandatool/src/maxegg/maxEggLoader.h | 28 + 2 files changed, 764 insertions(+) create mode 100755 pandatool/src/maxegg/maxEggLoader.cxx create mode 100755 pandatool/src/maxegg/maxEggLoader.h diff --git a/pandatool/src/maxegg/maxEggLoader.cxx b/pandatool/src/maxegg/maxEggLoader.cxx new file mode 100755 index 0000000000..df6ee5fe88 --- /dev/null +++ b/pandatool/src/maxegg/maxEggLoader.cxx @@ -0,0 +1,736 @@ +// Filename: maxEggImport.cxx +// Created by: jyelon (15Jul05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// +// +// This file contains the code for class MaxEggLoader. This class +// does the actual work of copying an EggData tree into the max 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 +#include "Max.h" +#include "maxImportRes.h" +#include "istdplug.h" +#include "stdmat.h" +#include "decomp.h" +#include "shape.h" +#include "simpobj.h" +#include "iparamb2.h" +#include "iskin.h" +#include "modstack.h" + +#include "maxEggLoader.h" + +class MaxEggMesh; +class MaxEggJoint; +class MaxEggTex; + +NotifyCategoryDeclNoExport(maxloader); +NotifyCategoryDef(maxloader, ""); + +class MaxEggLoader +{ +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); + MaxEggMesh *GetMesh(EggVertexPool *pool); + MaxEggJoint *FindJoint(EggGroup *joint); + MaxEggJoint *MakeJoint(EggGroup *joint, EggGroup *context); + MaxEggTex *GetTex(const string &fn); + void CreateSkinModifier(MaxEggMesh *M); + + typedef phash_map MeshTable; + typedef second_of_pair_iterator MeshIterator; + typedef phash_map JointTable; + typedef second_of_pair_iterator JointIterator; + typedef phash_map TexTable; + typedef second_of_pair_iterator TexIterator; + + MeshTable _mesh_tab; + JointTable _joint_tab; + TexTable _tex_tab; + int _next_tex; + CoordinateSystem _coord_sys; +}; + +Point3 ConvertCoordSys(CoordinateSystem sys, LVector3d vec) +{ + if (sys == CS_yup_right) { + return Point3(vec[0], -vec[2], vec[1]); + } else { + return Point3(vec[0], vec[1], vec[2]); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MaxEggTex +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class MaxEggTex +{ +public: + string _path; + int _id; + StdMat *_mat; + BitmapTex *_bmt; +}; + +MaxEggTex *MaxEggLoader::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); + + MaxEggTex *res = new MaxEggTex; + res->_path = fn; + res->_id = _next_tex ++; + res->_bmt = bmt; + res->_mat = mat; + + _tex_tab[fn] = res; + return res; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MaxEggJoint +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class MaxEggJoint +{ +public: + LMatrix4d _trans; + LVector3d _endpos; + LVector3d _perp; + double _thickness; + bool _inskin; + SimpleObject2 *_bone; + INode *_node; + EggGroup *_egg_joint; + MaxEggJoint *_parent; + vector _children; + +public: + void GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv); + LVector3d GetPos(void) { return _trans.get_row3(3); } + MaxEggJoint *ChooseBestChild(LVector3d dir); + void ChooseEndPos(double thickness); + void CreateMaxBone(CoordinateSystem sys); +}; + +void MaxEggJoint::GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv) +{ + xv = _trans.get_row3(0); + yv = _trans.get_row3(1); + zv = _trans.get_row3(2); + xv.normalize(); + yv.normalize(); + zv = xv.cross(yv); + zv.normalize(); + yv = zv.cross(xv); +} + +MaxEggJoint *MaxEggLoader::FindJoint(EggGroup *joint) +{ + if (joint==0) return 0; + return _joint_tab[joint]; +} + +MaxEggJoint *MaxEggLoader::MakeJoint(EggGroup *joint, EggGroup *context) +{ + MaxEggJoint *parent = FindJoint(context); + MaxEggJoint *result = new MaxEggJoint; + LMatrix4d t = joint->get_transform3d(); + 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; +} + +MaxEggJoint *MaxEggJoint::ChooseBestChild(LVector3d dir) +{ + if (dir.length() < 0.001) return 0; + dir.normalize(); + double firstbest = -1000; + MaxEggJoint *firstchild = 0; + LVector3d firstpos = GetPos(); + double secondbest = 0; + for (int i=0; i<_children.size(); i++) { + MaxEggJoint *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 MaxEggJoint::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(); + MaxEggJoint *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 MaxEggJoint::CreateMaxBone(CoordinateSystem sys) +{ + LVector3d rxv,ryv,rzv; + GetRotation(rxv, ryv, rzv); + Point3 xv(ConvertCoordSys(sys, rxv)); + Point3 yv(ConvertCoordSys(sys, ryv)); + Point3 zv(ConvertCoordSys(sys, rzv)); + 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; iNumParams(); 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); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MaxEggMesh +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef pair MaxEggWeight; + +struct MaxEggVertex +{ + Vertexd _pos; + Normald _normal; + vector _weights; + int _index; +}; + +struct MEV_Compare: public stl_hash_compare +{ + size_t operator()(const MaxEggVertex &key) const + { + return key._pos.add_hash(key._normal.get_hash()); + } + bool operator()(const MaxEggVertex &k1, const MaxEggVertex &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 (int i=0; i 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 VertTable; +typedef phash_map TVertTable; +typedef phash_map CVertTable; + +class MaxEggMesh +{ +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 MaxEggMesh::GetVert(EggVertex *vert, EggGroup *context, CoordinateSystem sys) +{ + MaxEggVertex 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(MaxEggWeight(membership, egg_joint)); + } + if (vtx._weights.size()==0) { + if (context != 0) + vtx._weights.push_back(MaxEggWeight(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 MaxEggMesh::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 MaxEggMesh::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; +} + +MaxEggMesh *MaxEggLoader::GetMesh(EggVertexPool *pool) +{ + MaxEggMesh *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 MaxEggMesh; + 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 MaxEggMesh::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 *MaxEggMesh::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 MaxEggLoader::CreateSkinModifier(MaxEggMesh *M) +{ + vector 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_weights.size(); i++) { + double strength = vert->_weights[i].first; + MaxEggJoint *joint = FindJoint(vert->_weights[i].second); + if (!joint->_inskin) { + joint->_inskin = true; + joints.push_back(joint); + } + } + } + for (int i=0; i_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 maxJoints; + Tab maxWeights; + maxJoints.ZeroCount(); + maxWeights.ZeroCount(); + for (int i=0; i_weights.size(); i++) { + float strength = (float)(vert->_weights[i].first); + MaxEggJoint *joint = FindJoint(vert->_weights[i].second); + maxWeights.Append(1,&strength); + maxJoints.Append(1,&(joint->_node)); + } + M->_iskin_import->AddWeights(M->_node, vert->_index, maxJoints, maxWeights); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TraverseEggData +// +// We have an EggData in memory, and now we're going to copy that +// over into the max scene graph. +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void MaxEggLoader::TraverseEggNode(EggNode *node, EggGroup *context) +{ + vector vertIndices; + vector tvertIndices; + vector 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_transform2d(); + } else { + texid = GetTex("")->_id; + } + + EggPolygon::const_iterator ci; + MaxEggMesh *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 (int i=1; iAddFace(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 MaxEggLoader::ConvertEggData(EggData *data, bool merge, bool model, bool anim) +{ + if (!merge) { + maxloader_cat.error() << "Currently, only 'merge' mode is implemented.\n"; + return false; + } + + if ((anim) || (!model)) { + maxloader_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) { + MaxEggMesh *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) { + MaxEggJoint *joint = *ji; + joint->ChooseEndPos(thickness); + joint->CreateMaxBone(_coord_sys); + } + + for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { + MaxEggMesh *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) { + MaxEggTex *tex = *ti; + mtl->SetSubMtlAndName(tex->_id, tex->_mat, name); + } + for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { + MaxEggMesh *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(); + + maxloader_cat.info() << "Egg import successful\n"; + return true; +} + +bool MaxEggLoader::ConvertEggFile(const char *name, bool merge, bool model, bool anim) +{ + EggData data; + Filename datafn = Filename::from_os_specific(name); + if (!data.read(datafn)) { + maxloader_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 MaxLoadEggData(EggData *data, bool merge, bool model, bool anim) +{ + MaxEggLoader loader; + return loader.ConvertEggData(data, merge, model, anim); +} + +bool MaxLoadEggFile(const char *name, bool merge, bool model, bool anim) +{ + MaxEggLoader loader; + return loader.ConvertEggFile(name, merge, model, anim); +} + diff --git a/pandatool/src/maxegg/maxEggLoader.h b/pandatool/src/maxegg/maxEggLoader.h new file mode 100755 index 0000000000..b89d29af33 --- /dev/null +++ b/pandatool/src/maxegg/maxEggLoader.h @@ -0,0 +1,28 @@ +// Filename: maxEggLoader.h +// Created by: jyelon (15jul05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef MAXEGGLOADER_H +#define MAXEGGLOADER_H + +class EggData; + +bool MaxLoadEggData(EggData *data, bool merge, bool model, bool anim); +bool MaxLoadEggFile(const char *name, bool merge, bool model, bool anim); + +#endif +