37 #include <maya/MStatus.h> 38 #include <maya/MPxCommand.h> 39 #include <maya/MString.h> 40 #include <maya/MStringArray.h> 41 #include <maya/MArgList.h> 42 #include <maya/MGlobal.h> 43 #include <maya/MObject.h> 44 #include <maya/MFloatPoint.h> 45 #include <maya/MFloatPointArray.h> 46 #include <maya/MFloatArray.h> 47 #include <maya/MPointArray.h> 48 #include <maya/MFnMesh.h> 49 #include <maya/MFnDependencyNode.h> 50 #include <maya/MFnTransform.h> 51 #include <maya/MFnLambertShader.h> 52 #include <maya/MPlug.h> 53 #include <maya/MFnSet.h> 54 #include <maya/MDGModifier.h> 55 #include <maya/MSelectionList.h> 56 #include <maya/MDagPath.h> 57 #include <maya/MFnSingleIndexedComponent.h> 58 #include <maya/MFnDoubleIndexedComponent.h> 59 #include <maya/MPlugArray.h> 60 #include <maya/MDagPathArray.h> 61 #include <maya/MMatrix.h> 62 #include <maya/MTransformationMatrix.h> 63 #include <maya/MFnIkJoint.h> 64 #include <maya/MFnSkinCluster.h> 65 #include <maya/MAnimControl.h> 66 #include <maya/MFnAnimCurve.h> 67 #include <maya/MFnNurbsSurface.h> 68 #include <maya/MFnEnumAttribute.h> 69 #include <maya/MFnSet.h> 76 using std::ostringstream;
86 class MayaEggNurbsSurface;
88 NotifyCategoryDeclNoExport(mayaloader);
89 NotifyCategoryDef(mayaloader,
"");
94 bool ConvertEggData(
EggData *data,
bool merge,
bool model,
bool anim,
bool respect_normals);
95 bool ConvertEggFile(
const char *name,
bool merge,
bool model,
bool anim,
bool respect_normals);
101 MayaEggJoint *FindJoint(
EggGroup *joint);
103 MayaEggGroup *FindGroup(
EggGroup *group);
106 void CreateSkinCluster(MayaEggGeom *M);
109 MObject GetDependencyNode(
string givenName);
113 typedef phash_map<EggGroup *, MayaEggMesh *, pointer_hash> MeshTable;
114 typedef phash_map<EggXfmSAnim *, MayaAnim *, pointer_hash> AnimTable;
115 typedef phash_map<EggGroup *, MayaEggJoint *, pointer_hash> JointTable;
116 typedef phash_map<EggGroup *, MayaEggGroup *, pointer_hash> GroupTable;
117 typedef phash_map<string, MayaEggTex *, string_hash> TexTable;
118 typedef phash_map<EggGroup *, MayaEggNurbsSurface *, pointer_hash> SurfaceTable;
122 JointTable _joint_tab;
123 GroupTable _group_tab;
125 SurfaceTable _surface_tab;
127 vector <MayaEggJoint *> _joint_list;
132 MTime::Unit _timeUnit;
134 void ParseFrameInfo(
string comment);
135 void PrintData(MayaEggMesh *mesh);
139 MSelectionList _collision_nodes;
142 MPoint MakeMPoint(
const LVector3d &vec)
144 return MPoint(vec[0], vec[1], vec[2]);
147 MFloatPoint MakeMayaPoint(
const LVector3d &vec)
149 return MFloatPoint(vec[0], vec[1], vec[2]);
152 MVector MakeMayaVector(
const LVector3d &vec)
154 return MVector(vec[0], vec[1], vec[2]);
157 MColor MakeMayaColor(
const LColor &vec)
159 return MColor(vec[0], vec[1], vec[2], vec[3]);
164 MStatus create_enum_attribute(MObject &node, MString fullName, MString briefName,
165 MStringArray fieldNames,
unsigned fieldIndex) {
168 MFnDependencyNode fnDN( node, &stat );
169 if ( MS::kSuccess != stat ) {
170 mayaloader_cat.error()
171 <<
"Could not create MFnDependencyNode" <<
"\n";
175 MFnEnumAttribute fnAttr;
176 MObject newAttr = fnAttr.create( fullName, briefName,
178 if ( MS::kSuccess != stat ) {
179 mayaloader_cat.error()
180 <<
"Could not create new enum attribute " << fullName.asChar() <<
"\n";
183 for (
unsigned i = 0; i < fieldNames.length(); i++){
184 fnAttr.addField(fieldNames[i], i);
187 stat = fnAttr.setDefault(fieldIndex);
188 if ( MS::kSuccess != stat ) {
189 mayaloader_cat.error()
190 <<
"Could not set value for enum attribute " << fullName.asChar() <<
"\n";
194 fnAttr.setKeyable(
true );
195 fnAttr.setReadable(
true );
196 fnAttr.setWritable(
true );
197 fnAttr.setStorable(
true );
200 stat = fnDN.addAttribute(newAttr, MFnDependencyNode::kLocalDynamicAttr);
201 if ( MS::kSuccess != stat ) {
202 mayaloader_cat.error()
203 <<
"Could not add new enum attribute " << fullName.asChar() <<
"\n";
217 MObject _file_texture;
219 MObject _shading_group;
221 MFnSingleIndexedComponent _component;
222 void AssignNames(
void);
225 void MayaEggTex::AssignNames(
void)
230 MFnDependencyNode shader(_shader);
231 MFnDependencyNode sgroup(_shading_group);
232 MFnDependencyNode filetex(_file_texture);
233 shader.setName(MString(_name.c_str())+
"Shader");
234 sgroup.setName(MString(_name.c_str()));
235 if (_file_texture != MObject::kNullObj) {
236 filetex.setName(MString(_name.c_str())+
"File");
240 MayaEggTex *MayaEggLoader::GetTex(
EggTexture* etex)
244 if (etex !=
nullptr) {
245 name = etex->get_name();
249 if (_tex_tab.count(fn)) {
254 MFnLambertShader shader;
255 MFnDependencyNode filetex;
271 shader.create(
true,&status);
272 MColor firstColor(1.0,1.0,1.0,1.0);
273 status = shader.setColor(firstColor);
274 if (status != MStatus::kSuccess) {
275 mayaloader_cat.error() <<
"setColor failed on LambertShader\n";
276 status.perror(
"shader setColor failed!");
278 sgroup.create(MSelectionList(), MFnSet::kRenderableOnly, &status);
279 MPlug surfplug = sgroup.findPlug(
"surfaceShader");
280 if (surfplug.connectedTo(oldplugs,
true,
false)) {
281 for (
unsigned int i=0; i<oldplugs.length(); i++) {
282 MPlug src = oldplugs[i];
283 status = dgmod.disconnect(src, surfplug);
284 if (status != MStatus::kSuccess) {
285 status.perror(
"Disconnecting old shader");
289 status = dgmod.connect(shader.findPlug(
"outColor"),surfplug);
290 if (status != MStatus::kSuccess) {
291 status.perror(
"Connecting shader");
294 filetex.create(
"file",&status);
295 MString fn_str(fn.c_str());
296 filetex.findPlug(
"fileTextureName").setValue(fn_str);
297 dgmod.connect(filetex.findPlug(
"outColor"),shader.findPlug(
"color"));
302 if (((tex !=
nullptr) && (tex->get_num_components() == 4))
303 || (etex->get_format() == EggTexture::F_alpha)
304 || (etex->get_format() == EggTexture::F_luminance_alpha))
305 dgmod.connect(filetex.findPlug(
"outTransparency"),shader.findPlug(
"transparency"));
307 status = dgmod.doIt();
308 if (status != MStatus::kSuccess) {
309 status.perror(
"DGMod doIt");
313 MayaEggTex *res =
new MayaEggTex;
316 res->_file_texture = filetex.object();
317 res->_shader = shader.object();
318 res->_shading_group = sgroup.object();
339 MayaEggGroup *pg = FindGroup(context);
340 MayaEggGroup *result =
new MayaEggGroup;
343 MObject parent = MObject::kNullObj;
346 if (mayaloader_cat.is_debug()) {
347 mayaloader_cat.debug() <<
"parent (group) :" << ((MFnDagNode)parent).name().asChar() << endl;
351 result->_name = group->get_name();
352 result->_group = dgn.create(
"transform", MString(result->_name.c_str()), parent, &status);
353 result->_addedEggFlag =
false;
355 if (group->get_cs_type() != EggGroup::CST_none)
356 _collision_nodes.add(result->_group,
true);
360 double matData[4][4] = {{tMat.get_cell(0,0), tMat.get_cell(0,1), tMat.get_cell(0,2), tMat.get_cell(0,3)},
361 {tMat.get_cell(1,0), tMat.get_cell(1,1), tMat.get_cell(1,2), tMat.get_cell(1,3)},
362 {tMat.get_cell(2,0), tMat.get_cell(2,1), tMat.get_cell(2,2), tMat.get_cell(2,3)},
363 {tMat.get_cell(3,0), tMat.get_cell(3,1), tMat.get_cell(3,2), tMat.get_cell(3,3)}};
364 MMatrix mat(matData);
366 MTransformationMatrix matrix = MTransformationMatrix(mat);
367 MFnTransform tFn(result->_group, &status);
368 if (status != MStatus::kSuccess) {
369 status.perror(
"MFnTransformNode:create failed!");
375 if (status != MStatus::kSuccess) {
376 status.perror(
"MFnDagNode:create failed!");
379 if ((pg) && (pg->_addedEggFlag ==
false)){
381 MStringArray eggFlags;
382 for (
int i = 0; i < context->get_num_object_types(); i++) {
383 eggFlags.append(MString(context->get_object_type(i).c_str()));
386 for (
unsigned i = 0; i < eggFlags.length(); i++) {
387 MString attrName =
"eggObjectTypes";
388 attrName += (int)(i + 1);
389 status = create_enum_attribute(parent, attrName, attrName, eggFlags, i);
390 if (status != MStatus::kSuccess) {
391 status.perror(
"create_enum_attribute failed!");
394 pg->_addedEggFlag =
true;
397 _group_tab[group] = result;
401 MayaEggGroup *MayaEggLoader::FindGroup(
EggGroup *group)
406 return _group_tab[group];
420 MDagPath _joint_dag_path;
425 MayaEggJoint *_parent;
426 vector <MayaEggJoint *> _children;
429 void GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv);
430 LVector3d GetPos(
void) {
return _trans.get_row3(3); }
431 MayaEggJoint *ChooseBestChild(LVector3d dir);
432 void ChooseEndPos(
double thickness);
433 void CreateMayaBone(MayaEggGroup *eggParent);
434 void AssignNames(
void);
437 void MayaEggJoint::GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv)
439 xv = _trans.get_row3(0);
440 yv = _trans.get_row3(1);
441 zv = _trans.get_row3(2);
449 void MayaEggJoint::AssignNames(
void)
451 string name = _egg_joint->get_name();
452 MFnDependencyNode joint(_joint);
453 joint.setName(name.c_str());
454 if (mayaloader_cat.is_spam()) {
455 mayaloader_cat.spam() <<
"joint " << joint.name().asChar() <<
": -> " << name << endl;
459 MayaEggJoint *MayaEggLoader::FindJoint(
EggGroup *joint)
461 if (joint==
nullptr) {
462 if (mayaloader_cat.is_spam()) {
463 mayaloader_cat.spam() <<
"joint:" << joint->get_name() <<
" is null: " << endl;
468 if (mayaloader_cat.is_spam()) {
469 mayaloader_cat.spam() <<
"joint:" << joint->get_name() <<
" is not a joint: " << endl;
473 return _joint_tab[joint];
478 MayaEggJoint *parent = FindJoint(context);
479 if (mayaloader_cat.is_debug()) {
480 string parent_name =
"";
482 parent_name = context->get_name();
484 MayaEggJoint *result =
new MayaEggJoint;
487 result->_trans = t * parent->_trans;
491 result->_endpos = LVector3d(0,0,0);
492 result->_perp = LVector3d(0,0,0);
493 result->_thickness = 0.0;
494 result->_egg_joint = joint;
495 result->_egg_parent = context;
496 result->_parent = parent;
497 result->_joint = MObject::kNullObj;
498 result->_inskin =
false;
501 parent->_children.push_back(result);
503 _joint_tab[joint] = result;
506 _joint_list.push_back(result);
511 MayaEggJoint *MayaEggJoint::ChooseBestChild(LVector3d dir)
513 if (dir.length() < 0.001) {
517 double firstbest = -1000;
518 MayaEggJoint *firstchild = 0;
519 LVector3d firstpos = GetPos();
520 double secondbest = 0;
521 for (
unsigned int i=0; i<_children.size(); i++) {
522 MayaEggJoint *child = _children[i];
523 LVector3d tryfwd = child->GetPos() - GetPos();
524 if ((child->GetPos() != firstpos) && (tryfwd.length() > 0.001)) {
525 LVector3d trydir = tryfwd;
527 double quality = trydir.dot(dir);
528 if (quality > firstbest) {
529 secondbest = firstbest;
531 firstpos = child->GetPos();
533 }
else if (quality > secondbest) {
534 secondbest = quality;
538 if (firstbest > secondbest + 0.1) {
544 void MayaEggJoint::ChooseEndPos(
double thickness)
546 LVector3d parentpos(0,0,0);
547 LVector3d parentendpos(0,0,1);
549 parentpos = _parent->GetPos();
550 parentendpos = _parent->_endpos;
552 LVector3d fwd = GetPos() - parentpos;
553 if (fwd.length() < 0.001) {
554 fwd = parentendpos - parentpos;
558 MayaEggJoint *child = ChooseBestChild(fwd);
560 _endpos = fwd * thickness * 0.8 + GetPos();
561 _thickness = thickness * 0.8;
563 _endpos = child->GetPos();
564 _thickness = (_endpos - GetPos()).length();
565 if (_thickness > thickness) _thickness = thickness;
567 LVector3d orient = _endpos - GetPos();
569 LVector3d altaxis = orient.cross(LVector3d(0,-1,0));
570 if (altaxis.length() < 0.001) {
571 altaxis = orient.cross(LVector3d(0,0,1));
573 _perp = altaxis.cross(orient);
577 void MayaEggJoint::CreateMayaBone(MayaEggGroup *eggParent)
579 LVector3d rxv, ryv, rzv;
583 rxv = _trans.get_row3(0);
584 ryv = _trans.get_row3(1);
585 rzv = _trans.get_row3(2);
587 MFloatPoint xv(MakeMayaPoint(rxv));
588 MFloatPoint yv(MakeMayaPoint(ryv));
589 MFloatPoint zv(MakeMayaPoint(rzv));
590 MFloatPoint pos(MakeMayaPoint(GetPos()));
591 MFloatPoint endpos(MakeMayaPoint(_endpos));
592 MFloatPoint tzv(MakeMayaPoint(_perp));
594 m[0][0]=xv.x; m[0][1]=xv.y; m[0][2]=xv.z; m[0][3]=0;
595 m[1][0]=yv.x; m[1][1]=yv.y; m[1][2]=yv.z; m[1][3]=0;
596 m[2][0]=zv.x; m[2][1]=zv.y; m[2][2]=zv.z; m[2][3]=0;
597 m[3][0]=pos.x; m[3][1]=pos.y; m[3][2]=pos.z; m[3][3]=1;
601 trans = trans * _parent->_joint_abs.inverse();
603 MTransformationMatrix mtm(trans);
607 ikj.create(_parent->_joint);
612 ikj.create(eggParent->_group);
619 _joint = ikj.object();
620 ikj.getPath(_joint_dag_path);
626 typedef std::pair<double, EggGroup *> MayaEggWeight;
633 vector<MayaEggWeight> _weights;
641 size_t operator()(
const MayaEggVertex &key)
const 643 return key._pos.add_hash(key._normal.get_hash());
645 bool operator()(
const MayaEggVertex &k1,
const MayaEggVertex &k2)
const 647 int n = k1._pos.compare_to(k2._pos);
654 n = k1._normal.compare_to(k2._normal);
661 n = k1._uv.compare_to(k2._uv);
668 n = k1._weights.size() - k2._weights.size();
675 for (
unsigned int i=0; i<k1._weights.size(); i++) {
676 double d = k1._weights[i].first - k2._weights[i].first;
683 EggGroup *g1 = k1._weights[i].second;
684 EggGroup *g2 = k2._weights[i].second;
692 n = k1._external_index - k2._external_index;
705 typedef phash_set<MayaEggVertex, MEV_Compare> VertTable;
715 MDagPath _shape_dag_path;
720 MFloatPointArray _vertexArray;
721 MVectorArray _normalArray;
722 MColorArray _vertColorArray;
723 MIntArray _vertColorIndices;
724 MIntArray _vertNormalIndices;
726 MStringArray _eggObjectTypes;
734 virtual void ConnectTextures(
void) = 0;
735 void AssignNames(
void);
736 void AddEggFlag(MString);
743 vtx._sumWeights = 0.0;
747 vtx._pos = vert->
get_pos3() * xform;
748 if (vert->has_normal()) {
749 vtx._normal = vert->get_normal() * xform;
755 vtx._external_index = vert->
get_index()-1;
757 EggVertex::GroupRef::const_iterator gri;
765 mayaloader_cat.warning() <<
"negative weight value " << membership <<
" is replaced with 0 on: " << context->get_name() << endl;
769 vtx._weights.push_back(MayaEggWeight(membership, egg_joint));
770 vtx._sumWeights += membership;
773 if (vtx._weights.size()==0) {
775 vtx._weights.push_back(MayaEggWeight(1.0, context));
776 vtx._sumWeights = 1.0;
791 VertTable::const_iterator vti = _vert_tab.find(vtx);
792 if (vti != _vert_tab.end()) {
796 if (mayaloader_cat.is_spam()) {
797 ostringstream stream;
798 stream <<
"(" << vti->_pos <<
" " << vti->_normal <<
" " << vti->_uv <<
")\n";
799 stream <<
"[" << vtx._pos <<
" " << vtx._normal <<
" " << vtx._uv <<
"]\n";
800 stream <<
"{" << vert->
get_pos3() <<
" ";
801 if (vert->has_normal()) {
802 stream << vert->get_normal() <<
" ";
808 mayaloader_cat.spam() <<
"found a matching vertex: " << *vert << endl << stream.str() << endl;
814 vtx._index = _vert_count++;
820 _vertexArray.append(MakeMayaPoint(vtx._pos));
821 if (vert->has_normal()) {
822 _normalArray.append(MakeMayaVector(vtx._normal));
823 _vertNormalIndices.append(vtx._index);
825 if (vert->has_color()) {
826 if (mayaloader_cat.is_spam()) {
827 mayaloader_cat.spam() <<
"found a vertex color\n";
829 _vertColorArray.append(MakeMayaColor(vert->
get_color()));
830 _vertColorIndices.append(vtx._index);
832 _vert_tab.insert(vtx);
837 void MayaEggGeom::AssignNames(
void)
839 string name = _pool->get_name();
840 size_t nsize = name.size();
841 if (nsize > 6 && name.rfind(
".verts") == (nsize - 6)) {
842 name.resize(nsize - 6);
844 if (nsize > 4 && name.rfind(
".cvs") == (nsize - 4)) {
845 name.resize(nsize - 4);
848 MFnDependencyNode dnshape(_shapeNode);
849 MFnDependencyNode dntrans(_transNode);
852 dntrans.setName(MString(name.c_str()));
855 string shape_name = string(dntrans.name().asChar());
856 string numbers (
"0123456789");
859 found=shape_name.find_last_not_of(numbers);
860 if (found!=string::npos)
861 shape_name.insert(found+1,
"Shape");
863 shape_name.append(
"Shape");
865 dnshape.setName(MString(shape_name.c_str()));
868 #define CTRLJOINT_DEFORM ((EggGroup*)((char*)(-1))) 871 EggGroup *MayaEggGeom::GetControlJoint(
void)
874 VertTable::const_iterator vert = _vert_tab.begin();
875 if (vert == _vert_tab.end()) {
878 switch (vert->_weights.size()) {
880 for (++vert; vert != _vert_tab.end(); ++vert) {
881 if (vert->_weights.size() != 0) {
882 return CTRLJOINT_DEFORM;
887 result = vert->_weights[0].second;
888 for (++vert; vert != _vert_tab.end(); ++vert) {
889 if ((vert->_weights.size() != 1) || (vert->_weights[0].second != result)) {
890 return CTRLJOINT_DEFORM;
895 return CTRLJOINT_DEFORM;
899 void MayaEggGeom::AddEggFlag(MString fieldName) {
900 bool addNewFlag =
true;
901 for (
unsigned i = 0; i < _eggObjectTypes.length(); i++) {
902 if (_eggObjectTypes[i] == fieldName) {
908 _eggObjectTypes.append(fieldName);
913 typedef phash_map<LTexCoordd, int> TVertTable;
914 typedef phash_map<LColor, int> CVertTable;
916 class MayaEggMesh final :
public MayaEggGeom
919 MColorArray _faceColorArray;
920 MIntArray _faceIndices;
921 MIntArray _polygonCounts;
922 MIntArray _polygonConnects;
931 vector<MayaEggTex*> _face_tex;
933 TVertTable _tvert_tab;
934 CVertTable _cvert_tab;
936 int GetTVert(
const LTexCoordd &uv);
937 int GetCVert(
const LColor &col);
938 int AddFace(
unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex);
940 void ConnectTextures(
void)
override;
943 int MayaEggMesh::GetTVert(
const LTexCoordd &uv)
945 if (_tvert_tab.count(uv)) {
946 if (mayaloader_cat.is_spam()) {
947 mayaloader_cat.spam() <<
"found uv coords idx: " << _tvert_tab[uv] << endl;
949 return _tvert_tab[uv];
951 int idx = _tvert_count++;
952 _uarray.append(uv.get_x());
953 _varray.append(uv.get_y());
954 _tvert_tab[uv] = idx;
955 if (mayaloader_cat.is_spam()) {
956 mayaloader_cat.spam() <<
"adding uv coords idx:" << idx << endl;
961 int MayaEggMesh::GetCVert(
const LColor &col)
975 MayaEggMesh *result = _mesh_tab[parent];
977 result =
new MayaEggMesh;
978 if (parent !=
nullptr) {
979 result->_name = parent->get_name();
981 result->_pool = pool;
982 result->_parent = parent;
983 result->_vert_count = 0;
984 result->_tvert_count = 0;
985 result->_cvert_count = 0;
986 result->_face_count = 0;
987 result->_vertColorArray.clear();
988 result->_vertNormalIndices.clear();
989 result->_vertColorIndices.clear();
990 result->_faceColorArray.clear();
991 result->_faceIndices.clear();
992 result->_eggObjectTypes.clear();
993 result->_renameTrans =
false;
994 _mesh_tab[parent] = result;
999 int MayaEggMesh::AddFace(
unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex)
1001 int idx = _face_count++;
1002 _polygonCounts.append(numVertices);
1003 for (
unsigned i = 0; i < mvertIndices.length(); i++)
1005 _polygonConnects.append(mvertIndices[i]);
1006 _uvIds.append(mtvertIndices[i]);
1008 _face_tex.push_back(tex);
1012 void MayaEggMesh::ConnectTextures(
void)
1014 bool subtex =
false;
1015 for (
int i=1; i<_face_count; i++) {
1016 if (_face_tex[i] != _face_tex[0]) {
1021 MFnSet sg(_face_tex[0]->_shading_group);
1022 sg.addMember(_shapeNode);
1025 for (
int i=0; i<_face_count; i++) {
1026 MayaEggTex *tex = _face_tex[i];
1027 if (tex->_component.object()==MObject::kNullObj) {
1028 tex->_component.create(MFn::kMeshPolygonComponent);
1030 tex->_component.addElement(i);
1032 for (
int i=0; i<_face_count; i++) {
1033 MayaEggTex *tex = _face_tex[i];
1034 if (tex->_component.object()!=MObject::kNullObj) {
1035 MFnSet sg(tex->_shading_group);
1036 sg.addMember(_shape_dag_path, tex->_component.object());
1037 tex->_component.setObject(MObject::kNullObj);
1044 class MayaEggNurbsSurface :
public MayaEggGeom
1049 MPointArray _cvArray;
1050 MDoubleArray _uKnotArray;
1051 MDoubleArray _vKnotArray;
1057 MFnNurbsSurface::Form _uForm;
1058 MFnNurbsSurface::Form _vForm;
1062 void ConnectTextures(
void);
1063 void PrintData(
void);
1068 MayaEggNurbsSurface *result = _surface_tab[parent];
1070 result =
new MayaEggNurbsSurface;
1071 result->_pool = pool;
1072 result->_parent = parent;
1073 result->_name = parent->get_name();
1075 result->_vert_count = 0;
1076 result->_vertColorArray.clear();
1077 result->_vertNormalIndices.clear();
1078 result->_vertColorIndices.clear();
1080 result->_cvArray.clear();
1081 result->_uKnotArray.clear();
1082 result->_vKnotArray.clear();
1084 result->_uDegree = 0;
1085 result->_vDegree = 0;
1086 result->_uNumCvs = 0;
1087 result->_vNumCvs = 0;
1088 result->_uForm = MFnNurbsSurface::kClosed;
1089 result->_vForm = MFnNurbsSurface::kClosed;
1091 result->_eggObjectTypes.clear();
1092 result->_renameTrans =
false;
1093 _surface_tab[parent] = result;
1098 void MayaEggNurbsSurface::ConnectTextures(
void)
1104 MColor firstColor(0.5,0.5,0.5,1.0);
1105 if (_vertColorArray.length() > 0) {
1106 firstColor = _vertColorArray[0];
1107 MFnLambertShader sh(_tex->_shader);
1108 status = sh.setColor(firstColor);
1109 if (status != MStatus::kSuccess) {
1110 mayaloader_cat.error() <<
"setColor failed on " << _name;
1111 status.perror(
"shader setColor failed!");
1114 MFnSet sg(_tex->_shading_group);
1115 status = sg.addMember(_shapeNode);
1116 if (status != MStatus::kSuccess) {
1117 mayaloader_cat.error() <<
"addMember failed on " << _name;
1118 status.perror(
"shader addMember failed!");
1123 void MayaEggNurbsSurface::PrintData(
void)
1125 if (mayaloader_cat.is_debug()) {
1126 mayaloader_cat.debug() <<
"nurbsSurface : " << _name << endl;
1128 mayaloader_cat.debug() <<
"u_form : " << _uForm << endl;
1129 mayaloader_cat.debug() <<
"v_form : " << _vForm << endl;
1158 void PrintData(
void);
1161 MayaAnim *MayaEggLoader::GetAnim(
EggXfmSAnim *pool)
1163 MayaAnim *result = _anim_tab[pool];
1165 result =
new MayaAnim;
1166 result->_pool = pool;
1167 result->_name = pool->get_name();
1168 _anim_tab[pool] = result;
1171 result->_joint = joint;
1177 void MayaAnim::PrintData(
void)
1179 if (mayaloader_cat.is_debug()) {
1180 mayaloader_cat.debug() <<
"anim on joint : " << _joint->get_name() << endl;
1182 _pool->write(mayaloader_cat.debug(), 0);
1187 void MayaEggLoader::CreateSkinCluster(MayaEggGeom *M)
1189 MString cmd(
"skinCluster -mi ");
1190 vector <MayaEggJoint *> joints;
1192 VertTable::const_iterator vert;
1193 int maxInfluences = 0;
1194 for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
1195 if ((
int)(vert->_weights.size()) > maxInfluences) {
1196 maxInfluences = vert->_weights.size();
1198 for (
unsigned int i=0; i<vert->_weights.size(); i++) {
1199 MayaEggJoint *joint = FindJoint(vert->_weights[i].second);
1200 if (joint && !joint->_inskin) {
1201 joint->_inskin =
true;
1202 joint->_index = joints.size();
1203 joints.push_back(joint);
1212 cmd += maxInfluences;
1219 if (joints.size() == 0) {
1224 for (
unsigned int i=0; i<joints.size(); i++) {
1225 MFnDependencyNode joint(joints[i]->_joint);
1227 cmd = cmd + joint.name();
1230 MFnDependencyNode shape(M->_shapeNode);
1232 cmd = cmd + shape.name();
1236 if (mayaloader_cat.is_spam()) {
1237 mayaloader_cat.spam() << cmd.asChar() << endl;
1238 string spamCmd = M->_pool->get_name();
1239 for (
unsigned int i=0; i<joints.size(); i++) {
1240 spamCmd = spamCmd +
" ";
1241 spamCmd = spamCmd + joints[i]->_egg_joint->get_name();
1243 mayaloader_cat.spam() << spamCmd <<
": total = " << joints.size() << endl;
1245 status = dgmod.commandToExecute(cmd);
1246 if (status != MStatus::kSuccess) {
1247 perror(
"skinCluster commandToExecute");
1250 status = dgmod.doIt();
1251 if (status != MStatus::kSuccess) {
1252 perror(
"skinCluster doIt");
1256 MPlugArray oldplugs;
1258 if (shape.typeName() ==
"mesh") {
1259 inPlug = shape.findPlug(
"inMesh");
1260 }
else if (shape.typeName() ==
"nurbsSurface") {
1261 inPlug = shape.findPlug(
"create");
1267 if ((!inPlug.connectedTo(oldplugs,
true,
false))||(oldplugs.length() != 1)) {
1268 cerr <<
"skinCluster command failed";
1271 MFnSkinCluster skinCluster(oldplugs[0].node());
1272 MIntArray influenceIndices;
1273 MFnSingleIndexedComponent component;
1274 component.create(MFn::kMeshVertComponent);
1275 component.setCompleteData(M->_vert_count);
1276 for (
unsigned int i=0; i<joints.size(); i++) {
1277 unsigned int index = skinCluster.indexForInfluenceObject(joints[i]->_joint_dag_path, &status);
1278 if (status != MStatus::kSuccess) {
1279 perror(
"skinCluster index");
1282 influenceIndices.append((
int)index);
1285 MDagPathArray paths;
1286 unsigned infcount = skinCluster.influenceObjects(paths, &status);
1287 if (status != MStatus::kSuccess) {
1288 perror(
"influenceObjects");
1291 for (
unsigned int i=0; i<infcount; i++) {
1292 unsigned int index = skinCluster.indexForInfluenceObject(paths[i], &status);
1293 if (status != MStatus::kSuccess) {
1294 perror(
"skinCluster index");
1297 skinCluster.setWeights(M->_shape_dag_path, component.object(), index, 0.0,
false,
nullptr);
1301 int tot = M->_vert_count * joints.size();
1302 values.setLength(tot);
1303 for (
int i=0; i<tot; i++) {
1306 for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) {
1307 for (
unsigned int i=0; i<vert->_weights.size(); i++) {
1308 double strength = vert->_weights[i].first / vert->_sumWeights;
1309 MayaEggJoint *joint = FindJoint(vert->_weights[i].second);
1310 values[vert->_index * joints.size() + joint->_index] = (PN_stdfloat)strength;
1313 skinCluster.setWeights(M->_shape_dag_path, component.object(), influenceIndices, values,
false,
nullptr);
1315 for (
unsigned int i=0; i<joints.size(); i++) {
1321 joints[i]->_inskin =
false;
1322 joints[i]->_index = -1;
1329 void MayaEggLoader::TraverseEggNode(
EggNode *node,
EggGroup *context,
string delim)
1331 vector<int> vertIndices;
1332 vector<int> tvertIndices;
1333 vector<int> cvertIndices;
1335 string delstring =
" ";
1337 if (node->
is_of_type(EggPolygon::get_class_type())) {
1344 if (poly->empty()) {
1349 MayaEggTex *tex = 0;
1350 LMatrix3d uvtrans = LMatrix3d::ident_mat();
1354 if (mayaloader_cat.is_spam()) {
1355 mayaloader_cat.spam() <<
"Texture format : " << etex->get_format() << endl;
1361 tex = GetTex(
nullptr);
1364 EggPolygon::const_iterator ci;
1365 MayaEggMesh *mesh = GetMesh(poly->
get_pool(), context);
1366 if (mayaloader_cat.is_spam()) {
1367 mayaloader_cat.spam() <<
"traverse mesh pointer " << mesh <<
"\n";
1369 vertIndices.clear();
1370 tvertIndices.clear();
1371 cvertIndices.clear();
1372 int numVertices = 0;
1373 for (ci = poly->begin(); ci != poly->end(); ++ci) {
1379 vertIndices.push_back(mesh->GetVert(vtx, context));
1380 tvertIndices.push_back(mesh->GetTVert(uv * uvtrans));
1381 cvertIndices.push_back(mesh->GetCVert(vtx->
get_color()));
1384 if (mayaloader_cat.is_spam()) {
1385 mayaloader_cat.spam() <<
"num vertices: " << vertIndices.size() <<
"\n";
1388 if (numVertices < 3)
1391 MIntArray mvertIndices;
1392 MIntArray mtvertIndices;
1393 for (
int i = 0; i < numVertices; i++) {
1394 mvertIndices.append(vertIndices[i]);
1395 mtvertIndices.append(tvertIndices[i]);
1397 if (poly->has_color()) {
1398 if (mayaloader_cat.is_spam()) {
1399 mayaloader_cat.spam() <<
"found a face color of " << poly->
get_color() << endl;
1401 mesh->_faceIndices.append(mesh->_face_count);
1402 mesh->_faceColorArray.append(MakeMayaColor(poly->
get_color()));
1404 mesh->AddFace(numVertices, mvertIndices, mtvertIndices, tex);
1408 mesh->AddEggFlag(
"double-sided");
1412 if (context->get_model_flag()) {
1413 mesh->AddEggFlag(
"model");
1417 switch (context->get_billboard_type()) {
1418 case EggGroup::BT_axis:
1419 mesh->AddEggFlag(
"billboard");
1422 case EggGroup::BT_point_camera_relative:
1423 mesh->AddEggFlag(
"billboard-point");
1431 for (
int i = 0; i < context->get_num_object_types(); i++) {
1432 mesh->AddEggFlag(MString(context->get_object_type(i).c_str()));
1435 }
else if (node->
is_of_type(EggNurbsSurface::get_class_type())) {
1439 EggNurbsSurface::const_iterator ci;
1441 MayaEggNurbsSurface *surface = GetSurface(pool, context);
1443 for (ci = eggNurbsSurface->begin(); ci != eggNurbsSurface->end(); ++ci) {
1445 surface->GetVert(vtx, context);
1449 MayaEggTex *tex = 0;
1450 LMatrix3d uvtrans = LMatrix3d::ident_mat();
1457 mayaloader_cat.debug() <<
"uvtrans?" << endl;
1461 tex = GetTex(
nullptr);
1464 surface->_tex = tex;
1469 for (uint ui = 0; ui < surface->_uNumCvs; ui++) {
1470 for (uint vi = 0; vi < surface->_vNumCvs; vi++) {
1472 surface->_cvArray.append(MakeMPoint(vtx->
get_pos3()));
1478 surface->_uKnotArray.append(eggNurbsSurface->
get_u_knot(i));
1483 surface->_vKnotArray.append(eggNurbsSurface->
get_v_knot(i));
1490 surface->_uForm = MFnNurbsSurface::kClosed;
1492 surface->_vForm = MFnNurbsSurface::kOpen;
1496 surface->_vForm = MFnNurbsSurface::kClosed;
1498 surface->_vForm = MFnNurbsSurface::kOpen;
1503 surface->AddEggFlag(
"double-sided");
1507 if (context->get_model_flag()) {
1508 surface->AddEggFlag(
"model");
1512 for (
int i = 0; i < context->get_num_object_types(); i++) {
1513 surface->AddEggFlag(MString(context->get_object_type(i).c_str()));
1516 }
else if (node->
is_of_type(EggComment::get_class_type())) {
1517 string comment = (DCAST(
EggComment, node))->get_comment();
1518 if (comment.find(
"2egg") != string::npos) {
1519 if (mayaloader_cat.is_spam()) {
1520 mayaloader_cat.spam() << delim+delstring <<
"found an EggComment: " << comment << endl;
1522 if (comment.find(
"chan") != string::npos) {
1523 ParseFrameInfo(comment);
1526 }
else if (node->
is_of_type(EggSAnimData::get_class_type())) {
1527 if (mayaloader_cat.is_debug()) {
1528 mayaloader_cat.debug() << delim+delstring <<
"found an EggSAnimData: " << node->get_name() << endl;
1535 }
else if (node->
is_of_type(EggGroupNode::get_class_type())) {
1537 if (node->
is_of_type(EggGroup::get_class_type())) {
1540 if (group->get_name() ==
"") {
1541 ostringstream stream;
1542 stream << _unnamed_idx;
1543 group->set_name(
"unnamed" + stream.str());
1547 string group_name = group->get_name();
1548 size_t found = group_name.find(
":");
1549 if (found != string::npos)
1550 group->set_name(group_name.replace(
int(found), 1,
"_"));
1552 string parent_name =
"";
1554 parent_name = context->get_name();
1556 if (mayaloader_cat.is_debug()) {
1557 mayaloader_cat.debug() << delim+delstring << group->get_name() <<
":" << parent_name << endl;
1559 MakeJoint(group, context);
1563 if (mayaloader_cat.is_debug()) {
1564 mayaloader_cat.debug() << delim+delstring << group->get_name() <<
"@" << parent_name << endl;
1566 MakeGroup(group, context);
1569 }
else if (node->
is_of_type(EggTable::get_class_type())) {
1571 if (mayaloader_cat.is_debug()) {
1572 mayaloader_cat.debug() << delim+delstring <<
"found an EggTable: " << node->get_name() << endl;
1574 }
else if (node->
is_of_type(EggXfmSAnim::get_class_type())) {
1577 if (mayaloader_cat.is_debug()) {
1578 mayaloader_cat.debug() << delim+delstring <<
"found an EggXfmSAnim: " << node->get_name() << endl;
1582 EggGroupNode::const_iterator ci;
1583 for (ci = group->begin(); ci != group->end(); ++ci) {
1584 TraverseEggNode(*ci, context, delim+delstring);
1589 bool MayaEggLoader::ConvertEggData(
EggData *data,
bool merge,
bool model,
bool anim,
bool respect_normals)
1592 mayaloader_cat.error() <<
"Currently, only 'merge' mode is implemented.\n";
1606 _timeUnit = MTime::kFilm;
1609 MeshTable::const_iterator ci;
1610 JointTable::const_iterator ji;
1611 TexTable::const_iterator ti;
1612 SurfaceTable::const_iterator si;
1613 AnimTable::const_iterator ei;
1615 if (MGlobal::isYAxisUp()) {
1616 data->set_coordinate_system(CS_yup_right);
1618 data->set_coordinate_system(CS_zup_right);
1621 if (mayaloader_cat.is_debug()) {
1622 mayaloader_cat.debug() <<
"root node: " << data->get_type() << endl;
1624 TraverseEggNode(data,
nullptr,
"");
1628 MFnSet collision_set;
1629 collision_set.create(_collision_nodes, MFnSet::kNone, &status);
1631 if (mayaloader_cat.is_spam()) {
1632 mayaloader_cat.spam() <<
"num meshes : " << _mesh_tab.size() << endl;
1634 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1635 MayaEggMesh *mesh = (*ci).second;
1636 if (mesh->_face_count==0) {
1644 MayaEggGroup *parentNode = FindGroup(mesh->_parent);
1645 MObject parent = MObject::kNullObj;
1647 parent = parentNode->_group;
1648 if (mayaloader_cat.is_debug()) {
1649 mayaloader_cat.debug() <<
"mesh's parent (group) : " << parentNode->_name << endl;
1652 mesh->_renameTrans =
true;
1653 if (mayaloader_cat.is_debug()) {
1654 mayaloader_cat.debug() <<
"mesh's parent (null) : " << endl;
1657 if (mayaloader_cat.is_spam()) {
1658 mayaloader_cat.spam() <<
"mesh pointer : " << mesh <<
" and parent_pointer: " << &parent << endl;
1659 mayaloader_cat.spam() <<
"mesh vert_count : " << mesh->_vert_count << endl;
1660 mayaloader_cat.spam() <<
"mesh face_count : " << mesh->_face_count << endl;
1661 mayaloader_cat.spam() <<
"mesh vertexArray size: " << mesh->_vertexArray.length() << endl;
1662 mayaloader_cat.spam() <<
"mesh polygonCounts size: " << mesh->_polygonCounts.length() << endl;
1663 mayaloader_cat.spam() <<
"mesh polygonConnects size: " << mesh->_polygonConnects.length() << endl;
1664 mayaloader_cat.spam() <<
"mesh uarray size: " << mesh->_uarray.length() << endl;
1665 mayaloader_cat.spam() <<
"mesh varray size: " << mesh->_varray.length() << endl;
1667 mesh->_transNode = mfn.create(mesh->_vert_count, mesh->_face_count,
1668 mesh->_vertexArray, mesh->_polygonCounts, mesh->_polygonConnects,
1669 mesh->_uarray, mesh->_varray,
1671 if (mayaloader_cat.is_spam()) {
1672 mayaloader_cat.spam() <<
"transNode created." << endl;
1675 if (!mesh->_renameTrans) {
1676 mesh->_transNode = parent;
1680 for (
unsigned i = 0; i < mesh->_eggObjectTypes.length(); i++) {
1681 MString attrName =
"eggObjectTypes";
1682 attrName += (int)(i + 1);
1683 status = create_enum_attribute(mesh->_transNode, attrName, attrName, mesh->_eggObjectTypes, i);
1684 if (status != MStatus::kSuccess) {
1685 status.perror(
"create_enum_attribute failed!");
1691 MPlug displayColors = mfn.findPlug(
"displayColors");
1692 displayColors.setValue((
bool)
true);
1694 mesh->_shapeNode = mfn.object();
1695 mfn.getPath(mesh->_shape_dag_path);
1696 mesh->ConnectTextures();
1698 if (mayaloader_cat.is_spam()) {
1699 mayaloader_cat.spam() <<
"textures connected." << endl;
1702 mfn.getCurrentUVSetName(cset);
1703 status = mfn.assignUVs(mesh->_polygonCounts, mesh->_uvIds, &cset);
1705 if (status != MStatus::kSuccess) {
1706 status.perror(
"assignUVs failed");
1707 if (mayaloader_cat.is_spam()) {
1712 if (mayaloader_cat.is_spam()) {
1713 mayaloader_cat.spam() <<
"uvs assigned." << endl;
1718 if (respect_normals) {
1719 status = mfn.setVertexNormals(mesh->_normalArray, mesh->_vertNormalIndices, MSpace::kTransform);
1720 if (status != MStatus::kSuccess) {
1721 status.perror(
"setVertexNormals failed!");
1725 if (mayaloader_cat.is_spam()) {
1726 mayaloader_cat.spam() <<
"vertex normals set." << endl;
1738 status = mfn.setVertexColors(mesh->_vertColorArray, mesh->_vertColorIndices);
1739 if (status != MStatus::kSuccess) {
1740 status.perror(
"setVertexColors failed!");
1742 status = mfn.setFaceColors(mesh->_faceColorArray, mesh->_faceIndices);
1750 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1751 MayaEggNurbsSurface *surface = (*si).second;
1752 if (surface->_cvArray.length()==0) {
1757 MFnNurbsSurface mfnNurbsSurface;
1759 MayaEggGroup *parentNode = FindGroup(surface->_parent);
1760 MObject parent = MObject::kNullObj;
1762 parent = parentNode->_group;
1763 if (mayaloader_cat.is_debug()) {
1764 mayaloader_cat.debug() <<
"surface's parent (group) : " << parentNode->_name << endl;
1767 surface->_renameTrans =
true;
1768 if (mayaloader_cat.is_debug()) {
1769 mayaloader_cat.debug() <<
"surface's parent (null) : " << endl;
1773 surface->_transNode = mfnNurbsSurface.create(surface->_cvArray, surface->_uKnotArray, surface->_vKnotArray,
1774 surface->_uDegree, surface->_vDegree, surface->_uForm, surface->_vForm,
1775 true, parent, &status);
1777 if (!surface->_renameTrans) {
1778 surface->_transNode = parent;
1782 for (
unsigned i = 0; i < surface->_eggObjectTypes.length(); i++) {
1783 MString attrName =
"eggObjectTypes";
1784 attrName += (int)(i + 1);
1785 status = create_enum_attribute(surface->_transNode, attrName, attrName, surface->_eggObjectTypes, i);
1786 if (status != MStatus::kSuccess) {
1787 status.perror(
"create_enum_attribute failed!");
1790 surface->_shapeNode = mfnNurbsSurface.object();
1791 mfnNurbsSurface.getPath(surface->_shape_dag_path);
1792 surface->ConnectTextures();
1794 mayaloader_cat.debug() << status.errorString().asChar() << endl;
1798 double thickness = 0.0;
1799 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1800 MayaEggJoint *joint = (*ji).second;
1801 double dfo = (joint->GetPos()).length();
1802 if (dfo > thickness) {
1806 if (mayaloader_cat.is_spam()) {
1807 mayaloader_cat.spam() <<
"thickness from joints: " << thickness << endl;
1809 thickness = thickness * 0.025;
1810 for (
unsigned int i=0; i<_joint_list.size(); i++) {
1811 MayaEggJoint *joint = _joint_list[i];
1812 if (mayaloader_cat.is_spam()) {
1813 mayaloader_cat.spam() <<
"creating a joint: " << joint->_egg_joint->get_name() << endl;
1815 joint->ChooseEndPos(thickness);
1816 joint->CreateMayaBone(FindGroup(joint->_egg_parent));
1818 if (mayaloader_cat.is_spam()) {
1819 mayaloader_cat.spam() <<
"went past all the joints" << endl;
1821 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1822 MayaEggMesh *mesh = (*ci).second;
1823 EggGroup *joint = mesh->GetControlJoint();
1825 CreateSkinCluster(mesh);
1828 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1829 MayaEggNurbsSurface *surface = (*si).second;
1830 EggGroup *joint = surface->GetControlJoint();
1832 CreateSkinCluster(surface);
1835 if (mayaloader_cat.is_spam()) {
1836 mayaloader_cat.spam() <<
"went past creating skin cluster" << endl;
1838 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1839 (*ci).second->AssignNames();
1841 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1842 (*si).second->AssignNames();
1844 if (mayaloader_cat.is_spam()) {
1845 mayaloader_cat.spam() <<
"went past mesh AssignNames" << endl;
1847 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1848 (*ji).second->AssignNames();
1850 if (mayaloader_cat.is_spam()) {
1851 mayaloader_cat.spam() <<
"went past joint AssignNames" << endl;
1853 for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
1854 (*ti).second->AssignNames();
1856 if (mayaloader_cat.is_spam()) {
1857 mayaloader_cat.spam() <<
"went past tex AssignNames" << endl;
1860 if (mayaloader_cat.is_debug()) {
1861 mayaloader_cat.debug() <<
"-fri: " << _frame_rate <<
" -sf: " << _start_frame
1862 <<
" -ef: " << _end_frame << endl;
1866 MTime maxFrame(_start_frame - 1, _timeUnit);
1867 MTime minFrame = maxFrame;
1869 for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) {
1870 MayaAnim *anim = (*ei).second;
1871 MObject node = GetDependencyNode(anim->_joint->get_name());
1872 MFnDagNode mfnNode(node, &status);
1874 MMatrix mMat = mfnNode.transformationMatrix(&status);
1876 MObject attrTX = mfnNode.attribute(
"translateX", &status);
1877 MObject attrTY = mfnNode.attribute(
"translateY", &status);
1878 MObject attrTZ = mfnNode.attribute(
"translateZ", &status);
1879 MObject attrRX = mfnNode.attribute(
"rotateX", &status);
1880 MObject attrRY = mfnNode.attribute(
"rotateY", &status);
1881 MObject attrRZ = mfnNode.attribute(
"rotateZ", &status);
1882 MObject attrSX = mfnNode.attribute(
"scaleX", &status);
1883 MObject attrSY = mfnNode.attribute(
"scaleY", &status);
1884 MObject attrSZ = mfnNode.attribute(
"scaleZ", &status);
1886 MFnAnimCurve mfnAnimCurveTX;
1887 MFnAnimCurve mfnAnimCurveTY;
1888 MFnAnimCurve mfnAnimCurveTZ;
1889 MFnAnimCurve mfnAnimCurveRX;
1890 MFnAnimCurve mfnAnimCurveRY;
1891 MFnAnimCurve mfnAnimCurveRZ;
1892 MFnAnimCurve mfnAnimCurveSX;
1893 MFnAnimCurve mfnAnimCurveSY;
1894 MFnAnimCurve mfnAnimCurveSZ;
1896 mfnAnimCurveTX.create(node, attrTX, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1897 mfnAnimCurveTY.create(node, attrTY, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1898 mfnAnimCurveTZ.create(node, attrTZ, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1899 mfnAnimCurveRX.create(node, attrRX, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1900 mfnAnimCurveRY.create(node, attrRY, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1901 mfnAnimCurveRZ.create(node, attrRZ, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1902 mfnAnimCurveSX.create(node, attrSX, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1903 mfnAnimCurveSY.create(node, attrSY, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1904 mfnAnimCurveSZ.create(node, attrSZ, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1906 MTransformationMatrix matrix( mMat );
1907 MVector trans = matrix.translation(MSpace::kTransform, &status);
1910 MTransformationMatrix::RotationOrder order = MTransformationMatrix::kXYZ;
1911 status = matrix.getRotation(rot, order);
1914 status = matrix.getScale(scale, MSpace::kTransform);
1915 MFnAnimCurve::TangentType tangent = MFnAnimCurve::kTangentClamped;
1916 MTime time(_start_frame - 1, _timeUnit);
1918 mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent,
nullptr, &status);
1919 mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent,
nullptr, &status);
1920 mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent,
nullptr, &status);
1921 mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent,
nullptr, &status);
1922 mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent,
nullptr, &status);
1923 mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent,
nullptr, &status);
1924 mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent,
nullptr, &status);
1925 mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent,
nullptr, &status);
1926 mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent,
nullptr, &status);
1928 for (
int frame = 0; frame < anim->_pool->get_num_rows(); frame++)
1931 anim->_pool->get_value(frame, tMat);
1933 double matData[4][4] = {{tMat.get_cell(0,0), tMat.get_cell(0,1), tMat.get_cell(0,2), tMat.get_cell(0,3)},
1934 {tMat.get_cell(1,0), tMat.get_cell(1,1), tMat.get_cell(1,2), tMat.get_cell(1,3)},
1935 {tMat.get_cell(2,0), tMat.get_cell(2,1), tMat.get_cell(2,2), tMat.get_cell(2,3)},
1936 {tMat.get_cell(3,0), tMat.get_cell(3,1), tMat.get_cell(3,2), tMat.get_cell(3,3)}};
1937 MMatrix mat(matData);
1939 matrix = MTransformationMatrix(mat);
1940 trans = matrix.translation(MSpace::kTransform, &status);
1941 status = matrix.getRotation(rot, order);
1942 status = matrix.getScale(scale, MSpace::kTransform);
1943 time = MTime(frame + _start_frame, _timeUnit);
1945 mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent,
nullptr, &status);
1946 mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent,
nullptr, &status);
1947 mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent,
nullptr, &status);
1948 mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent,
nullptr, &status);
1949 mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent,
nullptr, &status);
1950 mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent,
nullptr, &status);
1951 mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent,
nullptr, &status);
1952 mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent,
nullptr, &status);
1953 mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent,
nullptr, &status);
1955 if (maxFrame < time) {
1961 MAnimControl::setMaxTime(maxFrame);
1962 MAnimControl::setMinTime(minFrame);
1965 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1966 delete (*ci).second;
1968 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1969 delete (*ji).second;
1971 for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
1972 delete (*ti).second;
1974 for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) {
1975 delete (*ei).second;
1980 mayaloader_cat.info() <<
"Egg import successful\n";
1984 void MayaEggLoader::PrintData(MayaEggMesh *mesh)
1986 if (mayaloader_cat.is_spam()) {
1987 mayaloader_cat.spam() <<
"Mesh: " << mesh->_name << endl;
1988 mayaloader_cat.spam() <<
"num vertexArray: " << mesh->_vertexArray.length() << endl;
1989 ostringstream stream3;
1990 for (
unsigned int i=0; i < mesh->_vertexArray.length(); ++i) {
1991 stream3 <<
"[" << mesh->_vertexArray[i].x <<
" " << mesh->_vertexArray[i].y <<
" " << mesh->_vertexArray[i].z <<
"]" << endl;
1994 mayaloader_cat.spam() <<
"vertexArray: \n" << stream3.str() << endl;
1995 mayaloader_cat.spam() <<
"num polygonConnects: " << mesh->_polygonConnects.length() << endl;
1996 mayaloader_cat.spam() <<
"num uvCounts: " << mesh->_polygonCounts.length() << endl;
1997 mayaloader_cat.spam() <<
"num uvIds: " << mesh->_uvIds.length() << endl;
1998 ostringstream stream1, stream4;
2000 for (
unsigned int i=0; i < mesh->_polygonCounts.length(); ++i) {
2001 stream1 << mesh->_polygonCounts[i] <<
":->";
2002 stream4 << mesh->_polygonCounts[i] <<
":->";
2003 for (
int j=0; j < mesh->_polygonCounts[i]; ++j, ++k) {
2004 stream1 << mesh->_uvIds[k] <<
",";
2005 stream4 << mesh->_polygonConnects[k] <<
",";
2010 mayaloader_cat.spam() <<
"uvCounts:->uvIds " << endl << stream1.str() << endl;
2011 mayaloader_cat.spam() <<
"vertexCount:->polygonConnects" << endl << stream4.str() << endl;
2015 void MayaEggLoader::ParseFrameInfo(
string comment)
2019 pos = comment.find(
"-fri");
2020 if (pos != string::npos) {
2021 ls = comment.find(
" ", pos+4);
2022 le = comment.find(
" ", ls+1);
2023 if (mayaloader_cat.is_debug()) {
2024 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2026 _frame_rate = atoi(comment.substr(ls+1,le-ls-1).data());
2030 switch (_frame_rate) {
2032 _timeUnit = MTime::kGames;
2035 _timeUnit = MTime::kFilm;
2038 _timeUnit = MTime::kPALFrame;
2041 _timeUnit = MTime::kNTSCFrame;
2044 _timeUnit = MTime::kShowScan;
2047 _timeUnit = MTime::kPALField;
2050 _timeUnit = MTime::kNTSCField;
2053 _timeUnit = MTime::k2FPS;
2056 _timeUnit = MTime::k3FPS;
2059 _timeUnit = MTime::k4FPS;
2062 _timeUnit = MTime::k5FPS;
2065 _timeUnit = MTime::k6FPS;
2068 _timeUnit = MTime::k8FPS;
2071 _timeUnit = MTime::k10FPS;
2074 _timeUnit = MTime::k12FPS;
2077 _timeUnit = MTime::k16FPS;
2080 _timeUnit = MTime::k20FPS;
2083 _timeUnit = MTime::k40FPS;
2086 _timeUnit = MTime::k75FPS;
2089 _timeUnit = MTime::k80FPS;
2092 _timeUnit = MTime::k100FPS;
2095 _timeUnit = MTime::kFilm;
2100 pos = comment.find(
"-sf");
2101 if (pos != string::npos) {
2102 ls = comment.find(
" ", pos+3);
2103 le = comment.find(
" ", ls+1);
2104 if (mayaloader_cat.is_debug()) {
2105 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2107 if (le == string::npos) {
2108 _start_frame = atoi(comment.substr(ls+1,le).data());
2110 _start_frame = atoi(comment.substr(ls+1,le-ls-1).data());
2115 pos = comment.find(
"-ef");
2116 if (pos != string::npos) {
2117 ls = comment.find(
" ", pos+3);
2118 le = comment.find(
" ", ls+1);
2119 if (mayaloader_cat.is_debug()) {
2120 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2122 if (le == string::npos) {
2123 _end_frame = atoi(comment.substr(ls+1,le).data());
2125 _end_frame = atoi(comment.substr(ls+1,le-ls-1).data());
2134 bool MayaEggLoader::ConvertEggFile(
const char *name,
bool merge,
bool model,
bool anim,
bool respect_normals)
2138 if (!data.read(datafn)) {
2139 mayaloader_cat.error() <<
"Cannot read Egg file for import\n";
2142 return ConvertEggData(&data, merge, model, anim, respect_normals);
2145 MObject MayaEggLoader::GetDependencyNode(
string givenName)
2147 MObject node = MObject::kNullObj;
2151 pos = givenName.find(
":");
2152 if (pos != string::npos) {
2153 name = givenName.substr(pos+1);
2178 JointTable::const_iterator ji;
2179 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
2180 MayaEggJoint *joint = (*ji).second;
2181 if (mayaloader_cat.is_spam()) {
2182 mayaloader_cat.spam() <<
"traversing a joint: " << joint->_egg_joint->get_name() << endl;
2184 string jointName = joint->_egg_joint->get_name();
2185 if (jointName == name)
2187 node = joint->_joint;
2197 bool MayaLoadEggData(
EggData *data,
bool merge,
bool model,
bool anim,
bool respect_normals)
2199 MayaEggLoader loader;
2200 bool temp = loader.ConvertEggData(data, merge, model, anim, respect_normals);
2204 bool MayaLoadEggFile(
const char *name,
bool merge,
bool model,
bool anim,
bool respect_normals)
2206 MayaEggLoader loader;
2207 return loader.ConvertEggFile(name, merge, model, anim, respect_normals);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GroupRef::const_iterator gref_end() const
Returns an iterator that can, in conjunction with gref_begin(), be used to traverse the entire set of...
get_num_v_knots
Returns the number of knots in the V direction.
virtual bool is_joint() const
Returns true if this particular node represents a <Joint> entry or not.
get_num_u_knots
Returns the number of knots in the U direction.
virtual bool cleanup() override
Cleans up modeling errors in whatever context this makes sense.
int get_u_degree() const
Returns the degree of the surface in the U direction.
int get_num_u_cvs() const
Returns the number of control vertices that should be present in the U direction.
Specifies parameters that may be passed to the loader.
A base class for nodes in the hierarchy that are not leaf nodes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
Defines a texture map that may be applied to geometry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_v_knot
Returns the nth knot value defined in the V direction.
int get_vertex_index(int ui, int vi) const
Returns the index number within the EggPrimitive's list of the control vertex at position ui,...
GroupRef::const_iterator gref_begin() const
Returns an iterator that can, in conjunction with gref_end(), be used to traverse the entire set of g...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
This is the primary interface into all the egg data, and the root of the egg file structure.
LColor get_color() const
Returns the color set on this particular attribute.
bool is_closed_v() const
Returns true if the surface appears to be closed in the V direction.
get_vertex
Returns a particular index based on its index number.
int get_num_v_cvs() const
Returns the number of control vertices that should be present in the V direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
int get_index() const
Returns the index number of the vertex within its pool.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
static Texture * load_texture(const Filename &filename, int primary_file_num_channels=0, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads the given filename up into a texture, if it has not already been loaded, and returns the new te...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const Filename & get_fullpath() const
Returns the full pathname to the file, if it is known; otherwise, returns the same thing as get_filen...
bool is_closed_u() const
Returns true if the surface appears to be closed in the U direction.
get_u_knot
Returns the nth knot value defined in the U direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_pool
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for things that may be directly added into the egg hierarchy.
A parametric NURBS surface.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_texture
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
get_bface_flag
Retrieves the backfacing flag of the polygon.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_v_degree() const
Returns the degree of the surface in the V direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A collection of vertices.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
const LMatrix4d & get_vertex_to_node() const
Returns the transformation matrix suitable for converting the vertices as read from the egg file into...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.