Browse Source

set_bounds_type()

David Rose 17 years ago
parent
commit
ddbad77851

+ 7 - 2
panda/src/collide/collisionNode.cxx

@@ -331,8 +331,13 @@ compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
 
 
   PT(GeometricBoundingVolume) gbv = new BoundingBox;
   PT(GeometricBoundingVolume) gbv = new BoundingBox;
 
 
-  if (bounds_type == BoundingVolume::BT_box ||
-      (bounds_type != BoundingVolume::BT_sphere && all_box)) {
+  BoundingVolume::BoundsType btype = get_bounds_type();
+  if (btype == BoundingVolume::BT_default) {
+    btype = bounds_type;
+  }
+
+  if (btype == BoundingVolume::BT_box ||
+      (btype != BoundingVolume::BT_sphere && all_box)) {
     // If all of the child volumes are a BoundingBox, then our volume
     // If all of the child volumes are a BoundingBox, then our volume
     // is also a BoundingBox.
     // is also a BoundingBox.
     gbv = new BoundingBox;
     gbv = new BoundingBox;

+ 40 - 1
panda/src/gobj/geom.I

@@ -272,6 +272,43 @@ mark_bounds_stale() const {
   ((Geom *)this)->mark_internal_bounds_stale(cdata);
   ((Geom *)this)->mark_internal_bounds_stale(cdata);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Geom::set_bounds_type
+//       Access: Published
+//  Description: Specifies the desired type of bounding volume that
+//               will be created for this Geom.  This is normally
+//               BoundingVolume::BT_default, which means to set the
+//               type according to the config variable "bounds-type".
+//
+//               If this is BT_sphere or BT_box, a BoundingSphere or
+//               BoundingBox is explicitly created.  If it is BT_best,
+//               a BoundingBox is created.
+//
+//               This affects the implicit bounding volume only.  If
+//               an explicit bounding volume is set on the Geom with
+//               set_bounds(), that bounding volume type is used.
+//               (This is different behavior from the similar method
+//               on PandaNode.)
+////////////////////////////////////////////////////////////////////
+INLINE void Geom::
+set_bounds_type(BoundingVolume::BoundsType bounds_type) {
+  CDWriter cdata(_cycler, true);
+  cdata->_bounds_type = bounds_type;
+  mark_internal_bounds_stale(cdata);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Geom::get_bounds_type
+//       Access: Published
+//  Description: Returns the bounding volume type set with
+//               set_bounds_type().
+////////////////////////////////////////////////////////////////////
+INLINE BoundingVolume::BoundsType Geom::
+get_bounds_type() const {
+  CDReader cdata(_cycler);
+  return cdata->_bounds_type;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Geom::set_bounds
 //     Function: Geom::set_bounds
 //       Access: Published
 //       Access: Published
@@ -506,7 +543,8 @@ CData() :
   _usage_hint(UH_unspecified),
   _usage_hint(UH_unspecified),
   _got_usage_hint(false),
   _got_usage_hint(false),
   _nested_vertices(0),
   _nested_vertices(0),
-  _internal_bounds_stale(true)
+  _internal_bounds_stale(true),
+  _bounds_type(BoundingVolume::BT_default)
 {
 {
 }
 }
 
 
@@ -528,6 +566,7 @@ CData(const Geom::CData &copy) :
   _internal_bounds(copy._internal_bounds),
   _internal_bounds(copy._internal_bounds),
   _nested_vertices(copy._nested_vertices),
   _nested_vertices(copy._nested_vertices),
   _internal_bounds_stale(copy._internal_bounds_stale),
   _internal_bounds_stale(copy._internal_bounds_stale),
+  _bounds_type(copy._bounds_type),
   _user_bounds(copy._user_bounds)
   _user_bounds(copy._user_bounds)
 {
 {
 }
 }

+ 14 - 2
panda/src/gobj/geom.cxx

@@ -1261,9 +1261,14 @@ compute_internal_bounds(Geom::CData *cdata, Thread *current_thread) const {
                        InternalName::get_vertex(),
                        InternalName::get_vertex(),
                        cdata, current_thread);
                        cdata, current_thread);
 
 
+  BoundingVolume::BoundsType btype = cdata->_bounds_type;
+  if (btype == BoundingVolume::BT_default) {
+    btype = bounds_type;
+  }
+
   if (found_any) {
   if (found_any) {
     // Then we put the bounding volume around both of those points.
     // Then we put the bounding volume around both of those points.
-    if (bounds_type == BoundingVolume::BT_sphere) {
+    if (btype == BoundingVolume::BT_sphere) {
       // The user specifically requested a BoundingSphere, so oblige.
       // The user specifically requested a BoundingSphere, so oblige.
       BoundingBox box(min, max);
       BoundingBox box(min, max);
       box.local_object();
       box.local_object();
@@ -1287,7 +1292,7 @@ compute_internal_bounds(Geom::CData *cdata, Thread *current_thread) const {
 
 
   } else {
   } else {
     // No points; empty bounding volume.
     // No points; empty bounding volume.
-    if (bounds_type == BoundingVolume::BT_sphere) {
+    if (btype == BoundingVolume::BT_sphere) {
       cdata->_internal_bounds = new BoundingSphere;
       cdata->_internal_bounds = new BoundingSphere;
     } else {
     } else {
       cdata->_internal_bounds = new BoundingBox;
       cdata->_internal_bounds = new BoundingBox;
@@ -1647,6 +1652,8 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
   // Actually, we shouldn't bother writing out _geom_rendering; we'll
   // Actually, we shouldn't bother writing out _geom_rendering; we'll
   // just throw it away anyway.
   // just throw it away anyway.
   dg.add_uint16(_geom_rendering);
   dg.add_uint16(_geom_rendering);
+
+  dg.add_uint8(_bounds_type);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1697,6 +1704,11 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
 
   _got_usage_hint = false;
   _got_usage_hint = false;
   _modified = Geom::get_next_modified();
   _modified = Geom::get_next_modified();
+
+  _bounds_type = BoundingVolume::BT_default;
+  if (manager->get_file_minor_ver() >= 19) {
+    _bounds_type = (BoundingVolume::BoundsType)scan.get_uint8();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 3 - 0
panda/src/gobj/geom.h

@@ -124,6 +124,8 @@ PUBLISHED:
   CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
   CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
   int get_nested_vertices(Thread *current_thread = Thread::get_current_thread()) const;
   int get_nested_vertices(Thread *current_thread = Thread::get_current_thread()) const;
   INLINE void mark_bounds_stale() const;
   INLINE void mark_bounds_stale() const;
+  INLINE void set_bounds_type(BoundingVolume::BoundsType bounds_type);
+  INLINE BoundingVolume::BoundsType get_bounds_type() const;
   INLINE void set_bounds(const BoundingVolume *volume);
   INLINE void set_bounds(const BoundingVolume *volume);
   INLINE void clear_bounds();
   INLINE void clear_bounds();
 
 
@@ -302,6 +304,7 @@ private:
     CPT(BoundingVolume) _internal_bounds;
     CPT(BoundingVolume) _internal_bounds;
     int _nested_vertices;
     int _nested_vertices;
     bool _internal_bounds_stale;
     bool _internal_bounds_stale;
+    BoundingVolume::BoundsType _bounds_type;
     CPT(BoundingVolume) _user_bounds;
     CPT(BoundingVolume) _user_bounds;
     
     
   public:
   public:

+ 9 - 6
panda/src/mathutil/boundingVolume.cxx

@@ -168,7 +168,10 @@ as_bounding_plane() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 BoundingVolume::BoundsType BoundingVolume::
 BoundingVolume::BoundsType BoundingVolume::
 string_bounds_type(const string &str) {
 string_bounds_type(const string &str) {
-  if (strcmp(str.c_str(), "best") == 0) {
+  if (strcmp(str.c_str(), "default") == 0) {
+    return BT_default;
+
+  } else if (strcmp(str.c_str(), "best") == 0) {
     return BT_best;
     return BT_best;
 
 
   } else if (strcmp(str.c_str(), "sphere") == 0) {
   } else if (strcmp(str.c_str(), "sphere") == 0) {
@@ -178,7 +181,7 @@ string_bounds_type(const string &str) {
     return BT_box;
     return BT_box;
   }
   }
 
 
-  return BT_invalid;
+  return BT_default;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -412,6 +415,9 @@ contains_plane(const BoundingPlane *) const {
 ostream &
 ostream &
 operator << (ostream &out, BoundingVolume::BoundsType type) {
 operator << (ostream &out, BoundingVolume::BoundsType type) {
   switch (type) {
   switch (type) {
+  case BoundingVolume::BT_default:
+    return out << "default";
+
   case BoundingVolume::BT_best:
   case BoundingVolume::BT_best:
     return out << "best";
     return out << "best";
 
 
@@ -420,9 +426,6 @@ operator << (ostream &out, BoundingVolume::BoundsType type) {
 
 
   case BoundingVolume::BT_box:
   case BoundingVolume::BT_box:
     return out << "box";
     return out << "box";
-
-  case BoundingVolume::BT_invalid:
-    return out << "invalid";
   }
   }
 
 
   mathutil_cat.error()
   mathutil_cat.error()
@@ -436,7 +439,7 @@ operator >> (istream &in, BoundingVolume::BoundsType &type) {
   string word;
   string word;
   in >> word;
   in >> word;
   type = BoundingVolume::string_bounds_type(word);
   type = BoundingVolume::string_bounds_type(word);
-  if (type == BoundingVolume::BT_invalid) {
+  if (type == BoundingVolume::BT_default) {
     mathutil_cat->error()
     mathutil_cat->error()
       << "Invalid BoundingVolume::BoundsType string: " << word << "\n";
       << "Invalid BoundingVolume::BoundsType string: " << word << "\n";
   }
   }

+ 1 - 2
panda/src/mathutil/boundingVolume.h

@@ -100,11 +100,10 @@ PUBLISHED:
   // This enum is used to control the automatic generation of bounding
   // This enum is used to control the automatic generation of bounding
   // volumes.
   // volumes.
   enum BoundsType {
   enum BoundsType {
+    BT_default,
     BT_best,
     BT_best,
     BT_sphere,
     BT_sphere,
     BT_box,
     BT_box,
-
-    BT_invalid,    // Do not use this one
   };
   };
 
 
 public:
 public:

+ 7 - 2
panda/src/pgraph/geomNode.cxx

@@ -899,8 +899,13 @@ compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
 
 
   PT(GeometricBoundingVolume) gbv;
   PT(GeometricBoundingVolume) gbv;
 
 
-  if (bounds_type == BoundingVolume::BT_box ||
-      (bounds_type != BoundingVolume::BT_sphere && all_box)) {
+  BoundingVolume::BoundsType btype = get_bounds_type();
+  if (btype == BoundingVolume::BT_default) {
+    btype = bounds_type;
+  }
+
+  if (btype == BoundingVolume::BT_box ||
+      (btype != BoundingVolume::BT_sphere && all_box)) {
     // If all of the child volumes are a BoundingBox, then our volume
     // If all of the child volumes are a BoundingBox, then our volume
     // is also a BoundingBox.
     // is also a BoundingBox.
     gbv = new BoundingBox;
     gbv = new BoundingBox;

+ 63 - 2
panda/src/pgraph/pandaNode.cxx

@@ -162,6 +162,7 @@ PandaNode(const PandaNode &copy) :
     cdata->_draw_control_mask = copy_cdata->_draw_control_mask;
     cdata->_draw_control_mask = copy_cdata->_draw_control_mask;
     cdata->_draw_show_mask = copy_cdata->_draw_show_mask;
     cdata->_draw_show_mask = copy_cdata->_draw_show_mask;
     cdata->_into_collide_mask = copy_cdata->_into_collide_mask;
     cdata->_into_collide_mask = copy_cdata->_into_collide_mask;
+    cdata->_bounds_type = copy_cdata->_bounds_type;
     cdata->_user_bounds = copy_cdata->_user_bounds;
     cdata->_user_bounds = copy_cdata->_user_bounds;
     cdata->_internal_bounds = NULL;
     cdata->_internal_bounds = NULL;
     cdata->_internal_bounds_computed = UpdateSeq::initial();
     cdata->_internal_bounds_computed = UpdateSeq::initial();
@@ -2237,6 +2238,53 @@ write(ostream &out, int indent_level) const {
   out << "\n";
   out << "\n";
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::set_bounds_type
+//       Access: Published
+//  Description: Specifies the desired type of bounding volume that
+//               will be created for this node.  This is normally
+//               BoundingVolume::BT_default, which means to set the
+//               type according to the config variable "bounds-type".
+//
+//               If this is BT_sphere or BT_box, a BoundingSphere or
+//               BoundingBox is explicitly created.  If it is BT_best,
+//               the appropriate type to best enclose the node's
+//               children is created.
+//
+//               This affects the bounding volume returned by
+//               get_bounds(), which is not exactly the same bounding
+//               volume modified by set_bounds(), because a new
+//               bounding volume has to be created that includes this
+//               node and all of its children.
+////////////////////////////////////////////////////////////////////
+void PandaNode::
+set_bounds_type(BoundingVolume::BoundsType bounds_type) {
+  Thread *current_thread = Thread::get_current_thread();
+  OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
+    CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
+    cdata->_bounds_type = bounds_type;
+    mark_bounds_stale(pipeline_stage, current_thread);
+
+    // GeomNodes, CollisionNodes, and PGItems all have an internal
+    // bounds that may need to be updated when the bounds_type
+    // changes.
+    mark_internal_bounds_stale(pipeline_stage, current_thread);
+  }
+  CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::get_bounds_type
+//       Access: Published
+//  Description: Returns the bounding volume type set with
+//               set_bounds_type().
+////////////////////////////////////////////////////////////////////
+BoundingVolume::BoundsType PandaNode::
+get_bounds_type() const {
+  CDReader cdata(_cycler);
+  return cdata->_bounds_type;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::set_bounds
 //     Function: PandaNode::set_bounds
 //       Access: Published
 //       Access: Published
@@ -3932,8 +3980,13 @@ update_bounds(int pipeline_stage, PandaNode::CDLockedStageReader &cdata) {
         CPT(TransformState) transform = get_transform(current_thread);
         CPT(TransformState) transform = get_transform(current_thread);
         PT(GeometricBoundingVolume) gbv;
         PT(GeometricBoundingVolume) gbv;
 
 
-        if (bounds_type == BoundingVolume::BT_box ||
-            (bounds_type != BoundingVolume::BT_sphere && all_box && transform->is_identity())) {
+        BoundingVolume::BoundsType btype = cdataw->_bounds_type;
+        if (btype == BoundingVolume::BT_default) {
+          btype = bounds_type;
+        }
+
+        if (btype == BoundingVolume::BT_box ||
+            (btype != BoundingVolume::BT_sphere && all_box && transform->is_identity())) {
           // If all of the child volumes are a BoundingBox, and we
           // If all of the child volumes are a BoundingBox, and we
           // have no transform, then our volume is also a
           // have no transform, then our volume is also a
           // BoundingBox.
           // BoundingBox.
@@ -4115,6 +4168,7 @@ CData() :
   _draw_control_mask(DrawMask::all_off()),
   _draw_control_mask(DrawMask::all_off()),
   _draw_show_mask(DrawMask::all_on()),
   _draw_show_mask(DrawMask::all_on()),
   _into_collide_mask(CollideMask::all_off()),
   _into_collide_mask(CollideMask::all_off()),
+  _bounds_type(BoundingVolume::BT_default),
   _user_bounds(NULL),
   _user_bounds(NULL),
   _final_bounds(false),
   _final_bounds(false),
   _fancy_bits(0),
   _fancy_bits(0),
@@ -4147,6 +4201,7 @@ CData(const PandaNode::CData &copy) :
   _draw_control_mask(copy._draw_control_mask),
   _draw_control_mask(copy._draw_control_mask),
   _draw_show_mask(copy._draw_show_mask),
   _draw_show_mask(copy._draw_show_mask),
   _into_collide_mask(copy._into_collide_mask),
   _into_collide_mask(copy._into_collide_mask),
+  _bounds_type(copy._bounds_type),
   _user_bounds(copy._user_bounds),
   _user_bounds(copy._user_bounds),
   _final_bounds(copy._final_bounds),
   _final_bounds(copy._final_bounds),
   _fancy_bits(copy._fancy_bits),
   _fancy_bits(copy._fancy_bits),
@@ -4216,6 +4271,7 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
   dg.add_uint32(_draw_control_mask.get_word());
   dg.add_uint32(_draw_control_mask.get_word());
   dg.add_uint32(_draw_show_mask.get_word());
   dg.add_uint32(_draw_show_mask.get_word());
   dg.add_uint32(_into_collide_mask.get_word());
   dg.add_uint32(_into_collide_mask.get_word());
+  dg.add_uint8(_bounds_type);
 
 
   dg.add_uint32(_tag_data.size());
   dg.add_uint32(_tag_data.size());
   TagData::const_iterator ti;
   TagData::const_iterator ti;
@@ -4335,6 +4391,11 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
 
   _into_collide_mask.set_word(scan.get_uint32());
   _into_collide_mask.set_word(scan.get_uint32());
 
 
+  _bounds_type = BoundingVolume::BT_default;
+  if (manager->get_file_minor_ver() >= 19) {
+    _bounds_type = (BoundingVolume::BoundsType)scan.get_uint8();
+  }
+
   // Read in the tag list.
   // Read in the tag list.
   int num_tags = scan.get_uint32();
   int num_tags = scan.get_uint32();
   for (int i = 0; i < num_tags; i++) {
   for (int i = 0; i < num_tags; i++) {

+ 6 - 0
panda/src/pgraph/pandaNode.h

@@ -264,6 +264,9 @@ PUBLISHED:
   // returns the external bounding volume.  Although it might seem
   // returns the external bounding volume.  Although it might seem
   // strange and confusing to do this, this is actually the natural
   // strange and confusing to do this, this is actually the natural
   // way the user thinks about nodes and bounding volumes.
   // way the user thinks about nodes and bounding volumes.
+  void set_bounds_type(BoundingVolume::BoundsType bounds_type);
+  BoundingVolume::BoundsType get_bounds_type() const;
+
   void set_bounds(const BoundingVolume *volume);
   void set_bounds(const BoundingVolume *volume);
   void set_bound(const BoundingVolume *volume);
   void set_bound(const BoundingVolume *volume);
   INLINE void clear_bounds();
   INLINE void clear_bounds();
@@ -519,6 +522,9 @@ private:
     // or GeomNode.
     // or GeomNode.
     CollideMask _into_collide_mask;
     CollideMask _into_collide_mask;
 
 
+    // The requested bounding volume type.
+    BoundingVolume::BoundsType _bounds_type;
+
     // This is the user bounding volume, which is only specified by a
     // This is the user bounding volume, which is only specified by a
     // user.  It defaults to NULL, which means an empty volume.
     // user.  It defaults to NULL, which means an empty volume.
     CPT(BoundingVolume) _user_bounds;
     CPT(BoundingVolume) _user_bounds;

+ 6 - 1
panda/src/pgui/pgItem.cxx

@@ -312,7 +312,12 @@ compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
   // First, get ourselves a fresh, empty bounding volume.
   // First, get ourselves a fresh, empty bounding volume.
   PT(BoundingVolume) bound;
   PT(BoundingVolume) bound;
 
 
-  if (bounds_type == BoundingVolume::BT_sphere) {
+  BoundingVolume::BoundsType btype = get_bounds_type();
+  if (btype == BoundingVolume::BT_default) {
+    btype = bounds_type;
+  }
+
+  if (btype == BoundingVolume::BT_sphere) {
     bound = new BoundingSphere;
     bound = new BoundingSphere;
   } else {
   } else {
     bound = new BoundingBox;
     bound = new BoundingBox;

+ 2 - 1
panda/src/putil/bam.h

@@ -33,12 +33,13 @@ static const unsigned short _bam_major_ver = 6;
 // Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
 // Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
 
 
 static const unsigned short _bam_first_minor_ver = 14;
 static const unsigned short _bam_first_minor_ver = 14;
-static const unsigned short _bam_minor_ver = 18;
+static const unsigned short _bam_minor_ver = 19;
 // Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
 // Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
 // Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
 // Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
 // Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
 // Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
 // Bumped to minor version 17 on 8/6/08 to add PartBundle::_anim_preload.
 // Bumped to minor version 17 on 8/6/08 to add PartBundle::_anim_preload.
 // Bumped to minor version 18 on 8/14/08 to add Texture::_simple_ram_image.
 // Bumped to minor version 18 on 8/14/08 to add Texture::_simple_ram_image.
+// Bumped to minor version 19 on 8/14/08 to add PandaNode::_bounds_type.
 
 
 
 
 #endif
 #endif