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));
void set_fullpath(const Filename &fullpath)
Records the full pathname to the file, for the benefit of get_fullpath().
EggXfmSAnim * get_egg_anim(MayaNodeDesc *node_desc)
Returns the anim table corresponding to the joint for the indicated node.
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
void optimize()
Optimizes the data by collapsing a long table of duplicate values into a single value.
void setup(int order, int num_knots)
Prepares a new curve definition with the indicated order and number of knots.
void add_subset(const GlobPattern &glob)
Adds a name pattern to the list of subset nodes.
A handle to a Maya blend shape description.
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool open_api(bool revert_directory=true)
Attempts to open the Maya API if it was not already open, and returns true if successful,...
void tag_all()
Tags the entire hierarchy for conversion.
int get_num_nodes() const
Returns the total number of nodes in the hierarchy, not counting the root node.
EggTexture * create_unique_texture(const EggTexture ©, int eq)
Creates a new texture if there is not already one equivalent (according to eq, see EggTexture::is_equ...
void add_texture(EggTexture *texture)
Applies the indicated texture to the primitive.
void clear_subsets()
Empties the list of subset nodes added via add_subset().
void add_data(double value)
Adds a single element to the table.
virtual std::string get_name() const
Returns the English name of the file type this converter supports.
void bind_uvsets(MObject mesh)
Causes all shaders in the set to use the given mesh as a file-to-uvset map.
void close_api()
Closes the Maya API, if it was previously opened.
const LMatrix4d & get_node_frame_inv() const
Returns the inverse of the matrix returned by get_node_frame().
bool had_error() const
Returns true if an error was detected during the conversion process (unless _allow_errors is true),...
bool remove_object_type(const std::string &object_type)
Removes the first instance of the indicated object type from the group if it is present.
int get_external_index2() const
Returns the number set by set_external_index2().
EggVertex * add_vertex(EggVertex *vertex, int index=-1)
Adds the indicated vertex to the pool.
void set_pos(double pos)
Sets the vertex position.
A base class for nodes in the hierarchy that are not leaf nodes.
int get_v_index(int vertex_index) const
Returns the V index number of the given vertex within the EggPrimitive's linear list of vertices.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear()
Resets the entire tree in preparation for repopulating with a new scene.
LTexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const
If the shader has a projection (has_projection() returns true), this computes the appropriate UV corr...
Defines a texture map that may be applied to geometry.
EggVertex * get_vertex(int index) const
Returns the vertex in the pool with the indicated index number, or NULL if no vertices have that inde...
set_alpha_fullpath
Records the full pathname to the file, for the benefit of get_alpha_fullpath().
bool has_frame_inc() const
Returns true if the frame increment has been explicitly specified via set_frame_inc(),...
bool has_start_frame() const
Returns true if the starting frame has been explicitly specified via set_start_frame(),...
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
virtual DistanceUnit get_input_units()
This may be called after convert_file() has been called and returned true, indicating a successful co...
bool has_neutral_frame() const
Returns true if the neutral frame has been explicitly specified via set_neutral_frame(),...
void set_u_knot(int k, double value)
Resets the value of the indicated knot as indicated.
bool force_joint(const std::string &name) const
Returns true if the indicated name is on the list of DAG nodes to treat as a joint,...
void clear()
Removes all textures from the collection.
bool convert_maya()
Fills up the egg_data structure according to the global maya model data.
void init_libmayaegg()
Initializes the library.
EggData * get_egg_data()
Returns the EggData structure.
set_bface_flag
Sets the backfacing flag of the polygon.
std::string get_panda_uvset_name()
Maya's default uvset name is "map1".
bool has_projection() const
Returns true if the shader has a projection in effect.
Corresponding to an <S$Anim> entry, this stores a single column of numbers, for instance for a morph ...
LMatrix3d compute_texture_matrix() const
Returns a texture matrix corresponding to the texture transforms indicated by the shader.
void setup(int u_order, int v_order, int num_u_knots, int num_v_knots)
Prepares a new surface definition with the indicated order and number of knots in each dimension.
void clear()
Frees all of the Maya pointers kept within this object, in preparation for loading a new scene or rel...
virtual std::string get_additional_extensions() const
Returns a space-separated list of extension, in addition to the one returned by get_extension(),...
This is our own Panda specialization on the default STL list.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
double get_neutral_frame() const
Returns the value set by a previous call to set_neutral_frame().
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
void set_external_index(int external_index)
Sets a special index number that is associated with the EggVertex (but is not written to the egg file...
EggGroup * get_egg_group(MayaNodeDesc *node_desc)
Returns the EggGroupNode corresponding to the group or joint for the indicated node.
A single <Dxyz> or <Duv> or some such entry.
LColor get_color() const
Returns the color set on this particular attribute.
bool has_dag_path() const
Returns true if a Maya dag path has been associated with this node, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node, EggGroupNode *morph_node)
Removes all of the references to generated egg structures from the tree, and prepares the tree for ge...
MayaBlendDesc * get_blend_desc(int n) const
Returns the nth MayaBlendDesc object that affects the geometry in this node.
bool tag_named(const GlobPattern &glob)
Tags nodes matching the indicated glob (and all of their children) for conversion.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
iterator end() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
bool has_input_frame_rate() const
Returns true if the frame rate has been explicitly specified via set_input_frame_rate(),...
std::pair< iterator, bool > insert(const MorphType &value)
This is similar to the insert() interface for sets, except it does not guarantee that the resulting l...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MayaShader * find_shader_for_node(MObject node, bool legacy_shader)
Extracts the shader assigned to the indicated node.
void clear_force_joints()
Empties the list of force_joints added via add_force_joint().
bool has_user_data() const
Returns true if a generic user data pointer has recently been set and not yet cleared,...
virtual std::string get_extension() const
Returns the common extension of the file type this converter supports.
MayaNodeDesc * build_node(const MDagPath &dag_path)
Returns a pointer to the node corresponding to the indicated dag_path object, creating it first if ne...
DistanceUnit
This enumerated type lists all the kinds of units we're likely to come across in model conversion pro...
This is our own Panda specialization on the default STL vector.
iterator begin() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
MayaBlendDesc * get_blend_desc(int n) const
Returns the nth MayaBlendDesc object discovered in the tree.
MayaShaderColorDef * get_color_def(size_t idx=0) const
This is part of the deprecated codepath.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
void set_v_knot(int k, double value)
Resets the value of the indicated knot as indicated.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_fullpath(const std::string &s)
Replaces the entire filename: directory, basename, extension.
void clear_excludes()
Empties the list of excluded nodes added via add_exclude().
void reset_sliders()
Resets all of the sliders associated with all blend shapes down to 0.
WrapMode determine_wrap_v() const
Determines the appropriate wrap in the V direction.
bool get_bool_attribute(MObject &node, const string &attribute_name, bool &value)
Extracts the named boolean attribute from the MObject.
int get_num_cvs() const
Returns the total number of control vertices that *should* be defined for the surface.
void clear_error()
Resets the error flag to the no-error state.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void reverse_vertex_ordering()
Reverses the ordering of the vertices in this primitive, if appropriate, in order to change the direc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Describes a single instance of a node in the Maya scene graph, relating it to the corresponding egg s...
bool get_vec3d_attribute(MObject &node, const string &attribute_name, LVecBase3d &value)
Extracts the named three-component vector from the MObject.
The name of a file, such as a texture file or an Egg file.
This defines the various attributes that Maya may associate with the "color" channel for a particular...
void clear_ignore_sliders()
Empties the list of ignore_sliders added via add_ignore_slider().
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
double get_input_frame_rate() const
Returns the value set by a previous call to set_input_frame_rate().
LColor get_rgba(size_t idx=0) const
Returns the overall color of the shader as a single-precision rgba value, where the alpha component r...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_object_type(const std::string &object_type) const
Returns true if the indicated object type has been added to the group, or false otherwise.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
int get_num_blend_descs() const
Returns the number of unique MayaBlendDesc objects (and hence the number of morph sliders) discovered...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AnimationConvert get_animation_convert() const
Returns how source animation will be converted into egg structures.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
EggUserData * get_user_data() const
Returns the user data pointer most recently stored on this object, or NULL if nothing was previously ...
MayaNodeDesc * get_node(int n) const
Returns the nth node in the hierarchy, in an arbitrary ordering.
int get_u_index(int vertex_index) const
Returns the U index number of the given vertex within the EggPrimitive's linear list of vertices.
bool tag_joint_named(const GlobPattern &glob)
Tags nodes matching the indicated glob (and all of their children) for conversion.
Corresponds to a single "shader" in Maya.
MayaShader * find_shader_for_shading_engine(MObject engine, bool legacy_shader)
Returns the MayaShader object associated with the indicated "shading engine".
A parametric NURBS curve.
void optimize()
Optimizes the table by collapsing redundant sub-tables.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool ignore_slider(const std::string &name) const
Returns true if the indicated name is on the list of sliders to ignore, false otherwise.
const MDagPath & get_dag_path() const
Returns the dag path associated with this node.
bool is_tagged() const
Returns true if the node has been tagged to be converted, false otherwise.
void clear_subroots()
Empties the list of subroot nodes added via add_subroot().
double get_frame_inc() const
Returns the value set by a previous call to set_frame_inc().
bool build_hierarchy()
Walks through the complete Maya hierarchy but does not tag any nodes for conversion.
set_uv_name
Specifies the named set of texture coordinates that this texture will use when it is applied to geome...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class supervises the construction of an EggData structure from a single Maya file,...
get_num_textures
Returns the number of textures applied to the primitive.
set_knot
Resets the value of the indicated knot as indicated.
bool untag_named(const GlobPattern &glob)
Un-tags nodes matching the indicated glob (and all of their children) for conversion.
bool has_object_type(std::string object_type) const
Returns true if this node or any of its parent has_object_type of object_type.
double get_start_frame() const
Returns the value set by a previous call to set_start_frame().
std::string find_uv_link(const std::string &match)
Returns the current mapping from file to uvset for the given file texture name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
WrapMode determine_wrap_u() const
Determines the appropriate wrap in the U direction.
A base class for things that may be directly added into the egg hierarchy.
bool has_end_frame() const
Returns true if the ending frame has been explicitly specified via set_end_frame(),...
set_alpha_filename
Specifies a separate file that will be loaded in with the 1- or 3-component texture and applied as th...
bool calculate_normal(LNormald &result, CoordinateSystem cs=CS_default) const
Calculates the true polygon normal–the vector pointing out of the front of the polygon–based on the v...
void add_force_joint(const GlobPattern &glob)
Adds a name pattern to the list of force_joints.
A parametric NURBS surface.
bool has_dcs_type() const
Returns true if the specified DCS type is not DC_none and not DC_unspecified.
void ref_vertex(EggVertex *vert, double membership=1.0)
Adds the vertex to the set of those referenced by the group, at the indicated membership level.
void set_slider(PN_stdfloat value)
Moves the Maya slider associated with this blend shape to the indicated value.
EggSAnimData * get_egg_slider(MayaBlendDesc *blend_desc)
Returns the anim table corresponding to the slider for the indicated blend.
PN_stdfloat get_slider() const
Returns the current position of the Maya slider associated with this blend shape.
double get_output_frame_rate() const
Returns the value set by a previous call to set_output_frame_rate().
void set_from_selection(bool from_selection)
Sets the flag that indicates whether the currently selected Maya geometry will be converted.
int get_external_index() const
Returns the number set by set_external_index().
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void tag_joint_all()
Tags the entire hierarchy for conversion.
void set_external_index2(int external_index2)
Similar to set_external_index(), but this is a different number which may be used for a different pur...
This is our own Panda specialization on the default STL set.
void clear()
Frees all of the previously-defined MayaShader objects associated with this set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_cvs() const
Returns the total number of control vertices that *should* be defined for the curve.
int get_num_blend_descs() const
Returns the number of unique MayaBlendDesc objects (and hence the number of morph sliders) that affec...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_uv(const LTexCoordd &texCoord)
Replaces the unnamed UV coordinate pair on the vertex with the indicated value.
This is a base class for a family of converter classes that manage a conversion from some file type t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_subroot(const GlobPattern &glob)
Adds a name pattern to the list of subroot nodes.
virtual SomethingToEggConverter * make_copy()
Allocates and returns a new copy of the converter.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it.
bool has_output_frame_rate() const
Returns true if the frame rate has been explicitly specified via set_output_frame_rate(),...
This class contains extra user data which is piggybacked onto EggGroup objects for the purpose of the...
virtual bool convert_file(const Filename &filename)
Handles the reading of the input file and converting it to egg.
static TransformType string_transform_type(const std::string &arg)
Returns the TransformType value corresponding to the indicated string, or TT_invalid.
void add_ignore_slider(const GlobPattern &glob)
Adds a name pattern to the list of ignore_sliders.
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,...
bool tag_selected()
Tags the just the selected hierarchy for conversion, or the entire hierarchy if nothing is selected.
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
const LMatrix4d & get_vertex_frame_inv() const
Returns the inverse of the matrix returned by get_vertex_frame().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
double get_end_frame() const
Returns the value set by a previous call to set_end_frame().
void add_exclude(const GlobPattern &glob)
Adds a name pattern to the list of excluded nodes.