Ver código fonte

add egg visibility scalar

David Rose 22 anos atrás
pai
commit
093e99cd5a

+ 17 - 5
panda/src/builder/builder.cxx

@@ -59,8 +59,8 @@ Builder::
 // should all be given the same GeomNode, when possible.
 
 // However, if two buckets have different sets of scene graph
-// properties--that is, the _trans member is different--they must be
-// given separate GeomNodes.
+// properties--in particular, the _hidden member is different--they
+// must be given separate GeomNodes.
 
 // Furthermore, it's possible to name each bucket.  If two buckets
 // with the same Node pointer have different names, then they should
@@ -75,6 +75,9 @@ public:
     if (_node != other._node) {
       return _node < other._node;
     }
+    if (_bucket->_hidden != other._bucket->_hidden) {
+      return _bucket->_hidden < other._bucket->_hidden;
+    }
     if (_bucket->get_name() != other._bucket->get_name()) {
       return _bucket->get_name() < other._bucket->get_name();
     }
@@ -127,7 +130,6 @@ build(const string &default_name) {
        ++i) {
     BuilderBucket *bucket = (*i).get_bucket();
     PandaNode *node = bucket->_node;
-    //    const string &name = bucket->get_name();
     GeomNode *geom_node = NULL;
 
     if (node != (PandaNode *)NULL && 
@@ -197,10 +199,20 @@ build(const string &default_name) {
 
       } else if (node==NULL) {
         nassertr(base_geom_node == NULL, NULL);
-        base_geom_node = geom_node;
+        if (!nm._bucket->_hidden) {
+          base_geom_node = geom_node;
+        }
 
       } else {
-        node->add_child(geom_node);
+        if (nm._bucket->_hidden) {
+          // If the contents of the bucket are supposed to be hidden,
+          // add the GeomNode as a stashed child.
+          node->add_stashed(geom_node);
+        } else {
+          // Otherwise, in the normal case, the GeomNode is a normal,
+          // visible child of its parent.
+          node->add_child(geom_node);
+        }
       }
     }
   }

+ 9 - 20
panda/src/builder/builderBucket.cxx

