Browse Source

maya2egg should support LOD's

David Rose 20 years ago
parent
commit
2060e845bb

+ 84 - 0
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;
+  }
+}

+ 4 - 0
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;
 
 

+ 9 - 0
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;
   }
 

+ 2 - 0
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