40 #include <maya/MArgList.h>
41 #include <maya/MColor.h>
42 #include <maya/MDagPath.h>
43 #include <maya/MFnCamera.h>
44 #include <maya/MFnDagNode.h>
45 #include <maya/MFnTransform.h>
46 #include <maya/MFnLight.h>
47 #include <maya/MFnNurbsSurface.h>
48 #include <maya/MFnNurbsCurve.h>
49 #include <maya/MFnMesh.h>
50 #include <maya/MFnMeshData.h>
51 #include <maya/MFnPlugin.h>
52 #include <maya/MItDag.h>
53 #include <maya/MMatrix.h>
54 #include <maya/MObject.h>
55 #include <maya/MPoint.h>
56 #include <maya/MPointArray.h>
57 #include <maya/MDoubleArray.h>
58 #include <maya/MIntArray.h>
59 #include <maya/MPxCommand.h>
60 #include <maya/MStatus.h>
61 #include <maya/MString.h>
62 #include <maya/MTransformationMatrix.h>
63 #include <maya/MVector.h>
64 #include <maya/MTesselationParams.h>
65 #include <maya/MAnimControl.h>
66 #include <maya/MGlobal.h>
67 #include <maya/MAnimUtil.h>
68 #include <maya/MFnSkinCluster.h>
69 #include <maya/MFnWeightGeometryFilter.h>
70 #include <maya/MFnIkJoint.h>
71 #include <maya/MFnSingleIndexedComponent.h>
72 #include <maya/MFnDoubleIndexedComponent.h>
73 #include <maya/MFnBlendShapeDeformer.h>
74 #include <maya/MItDependencyGraph.h>
75 #include <maya/MDagPathArray.h>
76 #include <maya/MSelectionList.h>
87 MayaToEggConverter(
const string &program_name) :
88 _program_name(program_name),
94 _from_selection =
false;
96 _polygon_output =
false;
97 _polygon_tolerance = 0.01;
98 _respect_maya_double_sided = maya_default_double_sided;
99 _always_show_vertex_color = maya_default_vertex_color;
100 _keep_all_uvsets =
false;
102 _legacy_shader =
false;
103 _convert_cameras =
false;
104 _convert_lights =
false;
106 _transform_type = TT_model;
114 _program_name(copy._program_name),
115 _from_selection(copy._from_selection),
116 _subsets(copy._subsets),
117 _subroots(copy._subroots),
118 _excludes(copy._excludes),
119 _ignore_sliders(copy._ignore_sliders),
120 _force_joints(copy._force_joints),
123 _polygon_output(copy._polygon_output),
124 _polygon_tolerance(copy._polygon_tolerance),
125 _respect_maya_double_sided(copy._respect_maya_double_sided),
126 _always_show_vertex_color(copy._always_show_vertex_color),
127 _keep_all_uvsets(copy._keep_all_uvsets),
128 _convert_cameras(copy._convert_cameras),
129 _convert_lights(copy._convert_lights),
130 _round_uvs(copy._round_uvs),
131 _legacy_shader(copy._legacy_shader),
132 _transform_type(copy._transform_type)
140 ~MayaToEggConverter() {
188 <<
"Maya is not available.\n";
197 if (!_maya->read(filename)) {
199 <<
"Unable to read " << filename <<
"\n";
203 if (_character_name.empty()) {
227 _subroots.push_back(glob);
247 _subsets.push_back(glob);
263 _excludes.push_back(glob);
272 _ignore_sliders.clear();
284 _ignore_sliders.push_back(glob);
293 Globs::const_iterator gi;
294 for (gi = _ignore_sliders.begin(); gi != _ignore_sliders.end(); ++gi) {
295 if ((*gi).matches(name)) {
309 _force_joints.clear();
323 _force_joints.push_back(glob);
332 Globs::const_iterator gi;
333 for (gi = _force_joints.begin(); gi != _force_joints.end(); ++gi) {
334 if ((*gi).matches(name)) {
350 _from_selection = from_selection;
361 return _maya->get_units();
375 <<
"Maya is not available.\n";
379 if (_egg_data->get_coordinate_system() == CS_default) {
380 _egg_data->set_coordinate_system(_maya->get_coordinate_system());
384 <<
"Converting from Maya.\n";
387 double start_frame, end_frame, frame_inc, input_frame_rate, output_frame_rate;
391 start_frame = MAnimControl::minTime().value();
396 end_frame = MAnimControl::maxTime().value();
408 MTime time(1.0, MTime::kSeconds);
409 input_frame_rate = time.as(MTime::uiUnit());
414 output_frame_rate = input_frame_rate;
417 frame_inc = frame_inc * input_frame_rate / output_frame_rate;
422 if (!_subroots.empty()) {
423 Globs::const_iterator gi;
424 for (gi = _subroots.begin(); gi != _subroots.end(); ++gi) {
427 <<
"No node matching " << *gi <<
" found.\n";
439 if (_from_selection) {
441 }
else if (!_subsets.empty()) {
442 Globs::const_iterator gi;
443 for (gi = _subsets.begin(); gi != _subsets.end(); ++gi) {
446 <<
"No node matching " << *gi <<
" found.\n";
456 if (!_excludes.empty()) {
457 Globs::const_iterator gi;
458 for (gi = _excludes.begin(); gi != _excludes.end(); ++gi) {
461 <<
"No node matching " << *gi <<
" found.\n";
471 mayaegg_cat.info(
false)
472 <<
"frame " << start_frame <<
"\n";
473 MGlobal::viewFrame(MTime(start_frame, MTime::uiUnit()));
478 mayaegg_cat.info() <<
"ac_none" << endl;
486 all_ok = convert_flip(start_frame, end_frame, frame_inc,
492 all_ok = convert_char_model();
497 all_ok = convert_char_chan(start_frame, end_frame, frame_inc,
503 _animation_convert = AC_model;
504 if (!convert_char_model()) {
507 _animation_convert = AC_chan;
508 if (!convert_char_chan(start_frame, end_frame, frame_inc,
509 output_frame_rate)) {
527 <<
"Converted, no errors.\n";
530 <<
"Errors encountered in conversion.\n";
543 if (_maya ==
nullptr || !_maya->is_valid()) {
546 _maya = MayaApi::open_api(_program_name,
true, revert_directory);
548 return _maya->is_valid();
580 bool MayaToEggConverter::
581 convert_flip(
double start_frame,
double end_frame,
double frame_inc,
582 double output_frame_rate) {
587 if (_animation_convert == AC_flip) {
588 sequence_node->set_switch_flag(
true);
589 sequence_node->set_switch_fps(output_frame_rate);
592 MTime frame(start_frame, MTime::uiUnit());
593 MTime frame_stop(end_frame, MTime::uiUnit());
594 while (frame <= frame_stop) {
595 mayaegg_cat.info(
false)
596 <<
"frame " << frame.value() <<
"\n";
597 std::ostringstream name_strm;
598 name_strm <<
"frame" << frame.value();
602 MGlobal::viewFrame(frame);
603 if (!convert_hierarchy(frame_root)) {
617 bool MayaToEggConverter::
618 convert_char_model() {
621 mayaegg_cat.info(
false)
622 <<
"neutral frame " << frame.value() <<
"\n";
623 MGlobal::viewFrame(frame);
633 char_node->set_dart_type(EggGroup::DT_default);
635 return convert_hierarchy(char_node);
642 bool MayaToEggConverter::
643 convert_char_chan(
double start_frame,
double end_frame,
double frame_inc,
644 double output_frame_rate) {
650 bundle_node->set_table_type(EggTable::TT_bundle);
658 _tree._fps = output_frame_rate;
672 MTime frame(start_frame, MTime::uiUnit());
673 MTime frame_stop(end_frame, MTime::uiUnit());
674 while (frame <= frame_stop) {
675 if (mayaegg_cat.is_spam()) {
676 mayaegg_cat.spam(
false)
677 <<
"frame " << frame.value() <<
"\n";
681 std::cerr <<
"." << std::flush;
683 MGlobal::viewFrame(frame);
685 for (i = 0; i < num_nodes; i++) {
688 if (mayaegg_cat.is_spam()) {
690 <<
"joint " << node_desc->get_name() <<
"\n";
694 if (!anim->
add_data(tgroup->get_transform3d())) {
696 <<
"Invalid transform on " << node_desc->get_name()
697 <<
" frame " << frame.value() <<
".\n";
702 for (i = 0; i < num_sliders; i++) {
704 if (mayaegg_cat.is_spam()) {
706 <<
"slider " << blend_desc->get_name() <<
"\n";
718 for (i = 0; i < num_nodes; i++) {
725 for (i = 0; i < num_sliders; i++) {
731 mayaegg_cat.info(
false)
740 bool MayaToEggConverter::
745 mayaegg_cat.info() <<
"will round up uv coordinates" << endl;
748 if (_keep_all_uvsets) {
749 mayaegg_cat.info() <<
"will keep_all_uvsets" << endl;
751 if (_polygon_output) {
752 mayaegg_cat.info() <<
"will convert NURBS to polys" << endl;
754 if (_convert_cameras) {
755 mayaegg_cat.info() <<
"will convert camera nodes to locators" << endl;
757 if (_convert_lights) {
758 mayaegg_cat.info() <<
"will convert light nodes to locators" << endl;
761 if (_legacy_shader) {
762 mayaegg_cat.info() <<
"will disable modern Phong shader path. using legacy" << endl;
765 for (
int i = 0; i < num_nodes; i++) {
767 if (!process_model_node(node)) {
779 bool MayaToEggConverter::
789 MFnDagNode dag_node(dag_path, &status);
791 status.perror(
"MFnDagNode constructor");
792 mayaegg_cat.error() << dag_path.fullPathName().asChar() <<
"\n";
796 MObject node = dag_path.transform(&status);
798 status.perror(
"dag_path.transform()");
802 string path = dag_path.fullPathName().asChar();
804 if (mayaegg_cat.is_debug()) {
806 << path <<
": " << dag_node.typeName().asChar();
808 if (MAnimUtil::isAnimated(dag_path)) {
809 mayaegg_cat.debug(
false)
813 mayaegg_cat.debug(
false) <<
"\n";
816 if (dag_node.inUnderWorld()) {
817 if (mayaegg_cat.is_debug()) {
819 <<
"Ignoring underworld node " << path
823 }
else if (dag_node.isIntermediateObject()) {
824 if (mayaegg_cat.is_debug()) {
826 <<
"Ignoring intermediate object " << path
830 }
else if (dag_path.hasFn(MFn::kCamera)) {
831 if (_convert_cameras) {
832 MFnCamera camera (dag_path, &status);
834 status.perror(
"MFnCamera constructor");
839 if (mayaegg_cat.is_spam()) {
840 MPoint eyePoint = camera.eyePoint(MSpace::kWorld);
841 MVector upDirection = camera.upDirection(MSpace::kWorld);
842 MVector viewDirection = camera.viewDirection(MSpace::kWorld);
843 mayaegg_cat.spam() <<
" eyePoint: " << eyePoint.x <<
" "
844 << eyePoint.y <<
" " << eyePoint.z << endl;
845 mayaegg_cat.spam() <<
" upDirection: " << upDirection.x <<
" "
846 << upDirection.y <<
" " << upDirection.z << endl;
847 mayaegg_cat.spam() <<
" viewDirection: " << viewDirection.x <<
" "
848 << viewDirection.y <<
" " << viewDirection.z << endl;
849 mayaegg_cat.spam() <<
" aspectRatio: " << camera.aspectRatio() << endl;
850 mayaegg_cat.spam() <<
" horizontalFilmAperture: "
851 << camera.horizontalFilmAperture() << endl;
852 mayaegg_cat.spam() <<
" verticalFilmAperture: "
853 << camera.verticalFilmAperture() << endl;
858 if (mayaegg_cat.is_debug()) {
859 mayaegg_cat.warning()
860 <<
"Saving camera nodes as a locator: " << path <<
"\n";
867 if (_animation_convert != AC_model) {
872 egg_group->set_dcs_type(EggGroup::DC_net);
874 get_transform(node_desc, dag_path, egg_group);
875 make_camera_locator(dag_path, dag_node, egg_group);
877 if (mayaegg_cat.is_debug()) {
879 <<
"Ignoring camera node " << path
885 }
else if (dag_path.hasFn(MFn::kLight)) {
886 if (_convert_lights) {
887 MFnLight light (dag_path, &status);
889 status.perror(
"MFnLight constructor");
895 if (mayaegg_cat.is_debug()) {
896 mayaegg_cat.warning() <<
"Saving light node as a locator: " << path << endl;
903 if (_animation_convert != AC_model) {
908 egg_group->set_dcs_type(EggGroup::DC_net);
910 get_transform(node_desc, dag_path, egg_group);
911 make_light_locator(dag_path, dag_node, egg_group);
913 if (mayaegg_cat.is_debug()) {
915 <<
"Ignoring light node " << path
921 MFnLight light (dag_path, &status);
923 status.perror(
"MFnLight constructor");
924 mayaegg_cat.error() <<
"light extraction failed" << endl;
928 if (mayaegg_cat.is_info()) {
929 MString name = dag_path.partialPathName();
930 mayaegg_cat.info() <<
"-- Light found -- tranlations in cm, rotations in rads\n";
931 mayaegg_cat.info() <<
"\"" << name.asChar() <<
"\" : \n";
935 MObject transformNode = dag_path.transform(&status);
937 if (!status && status.statusCode () == MStatus::kInvalidParameter)
939 MFnDagNode transform (transformNode, &status);
941 status.perror(
"MFnDagNode constructor");
944 MTransformationMatrix matrix (transform.transformationMatrix());
945 MVector tl = matrix.translation(MSpace::kWorld);
958 mayaegg_cat.info() <<
" \"translation\" : (" << tl.x <<
", " << tl.z <<
", " << tl.y <<
")"
960 double threeDoubles[3];
961 MTransformationMatrix::RotationOrder rOrder;
963 matrix.getRotation (threeDoubles, rOrder, MSpace::kWorld);
964 mayaegg_cat.info() <<
" \"rotation\": ("
965 << threeDoubles[0] <<
", "
966 << threeDoubles[2] <<
", "
967 << threeDoubles[1] <<
")\n";
968 matrix.getScale (threeDoubles, MSpace::kWorld);
969 mayaegg_cat.info() <<
" \"scale\" : ("
970 << threeDoubles[0] <<
", "
971 << threeDoubles[2] <<
", "
972 << threeDoubles[1] <<
")\n";
976 color = light.color();
977 mayaegg_cat.info() <<
" \"color\" : ("
981 color = light.shadowColor();
982 mayaegg_cat.info() <<
" \"intensity\" : " << light.intensity() << endl;
984 }
else if (dag_path.hasFn(MFn::kNurbsSurface)) {
986 get_transform(node_desc, dag_path, egg_group);
989 MFnNurbsSurface surface(dag_path, &status);
992 <<
"Error in node " << path
994 <<
" it appears to have a NURBS surface, but does not.\n";
996 make_nurbs_surface(node_desc, dag_path, surface, egg_group);
999 }
else if (dag_path.hasFn(MFn::kNurbsCurve)) {
1003 if (_animation_convert != AC_model) {
1005 get_transform(node_desc, dag_path, egg_group);
1008 MFnNurbsCurve curve(dag_path, &status);
1011 <<
"Error in node " << path <<
":\n"
1012 <<
" it appears to have a NURBS curve, but does not.\n";
1014 make_nurbs_curve(dag_path, curve, egg_group);
1019 }
else if (dag_path.hasFn(MFn::kMesh)) {
1022 get_transform(node_desc, dag_path, egg_group);
1023 MFnMesh mesh(dag_path, &status);
1026 <<
"Error in node " << path <<
":\n"
1027 <<
" it appears to have a polygon mesh, but does not.\n";
1029 make_polyset(node_desc, dag_path, mesh, egg_group);
1047 }
else if (dag_path.hasFn(MFn::kLocator)) {
1048 if (_animation_convert == AC_none) {
1055 if (mayaegg_cat.is_debug()) {
1057 <<
"Locator at " << path <<
"\n";
1064 if (_animation_convert != AC_model) {
1069 egg_group->set_dcs_type(EggGroup::DC_net);
1071 get_transform(node_desc, dag_path, egg_group);
1072 make_locator(dag_path, dag_node, egg_group);
1077 if (_animation_convert == AC_none) {
1083 get_transform(node_desc, dag_path, egg_group);
1093 void MayaToEggConverter::
1094 get_transform(
MayaNodeDesc *node_desc,
const MDagPath &dag_path,
1096 if (_animation_convert == AC_model) {
1101 if (mayaegg_cat.is_spam()) {
1103 <<
"gt: joint " << node_desc->get_name() <<
"\n";
1105 get_joint_transform(dag_path, egg_group);
1111 MObject transformNode = dag_path.transform(&status);
1112 if (!status && status.statusCode() == MStatus::kInvalidParameter) {
1118 if (egg_group->get_billboard_type() == EggGroup::BT_none) {
1119 switch (_transform_type) {
1124 if (!egg_group->get_model_flag() && !egg_group->
has_dcs_type()) {
1142 MMatrix mat = dag_path.inclusiveMatrix(&status);
1144 status.perror(
"Can't get transform matrix");
1147 LMatrix4d m4d(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
1148 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
1149 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
1150 mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
1155 MFnTransform transform(transformNode, &status);
1157 status.perror(
"MFnTransform constructor");
1160 MPoint pivot = transform.rotatePivot(MSpace::kObject, &status);
1162 status.perror(
"Can't get rotate pivot");
1168 LPoint3d p3d(pivot[0], pivot[1], pivot[2]);
1172 m4d.set_row(3, p3d);
1176 if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
1189 void MayaToEggConverter::
1190 get_joint_transform(
const MDagPath &dag_path,
EggGroup *egg_group) {
1195 MObject transformNode = dag_path.transform(&status);
1197 if (!status && status.statusCode() == MStatus::kInvalidParameter) {
1201 MFnDagNode transform(transformNode, &status);
1203 status.perror(
"MFnDagNode constructor");
1207 MTransformationMatrix matrix(transform.transformationMatrix());
1209 if (mayaegg_cat.is_spam()) {
1210 MVector t = matrix.translation(MSpace::kWorld);
1212 <<
" translation: ["
1217 MTransformationMatrix::RotationOrder rOrder;
1219 matrix.getRotation(d, rOrder, MSpace::kWorld);
1225 matrix.getScale(d, MSpace::kWorld);
1231 matrix.getShear(d, MSpace::kWorld);
1239 MMatrix mat = matrix.asMatrix();
1241 ident_mat.setToIdentity();
1243 if (!mat.isEquivalent(ident_mat, 0.0001)) {
1245 (LMatrix4d(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
1246 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
1247 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
1248 mat[3][0], mat[3][1], mat[3][2], mat[3][3]));
1256 void MayaToEggConverter::
1257 make_nurbs_surface(
MayaNodeDesc *node_desc,
const MDagPath &dag_path,
1258 MFnNurbsSurface &surface,
EggGroup *egg_group) {
1260 string name = surface.name().asChar();
1262 if (mayaegg_cat.is_spam()) {
1265 << surface.numCVsInU()
1267 << surface.numCVsInV()
1271 << surface.numKnotsInU()
1273 << surface.numKnotsInV()
1277 << surface.numSpansInU()
1279 << surface.numSpansInV()
1284 if (_polygon_output) {
1286 MTesselationParams params;
1287 params.setFormatType(MTesselationParams::kStandardFitFormat);
1288 params.setOutputType(MTesselationParams::kQuads);
1289 params.setStdFractionalTolerance(_polygon_tolerance);
1293 MDagPath polyset_path = dag_path;
1294 MObject polyset_parent = polyset_path.node();
1296 surface.tesselate(params, polyset_parent, &status);
1298 status.perror(
"MFnNurbsSurface::tesselate");
1302 status = polyset_path.push(polyset);
1304 status.perror(
"MDagPath::push");
1307 MFnMesh polyset_fn(polyset, &status);
1309 status.perror(
"MFnMesh constructor");
1312 make_polyset(node_desc, polyset_path, polyset_fn, egg_group, shader);
1315 MFnDagNode parent_node(polyset_parent, &status);
1317 status.perror(
"MFnDagNode constructor");
1320 status = parent_node.removeChild(polyset);
1322 status.perror(
"MFnDagNode::removeChild");
1328 MPointArray cv_array;
1329 status = surface.getCVs(cv_array, MSpace::kWorld);
1331 status.perror(
"MFnNurbsSurface::getCVs");
1338 if (_animation_convert == AC_model) {
1340 morph_cvs.reserve(num_sliders);
1341 for (
int i = 0; i < num_sliders; i++) {
1347 MPointArray cv_array;
1348 status = surface.getCVs(cv_array, MSpace::kWorld);
1352 status.perror(
"MFnNurbsSurface::getCVs");
1355 morph_cvs.push_back(cv_array);
1359 MDoubleArray u_knot_array, v_knot_array;
1360 status = surface.getKnotsInU(u_knot_array);
1362 status.perror(
"MFnNurbsSurface::getKnotsInU");
1365 status = surface.getKnotsInV(v_knot_array);
1367 status.perror(
"MFnNurbsSurface::getKnotsInV");
1371 MFnNurbsSurface::Form u_form = surface.formInU();
1372 MFnNurbsSurface::Form v_form = surface.formInV();
1374 int u_degree = surface.degreeU();
1375 int v_degree = surface.degreeV();
1377 int u_cvs = surface.numCVsInU();
1378 int v_cvs = surface.numCVsInV();
1382 int maya_u_cvs = (u_form == MFnNurbsSurface::kPeriodic) ? u_cvs - u_degree : u_cvs;
1383 int maya_v_cvs = (v_form == MFnNurbsSurface::kPeriodic) ? v_cvs - v_degree : v_cvs;
1385 int u_knots = surface.numKnotsInU();
1386 int v_knots = surface.numKnotsInV();
1388 assert(u_knots == u_cvs + u_degree - 1);
1389 assert(v_knots == v_cvs + v_degree - 1);
1391 string vpool_name = name +
".cvs";
1396 egg_nurbs->
setup(u_degree + 1, v_degree + 1,
1397 u_knots + 2, v_knots + 2);
1402 for (i = 0; i < u_knots; i++) {
1403 egg_nurbs->
set_u_knot(i + 1, u_knot_array[i]);
1405 egg_nurbs->
set_u_knot(u_knots + 1, u_knot_array[u_knots - 1]);
1408 for (i = 0; i < v_knots; i++) {
1409 egg_nurbs->
set_v_knot(i + 1, v_knot_array[i]);
1411 egg_nurbs->
set_v_knot(v_knots + 1, v_knot_array[v_knots - 1]);
1418 int maya_vi = v_cvs * ui + vi;
1421 status = cv_array[maya_vi].get(v);
1423 status.perror(
"MPoint::get");
1426 LPoint4d p4d(v[0], v[1], v[2], v[3]);
1427 p4d = p4d * vertex_frame_inv;
1431 if (!morph_cvs.empty()) {
1433 LPoint3d p3d(v[0] / v[3], v[1] / v[3], v[2] / v[3]);
1435 for (
unsigned int si = 0; si < morph_cvs.size(); si++) {
1437 status = morph_cvs[si][maya_vi].get(v);
1439 status.perror(
"MPoint::get");
1441 LPoint3d m3d(v[0] / v[3], v[1] / v[3], v[2] / v[3]);
1442 LVector3d delta = m3d - p3d;
1443 if (!delta.almost_equal(LVector3d::zero())) {
1445 vert->_dxyzs.
insert(dxyz);
1456 unsigned num_trims = surface.numRegions();
1457 int trim_curve_index = 0;
1458 for (
unsigned ti = 0; ti < num_trims; ti++) {
1459 unsigned num_loops = surface.numBoundaries(ti);
1461 if (num_loops > 0) {
1465 for (
unsigned li = 0; li < num_loops; li++) {
1469 MFnNurbsSurface::BoundaryType type =
1470 surface.boundaryType(ti, li, &status);
1471 bool keep_loop =
false;
1474 status.perror(
"MFnNurbsSurface::BoundaryType");
1476 keep_loop = (type == MFnNurbsSurface::kInner ||
1477 type == MFnNurbsSurface::kOuter);
1481 unsigned num_edges = surface.numEdges(ti, li);
1482 for (
unsigned ei = 0; ei < num_edges; ei++) {
1483 MObjectArray edge = surface.edge(ti, li, ei,
true, &status);
1485 status.perror(
"MFnNurbsSurface::edge");
1487 unsigned num_segs = edge.length();
1488 for (
unsigned si = 0; si < num_segs; si++) {
1489 MObject segment = edge[si];
1490 if (segment.hasFn(MFn::kNurbsCurve)) {
1491 MFnNurbsCurve curve(segment, &status);
1494 <<
"Trim curve appears to be a nurbs curve, but isn't.\n";
1498 make_trim_curve(curve, name, egg_group, trim_curve_index);
1500 if (egg_curve !=
nullptr) {
1501 egg_loop.push_back(egg_curve);
1506 <<
"Trim curve segment is not a nurbs curve.\n";
1520 if (shader !=
nullptr) {
1521 set_shader_attributes(*egg_nurbs, *shader);
1525 bool got_weights =
false;
1528 MFloatArray weights;
1529 if (_animation_convert == AC_model) {
1531 get_vertex_weights(dag_path, surface, joints, weights);
1534 if (got_weights && !joints.empty()) {
1535 int num_joints = joints.size();
1536 int num_weights = (int)weights.length();
1537 int num_verts = num_weights / num_joints;
1539 nassertv(num_weights == num_verts * num_joints);
1545 int maya_vi = maya_v_cvs * ui + vi;
1546 nassertv(maya_vi < num_verts);
1549 for (
int ji = 0; ji < num_joints; ++ji) {
1550 PN_stdfloat weight = weights[maya_vi * num_joints + ji];
1551 if (weight != 0.0f) {
1553 if (joint !=
nullptr) {
1567 make_trim_curve(
const MFnNurbsCurve &curve,
const string &nurbs_name,
1569 if (mayaegg_cat.is_spam()) {
1588 MPointArray cv_array;
1589 status = curve.getCVs(cv_array, MSpace::kWorld);
1591 status.perror(
"MFnNurbsCurve::getCVs");
1594 MDoubleArray knot_array;
1595 status = curve.getKnots(knot_array);
1597 status.perror(
"MFnNurbsCurve::getKnots");
1605 int degree = curve.degree();
1606 int cvs = curve.numCVs();
1607 int knots = curve.numKnots();
1609 assert(knots == cvs + degree - 1);
1611 string trim_name =
"trim" + format_string(trim_curve_index);
1613 string vpool_name = nurbs_name +
"." + trim_name;
1618 egg_curve->
setup(degree + 1, knots + 2);
1622 egg_curve->
set_knot(0, knot_array[0]);
1623 for (i = 0; i < knots; i++) {
1624 egg_curve->
set_knot(i + 1, knot_array[i]);
1626 egg_curve->
set_knot(knots + 1, knot_array[knots - 1]);
1630 MStatus status = cv_array[i].get(v);
1632 status.perror(
"MPoint::get");
1635 vert.
set_pos(LPoint3d(v[0], v[1], v[3]));
1648 void MayaToEggConverter::
1649 make_nurbs_curve(
const MDagPath &,
const MFnNurbsCurve &curve,
1652 string name = curve.name().asChar();
1654 if (mayaegg_cat.is_spam()) {
1669 MPointArray cv_array;
1670 status = curve.getCVs(cv_array, MSpace::kWorld);
1672 status.perror(
"MFnNurbsCurve::getCVs");
1675 MDoubleArray knot_array;
1676 status = curve.getKnots(knot_array);
1678 status.perror(
"MFnNurbsCurve::getKnots");
1686 int degree = curve.degree();
1687 int cvs = curve.numCVs();
1688 int knots = curve.numKnots();
1690 assert(knots == cvs + degree - 1);
1692 string vpool_name = name +
".cvs";
1698 egg_curve->
setup(degree + 1, knots + 2);
1702 egg_curve->
set_knot(0, knot_array[0]);
1703 for (i = 0; i < knots; i++) {
1704 egg_curve->
set_knot(i + 1, knot_array[i]);
1706 egg_curve->
set_knot(knots + 1, knot_array[knots - 1]);
1712 MStatus status = cv_array[i].get(v);
1714 status.perror(
"MPoint::get");
1717 LPoint4d p4d(v[0], v[1], v[2], v[3]);
1718 p4d = p4d * vertex_frame_inv;
1724 if (shader !=
nullptr) {
1725 set_shader_attributes(*egg_curve, *shader);
1732 int MayaToEggConverter::
1733 round(
double value) {
1735 return -(floor(-value + 0.5));
1738 return floor( value + 0.5);
1745 void MayaToEggConverter::
1746 make_polyset(
MayaNodeDesc *node_desc,
const MDagPath &dag_path,
1747 const MFnMesh &mesh,
EggGroup *egg_group,
1750 string name = mesh.name().asChar();
1752 MObject mesh_object = mesh.object();
1753 bool maya_double_sided =
false;
1756 if (mayaegg_cat.is_spam()) {
1759 << mesh.numPolygons()
1763 << mesh.numVertices()
1767 if (mesh.numPolygons() == 0) {
1768 if (mayaegg_cat.is_debug()) {
1770 <<
"Ignoring empty mesh " << name <<
"\n";
1775 string vpool_name = name +
".verts";
1790 MObject component_obj;
1791 MItMeshPolygon pi(dag_path, component_obj, &status);
1793 status.perror(
"MItMeshPolygon constructor");
1797 MObjectArray shaders;
1798 MIntArray poly_shader_indices;
1800 status = mesh.getConnectedShaders(dag_path.instanceNumber(),
1801 shaders, poly_shader_indices);
1803 status.perror(
"MFnMesh::getConnectedShaders");
1814 bool egg_vertex_color =
false;
1815 bool egg_double_sided =
false;
1816 if (egg_group->
has_user_data(MayaEggGroupUserData::get_class_type())) {
1819 egg_vertex_color = user_data->_vertex_color;
1820 egg_double_sided = user_data->_double_sided;
1823 bool double_sided = maya_double_sided;
1824 if (!_respect_maya_double_sided) {
1827 if (!egg_double_sided) {
1828 double_sided =
false;
1832 bool keep_all_uvsets = _keep_all_uvsets || node_desc->
has_object_type(
"keep-all-uvsets");
1834 mayaegg_cat.info() <<
"will keep_all_uvsets" << endl;
1839 while (!pi.isDone()) {
1850 int index = pi.index();
1851 nassertv(index >= 0 && index < (
int)poly_shader_indices.length());
1852 int shader_index = poly_shader_indices[index];
1854 if (shader_index != -1) {
1855 nassertv(shader_index >= 0 && shader_index < (
int)shaders.length());
1856 MObject engine = shaders[shader_index];
1861 }
else if (default_shader !=
nullptr) {
1862 shader = default_shader;
1868 if (shader !=
nullptr) {
1869 set_shader_attributes(*egg_poly, *shader,
true);
1884 bool ignore_vertex_color =
false;
1885 if ( default_color_def !=
nullptr) {
1886 ignore_vertex_color = default_color_def->_has_texture && !(egg_vertex_color || _always_show_vertex_color);
1889 LColor poly_color(1.0f, 1.0f, 1.0f, 1.0f);
1890 if (!ignore_vertex_color) {
1894 egg_poly->clear_color();
1898 long num_verts = pi.polygonVertexCount();
1900 LPoint3d centroid(0.0, 0.0, 0.0);
1902 if (default_color_def !=
nullptr && default_color_def->
has_projection()) {
1905 for (i = 0; i < num_verts; i++) {
1906 MPoint p = pi.point(i, MSpace::kWorld);
1907 LPoint3d p3d(p[0], p[1], p[2]);
1908 p3d = p3d * vertex_frame_inv;
1911 centroid /= (double)num_verts;
1913 for (i = 0; i < num_verts; i++) {
1916 MPoint p = pi.point(i, MSpace::kWorld);
1917 LPoint3d p3d(p[0] / p[3], p[1] / p[3], p[2] / p[3]);
1918 p3d = p3d * vertex_frame_inv;
1922 status = pi.getNormal(i, n, MSpace::kWorld);
1924 status.perror(
"MItMeshPolygon::getNormal");
1926 LNormald n3d(n[0], n[1], n[2]);
1927 n3d = n3d * vertex_frame_inv;
1928 vert.set_normal(n3d);
1932 if (mayaegg_cat.is_spam()) {
1933 if (shader !=
nullptr) {
1934 mayaegg_cat.spam() <<
"shader->_color.size is " << shader->_color.size() << endl;
1936 mayaegg_cat.spam() <<
"primitive->tref.size is " << egg_poly->
get_num_textures() << endl;
1938 for (
size_t ti=0; ti< _shaders._uvset_names.size(); ++ti) {
1940 string uvset_name(_shaders._uvset_names[ti]);
1941 string panda_uvset_name = uvset_name;
1942 if (panda_uvset_name ==
"map1") {
1943 panda_uvset_name =
"default";
1945 if (mayaegg_cat.is_spam()) {
1946 mayaegg_cat.spam() <<
"--uvset_name :" << uvset_name << endl;
1953 bool keep_uv = keep_all_uvsets;
1954 bool project_uv =
false;
1955 LTexCoordd uv_projection;
1957 if (shader !=
nullptr) {
1958 for (
size_t tj = 0; tj < shader->_all_maps.size(); ++tj) {
1960 if (def->_uvset_name == uvset_name) {
1961 if (mayaegg_cat.is_spam()) {
1962 mayaegg_cat.spam() <<
"matched colordef idx: " << tj << endl;
1967 uv_projection = def->
project_uv(p3d, centroid);
1976 if (mayaegg_cat.is_spam()) {
1977 mayaegg_cat.spam() <<
"discarding unused uvset " << uvset_name << endl;
1985 vert.
set_uv(panda_uvset_name, uv_projection);
1989 MString uv_mstring(uvset_name.c_str());
1990 if (pi.hasUVs(uv_mstring, &status)) {
1991 status = pi.getUV(i, uvs, &uv_mstring);
1993 status.perror(
"MItMeshPolygon::getUV");
1996 if (uvs[0] > 1.0 || uvs[0] < -1.0) {
1998 uvs[0] = (long)(uvs[0]*1000);
1999 mayaegg_cat.debug() <<
"before rounding uvs[0]: " << uvs[0] << endl;
2000 uvs[0] = (double)(round((
double)uvs[0]/10.0)*10.0)/1000.0;
2001 mayaegg_cat.debug() <<
"after rounding uvs[0]: " << uvs[0] << endl;
2003 if (uvs[1] > 1.0 || uvs[1] < -1.0) {
2004 uvs[1] = (long)(uvs[1]*1000);
2005 mayaegg_cat.debug() <<
"before rounding uvs[1]: " << uvs[1] << endl;
2006 uvs[1] = (double)(round((
double)uvs[1]/10.0)*10.0)/1000.0;
2007 mayaegg_cat.debug() <<
"after rounding uvs[1]: " << uvs[1] << endl;
2010 vert.
set_uv(panda_uvset_name, LTexCoordd(uvs[0], uvs[1]));
2016 if (!ignore_vertex_color) {
2017 if (mayaegg_cat.is_spam()) {
2018 mayaegg_cat.spam() <<
"poly_color = " << poly_color << endl;
2020 set_vertex_color(vert,pi,i,shader,poly_color);
2030 LNormald face_normal;
2031 bool got_face_normal =
false;
2034 status = pi.getNormal(n, MSpace::kWorld);
2036 status.perror(
"MItMeshPolygon::getNormal face");
2038 face_normal.set(n[0], n[1], n[2]);
2039 face_normal = face_normal * vertex_frame_inv;
2040 got_face_normal =
true;
2041 egg_poly->set_normal(face_normal);
2047 LNormald order_normal;
2049 if (order_normal.dot(face_normal) < 0.0) {
2051 if (mayaegg_cat.is_debug()) {
2053 <<
"reversing polygon\n";
2060 if (mayaegg_cat.is_spam()) {
2061 mayaegg_cat.spam() <<
"done traversing polys" << endl;
2067 bool got_weights =
false;
2070 MFloatArray weights;
2071 if (_animation_convert == AC_model) {
2073 get_vertex_weights(dag_path, mesh, joints, weights);
2076 if (got_weights && !joints.empty()) {
2077 int num_joints = joints.size();
2078 int num_weights = (int)weights.length();
2079 int num_verts = num_weights / num_joints;
2081 nassertv(num_weights == num_verts * num_joints);
2084 for (vi = vpool->
begin(); vi != vpool->
end(); ++vi) {
2087 nassertv(maya_vi >= 0 && maya_vi < num_verts);
2089 for (
int ji = 0; ji < num_joints; ++ji) {
2090 PN_stdfloat weight = weights[maya_vi * num_joints + ji];
2091 if (weight != 0.0f) {
2093 if (joint !=
nullptr) {
2108 if (_animation_convert == AC_model) {
2109 int num_orig_mesh_verts = mesh.numVertices();
2112 for (
int i = 0; i < num_sliders; i++) {
2121 MFnMesh blend_mesh(dag_path, &status);
2123 mayaegg_cat.warning()
2124 << name <<
" no longer has a mesh after applying "
2125 << blend_desc->get_name() <<
"\n";
2128 if (blend_mesh.numVertices() != num_orig_mesh_verts) {
2129 mayaegg_cat.warning()
2130 <<
"Ignoring " << blend_desc->get_name() <<
" for "
2131 << name <<
"; blend shape has " << blend_mesh.numVertices()
2132 <<
" vertices while original shape has "
2133 << num_orig_mesh_verts <<
".\n";
2137 status = blend_mesh.getPoints(verts, MSpace::kWorld);
2139 status.perror(
"MFnMesh::getPoints");
2141 int num_verts = (int)verts.length();
2143 for (vi = vpool->
begin(); vi != vpool->
end(); ++vi) {
2146 nassertv(maya_vi >= 0 && maya_vi < num_verts);
2148 const MPoint &m = verts[maya_vi];
2149 LPoint3d m3d(m[0] / m[3], m[1] / m[3], m[2] / m[3]);
2150 m3d = m3d * vertex_frame_inv;
2152 LVector3d delta = m3d - vert->
get_pos3();
2153 if (!delta.almost_equal(LVector3d::zero())) {
2155 vert->_dxyzs.
insert(dxyz);
2160 MFloatVectorArray norms;
2161 status = blend_mesh.getNormals(norms, MSpace::kWorld);
2163 status.perror(
"MFnMesh::getNormals");
2165 int num_norms = (int)norms.length();
2167 for (vi = vpool->
begin(); vi != vpool->
end(); ++vi) {
2170 nassertv(maya_vi >= 0 && maya_vi < num_norms);
2172 const MFloatVector &m = norms[maya_vi];
2173 LVector3d m3d(m[0], m[1], m[2]);
2174 m3d = m3d * vertex_frame_inv;
2176 LNormald delta = m3d - vert->get_normal();
2177 if (!delta.almost_equal(LVector3d::zero())) {
2179 vert->_dnormals.
insert(dnormal);
2197 void MayaToEggConverter::
2198 make_locator(
const MDagPath &dag_path,
const MFnDagNode &dag_node,
2202 unsigned int num_children = dag_node.childCount();
2204 bool found_locator =
false;
2205 for (
unsigned int ci = 0; ci < num_children && !found_locator; ci++) {
2206 locator = dag_node.child(ci);
2207 found_locator = (locator.apiType() == MFn::kLocator);
2210 if (!found_locator) {
2212 <<
"Couldn't find locator within locator node "
2213 << dag_path.fullPathName().asChar() <<
"\n";
2220 <<
"Couldn't get position of locator "
2221 << dag_path.fullPathName().asChar() <<
"\n";
2227 MMatrix mat = dag_path.inclusiveMatrix(&status);
2229 status.perror(
"Can't get coordinate space for locator");
2232 LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
2233 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
2234 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
2235 mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
2250 void MayaToEggConverter::
2251 make_camera_locator(
const MDagPath &dag_path,
const MFnDagNode &dag_node,
2255 unsigned int num_children = dag_node.childCount();
2257 bool found_camera =
false;
2258 for (
unsigned int ci = 0; ci < num_children && !found_camera; ci++) {
2259 locator = dag_node.child(ci);
2260 found_camera = (locator.apiType() == MFn::kCamera);
2263 if (!found_camera) {
2265 <<
"Couldn't find camera"
2266 << dag_path.fullPathName().asChar() <<
"\n";
2269 MFnCamera camera (dag_path, &status);
2271 status.perror(
"MFnCamera constructor");
2274 MPoint eyePoint = camera.eyePoint(MSpace::kWorld);
2275 LPoint3d p3d (eyePoint.x, eyePoint.y, eyePoint.z);
2290 void MayaToEggConverter::
2291 make_light_locator(
const MDagPath &dag_path,
const MFnDagNode &dag_node,
2295 unsigned int num_children = dag_node.childCount();
2297 bool found_alight =
false;
2298 bool found_dlight =
false;
2299 bool found_plight =
false;
2300 for (
unsigned int ci = 0; ci < num_children && !found_alight && !found_dlight && !found_plight; ci++) {
2301 locator = dag_node.child(ci);
2302 found_alight = (locator.apiType() == MFn::kAmbientLight);
2303 found_dlight = (locator.apiType() == MFn::kDirectionalLight);
2304 found_plight = (locator.apiType() == MFn::kPointLight);
2307 if (!found_alight && !found_dlight && !found_plight) {
2309 <<
"Couldn't find light within locator node "
2310 << dag_path.fullPathName().asChar() <<
"\n";
2318 MMatrix mat = dag_path.inclusiveMatrix(&status);
2320 status.perror(
"Can't get coordinate space for light");
2323 LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
2324 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
2325 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
2326 mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
2339 bool MayaToEggConverter::
2340 get_vertex_weights(
const MDagPath &dag_path,
const MFnMesh &mesh,
2346 MObject attr = mesh.attribute(
"inMesh");
2350 MPlug history(mesh.object(), attr);
2351 MItDependencyGraph it(history, MFn::kDependencyNode,
2352 MItDependencyGraph::kUpstream,
2353 MItDependencyGraph::kDepthFirst,
2354 MItDependencyGraph::kNodeLevel);
2356 while (!it.isDone()) {
2359 MObject c_node = it.thisNode();
2360 if (c_node.hasFn(MFn::kSkinClusterFilter)) {
2362 MFnSkinCluster cluster(c_node, &status);
2364 status.perror(
"MFnSkinCluster constructor");
2370 MDagPathArray influence_objects;
2371 cluster.influenceObjects(influence_objects, &status);
2373 status.perror(
"MFnSkinCluster::influenceObjects");
2379 for (
unsigned oi = 0; oi < influence_objects.length(); oi++) {
2380 MDagPath joint_dag_path = influence_objects[oi];
2383 joints.push_back(joint);
2388 MFnSingleIndexedComponent sic;
2389 MObject sic_object = sic.create(MFn::kMeshVertComponent);
2390 sic.setCompleteData(mesh.numVertices());
2391 unsigned influence_count;
2393 status = cluster.getWeights(dag_path, sic_object,
2394 weights, influence_count);
2396 status.perror(
"MFnSkinCluster::getWeights");
2398 if (influence_count != influence_objects.length()) {
2400 <<
"MFnSkinCluster::influenceObjects() returns "
2401 << influence_objects.length()
2402 <<
" objects, but MFnSkinCluster::getWeights() reports "
2403 << influence_count <<
" objects.\n";
2412 }
else if (c_node.hasFn(MFn::kWeightGeometryFilt)) {
2414 MFnWeightGeometryFilter cluster(c_node, &status);
2416 status.perror(
"MFnWeightGeometryFilter constructor");
2420 MPlug matrix_plug = cluster.findPlug(
"matrix");
2421 if (!matrix_plug.isNull()) {
2422 MPlugArray matrix_pa;
2423 matrix_plug.connectedTo(matrix_pa,
true,
false, &status);
2425 status.perror(
"Can't find connected Joint");
2427 MObject jointObj = matrix_pa[0].node();
2428 MFnIkJoint jointFn(jointObj, &status);
2430 status.perror(
"Can't find connected JointDag");
2433 MDagPath joint_dag_path = MDagPath();
2434 status = jointFn.getPath(joint_dag_path);
2436 status.perror(
"MFnIkJoint::dagPath");
2440 joints.push_back(joint);
2444 MFnSingleIndexedComponent sic;
2445 MObject sic_object = sic.create(MFn::kMeshVertComponent);
2446 sic.setCompleteData(mesh.numVertices());
2448 status = cluster.getWeights(dag_path, sic_object,
2451 status.perror(
"MFnWeightGeometryFilter::getWeights");
2473 bool MayaToEggConverter::
2474 get_vertex_weights(
const MDagPath &dag_path,
const MFnNurbsSurface &surface,
2480 MObject attr = surface.attribute(
"create");
2484 MPlug history(surface.object(), attr);
2485 MItDependencyGraph it(history, MFn::kDependencyNode,
2486 MItDependencyGraph::kUpstream,
2487 MItDependencyGraph::kDepthFirst,
2488 MItDependencyGraph::kNodeLevel);
2490 while (!it.isDone()) {
2493 MObject c_node = it.thisNode();
2494 if (c_node.hasFn(MFn::kSkinClusterFilter)) {
2496 MFnSkinCluster cluster(c_node, &status);
2498 status.perror(
"MFnSkinCluster constructor");
2504 MDagPathArray influence_objects;
2505 cluster.influenceObjects(influence_objects, &status);
2507 status.perror(
"MFnSkinCluster::influenceObjects");
2513 for (
unsigned oi = 0; oi < influence_objects.length(); oi++) {
2514 MDagPath joint_dag_path = influence_objects[oi];
2517 joints.push_back(joint);
2522 MFnDoubleIndexedComponent dic;
2523 MObject dic_object = dic.create(MFn::kSurfaceCVComponent);
2524 dic.setCompleteData(surface.numCVsInU(), surface.numCVsInV());
2525 unsigned influence_count;
2527 status = cluster.getWeights(dag_path, dic_object,
2528 weights, influence_count);
2530 status.perror(
"MFnSkinCluster::getWeights");
2532 if (influence_count != influence_objects.length()) {
2534 <<
"MFnSkinCluster::influenceObjects() returns "
2535 << influence_objects.length()
2536 <<
" objects, but MFnSkinCluster::getWeights() reports "
2537 << influence_count <<
" objects.\n";
2561 void MayaToEggConverter::
2564 if (shader._legacy_mode) {
2565 set_shader_legacy(primitive, shader, mesh);
2567 set_shader_modern(primitive, shader, mesh);
2579 void MayaToEggConverter::
2583 for (
size_t idx=0; idx < shader._all_maps.size(); idx++) {
2585 if ((def->_is_alpha)&&(def->_opposite != 0)) {
2592 tex.set_format(def->_is_alpha ? EggTexture::F_alpha : EggTexture::F_rgb);
2593 apply_texture_filename(tex, *def);
2594 if (def->_opposite) {
2595 apply_texture_alpha_filename(tex, *def);
2597 apply_texture_uvprops(tex, *def);
2598 apply_texture_blendtype(tex, *def);
2619 void MayaToEggConverter::
2626 bool is_rgb =
false;
2627 bool is_decal =
false;
2628 bool is_interpolate =
false;
2631 for (i=0; i<(int)shader._color.size()-1; ++i) {
2633 if (color_def->_has_texture) {
2634 if ((EggTexture::EnvType)color_def->_interpolate) {
2635 is_interpolate =
true;
2637 else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_modulate) {
2640 if (!color_def->_keep_alpha)
2643 else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_decal) {
2656 string dummy_uvset_name;
2661 for (i=shader._color.size()-1; i>=0; --i) {
2663 if (mayaegg_cat.is_spam()) {
2664 mayaegg_cat.spam() <<
"slot " << i <<
":got color_def: " << color_def << endl;
2666 if (color_def->_has_texture || trans_def._has_texture) {
2668 if (mayaegg_cat.is_spam()) {
2669 mayaegg_cat.spam() <<
"got shader name:" << shader.get_name() << endl;
2670 mayaegg_cat.spam() <<
"ssa:texture name[" << i <<
"]: " << color_def->_texture_name << endl;
2673 string uvset_name = _shaders.
find_uv_link(color_def->_texture_name);
2674 if (mayaegg_cat.is_spam()) {
2675 mayaegg_cat.spam() <<
"ssa:corresponding uvset name is " << uvset_name << endl;
2678 if (color_def->_has_texture) {
2684 _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath);
2685 tex.set_filename(outpath);
2687 apply_texture_uvprops(tex, *color_def);
2691 if (trans_def._has_texture) {
2692 if (color_def->_wrap_u != trans_def._wrap_u ||
2693 color_def->_wrap_u != trans_def._wrap_u) {
2694 mayaegg_cat.warning()
2695 <<
"Shader " << shader.get_name()
2696 <<
" has contradictory wrap modes on color and texture.\n";
2699 if (!compare_texture_uvprops(tex, trans_def)) {
2702 if (bad_shaders.insert(shader.get_name()).second) {
2704 <<
"Color and transparency texture properties differ on shader "
2705 << shader.get_name() <<
"\n";
2717 if (trans_def._texture_filename == color_def->_texture_filename) {
2728 _path_replace->full_convert_path(filename, get_model_path(),
2730 tex.set_alpha_filename(outpath);
2731 tex.set_alpha_fullpath(fullpath);
2740 if (shader._color.size() > 1) {
2745 if ((
size_t)i != shader._color.size() - 1) {
2746 if (!i && is_interpolate) {
2750 tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_interpolate);
2751 tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_previous);
2752 tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
2753 tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_last_saved_result);
2754 tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
2755 tex.set_combine_source(EggTexture::CC_rgb, 2, EggTexture::CS_texture);
2756 tex.set_combine_operand(EggTexture::CC_rgb, 2, EggTexture::CO_src_alpha);
2758 tex.set_combine_mode(EggTexture::CC_alpha, EggTexture::CM_interpolate);
2759 tex.set_combine_source(EggTexture::CC_alpha, 0, EggTexture::CS_previous);
2760 tex.set_combine_operand(EggTexture::CC_alpha, 0, EggTexture::CO_src_alpha);
2761 tex.set_combine_source(EggTexture::CC_alpha, 1, EggTexture::CS_last_saved_result);
2762 tex.set_combine_operand(EggTexture::CC_alpha, 1, EggTexture::CO_src_alpha);
2763 tex.set_combine_source(EggTexture::CC_alpha, 2, EggTexture::CS_texture);
2764 tex.set_combine_operand(EggTexture::CC_alpha, 2, EggTexture::CO_src_alpha);
2767 if (is_interpolate) {
2768 tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate);
2769 tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color);
2770 tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
2771 tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_texture);
2772 tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
2775 tex.set_env_type((EggTexture::EnvType)color_def->_blend_type);
2776 if (tex.get_env_type() == EggTexture::ET_modulate) {
2777 if (color_def->_has_alpha_channel) {
2780 if (mayaegg_cat.is_spam()) {
2782 << color_def->_texture_name
2783 <<
" should not have alpha channel in multiply mode: ignoring\n";
2789 tex.set_format(EggTexture::F_rgb);
2796 if (is_interpolate) {
2798 tex.set_saved_result(
true);
2800 else if (is_decal) {
2806 EggTexture texDummy(shader.get_name()+
".dummy",
"");
2807 if (mayaegg_cat.is_debug()) {
2808 mayaegg_cat.debug() <<
"creating dummy shader: " << texDummy.get_name() << endl;
2810 texDummy.set_filename(outpath);
2811 texDummy.set_fullpath(fullpath);
2812 apply_texture_uvprops(texDummy, *color_def);
2813 texDummy.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate);
2814 texDummy.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color);
2815 texDummy.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
2816 texDummy.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_previous);
2817 texDummy.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
2821 tex.set_env_type(EggTexture::ET_replace);
2830 _path_replace->full_convert_path(filename, get_model_path(),
2832 tex.set_filename(outpath);
2834 tex.set_format(EggTexture::F_alpha);
2835 apply_texture_uvprops(tex, trans_def);
2838 if (mayaegg_cat.is_debug()) {
2839 mayaegg_cat.debug() <<
"ssa:tref_name:" << tex.get_name() << endl;
2841 if (is_rgb && i == (
int)shader._color.size()-1) {
2843 tex.set_format(EggTexture::F_rgb);
2849 if (uvset_name.find(
"not found") == string::npos) {
2851 color_def->_uvset_name.assign(uvset_name.c_str());
2852 if (uvset_name !=
"map1") {
2855 if (i == (
int)shader._color.size()-1 && is_decal) {
2856 dummy_uvset_name.assign(color_def->_uvset_name);
2861 if (color_def->_uvset_name !=
"map1") {
2867 if (dummy_tex !=
nullptr) {
2873 if (mayaegg_cat.is_spam()) {
2874 mayaegg_cat.spam() <<
"ssa:rgba = " << rgba << endl;
2879 if (color_def && color_def->_has_texture) {
2884 if (trans_def._has_texture) {
2890 rgba[0] *= color_def->_color_gain[0];
2891 rgba[1] *= color_def->_color_gain[1];
2892 rgba[2] *= color_def->_color_gain[2];
2893 rgba[3] *= color_def->_color_gain[3];
2894 if (mayaegg_cat.is_spam()) {
2895 mayaegg_cat.spam() <<
"ssa:rgba = " << rgba << endl;
2899 primitive.set_color(rgba);
2901 if (mayaegg_cat.is_spam()) {
2902 mayaegg_cat.spam() <<
" set_shader_attributes : end\n";
2910 void MayaToEggConverter::
2913 tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
2914 tex.set_magfilter(EggTexture::FT_linear);
2916 EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
2917 EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
2919 tex.set_wrap_u(wrap_u);
2920 tex.set_wrap_v(wrap_v);
2923 if (!mat.almost_equal(LMatrix3d::ident_mat())) {
2931 void MayaToEggConverter::
2933 switch (color_def._blend_type) {
2934 case MayaShaderColorDef::BT_unspecified:
2935 tex.set_env_type(EggTexture::ET_unspecified);
2937 case MayaShaderColorDef::BT_modulate:
2938 tex.set_env_type(EggTexture::ET_modulate);
2940 case MayaShaderColorDef::BT_decal:
2941 tex.set_env_type(EggTexture::ET_decal);
2943 case MayaShaderColorDef::BT_blend:
2944 tex.set_env_type(EggTexture::ET_blend);
2946 case MayaShaderColorDef::BT_replace:
2947 tex.set_env_type(EggTexture::ET_replace);
2949 case MayaShaderColorDef::BT_add:
2950 tex.set_env_type(EggTexture::ET_add);
2952 case MayaShaderColorDef::BT_blend_color_scale:
2953 tex.set_env_type(EggTexture::ET_blend_color_scale);
2955 case MayaShaderColorDef::BT_modulate_glow:
2956 tex.set_env_type(EggTexture::ET_modulate_glow);
2958 case MayaShaderColorDef::BT_modulate_gloss:
2959 tex.set_env_type(EggTexture::ET_modulate_gloss);
2961 case MayaShaderColorDef::BT_normal:
2962 tex.set_env_type(EggTexture::ET_normal);
2964 case MayaShaderColorDef::BT_normal_height:
2965 tex.set_env_type(EggTexture::ET_normal_height);
2967 case MayaShaderColorDef::BT_glow:
2968 tex.set_env_type(EggTexture::ET_glow);
2970 case MayaShaderColorDef::BT_gloss:
2971 tex.set_env_type(EggTexture::ET_gloss);
2973 case MayaShaderColorDef::BT_height:
2974 tex.set_env_type(EggTexture::ET_height);
2976 case MayaShaderColorDef::BT_selector:
2977 tex.set_env_type(EggTexture::ET_selector);
2985 void MayaToEggConverter::
2989 _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath);
2990 tex.set_filename(outpath);
2997 void MayaToEggConverter::
2999 if (def._opposite) {
3000 tex.set_format(EggTexture::F_rgba);
3001 if (def._opposite->_texture_filename != def._texture_filename) {
3004 _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath);
3017 bool MayaToEggConverter::
3022 EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
3023 EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
3027 if (wrap_u == EggTexture::WM_repeat) {
3028 tex.set_wrap_u(wrap_u);
3033 if (wrap_v == EggTexture::WM_repeat) {
3034 tex.set_wrap_v(wrap_v);
3040 LMatrix4d mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
3041 m(1, 0), m(1, 1), 0.0, m(1, 2),
3043 m(2, 0), m(2, 1), 0.0, m(2, 2));
3057 bool MayaToEggConverter::
3066 EggGroupNode::iterator ci;
3067 for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
3069 if (child->
is_of_type(EggGroup::get_class_type())) {
3072 if (decal_base !=
nullptr) {
3074 <<
"Two children of " << egg_parent->get_name()
3075 <<
" both have decalbase set: " << decal_base->get_name()
3076 <<
" and " << child_group->get_name() <<
"\n";
3080 decal_base = child_group;
3084 decal_children.push_back(child_group);
3089 if (decal_base ==
nullptr) {
3090 if (!decal_children.empty()) {
3091 mayaegg_cat.warning()
3092 << decal_children.front()->get_name()
3093 <<
" has decal, but no sibling node has decalbase.\n";
3097 if (decal_children.empty()) {
3098 mayaegg_cat.warning()
3099 << decal_base->get_name()
3100 <<
" has decalbase, but no sibling nodes have decal.\n";
3108 for (di = decal_children.begin(); di != decal_children.end(); ++di) {
3114 decal_base->set_decal_flag(
true);
3119 for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
3121 if (child->
is_of_type(EggGroupNode::get_class_type())) {
3123 if (!reparent_decals(child_group)) {
3138 if (cmp_nocase(arg,
"all") == 0) {
3140 }
else if (cmp_nocase(arg,
"model") == 0) {
3142 }
else if (cmp_nocase(arg,
"dcs") == 0) {
3144 }
else if (cmp_nocase(arg,
"none") == 0) {
3155 void MayaToEggConverter::
3156 set_vertex_color(
EggVertex &vert, MItMeshPolygon &pi,
int vert_index,
const MayaShader *shader,
const LColor &color) {
3157 if (shader ==
nullptr || shader->_legacy_mode) {
3158 set_vertex_color_legacy(vert, pi, vert_index, shader, color);
3160 set_vertex_color_modern(vert, pi, vert_index, shader, color);
3169 void MayaToEggConverter::
3170 set_vertex_color_legacy(
EggVertex &vert, MItMeshPolygon &pi,
int vert_index,
const MayaShader *shader,
const LColor &color){
3171 if (pi.hasColor()) {
3173 MStatus status = pi.getColor(c, vert_index);
3175 status.perror(
"MItMeshPolygon::getColor");
3182 vert.set_color(LColor(c.r * color[0], c.g * color[1], c.b * color[2], c.a * color[3]));
3184 if (mayaegg_cat.is_spam()) {
3185 mayaegg_cat.spam() <<
"maya_color = " << c.r <<
" " << c.g <<
" " << c.b <<
" " << c.a << endl;
3186 mayaegg_cat.spam() <<
"vert_color = " << vert.
get_color() << endl;
3190 vert.set_color(color);
3200 void MayaToEggConverter::
3201 set_vertex_color_modern(
EggVertex &vert, MItMeshPolygon &pi,
int vert_index,
const MayaShader *shader,
const LColor &color) {
3203 if (pi.hasColor(vert_index)) {
3205 MStatus status = pi.getColor(c, vert_index);
3207 vert.set_color(LColor(c.r, c.g, c.b, c.a));
3214 if (shader->_color_maps.empty()) {
3215 const LColord &c = shader->_flat_color;
3216 vert.set_color(LColor((PN_stdfloat)c[0], (PN_stdfloat)c[1], (PN_stdfloat)c[2], (PN_stdfloat)c[3]));
3219 vert.set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));