@@ -46,7 +46,6 @@ BuilderBucket() {
 ////////////////////////////////////////////////////////////////////
 BuilderBucket::
 BuilderBucket(const BuilderBucket &copy) {
-  _node = NULL;
   (*this) = copy;
 }
 
@@ -67,9 +66,7 @@ operator = (const BuilderBucket &copy) {
   set_colors(copy._colors);
 
   _node = copy._node;
-  _drawBin = copy._drawBin;
-  _drawOrder = copy._drawOrder;
-
+  _hidden = copy._hidden;
   _state = copy._state;
 
   return *this;
@@ -166,6 +163,10 @@ operator < (const BuilderBucket &other) const {
     return _node < other._node;
   }
 
+  if (_hidden != other._hidden) {
+    return _hidden < other._hidden;
+  }
+
   if (_coords != other._coords)
     return _coords < other._coords;
   if (_normals != other._normals)
@@ -175,11 +176,6 @@ operator < (const BuilderBucket &other) const {
   if (_colors != other._colors)
     return _colors < other._colors;
 
-  if (_drawBin != other._drawBin)
-    return _drawBin < other._drawBin;
-  if (_drawOrder != other._drawOrder)
-    return _drawOrder < other._drawOrder;
-
   if (_state != other._state) {
     return _state < other._state;
   }
@@ -201,6 +197,9 @@ output(ostream &out) const {
   }
   out << "\n";
 
+  if (_hidden) {
+    out << "_hidden\n";
+  }
 
   if (_coords != (Vertexf *)NULL) {
     out << "_coords = " << (void *)_coords << "\n";
@@ -218,14 +217,6 @@ output(ostream &out) const {
     out << "_colors = " << (void *)_colors << "\n";
   }
 
-  if (_drawBin != -1) {
-    out << "_drawBin = " << _drawBin << "\n";
-  }
-
-  if (_drawOrder != 0) {
-    out << "_drawOrder = " << _drawOrder << "\n";
-  }
-
   if (!_state->is_empty()) {
     out << *_state << "\n";
   }
@@ -245,9 +236,7 @@ output(ostream &out) const {
 BuilderBucket::
 BuilderBucket(int) {
   _node = NULL;
-
-  _drawBin = -1;
-  _drawOrder = 0;
+  _hidden = false;
 
   // From BuilderProperties
   _mesh = true;

+ 1 - 4
panda/src/builder/builderBucket.h

@@ -87,11 +87,8 @@ public:
   virtual void output(ostream &out) const;
 
   PandaNode *_node;
-
-  short _drawBin;
-  unsigned int _drawOrder;
-
   CPT(RenderState) _state;
+  bool _hidden;
 
 protected:
   PTA_Vertexf _coords;

+ 23 - 3
panda/src/doc/eggSyntax.txt

@@ -449,6 +449,18 @@ GEOMETRY ENTRIES
     which is a GeomBinFixed object that always exists by default.
 
 
+  <Scalar> visibility { hidden | normal }
+
+    If the visibility of a primitive is set to "hidden", the primitive
+    is not generated as a normally visible primitive.  If the Configrc
+    variable egg-suppress-hidden is set to true, the primitive is not
+    converted at all; otherwise, it is converted as a "stashed" node.
+
+    This, like the other rendering flags alpha, draw_order, and bin,
+    may be specified at the group level, within the primitive level,
+    or even within a texture.
+
+
 <PointLight> name { 
     [attributes] 
     <VertexRef> { 
@@ -459,7 +471,7 @@ GEOMETRY ENTRIES
 
   A PointLight is a set of single points.  One point is drawn for each
   vertex listed in the <VertexRef>.  Normals, textures, and colors may
-  be specified for PointLights, as well as draw-order, plus one
+  be specified for PointLights, as well as draw_order, plus one
   additional attribute valid only for PointLights and Lines:
 
   <Scalar> thick { number }
@@ -482,7 +494,7 @@ GEOMETRY ENTRIES
   A Line is a connected set of line segments.  The listed N vertices
   define a series of N-1 line segments, drawn between vertex 0 and
   vertex 1, vertex 1 and vertex 2, etc.  As with a PointLight,
-  normals, textures, colors, draw-order, and the "thick" attribute are
+  normals, textures, colors, draw_order, and the "thick" attribute are
   all valid.
 
 
@@ -614,7 +626,7 @@ surfaces.  Non-player tools, however, may respect them.
   A NURBS surface is an extension of a NURBS curve into two parametric
   dimensions, u and v.  NURBS surfaces may be given the same set of
   attributes assigned to polygons, except for normals: <TRef>,
-  <Texture>, <MRef>, <RGBA>, and draw-order are all valid attributes
+  <Texture>, <MRef>, <RGBA>, and draw_order are all valid attributes
   for NURBS.  NURBS vertices, similarly, may be colored or morphed,
   but <Normal> and <UV> entries do not apply to NURBS vertices.  The
   attributes may also include <NURBSCurve> and <Trim> entries; see
@@ -840,6 +852,14 @@ GROUPING ENTRIES
     node that do not explicitly set their own drawing order.  See the
     description of draw_order for geometry attributes, above.
 
+  <Scalar> visibility { hidden | normal }
+
+    If the visibility of a group is set to "hidden", the primitives
+    nested within that group are not generated as a normally visible
+    primitive.  If the Configrc variable egg-suppress-hidden is set to
+    true, the primitives are not converted at all; otherwise, they are
+    converted as a "stashed" node.
+
   <Scalar> write_through { boolean-value }
 
     If this is present and boolean-value is non-zero, it places the

+ 19 - 2
panda/src/egg/eggGroup.cxx

@@ -426,7 +426,7 @@ determine_alpha_mode() {
 //       Access: Public, Virtual
 //  Description: Walks back up the hierarchy, looking for an EggGroup
 //               or EggPrimitive or some such object at this level or
-//               above this group that has an depth_write_mode other
+//               above this group that has a depth_write_mode other
 //               than DWM_unspecified.  Returns a valid EggRenderMode
 //               pointer if one is found, or NULL otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -443,7 +443,7 @@ determine_depth_write_mode() {
 //       Access: Public, Virtual
 //  Description: Walks back up the hierarchy, looking for an EggGroup
 //               or EggPrimitive or some such object at this level or
-//               above this group that has an depth_test_mode other
+//               above this group that has a depth_test_mode other
 //               than DTM_unspecified.  Returns a valid EggRenderMode
 //               pointer if one is found, or NULL otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -455,6 +455,23 @@ determine_depth_test_mode() {
   return EggGroupNode::determine_depth_test_mode();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::determine_visibility_mode
+//       Access: Public, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this group that has a visibility_mode other
+//               than VM_unspecified.  Returns a valid EggRenderMode
+//               pointer if one is found, or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggGroup::
+determine_visibility_mode() {
+  if (get_visibility_mode() != VM_unspecified) {
+    return this;
+  }
+  return EggGroupNode::determine_visibility_mode();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggGroup::determine_draw_order
 //       Access: Public, Virtual

+ 1 - 0
panda/src/egg/eggGroup.h

@@ -114,6 +114,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_alpha_mode();
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
+  virtual EggRenderMode *determine_visibility_mode();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
 

+ 18 - 0
panda/src/egg/eggNode.cxx

@@ -112,6 +112,24 @@ determine_depth_test_mode() {
   return _parent->determine_depth_test_mode();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggNode::determine_visibility_mode
+//       Access: Public, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this node that has a visibility_mode other than
+//               VM_unspecified.  Returns a valid EggRenderMode pointer
+//               if one is found, or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggNode::
+determine_visibility_mode() {
+  if (_parent == (EggGroupNode *)NULL) {
+    // Too bad; we're done.
+    return (EggRenderMode *)NULL;
+  }
+  return _parent->determine_visibility_mode();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggNode::determine_draw_order
 //       Access: Public, Virtual

+ 1 - 0
panda/src/egg/eggNode.h

@@ -75,6 +75,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_alpha_mode();
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
+  virtual EggRenderMode *determine_visibility_mode();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
 

+ 25 - 0
panda/src/egg/eggPrimitive.cxx

@@ -102,6 +102,31 @@ determine_depth_test_mode() {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggPrimitive::determine_visibility_mode
+//       Access: Public, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this node that has a visibility_mode other than
+//               VM_unspecified.  Returns a valid EggRenderMode pointer
+//               if one is found, or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggPrimitive::
+determine_visibility_mode() {
+  if (get_visibility_mode() != VM_unspecified) {
+    return this;
+  }
+
+  EggRenderMode *result = EggNode::determine_visibility_mode();
+  if (result == (EggRenderMode *)NULL) {
+    if (has_texture() &&
+        get_texture()->get_visibility_mode() != VM_unspecified) {
+      result = get_texture();
+    }
+  }
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggPrimitive::determine_draw_order
 //       Access: Public, Virtual

+ 1 - 0
panda/src/egg/eggPrimitive.h

@@ -71,6 +71,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_alpha_mode();
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
+  virtual EggRenderMode *determine_visibility_mode();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
 

+ 26 - 30
panda/src/egg/eggRenderMode.I

@@ -17,20 +17,6 @@
 ////////////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggRenderMode::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE EggRenderMode::
-EggRenderMode() {
-  _alpha_mode = AM_unspecified;
-  _depth_write_mode = DWM_unspecified;
-  _depth_test_mode = DTM_unspecified;
-  _draw_order = 0;
-  _has_draw_order = false;
-}
-
 
 ////////////////////////////////////////////////////////////////////
 //     Function: EggRenderMode::Copy Constructor
@@ -42,22 +28,6 @@ EggRenderMode(const EggRenderMode &copy) {
   (*this) = copy;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggRenderMode::Copy assignment operator
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE EggRenderMode &EggRenderMode::
-operator = (const EggRenderMode &copy) {
-  _alpha_mode = copy._alpha_mode;
-  _depth_write_mode = copy._depth_write_mode;
-  _depth_test_mode = copy._depth_test_mode;
-  _draw_order = copy._draw_order;
-  _has_draw_order = copy._has_draw_order;
-  return *this;
-}
-
-
 ////////////////////////////////////////////////////////////////////
 //     Function: EggRenderMode::set_depth_write_mode
 //       Access: Public
@@ -108,6 +78,32 @@ get_depth_test_mode() const {
   return _depth_test_mode;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::set_visibility_mode
+//       Access: Public
+//  Description: Specifies whether this geometry is to be considered
+//               normally visible, or hidden.  If it is hidden, it is
+//               either not loaded into the scene graph at all, or
+//               loaded as a "stashed" node, according to the setting
+//               of egg-suppress-hidden.
+////////////////////////////////////////////////////////////////////
+INLINE void EggRenderMode::
+set_visibility_mode(VisibilityMode mode) {
+  _visibility_mode = mode;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::get_visibility_mode
+//       Access: Public
+//  Description: Returns the visibility mode that was set, or
+//               VM_unspecified if nothing was set.  See
+//               set_visibility_mode().
+////////////////////////////////////////////////////////////////////
+INLINE EggRenderMode::VisibilityMode EggRenderMode::
+get_visibility_mode() const {
+  return _visibility_mode;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggRenderMode::set_alpha_mode
 //       Access: Public

+ 82 - 4
panda/src/egg/eggRenderMode.cxx

@@ -17,12 +17,43 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "eggRenderMode.h"
-#include <indent.h>
-#include <string_utils.h>
-#include <notify.h>
+#include "indent.h"
+#include "string_utils.h"
+#include "notify.h"
 
 TypeHandle EggRenderMode::_type_handle;
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+EggRenderMode::
+EggRenderMode() {
+  _alpha_mode = AM_unspecified;
+  _depth_write_mode = DWM_unspecified;
+  _depth_test_mode = DTM_unspecified;
+  _visibility_mode = VM_unspecified;
+  _draw_order = 0;
+  _has_draw_order = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::Copy assignment operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+EggRenderMode &EggRenderMode::
+operator = (const EggRenderMode &copy) {
+  _alpha_mode = copy._alpha_mode;
+  _depth_write_mode = copy._depth_write_mode;
+  _depth_test_mode = copy._depth_test_mode;
+  _visibility_mode = copy._visibility_mode;
+  _draw_order = copy._draw_order;
+  _has_draw_order = copy._has_draw_order;
+  return *this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggRenderMode::write
 //       Access: Public
@@ -43,6 +74,10 @@ write(ostream &out, int indent_level) const {
     indent(out, indent_level)
       << "<Scalar> depth_test { " << get_depth_test_mode() << " }\n";
   }
+  if (get_visibility_mode() != VM_unspecified) {
+    indent(out, indent_level)
+      << "<Scalar> visibility { " << get_visibility_mode() << " }\n";
+  }
   if (has_draw_order()) {
     indent(out, indent_level)
       << "<Scalar> draw-order { " << get_draw_order() << " }\n";
@@ -63,6 +98,7 @@ operator == (const EggRenderMode &other) const {
   if (_alpha_mode != other._alpha_mode ||
       _depth_write_mode != other._depth_write_mode ||
       _depth_test_mode != other._depth_test_mode ||
+      _visibility_mode != other._visibility_mode ||
       _has_draw_order != other._has_draw_order) {
     return false;
   }
@@ -96,6 +132,9 @@ operator < (const EggRenderMode &other) const {
   if (_depth_test_mode != other._depth_test_mode) {
     return (int)_depth_test_mode < (int)other._depth_test_mode;
   }
+  if (_visibility_mode != other._visibility_mode) {
+    return (int)_visibility_mode < (int)other._visibility_mode;
+  }
 
   if (_has_draw_order != other._has_draw_order) {
     return (int)_has_draw_order < (int)other._has_draw_order;
@@ -167,7 +206,7 @@ string_depth_write_mode(const string &string) {
 //     Function: EggRenderMode::string_depth_test_mode
 //       Access: Public
 //  Description: Returns the DepthTestMode value associated with the
-//               given string representation, or DWM_unspecified if
+//               given string representation, or DTM_unspecified if
 //               the string does not match any known DepthTestMode
 //               value.
 ////////////////////////////////////////////////////////////////////
@@ -182,6 +221,25 @@ string_depth_test_mode(const string &string) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::string_visibility_mode
+//       Access: Public
+//  Description: Returns the HiddenMode value associated with the
+//               given string representation, or VM_unspecified if
+//               the string does not match any known HiddenMode
+//               value.
+////////////////////////////////////////////////////////////////////
+EggRenderMode::VisibilityMode EggRenderMode::
+string_visibility_mode(const string &string) {
+  if (cmp_nocase_uh(string, "hidden") == 0) {
+    return VM_hidden;
+  } else if (cmp_nocase_uh(string, "normal") == 0) {
+    return VM_normal;
+  } else {
+    return VM_unspecified;
+  }
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: AlphaMode output operator
@@ -250,3 +308,23 @@ ostream &operator << (ostream &out, EggRenderMode::DepthTestMode mode) {
 }
 
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: VisibilityMode output operator
+//  Description:
+////////////////////////////////////////////////////////////////////
+ostream &operator << (ostream &out, EggRenderMode::VisibilityMode mode) {
+  switch (mode) {
+  case EggRenderMode::VM_unspecified:
+    return out << "unspecified";
+  case EggRenderMode::VM_hidden:
+    return out << "hidden";
+  case EggRenderMode::VM_normal:
+    return out << "normal";
+  }
+
+  nassertr(false, out);
+  return out << "(**invalid**)";
+}
+
+

+ 12 - 2
panda/src/egg/eggRenderMode.h

@@ -39,9 +39,9 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAEGG EggRenderMode {
 PUBLISHED:
-  INLINE EggRenderMode();
+  EggRenderMode();
   INLINE EggRenderMode(const EggRenderMode &copy);
-  INLINE EggRenderMode &operator = (const EggRenderMode &copy);
+  EggRenderMode &operator = (const EggRenderMode &copy);
 
   void write(ostream &out, int indent_level) const;
 
@@ -65,6 +65,10 @@ PUBLISHED:
     DTM_unspecified, DTM_off, DTM_on
   };
 
+  enum VisibilityMode {
+    VM_unspecified, VM_hidden, VM_normal
+  };
+
   INLINE void set_alpha_mode(AlphaMode mode);
   INLINE AlphaMode get_alpha_mode() const;
 
@@ -74,6 +78,9 @@ PUBLISHED:
   INLINE void set_depth_test_mode(DepthTestMode mode);
   INLINE DepthTestMode get_depth_test_mode() const;
 
+  INLINE void set_visibility_mode(VisibilityMode mode);
+  INLINE VisibilityMode get_visibility_mode() const;
+
   INLINE void set_draw_order(int order);
   INLINE int get_draw_order() const;
   INLINE bool has_draw_order() const;
@@ -92,11 +99,13 @@ PUBLISHED:
   static AlphaMode string_alpha_mode(const string &string);
   static DepthWriteMode string_depth_write_mode(const string &string);
   static DepthTestMode string_depth_test_mode(const string &string);
+  static VisibilityMode string_visibility_mode(const string &string);
 
 private:
   AlphaMode _alpha_mode;
   DepthWriteMode _depth_write_mode;
   DepthTestMode _depth_test_mode;
+  VisibilityMode _visibility_mode;
   int _draw_order;
   bool _has_draw_order;
   string _bin;
@@ -117,6 +126,7 @@ private:
 ostream &operator << (ostream &out, EggRenderMode::AlphaMode mode);
 ostream &operator << (ostream &out, EggRenderMode::DepthWriteMode mode);
 ostream &operator << (ostream &out, EggRenderMode::DepthTestMode mode);
+ostream &operator << (ostream &out, EggRenderMode::VisibilityMode mode);
 
 #include "eggRenderMode.I"
 

+ 49 - 0
panda/src/egg/parser.yxx

@@ -391,6 +391,15 @@ texture_body:
       texture->set_depth_test_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "visibility") == 0) {
+    EggRenderMode::VisibilityMode m = 
+      EggRenderMode::string_visibility_mode(strval);
+    if (m == EggRenderMode::VM_unspecified) {
+      eggyywarning("Unknown visibility mode " + strval);
+    } else {
+      texture->set_visibility_mode(m);
+    }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     texture->set_draw_order((int)value);
 
@@ -904,6 +913,16 @@ group_body:
     } else {
       group->set_depth_test_mode(m);
     }
+
+  } else if (cmp_nocase_uh(name, "visibility") == 0) {
+    EggRenderMode::VisibilityMode m = 
+      EggRenderMode::string_visibility_mode(strval);
+    if (m == EggRenderMode::VM_unspecified) {
+      eggyywarning("Unknown visibility mode " + strval);
+    } else {
+      group->set_visibility_mode(m);
+    }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     group->set_draw_order(ulong_value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {
@@ -1465,6 +1484,16 @@ primitive_body:
     } else {
       primitive->set_depth_test_mode(m);
     }
+
+  } else if (cmp_nocase_uh(name, "visibility") == 0) {
+    EggRenderMode::VisibilityMode m = 
+      EggRenderMode::string_visibility_mode(strval);
+    if (m == EggRenderMode::VM_unspecified) {
+      eggyywarning("Unknown visibility mode " + strval);
+    } else {
+      primitive->set_visibility_mode(m);
+    }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {
@@ -1532,6 +1561,16 @@ nurbs_surface_body:
     } else {
       primitive->set_depth_test_mode(m);
     }
+
+  } else if (cmp_nocase_uh(name, "visibility") == 0) {
+    EggRenderMode::VisibilityMode m = 
+      EggRenderMode::string_visibility_mode(strval);
+    if (m == EggRenderMode::VM_unspecified) {
+      eggyywarning("Unknown visibility mode " + strval);
+    } else {
+      primitive->set_visibility_mode(m);
+    }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {
@@ -1596,6 +1635,16 @@ nurbs_curve_body:
     } else {
       primitive->set_depth_test_mode(m);
     }
+
+  } else if (cmp_nocase_uh(name, "visibility") == 0) {
+    EggRenderMode::VisibilityMode m = 
+      EggRenderMode::string_visibility_mode(strval);
+    if (m == EggRenderMode::VM_unspecified) {
+      eggyywarning("Unknown visibility mode " + strval);
+    } else {
+      primitive->set_visibility_mode(m);
+    }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {

+ 6 - 0
panda/src/egg2pg/config_egg2pg.cxx

@@ -71,6 +71,12 @@ bool egg_load_classic_nurbs_curves = config_egg2pg.GetBool("egg-load-classic-nur
 // be loaded.
 bool egg_accept_errors = config_egg2pg.GetBool("egg-accept-errors", true);
 
+// When this is true, objects flagged as "hidden" with the visibility
+// scalar are not created at all.  When false, these objects are
+// created, but initially stashed.
+bool egg_suppress_hidden = config_egg2pg.GetBool("egg-suppress-hidden", false);
+
+
 CoordinateSystem egg_coordinate_system = CS_invalid;
 EggRenderMode::AlphaMode egg_alpha_mode = EggRenderMode::AM_unspecified;
 

+ 2 - 0
panda/src/egg2pg/config_egg2pg.h

@@ -55,6 +55,8 @@ extern EXPCL_PANDAEGG bool egg_show_collision_solids;
 extern EXPCL_PANDAEGG bool egg_load_old_curves;
 extern EXPCL_PANDAEGG bool egg_load_classic_nurbs_curves;
 extern EXPCL_PANDAEGG bool egg_accept_errors;
+extern EXPCL_PANDAEGG bool egg_accept_errors;
+extern EXPCL_PANDAEGG bool egg_suppress_hidden;
 extern EXPCL_PANDAEGG EggRenderMode::AlphaMode egg_alpha_mode;
 
 extern EXPCL_PANDAEGG void init_libegg2pg();

+ 31 - 0
panda/src/egg2pg/eggLoader.cxx

@@ -238,6 +238,10 @@ make_nonindexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
                           const LMatrix4d *transform) {
   BuilderBucket bucket;
   setup_bucket(bucket, parent, egg_prim);
+  if (bucket._hidden && egg_suppress_hidden) {
+    // Eat this primitive.
+    return;
+  }
 
   LMatrix4d mat;
 
@@ -331,6 +335,10 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
                        ComputedVerticesMaker &_comp_verts_maker) {
   BuilderBucket bucket;
   setup_bucket(bucket, parent, egg_prim);
+  if (bucket._hidden && egg_suppress_hidden) {
+    // Eat this primitive.
+    return;
+  }
 
   bucket.set_coords(_comp_verts_maker._coords);
   bucket.set_normals(_comp_verts_maker._norms);
@@ -510,6 +518,10 @@ make_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
   // from it.
   BuilderBucket bucket;
   setup_bucket(bucket, parent, egg_curve);
+  if (bucket._hidden && egg_suppress_hidden) {
+    // Eat this primitive.
+    return;
+  }
 
   rope->set_state(bucket._state);
 
@@ -661,6 +673,10 @@ make_nurbs_surface(EggNurbsSurface *egg_surface, PandaNode *parent,
   // from it.
   BuilderBucket bucket;
   setup_bucket(bucket, parent, egg_surface);
+  if (bucket._hidden && egg_suppress_hidden) {
+    // Eat this primitive.
+    return;
+  }
 
   sheet->set_state(bucket._state);
 
@@ -1235,6 +1251,7 @@ setup_bucket(BuilderBucket &bucket, PandaNode *parent,
   EggRenderMode::AlphaMode am = EggRenderMode::AM_unspecified;
   EggRenderMode::DepthWriteMode dwm = EggRenderMode::DWM_unspecified;
   EggRenderMode::DepthTestMode dtm = EggRenderMode::DTM_unspecified;
+  EggRenderMode::VisibilityMode vm = EggRenderMode::VM_unspecified;
   bool implicit_alpha = false;
   bool has_draw_order = false;
   int draw_order = 0;
@@ -1254,6 +1271,10 @@ setup_bucket(BuilderBucket &bucket, PandaNode *parent,
   if (render_mode != (EggRenderMode *)NULL) {
     dtm = render_mode->get_depth_test_mode();
   }
+  render_mode = egg_prim->determine_visibility_mode();
+  if (render_mode != (EggRenderMode *)NULL) {
+    vm = render_mode->get_visibility_mode();
+  }
   render_mode = egg_prim->determine_draw_order();
   if (render_mode != (EggRenderMode *)NULL) {
     has_draw_order = true;
@@ -1383,6 +1404,16 @@ setup_bucket(BuilderBucket &bucket, PandaNode *parent,
     break;
   }
 
+  switch (vm) {
+  case EggRenderMode::VM_hidden:
+    bucket._hidden = true;
+    break;
+
+  case EggRenderMode::VM_normal:
+  default:
+    break;
+  }
+
   if (has_bin) {
     bucket.add_attrib(CullBinAttrib::make(bin, draw_order));