diff --git a/pandatool/src/mayaegg/mayaNodeDesc.cxx b/pandatool/src/mayaegg/mayaNodeDesc.cxx index 7282a18091..2a1cd31ef2 100755 --- a/pandatool/src/mayaegg/mayaNodeDesc.cxx +++ b/pandatool/src/mayaegg/mayaNodeDesc.cxx @@ -62,6 +62,7 @@ MayaNodeDesc(MayaNodeTree *tree, MayaNodeDesc *parent, const string &name) : _egg_table = (EggTable *)NULL; _anim = (EggXfmSAnim *)NULL; _joint_type = JT_none; + _is_lod = false; _tagged = false; // Add ourselves to our parent. @@ -433,3 +434,86 @@ check_blend_shapes(const MFnDagNode &node, const string &attrib_name) { it.next(); } } + +//////////////////////////////////////////////////////////////////// +// Function: MayaNodeDesc::check_lods +// Access: Private +// Description: Walks through the hierarchy again and checks for LOD +// specifications. Any such specifications found are +// recorded on the child nodes of the lodGroups +// themselves: the nodes that actually switch in and +// out. (This is the way they are recorded in an egg +// file.) +//////////////////////////////////////////////////////////////////// +void MayaNodeDesc:: +check_lods() { + // Walk through the children first. This makes it easier in the + // below (we only have to return in the event of an error). + Children::iterator ci; + for (ci = _children.begin(); ci != _children.end(); ++ci) { + MayaNodeDesc *child = (*ci); + child->check_lods(); + } + + // Now consider whether this node is an lodGroup. + if (_dag_path != (MDagPath *)NULL && + _dag_path->hasFn(MFn::kLodGroup)) { + // This node is a parent lodGroup; its children, therefore, are + // LOD's. + MStatus status; + MFnDagNode dag_node(*_dag_path, &status); + if (!status) { + status.perror("Couldn't get node from dag path for lodGroup"); + return; + } + + MPlug plug = dag_node.findPlug("threshold", &status); + if (!status) { + status.perror("Couldn't get threshold attributes on lodGroup"); + return; + } + + // There ought to be the one fewer elements in the array than + // there are children of the node. + unsigned int num_elements = plug.numElements(); + if (num_elements + 1 != _children.size()) { + mayaegg_cat.warning() + << "Node " << get_name() << " has " << plug.numElements() + << " LOD entries, but " << _children.size() + << " children. Ignoring LOD specification.\n"; + return; + } + + // Should we also consider cameraMatrix, to transform the LOD's + // origin? It's not clear precisely what this transform matrix + // means in Maya, so we'll wait until we have a sample file that + // demonstrates its use. + + double switch_out = 0.0; + for (unsigned int i = 0; i < num_elements; ++i) { + MPlug element = plug.elementByLogicalIndex(i); + MayaNodeDesc *child = _children[i]; + + double switch_in; + status = element.getValue(switch_in); + if (!status) { + status.perror("Couldn't get double value from threshold."); + return; + } + + child->_is_lod = true; + child->_switch_in = switch_in; + child->_switch_out = switch_out; + + switch_out = switch_in; + } + + // Also set the last child. Maya wants this to switch in at + // infinity, but Panda doesn't have such a concept; we'll settle + // for four times the switch_out distance. + MayaNodeDesc *child = _children[num_elements]; + child->_is_lod = true; + child->_switch_in = switch_out * 4.0; + child->_switch_out = switch_out; + } +} diff --git a/pandatool/src/mayaegg/mayaNodeDesc.h b/pandatool/src/mayaegg/mayaNodeDesc.h index 81f48ae4b5..a43172ba44 100755 --- a/pandatool/src/mayaegg/mayaNodeDesc.h +++ b/pandatool/src/mayaegg/mayaNodeDesc.h @@ -76,6 +76,7 @@ private: void check_pseudo_joints(bool joint_above); void check_blend_shapes(const MFnDagNode &node, const string &attrib_name); + void check_lods(); MDagPath *_dag_path; @@ -95,6 +96,9 @@ private: }; JointType _joint_type; + bool _is_lod; + double _switch_in, _switch_out; + bool _tagged; diff --git a/pandatool/src/mayaegg/mayaNodeTree.cxx b/pandatool/src/mayaegg/mayaNodeTree.cxx index 9533906104..5c1ebcc0c2 100755 --- a/pandatool/src/mayaegg/mayaNodeTree.cxx +++ b/pandatool/src/mayaegg/mayaNodeTree.cxx @@ -27,6 +27,7 @@ #include "eggXfmSAnim.h" #include "eggSAnimData.h" #include "eggData.h" +#include "eggSwitchCondition.h" #include "dcast.h" #include "pre_maya_include.h" @@ -105,6 +106,7 @@ build_hierarchy() { if (all_ok) { _root->check_pseudo_joints(false); + _root->check_lods(); } return all_ok; @@ -385,6 +387,13 @@ get_egg_group(MayaNodeDesc *node_desc) { egg_group->set_user_data(user_data); } + if (node_desc->_is_lod) { + // Create an LOD specification. + egg_group->set_lod(EggSwitchConditionDistance(node_desc->_switch_in, + node_desc->_switch_out, + LPoint3d::zero())); + } + node_desc->_egg_group = egg_group; } diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index 63e6f25ca6..3d622c62ec 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -46,6 +46,7 @@ class EggPrimitive; class EggXfmSAnim; class MayaShaderColorDef; +class MObject; class MDagPath; class MFnDagNode; class MFnNurbsSurface; @@ -111,6 +112,7 @@ private: void get_transform(MayaNodeDesc *node_desc, const MDagPath &dag_path, EggGroup *egg_group); void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group); + void apply_lod_attributes(EggGroup *egg_group, MFnDagNode &lod_group); // I ran into core dumps trying to pass around a MFnMesh object by // value. From now on, all MFn* objects will be passed around by