Explorar o código

add support for -suppress in egg-optchar

David Rose %!s(int64=21) %!d(string=hai) anos
pai
achega
4a5c29bde8

+ 12 - 0
panda/src/egg/eggGroup.I

@@ -238,6 +238,18 @@ get_dcs_type() const {
   return (DCSType)(_flags2 & F2_dcs_type);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::has_dcs_type
+//       Access: Public
+//  Description: Returns true if the specified DCS type is not
+//               DC_none and not DC_unspecified.
+////////////////////////////////////////////////////////////////////
+INLINE bool EggGroup::
+has_dcs_type() const {
+  DCSType type = get_dcs_type();
+  return (type != DC_none && type != DC_unspecified);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggGroup::set_dart_type
 //       Access: Public

+ 9 - 5
panda/src/egg/eggGroup.cxx

@@ -306,7 +306,7 @@ write_collide_flags(ostream &out, int indent_level) const {
 ////////////////////////////////////////////////////////////////////
 void EggGroup::
 write_model_flags(ostream &out, int indent_level) const {
-  if (get_dcs_type() != DC_none) {
+  if (get_dcs_type() != DC_unspecified) {
     indent(out, indent_level) 
       << "<DCS> { " << get_dcs_type() << " }\n";
   }
@@ -783,19 +783,21 @@ string_dart_type(const string &string) {
 //     Function: EggGroup::string_dcs_type
 //       Access: Public, Static
 //  Description: Returns the DCSType value associated with the given
-//               string representation, or DC_none if the string
-//               does not match any known DCSType value.
+//               string representation, or DC_unspecified if the
+//               string does not match any known DCSType value.
 ////////////////////////////////////////////////////////////////////
 EggGroup::DCSType EggGroup::
 string_dcs_type(const string &string) {
-  if (cmp_nocase_uh(string, "local") == 0) {
+  if (cmp_nocase_uh(string, "none") == 0) {
+    return DC_none;
+  } else if (cmp_nocase_uh(string, "local") == 0) {
     return DC_local;
   } else if (cmp_nocase_uh(string, "net") == 0) {
     return DC_net;
   } else if (cmp_nocase_uh(string, "default") == 0) {
     return DC_default;
   } else {
-    return DC_none;
+    return DC_unspecified;
   }
 }
 
@@ -1163,6 +1165,8 @@ ostream &operator << (ostream &out, EggGroup::DartType t) {
 ////////////////////////////////////////////////////////////////////
 ostream &operator << (ostream &out, EggGroup::DCSType t) {
   switch (t) {
+  case EggGroup::DC_unspecified:
+    return out << "unspecified";
   case EggGroup::DC_none:
     return out << "none";
   case EggGroup::DC_local:

+ 11 - 9
panda/src/egg/eggGroup.h

@@ -59,10 +59,11 @@ PUBLISHED:
   };
   enum DCSType {
     // The bits here must correspond to those in Flags2, below.
-    DC_none                  = 0x00000000,
-    DC_local                 = 0x00000010,
-    DC_net                   = 0x00000020,
-    DC_default               = 0x00000030,
+    DC_unspecified           = 0x00000000,
+    DC_none                  = 0x00000010,
+    DC_local                 = 0x00000020,
+    DC_net                   = 0x00000030,
+    DC_default               = 0x00000040,
   };
   enum BillboardType {
     // The bits here must correspond to those in Flags, below.
@@ -147,6 +148,7 @@ PUBLISHED:
 
   INLINE void set_dcs_type(DCSType type);
   INLINE DCSType get_dcs_type() const;
+  INLINE bool has_dcs_type() const;
 
   INLINE void set_dart_type(DartType type);
   INLINE DartType get_dart_type() const;
@@ -279,11 +281,11 @@ private:
     F2_into_collide_mask     = 0x00000004,
     F2_billboard_center      = 0x00000008,
 
-    F2_dcs_type              = 0x00000030,
-    F2_portal_flag           = 0x00000040,
-    F2_polylight_flag        = 0x00000080,
-    F2_indexed_flag          = 0x00000100,
-    F2_has_indexed_flag      = 0x00000200,
+    F2_dcs_type              = 0x00000070,
+    F2_portal_flag           = 0x00000080,
+    F2_polylight_flag        = 0x00000100,
+    F2_indexed_flag          = 0x00000200,
+    F2_has_indexed_flag      = 0x00000400,
   };
 
   int _flags;

+ 1 - 1
panda/src/egg/parser.yxx

@@ -1209,7 +1209,7 @@ group_body:
   string strval = $4;
 
   EggGroup::DCSType f = EggGroup::string_dcs_type(strval);
-  if (f == EggGroup::DC_none) {
+  if (f == EggGroup::DC_unspecified) {
     eggyywarning("Unknown DCS type " + strval);
   } else {
     group->set_dcs_type(f);

+ 14 - 8
panda/src/egg2pg/characterMaker.cxx

@@ -287,7 +287,7 @@ build_joint_hierarchy(EggNode *egg_node, PartGroup *part) {
       index = _parts.size();
       _parts.push_back(joint);
 
-      if (egg_group->get_dcs_type() != EggGroup::DC_none) {
+      if (egg_group->has_dcs_type()) {
         // If the joint requested an explicit DCS, create a node for
         // it.
         PT(ModelNode) geom_node = new ModelNode(egg_group->get_name());
@@ -556,7 +556,7 @@ determine_primitive_home(EggPrimitive *egg_primitive) {
 
   if (egg_group != (EggGroup *)NULL &&
       egg_group->get_group_type() == EggGroup::GT_joint &&
-      egg_group->get_dcs_type() == EggGroup::DC_none) {
+      !egg_group->has_dcs_type()) {
     // If the home is a joint without a <DCS> flag--this is the normal
     // case--we'll move the polygon under the character node and
     // animate it from there explicitly.
@@ -673,15 +673,21 @@ determine_bin_home(EggBin *egg_bin) {
 
   if (egg_group != (EggGroup *)NULL &&
       egg_group->get_group_type() == EggGroup::GT_joint &&
-      egg_group->get_dcs_type() == EggGroup::DC_none) {
+      !egg_group->has_dcs_type()) {
     // If we have rigid geometry that is assigned to a joint without a
     // <DCS> flag, which means the joint didn't get created as its own
     // node, go ahead and make an implicit node for the joint.
-    
-    // The alternative is to return NULL to treat the geometry as
-    // dynamic (and animate it by animating its vertices), but display
-    // lists and vertex buffers will perform better if as much
-    // geometry as possible is rigid.
+
+    if (egg_group->get_dcs_type() == EggGroup::DC_none) {
+      // Unless the user specifically forbade exposing the joint by
+      // putting an explicit "<DCS> { none }" entry in the joint.  In
+      // this case, we return NULL to treat the geometry as dynamic
+      // (and animate it by animating its vertices), but display lists
+      // and vertex buffers will perform better if as much geometry as
+      // possible is rigid.
+      return NULL;
+    }
+
     CharacterJoint *joint;
     DCAST_INTO_R(joint, egg_to_part(egg_group), home);
     egg_group->set_dcs_type(EggGroup::DC_default);

+ 2 - 2
panda/src/egg2pg/eggLoader.cxx

@@ -1747,8 +1747,7 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
       make_node(*ci, node);
     }
 
-  } else if (egg_group->get_model_flag() || 
-             egg_group->get_dcs_type() != EggGroup::DC_none) {
+  } else if (egg_group->get_model_flag() || egg_group->has_dcs_type()) {
     // A model or DCS flag; create a model node.
     node = new ModelNode(egg_group->get_name());
     switch (egg_group->get_dcs_type()) {
@@ -1762,6 +1761,7 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
       break;
 
     case EggGroup::DC_none:
+    case EggGroup::DC_unspecified:
       break;
     }
 

+ 28 - 0
pandatool/src/egg-optchar/eggOptchar.cxx

@@ -91,6 +91,15 @@ EggOptchar() {
      "and objects can be parented to it.  This implies -keep.",
      &EggOptchar::dispatch_vector_string_comma, NULL, &_expose_components);
 
+  add_option
+    ("suppress", "joint[,joint...]", 0,
+     "The opposite of suppress, this prevents the named joints from "
+     "being created with an implicit DCS attribute, even if they contain "
+     "rigid geometry.  The default is to create an implicit node for any "
+     "joint that contains rigid geometry, to take advantage of display "
+     "list and/or vertex buffer caching.  This does not imply -keep.",
+     &EggOptchar::dispatch_vector_string_comma, NULL, &_suppress_components);
+
   add_option
     ("flag", "node[,node...][=name]", 0,
      "Assign the indicated name to the geometry within the given nodes.  "
@@ -471,6 +480,7 @@ determine_removed_components() {
   Names keep_names;
   Names drop_names;
   Names expose_names;
+  Names suppress_names;
   Names names_used;
 
   vector_string::const_iterator si;
@@ -484,6 +494,9 @@ determine_removed_components() {
     keep_names.insert(*si);
     expose_names.insert(*si);
   }
+  for (si = _suppress_components.begin(); si != _suppress_components.end(); ++si) {
+    suppress_names.insert(*si);
+  }
 
   // We always keep the root joint, which has no name.
   keep_names.insert("");
@@ -502,6 +515,13 @@ determine_removed_components() {
       nassertv(user_data != (EggOptcharUserData *)NULL);
 
       const string &name = comp_data->get_name();
+      if (suppress_names.find(name) != suppress_names.end()) {
+        // If this component is not dropped, it will not be implicitly
+        // exposed.
+        names_used.insert(name);
+        user_data->_flags |= EggOptcharUserData::F_suppress;
+      }
+
       if (drop_names.find(name) != drop_names.end()) {
         // Remove this component by user request.
         names_used.insert(name);
@@ -557,6 +577,12 @@ determine_removed_components() {
       nout << "No such component: " << name << "\n";
     }
   }
+  for (si = _suppress_components.begin(); si != _suppress_components.end(); ++si) {
+    const string &name = (*si);
+    if (names_used.find(name) == names_used.end()) {
+      nout << "No such component: " << name << "\n";
+    }
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -649,6 +675,8 @@ process_joints() {
         joint_data->reparent_to(best_parent);
         if ((user_data->_flags & EggOptcharUserData::F_expose) != 0) {
           joint_data->expose();
+        } else if ((user_data->_flags & EggOptcharUserData::F_suppress) != 0) {
+          joint_data->expose(EggGroup::DC_none);
         }
         num_kept++;
       }

+ 1 - 0
pandatool/src/egg-optchar/eggOptchar.h

@@ -100,6 +100,7 @@ private:
   vector_string _keep_components;
   vector_string _drop_components;
   vector_string _expose_components;
+  vector_string _suppress_components;
 
   class DoubleString {
   public:

+ 1 - 0
pandatool/src/egg-optchar/eggOptcharUserData.h

@@ -47,6 +47,7 @@ public:
     F_top      = 0x0008,
     F_remove   = 0x0010,
     F_expose   = 0x0020,
+    F_suppress = 0x0040,
   };
   int _flags;
   LMatrix4d _static_mat;

+ 3 - 3
pandatool/src/maxegg/maxToEggConverter.cxx

@@ -718,13 +718,13 @@ get_transform(INode *max_node, EggGroup *egg_group) {
     
   case TT_model:
     if (!egg_group->get_model_flag() &&
-        egg_group->get_dcs_type() == EggGroup::DC_none) {
+        !egg_group->has_dcs_type()) {
       return;
     }
     break;
     
   case TT_dcs: 
-    if (egg_group->get_dcs_type() == EggGroup::DC_none) {
+    if (!egg_group->get_dcs_type()) {
       return;
     }
     break;
@@ -2415,4 +2415,4 @@ Modifier* MaxToEggConverter::FindSkinModifier (INode* node, const Class_ID &type
 
   // Not found.
   return NULL;
-}
+}

+ 2 - 3
pandatool/src/mayaegg/mayaToEggConverter.cxx

@@ -931,14 +931,13 @@ get_transform(MayaNodeDesc *node_desc, const MDagPath &dag_path,
       break;
       
     case TT_model:
-      if (!egg_group->get_model_flag() &&
-          egg_group->get_dcs_type() == EggGroup::DC_none) {
+      if (!egg_group->get_model_flag() && !egg_group->has_dcs_type()) {
         return;
       }
       break;
       
     case TT_dcs: 
-      if (egg_group->get_dcs_type() == EggGroup::DC_none) {
+      if (!egg_group->has_dcs_type()) {
         return;
       }
       break;