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>
76using std::ostringstream;
86class MayaEggNurbsSurface;
88NotifyCategoryDeclNoExport(mayaloader);
89NotifyCategoryDef(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;
142MPoint MakeMPoint(
const LVector3d &vec)
144 return MPoint(vec[0], vec[1], vec[2]);
147MFloatPoint MakeMayaPoint(
const LVector3d &vec)
149 return MFloatPoint(vec[0], vec[1], vec[2]);
152MVector MakeMayaVector(
const LVector3d &vec)
154 return MVector(vec[0], vec[1], vec[2]);
157MColor MakeMayaColor(
const LColor &vec)
159 return MColor(vec[0], vec[1], vec[2], vec[3]);
164MStatus 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);
225void 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");
240MayaEggTex *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;
401MayaEggGroup *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);
437void 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);
449void 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;
459MayaEggJoint *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);
511MayaEggJoint *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) {
544void 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);
577void 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);
626typedef 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;
705typedef 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);
837void 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)))
871EggGroup *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;
899void 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);
913typedef phash_map<LTexCoordd, int> TVertTable;
914typedef phash_map<LColor, int> CVertTable;
916class 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;
943int 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;
961int 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;
999int 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);
1012void 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);
1044class 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;
1098void 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!");
1123void 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);
1161MayaAnim *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;
1177void 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);
1187void 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;
1329void 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())) {
1578 if (mayaloader_cat.is_debug()) {
1579 mayaloader_cat.debug() << delim+delstring <<
"found an EggXfmSAnim: " << node->get_name() << endl;
1583 EggGroupNode::const_iterator ci;
1584 for (ci = group->begin(); ci != group->end(); ++ci) {
1585 TraverseEggNode(*ci, context, delim+delstring);
1590bool MayaEggLoader::ConvertEggData(
EggData *data,
bool merge,
bool model,
bool anim,
bool respect_normals)
1593 mayaloader_cat.error() <<
"Currently, only 'merge' mode is implemented.\n";
1607 _timeUnit = MTime::kFilm;
1610 MeshTable::const_iterator ci;
1611 JointTable::const_iterator ji;
1612 TexTable::const_iterator ti;
1613 SurfaceTable::const_iterator si;
1614 AnimTable::const_iterator ei;
1616 if (MGlobal::isYAxisUp()) {
1617 data->set_coordinate_system(CS_yup_right);
1619 data->set_coordinate_system(CS_zup_right);
1622 if (mayaloader_cat.is_debug()) {
1623 mayaloader_cat.debug() <<
"root node: " << data->get_type() << endl;
1625 TraverseEggNode(data,
nullptr,
"");
1629 MFnSet collision_set;
1630 collision_set.create(_collision_nodes, MFnSet::kNone, &status);
1632 if (mayaloader_cat.is_spam()) {
1633 mayaloader_cat.spam() <<
"num meshes : " << _mesh_tab.size() << endl;
1635 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1636 MayaEggMesh *mesh = (*ci).second;
1637 if (mesh->_face_count==0) {
1645 MayaEggGroup *parentNode = FindGroup(mesh->_parent);
1646 MObject parent = MObject::kNullObj;
1648 parent = parentNode->_group;
1649 if (mayaloader_cat.is_debug()) {
1650 mayaloader_cat.debug() <<
"mesh's parent (group) : " << parentNode->_name << endl;
1653 mesh->_renameTrans =
true;
1654 if (mayaloader_cat.is_debug()) {
1655 mayaloader_cat.debug() <<
"mesh's parent (null) : " << endl;
1658 if (mayaloader_cat.is_spam()) {
1659 mayaloader_cat.spam() <<
"mesh pointer : " << mesh <<
" and parent_pointer: " << &parent << endl;
1660 mayaloader_cat.spam() <<
"mesh vert_count : " << mesh->_vert_count << endl;
1661 mayaloader_cat.spam() <<
"mesh face_count : " << mesh->_face_count << endl;
1662 mayaloader_cat.spam() <<
"mesh vertexArray size: " << mesh->_vertexArray.length() << endl;
1663 mayaloader_cat.spam() <<
"mesh polygonCounts size: " << mesh->_polygonCounts.length() << endl;
1664 mayaloader_cat.spam() <<
"mesh polygonConnects size: " << mesh->_polygonConnects.length() << endl;
1665 mayaloader_cat.spam() <<
"mesh uarray size: " << mesh->_uarray.length() << endl;
1666 mayaloader_cat.spam() <<
"mesh varray size: " << mesh->_varray.length() << endl;
1668 mesh->_transNode = mfn.create(mesh->_vert_count, mesh->_face_count,
1669 mesh->_vertexArray, mesh->_polygonCounts, mesh->_polygonConnects,
1670 mesh->_uarray, mesh->_varray,
1672 if (mayaloader_cat.is_spam()) {
1673 mayaloader_cat.spam() <<
"transNode created." << endl;
1676 if (!mesh->_renameTrans) {
1677 mesh->_transNode = parent;
1681 for (
unsigned i = 0; i < mesh->_eggObjectTypes.length(); i++) {
1682 MString attrName =
"eggObjectTypes";
1683 attrName += (int)(i + 1);
1684 status = create_enum_attribute(mesh->_transNode, attrName, attrName, mesh->_eggObjectTypes, i);
1685 if (status != MStatus::kSuccess) {
1686 status.perror(
"create_enum_attribute failed!");
1692 MPlug displayColors = mfn.findPlug(
"displayColors");
1693 displayColors.setValue((
bool)
true);
1695 mesh->_shapeNode = mfn.object();
1696 mfn.getPath(mesh->_shape_dag_path);
1697 mesh->ConnectTextures();
1699 if (mayaloader_cat.is_spam()) {
1700 mayaloader_cat.spam() <<
"textures connected." << endl;
1703 mfn.getCurrentUVSetName(cset);
1704 status = mfn.assignUVs(mesh->_polygonCounts, mesh->_uvIds, &cset);
1706 if (status != MStatus::kSuccess) {
1707 status.perror(
"assignUVs failed");
1708 if (mayaloader_cat.is_spam()) {
1713 if (mayaloader_cat.is_spam()) {
1714 mayaloader_cat.spam() <<
"uvs assigned." << endl;
1719 if (respect_normals) {
1720 status = mfn.setVertexNormals(mesh->_normalArray, mesh->_vertNormalIndices, MSpace::kTransform);
1721 if (status != MStatus::kSuccess) {
1722 status.perror(
"setVertexNormals failed!");
1726 if (mayaloader_cat.is_spam()) {
1727 mayaloader_cat.spam() <<
"vertex normals set." << endl;
1739 status = mfn.setVertexColors(mesh->_vertColorArray, mesh->_vertColorIndices);
1740 if (status != MStatus::kSuccess) {
1741 status.perror(
"setVertexColors failed!");
1743 status = mfn.setFaceColors(mesh->_faceColorArray, mesh->_faceIndices);
1751 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1752 MayaEggNurbsSurface *surface = (*si).second;
1753 if (surface->_cvArray.length()==0) {
1758 MFnNurbsSurface mfnNurbsSurface;
1760 MayaEggGroup *parentNode = FindGroup(surface->_parent);
1761 MObject parent = MObject::kNullObj;
1763 parent = parentNode->_group;
1764 if (mayaloader_cat.is_debug()) {
1765 mayaloader_cat.debug() <<
"surface's parent (group) : " << parentNode->_name << endl;
1768 surface->_renameTrans =
true;
1769 if (mayaloader_cat.is_debug()) {
1770 mayaloader_cat.debug() <<
"surface's parent (null) : " << endl;
1774 surface->_transNode = mfnNurbsSurface.create(surface->_cvArray, surface->_uKnotArray, surface->_vKnotArray,
1775 surface->_uDegree, surface->_vDegree, surface->_uForm, surface->_vForm,
1776 true, parent, &status);
1778 if (!surface->_renameTrans) {
1779 surface->_transNode = parent;
1783 for (
unsigned i = 0; i < surface->_eggObjectTypes.length(); i++) {
1784 MString attrName =
"eggObjectTypes";
1785 attrName += (int)(i + 1);
1786 status = create_enum_attribute(surface->_transNode, attrName, attrName, surface->_eggObjectTypes, i);
1787 if (status != MStatus::kSuccess) {
1788 status.perror(
"create_enum_attribute failed!");
1791 surface->_shapeNode = mfnNurbsSurface.object();
1792 mfnNurbsSurface.getPath(surface->_shape_dag_path);
1793 surface->ConnectTextures();
1795 mayaloader_cat.debug() << status.errorString().asChar() << endl;
1799 double thickness = 0.0;
1800 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1801 MayaEggJoint *joint = (*ji).second;
1802 double dfo = (joint->GetPos()).length();
1803 if (dfo > thickness) {
1807 if (mayaloader_cat.is_spam()) {
1808 mayaloader_cat.spam() <<
"thickness from joints: " << thickness << endl;
1810 thickness = thickness * 0.025;
1811 for (
unsigned int i=0; i<_joint_list.size(); i++) {
1812 MayaEggJoint *joint = _joint_list[i];
1813 if (mayaloader_cat.is_spam()) {
1814 mayaloader_cat.spam() <<
"creating a joint: " << joint->_egg_joint->get_name() << endl;
1816 joint->ChooseEndPos(thickness);
1817 joint->CreateMayaBone(FindGroup(joint->_egg_parent));
1819 if (mayaloader_cat.is_spam()) {
1820 mayaloader_cat.spam() <<
"went past all the joints" << endl;
1822 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1823 MayaEggMesh *mesh = (*ci).second;
1824 EggGroup *joint = mesh->GetControlJoint();
1826 CreateSkinCluster(mesh);
1829 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1830 MayaEggNurbsSurface *surface = (*si).second;
1831 EggGroup *joint = surface->GetControlJoint();
1833 CreateSkinCluster(surface);
1836 if (mayaloader_cat.is_spam()) {
1837 mayaloader_cat.spam() <<
"went past creating skin cluster" << endl;
1839 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1840 (*ci).second->AssignNames();
1842 for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) {
1843 (*si).second->AssignNames();
1845 if (mayaloader_cat.is_spam()) {
1846 mayaloader_cat.spam() <<
"went past mesh AssignNames" << endl;
1848 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1849 (*ji).second->AssignNames();
1851 if (mayaloader_cat.is_spam()) {
1852 mayaloader_cat.spam() <<
"went past joint AssignNames" << endl;
1854 for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
1855 (*ti).second->AssignNames();
1857 if (mayaloader_cat.is_spam()) {
1858 mayaloader_cat.spam() <<
"went past tex AssignNames" << endl;
1861 if (mayaloader_cat.is_debug()) {
1862 mayaloader_cat.debug() <<
"-fri: " << _frame_rate <<
" -sf: " << _start_frame
1863 <<
" -ef: " << _end_frame << endl;
1867 MTime maxFrame(_start_frame - 1, _timeUnit);
1868 MTime minFrame = maxFrame;
1870 for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) {
1871 MayaAnim *anim = (*ei).second;
1872 MObject node = GetDependencyNode(anim->_joint->get_name());
1873 MFnDagNode mfnNode(node, &status);
1875 MMatrix mMat = mfnNode.transformationMatrix(&status);
1877 MObject attrTX = mfnNode.attribute(
"translateX", &status);
1878 MObject attrTY = mfnNode.attribute(
"translateY", &status);
1879 MObject attrTZ = mfnNode.attribute(
"translateZ", &status);
1880 MObject attrRX = mfnNode.attribute(
"rotateX", &status);
1881 MObject attrRY = mfnNode.attribute(
"rotateY", &status);
1882 MObject attrRZ = mfnNode.attribute(
"rotateZ", &status);
1883 MObject attrSX = mfnNode.attribute(
"scaleX", &status);
1884 MObject attrSY = mfnNode.attribute(
"scaleY", &status);
1885 MObject attrSZ = mfnNode.attribute(
"scaleZ", &status);
1887 MFnAnimCurve mfnAnimCurveTX;
1888 MFnAnimCurve mfnAnimCurveTY;
1889 MFnAnimCurve mfnAnimCurveTZ;
1890 MFnAnimCurve mfnAnimCurveRX;
1891 MFnAnimCurve mfnAnimCurveRY;
1892 MFnAnimCurve mfnAnimCurveRZ;
1893 MFnAnimCurve mfnAnimCurveSX;
1894 MFnAnimCurve mfnAnimCurveSY;
1895 MFnAnimCurve mfnAnimCurveSZ;
1897 mfnAnimCurveTX.create(node, attrTX, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1898 mfnAnimCurveTY.create(node, attrTY, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1899 mfnAnimCurveTZ.create(node, attrTZ, MFnAnimCurve::kAnimCurveTL,
nullptr, &status);
1900 mfnAnimCurveRX.create(node, attrRX, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1901 mfnAnimCurveRY.create(node, attrRY, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1902 mfnAnimCurveRZ.create(node, attrRZ, MFnAnimCurve::kAnimCurveTA,
nullptr, &status);
1903 mfnAnimCurveSX.create(node, attrSX, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1904 mfnAnimCurveSY.create(node, attrSY, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1905 mfnAnimCurveSZ.create(node, attrSZ, MFnAnimCurve::kAnimCurveTU,
nullptr, &status);
1907 MTransformationMatrix matrix( mMat );
1908 MVector trans = matrix.translation(MSpace::kTransform, &status);
1911 MTransformationMatrix::RotationOrder order = MTransformationMatrix::kXYZ;
1912 status = matrix.getRotation(rot, order);
1915 status = matrix.getScale(scale, MSpace::kTransform);
1916 MFnAnimCurve::TangentType tangent = MFnAnimCurve::kTangentClamped;
1917 MTime time(_start_frame - 1, _timeUnit);
1919 mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent,
nullptr, &status);
1920 mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent,
nullptr, &status);
1921 mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent,
nullptr, &status);
1922 mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent,
nullptr, &status);
1923 mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent,
nullptr, &status);
1924 mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent,
nullptr, &status);
1925 mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent,
nullptr, &status);
1926 mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent,
nullptr, &status);
1927 mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent,
nullptr, &status);
1929 for (
int frame = 0; frame < anim->_pool->
get_num_rows(); frame++)
1934 double matData[4][4] = {{tMat.get_cell(0,0), tMat.get_cell(0,1), tMat.get_cell(0,2), tMat.get_cell(0,3)},
1935 {tMat.get_cell(1,0), tMat.get_cell(1,1), tMat.get_cell(1,2), tMat.get_cell(1,3)},
1936 {tMat.get_cell(2,0), tMat.get_cell(2,1), tMat.get_cell(2,2), tMat.get_cell(2,3)},
1937 {tMat.get_cell(3,0), tMat.get_cell(3,1), tMat.get_cell(3,2), tMat.get_cell(3,3)}};
1938 MMatrix mat(matData);
1940 matrix = MTransformationMatrix(mat);
1941 trans = matrix.translation(MSpace::kTransform, &status);
1942 status = matrix.getRotation(rot, order);
1943 status = matrix.getScale(scale, MSpace::kTransform);
1944 time = MTime(frame + _start_frame, _timeUnit);
1946 mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent,
nullptr, &status);
1947 mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent,
nullptr, &status);
1948 mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent,
nullptr, &status);
1949 mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent,
nullptr, &status);
1950 mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent,
nullptr, &status);
1951 mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent,
nullptr, &status);
1952 mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent,
nullptr, &status);
1953 mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent,
nullptr, &status);
1954 mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent,
nullptr, &status);
1956 if (maxFrame < time) {
1962 MAnimControl::setMaxTime(maxFrame);
1963 MAnimControl::setMinTime(minFrame);
1966 for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) {
1967 delete (*ci).second;
1969 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
1970 delete (*ji).second;
1972 for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) {
1973 delete (*ti).second;
1975 for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) {
1976 delete (*ei).second;
1981 mayaloader_cat.info() <<
"Egg import successful\n";
1985void MayaEggLoader::PrintData(MayaEggMesh *mesh)
1987 if (mayaloader_cat.is_spam()) {
1988 mayaloader_cat.spam() <<
"Mesh: " << mesh->_name << endl;
1989 mayaloader_cat.spam() <<
"num vertexArray: " << mesh->_vertexArray.length() << endl;
1990 ostringstream stream3;
1991 for (
unsigned int i=0; i < mesh->_vertexArray.length(); ++i) {
1992 stream3 <<
"[" << mesh->_vertexArray[i].x <<
" " << mesh->_vertexArray[i].y <<
" " << mesh->_vertexArray[i].z <<
"]" << endl;
1995 mayaloader_cat.spam() <<
"vertexArray: \n" << stream3.str() << endl;
1996 mayaloader_cat.spam() <<
"num polygonConnects: " << mesh->_polygonConnects.length() << endl;
1997 mayaloader_cat.spam() <<
"num uvCounts: " << mesh->_polygonCounts.length() << endl;
1998 mayaloader_cat.spam() <<
"num uvIds: " << mesh->_uvIds.length() << endl;
1999 ostringstream stream1, stream4;
2001 for (
unsigned int i=0; i < mesh->_polygonCounts.length(); ++i) {
2002 stream1 << mesh->_polygonCounts[i] <<
":->";
2003 stream4 << mesh->_polygonCounts[i] <<
":->";
2004 for (
int j=0; j < mesh->_polygonCounts[i]; ++j, ++k) {
2005 stream1 << mesh->_uvIds[k] <<
",";
2006 stream4 << mesh->_polygonConnects[k] <<
",";
2011 mayaloader_cat.spam() <<
"uvCounts:->uvIds " << endl << stream1.str() << endl;
2012 mayaloader_cat.spam() <<
"vertexCount:->polygonConnects" << endl << stream4.str() << endl;
2016void MayaEggLoader::ParseFrameInfo(
string comment)
2020 pos = comment.find(
"-fri");
2021 if (pos != string::npos) {
2022 ls = comment.find(
" ", pos+4);
2023 le = comment.find(
" ", ls+1);
2024 if (mayaloader_cat.is_debug()) {
2025 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2027 _frame_rate = atoi(comment.substr(ls+1,le-ls-1).data());
2031 switch (_frame_rate) {
2033 _timeUnit = MTime::kGames;
2036 _timeUnit = MTime::kFilm;
2039 _timeUnit = MTime::kPALFrame;
2042 _timeUnit = MTime::kNTSCFrame;
2045 _timeUnit = MTime::kShowScan;
2048 _timeUnit = MTime::kPALField;
2051 _timeUnit = MTime::kNTSCField;
2054 _timeUnit = MTime::k2FPS;
2057 _timeUnit = MTime::k3FPS;
2060 _timeUnit = MTime::k4FPS;
2063 _timeUnit = MTime::k5FPS;
2066 _timeUnit = MTime::k6FPS;
2069 _timeUnit = MTime::k8FPS;
2072 _timeUnit = MTime::k10FPS;
2075 _timeUnit = MTime::k12FPS;
2078 _timeUnit = MTime::k16FPS;
2081 _timeUnit = MTime::k20FPS;
2084 _timeUnit = MTime::k40FPS;
2087 _timeUnit = MTime::k75FPS;
2090 _timeUnit = MTime::k80FPS;
2093 _timeUnit = MTime::k100FPS;
2096 _timeUnit = MTime::kFilm;
2101 pos = comment.find(
"-sf");
2102 if (pos != string::npos) {
2103 ls = comment.find(
" ", pos+3);
2104 le = comment.find(
" ", ls+1);
2105 if (mayaloader_cat.is_debug()) {
2106 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2108 if (le == string::npos) {
2109 _start_frame = atoi(comment.substr(ls+1,le).data());
2111 _start_frame = atoi(comment.substr(ls+1,le-ls-1).data());
2116 pos = comment.find(
"-ef");
2117 if (pos != string::npos) {
2118 ls = comment.find(
" ", pos+3);
2119 le = comment.find(
" ", ls+1);
2120 if (mayaloader_cat.is_debug()) {
2121 mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl;
2123 if (le == string::npos) {
2124 _end_frame = atoi(comment.substr(ls+1,le).data());
2126 _end_frame = atoi(comment.substr(ls+1,le-ls-1).data());
2135bool MayaEggLoader::ConvertEggFile(
const char *name,
bool merge,
bool model,
bool anim,
bool respect_normals)
2139 if (!data.read(datafn)) {
2140 mayaloader_cat.error() <<
"Cannot read Egg file for import\n";
2143 return ConvertEggData(&data, merge, model, anim, respect_normals);
2146MObject MayaEggLoader::GetDependencyNode(
string givenName)
2148 MObject node = MObject::kNullObj;
2152 pos = givenName.find(
":");
2153 if (pos != string::npos) {
2154 name = givenName.substr(pos+1);
2179 JointTable::const_iterator ji;
2180 for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) {
2181 MayaEggJoint *joint = (*ji).second;
2182 if (mayaloader_cat.is_spam()) {
2183 mayaloader_cat.spam() <<
"traversing a joint: " << joint->_egg_joint->get_name() << endl;
2185 string jointName = joint->_egg_joint->get_name();
2186 if (jointName == name)
2188 node = joint->_joint;
2198bool MayaLoadEggData(
EggData *data,
bool merge,
bool model,
bool anim,
bool respect_normals)
2200 MayaEggLoader loader;
2201 bool temp = loader.ConvertEggData(data, merge, model, anim, respect_normals);
2205bool MayaLoadEggFile(
const char *name,
bool merge,
bool model,
bool anim,
bool respect_normals)
2207 MayaEggLoader loader;
2208 return loader.ConvertEggFile(name, merge, model, anim, respect_normals);
LColor get_color() const
Returns the color set on this particular attribute.
This is the primary interface into all the egg data, and the root of the egg file structure.
const Filename & get_fullpath() const
Returns the full pathname to the file, if it is known; otherwise, returns the same thing as get_filen...
A base class for nodes in the hierarchy that are not leaf nodes.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
virtual bool is_joint() const
Returns true if this particular node represents a <Joint> entry or not.
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
A base class for things that may be directly added into the egg hierarchy.
const LMatrix4d & get_vertex_to_node() const
Returns the transformation matrix suitable for converting the vertices as read from the egg file into...
A parametric NURBS surface.
bool is_closed_u() const
Returns true if the surface appears to be closed in the U direction.
bool is_closed_v() const
Returns true if the surface appears to be closed in the V direction.
get_num_u_knots
Returns the number of knots in the U 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,...
int get_v_degree() const
Returns the degree of the surface in the V direction.
get_v_knot
Returns the nth knot value defined in the V direction.
int get_num_v_cvs() const
Returns the number of control vertices that should be present in the V direction.
int get_u_degree() const
Returns the degree of the surface in the U direction.
get_u_knot
Returns the nth knot value defined in the U direction.
int get_num_u_cvs() const
Returns the number of control vertices that should be present in the U direction.
get_num_v_knots
Returns the number of knots in the V direction.
virtual bool cleanup() override
Cleans up modeling errors in whatever context this makes sense.
get_pool
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
get_vertex
Returns a particular index based on its index number.
get_bface_flag
Retrieves the backfacing flag of the polygon.
get_texture
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
Defines a texture map that may be applied to geometry.
A collection of vertices.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
int get_index() const
Returns the index number of the vertex within its pool.
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
GroupRef::const_iterator gref_end() const
Returns an iterator that can, in conjunction with gref_begin(), be used to traverse the entire set of...
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...
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine entries that specify...
virtual void write(std::ostream &out, int indent_level) const
Writes the data to the indicated output stream in Egg format.
int get_num_rows() const
Returns the effective number of rows in the table.
void get_value(int row, LMatrix4d &mat) const
Returns the value of the aggregate row of the table as a matrix.
The name of a file, such as a texture file or an Egg file.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
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,...
Specifies parameters that may be passed to the loader.
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...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.