Explorar o código

support locator nodes

David Rose %!s(int64=23) %!d(string=hai) anos
pai
achega
a7967b955c

+ 49 - 12
pandatool/src/maya/maya_funcs.cxx

@@ -209,6 +209,43 @@ get_vec2d_attribute(MObject &node, const string &attribute_name,
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: get_vec3d_attribute
+//  Description: Extracts the named three-component vector from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_vec3d_attribute(MObject &node, const string &attribute_name,
+                    LVecBase3d &value) {
+  MStatus status;
+
+  MObject vec3d_object;
+  if (!get_maya_attribute(node, attribute_name, vec3d_object)) {
+    maya_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have a vec3d object value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+
+  MFnNumericData data(vec3d_object, &status);
+  if (!status) {
+    maya_cat.error()
+      << "Attribute " << attribute_name << " is of type "
+      << vec3d_object.apiTypeStr() << ", not a NumericData.\n";
+    return false;
+  }
+
+  status = data.getData(value[0], value[1], value[2]);
+  if (!status) {
+    maya_cat.error()
+      << "Unable to extract 3 doubles from " << attribute_name
+      << ", of type " << vec3d_object.apiTypeStr() << "\n";
+  }
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: get_mat4d_attribute
 //  Description: Extracts the named 4x4 matrix from the MObject.
@@ -482,19 +519,19 @@ list_maya_attributes(MObject &node) {
   status = node_fn.getConnections(connections);
   if (!status) {
     status.perror("MFnDependencyNode::getConnections");
-    return;
-  }
 
-  maya_cat.info()
-    << name << " has " << connections.length() << " connections.\n";
-  for (i = 0; i < connections.length(); i++) {
-    MPlug plug = connections[i];
-    maya_cat.info(false)
-      << "  " << i << ". " << plug.name().asChar() << ", "
-      << plug.attribute().apiTypeStr() << ", " 
-      << plug.node().apiTypeStr() << "\n";
-  }
-  
+  } else {
+    maya_cat.info()
+      << name << " has " << connections.length() << " connections.\n";
+    for (i = 0; i < connections.length(); i++) {
+      MPlug plug = connections[i];
+      maya_cat.info(false)
+        << "  " << i << ". " << plug.name().asChar() << ", "
+        << plug.attribute().apiTypeStr() << ", " 
+        << plug.node().apiTypeStr() << "\n";
+    }
+  }
+    
   maya_cat.info()
     << name << " has " << node_fn.attributeCount() << " attributes.\n";
   for (i = 0; i < node_fn.attributeCount(); i++) {

+ 4 - 0
pandatool/src/maya/maya_funcs.h

@@ -67,6 +67,10 @@ bool
 get_vec2d_attribute(MObject &node, const string &attribute_name,
                     LVecBase2d &value);
 
+bool
+get_vec3d_attribute(MObject &node, const string &attribute_name,
+                    LVecBase3d &value);
+
 bool
 get_mat4d_attribute(MObject &node, const string &attribute_name,
                     LMatrix4d &value);

+ 97 - 49
pandatool/src/mayaegg/mayaToEggConverter.cxx

@@ -589,7 +589,7 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
 
   if (mayaegg_cat.is_debug()) {
     mayaegg_cat.debug()
-      << dag_path.fullPathName() << ": " << dag_node.typeName();
+      << dag_path.fullPathName().asChar() << ": " << dag_node.typeName();
 
     if (MAnimUtil::isAnimated(dag_path)) {
       mayaegg_cat.debug(false)
@@ -602,25 +602,29 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
   if (dag_node.inUnderWorld()) {
     if (mayaegg_cat.is_debug()) {
       mayaegg_cat.debug()
-        << "Ignoring underworld node " << dag_path.fullPathName() << "\n";
+        << "Ignoring underworld node " << dag_path.fullPathName().asChar()
+        << "\n";
     }
 
   } else if (dag_node.isIntermediateObject()) {
     if (mayaegg_cat.is_debug()) {
       mayaegg_cat.debug()
-        << "Ignoring intermediate object " << dag_path.fullPathName() << "\n";
+        << "Ignoring intermediate object " << dag_path.fullPathName().asChar()
+        << "\n";
     }
 
   } else if (dag_path.hasFn(MFn::kCamera)) {
     if (mayaegg_cat.is_debug()) {
       mayaegg_cat.debug()
-        << "Ignoring camera node " << dag_path.fullPathName() << "\n";
+        << "Ignoring camera node " << dag_path.fullPathName().asChar()
+        << "\n";
     }
 
   } else if (dag_path.hasFn(MFn::kLight)) {
     if (mayaegg_cat.is_debug()) {
       mayaegg_cat.debug()
-        << "Ignoring light node " << dag_path.fullPathName() << "\n";
+        << "Ignoring light node " << dag_path.fullPathName().asChar()
+        << "\n";
     }
 
   } else if (dag_path.hasFn(MFn::kJoint)) {
@@ -653,7 +657,8 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
       MFnNurbsSurface surface(dag_path, &status);
       if (!status) {
         mayaegg_cat.info()
-          << "Error in node " << dag_path.fullPathName() << ":\n"
+          << "Error in node " << dag_path.fullPathName().asChar()
+          << ":\n"
           << "  it appears to have a NURBS surface, but does not.\n";
       } else {
         make_nurbs_surface(dag_path, surface, egg_group, egg_root);
@@ -677,7 +682,7 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
         MFnNurbsCurve curve(dag_path, &status);
         if (!status) {
           mayaegg_cat.info()
-            << "Error in node " << dag_path.fullPathName() << ":\n"
+            << "Error in node " << dag_path.fullPathName().asChar() << ":\n"
             << "  it appears to have a NURBS curve, but does not.\n";
         } else {
           make_nurbs_curve(dag_path, curve, egg_group, egg_root);
@@ -701,13 +706,28 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
       MFnMesh mesh(dag_path, &status);
       if (!status) {
         mayaegg_cat.info()
-          << "Error in node " << dag_path.fullPathName() << ":\n"
+          << "Error in node " << dag_path.fullPathName().asChar() << ":\n"
           << "  it appears to have a polygon mesh, but does not.\n";
       } else {
         make_polyset(dag_path, mesh, egg_group, egg_root);
       }
     }
 
+  } else if (dag_path.hasFn(MFn::kLocator)) {
+    EggGroup *egg_group = get_egg_group(dag_path, egg_root);
+
+    if (egg_group == (EggGroup *)NULL) {
+      mayaegg_cat.error()
+        << "Cannot determine group node.\n";
+      return false;
+
+    } else {
+      if (_animation_convert != AC_model) {
+        get_transform(dag_path, egg_group);
+      }
+      make_locator(dag_path, dag_node, egg_group, egg_root);
+    }
+
   } else {
     // Get the translation/rotation/scale data
     EggGroup *egg_group = get_egg_group(dag_path, egg_root);
@@ -744,7 +764,7 @@ process_chan_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
 
     if (mayaegg_cat.is_debug()) {
       mayaegg_cat.debug()
-        << dag_path.fullPathName() << ": " << dag_node.typeName();
+        << dag_path.fullPathName().asChar() << ": " << dag_node.typeName();
       
       if (MAnimUtil::isAnimated(dag_path)) {
         mayaegg_cat.debug(false)
@@ -838,54 +858,20 @@ get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
     return;
   }
 
-  MFnDagNode dagNode(transformNode, &status);
+  // Extract the matrix from the dag path, and convert it to the local
+  // frame.
+  MMatrix mat = dag_path.inclusiveMatrix(&status);
   if (!status) {
-    status.perror("MFnDagNode constructor");
+    status.perror("Can't get transform matrix");
     return;
   }
-
-  MTransformationMatrix matrix(dagNode.transformationMatrix());
-
-  if (mayaegg_cat.is_spam()) {
-    mayaegg_cat.spam()
-      << "  translation: " << matrix.translation(MSpace::kWorld)
-      << "\n";
-    double d[3];
-    MTransformationMatrix::RotationOrder rOrder;
-
-    matrix.getRotation(d, rOrder, MSpace::kWorld);
-    mayaegg_cat.spam()
-      << "  rotation: ["
-      << d[0] << ", "
-      << d[1] << ", "
-      << d[2] << "]\n";
-    matrix.getScale(d, MSpace::kWorld);
-    mayaegg_cat.spam()
-      << "  scale: ["
-      << d[0] << ", "
-      << d[1] << ", "
-      << d[2] << "]\n";
-  }
-
-  MMatrix mat = matrix.asMatrix();
   LMatrix4d m4d(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
                 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
                 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
                 mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
-
-  // Now convert the matrix to the local frame.
-  mat = dag_path.inclusiveMatrix(&status);
-  if (!status) {
-    status.perror("Can't get coordinate space for matrix");
-    return;
-  }
-  LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
-                mat[1][0], mat[1][1], mat[1][2], mat[1][3],
-                mat[2][0], mat[2][1], mat[2][2], mat[2][3],
-                mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
-  m4d = m4d * n2w * egg_group->get_node_frame_inv();
+  m4d = m4d * egg_group->get_node_frame_inv();
   if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
-    egg_group->set_transform(m4d);
+    egg_group->add_matrix(m4d);
   }
 }
 
@@ -1510,6 +1496,68 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_locator
+//       Access: Private
+//  Description: Locators are used in Maya to indicate a particular
+//               position in space to the user or the modeler.  We
+//               represent that in egg with an ordinary Group node,
+//               which we transform by the locator's position, so that
+//               the indicated point becomes the origin at this node
+//               and below.
+////////////////////////////////////////////////////////////////////
+void MayaToEggConverter::
+make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
+             EggGroup *egg_group, EggGroupNode *egg_root) {
+  MStatus status;
+
+  unsigned int num_children = dag_node.childCount();
+  MObject locator;
+  bool found_locator = false;
+  for (unsigned int ci = 0; ci < num_children && !found_locator; ci++) {
+    locator = dag_node.child(ci);
+    found_locator = (locator.apiType() == MFn::kLocator);
+  }
+
+  if (!found_locator) {
+    mayaegg_cat.error()
+      << "Couldn't find locator within locator node " 
+      << dag_path.fullPathName().asChar() << "\n";
+    return;
+  }
+
+  LPoint3d p3d;
+  if (!get_vec3d_attribute(locator, "localPosition", p3d)) {
+    mayaegg_cat.error()
+      << "Couldn't get position of locator " 
+      << dag_path.fullPathName().asChar() << "\n";
+    return;
+  }
+
+  // We need to convert the position to world coordinates.  For some
+  // reason, Maya can only tell it to us in local coordinates.
+  MMatrix mat = dag_path.inclusiveMatrix(&status);
+  if (!status) {
+    status.perror("Can't get coordinate space for locator");
+    return;
+  }
+  LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
+                mat[1][0], mat[1][1], mat[1][2], mat[1][3],
+                mat[2][0], mat[2][1], mat[2][2], mat[2][3],
+                mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+  p3d = p3d * n2w;
+
+  // Now convert the locator point into the group's space.
+  p3d = p3d * egg_group->get_node_frame_inv();
+
+  egg_group->add_translate(p3d);
+
+  // Presumably, the locator's position has some meaning to the
+  // end-user, so we will implicitly tag it with the DCS flag so it
+  // won't get flattened out.
+  egg_group->set_dcs_flag(true);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: MayaToEggConverter::get_vertex_weights
 //       Access: Private

+ 3 - 0
pandatool/src/mayaegg/mayaToEggConverter.h

@@ -42,6 +42,7 @@ class EggXfmSAnim;
 class MayaShaderColorDef;
 
 class MDagPath;
+class MFnDagNode;
 class MFnNurbsSurface;
 class MFnNurbsCurve;
 class MFnMesh;
@@ -103,6 +104,8 @@ private:
                     const MFnMesh &mesh,
                     EggGroup *egg_group, EggGroupNode *egg_root,
                     MayaShader *default_shader = NULL);
+  void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
+                    EggGroup *egg_group, EggGroupNode *egg_root);
   bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
                           EggGroupNode *egg_root,
                           pvector<EggGroup *> &joints, MFloatArray &weights);