From 3790f2756cebce3cb0c06fd8290b226728cb656b Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 26 Mar 2002 00:09:33 +0000 Subject: [PATCH] implement qpNodePath.showBounds() --- panda/src/dgraph/qpdataNode.h | 2 +- panda/src/pgraph/Sources.pp | 3 + panda/src/pgraph/config_pgraph.cxx | 3 + panda/src/pgraph/cullTraverserData.cxx | 16 +-- panda/src/pgraph/cullTraverserData.h | 2 +- panda/src/pgraph/cullableObject.I | 17 +++ panda/src/pgraph/cullableObject.h | 5 +- panda/src/pgraph/pgraph_composite2.cxx | 1 + panda/src/pgraph/qpcullTraverser.cxx | 128 +++++++++++++++++++++- panda/src/pgraph/qpcullTraverser.h | 6 ++ panda/src/pgraph/qpnodePath.cxx | 54 +++++++++- panda/src/pgraph/qpnodePath.h | 2 + panda/src/pgraph/renderEffects.I | 21 ++++ panda/src/pgraph/renderEffects.cxx | 15 +++ panda/src/pgraph/renderEffects.h | 4 + panda/src/pgraph/showBoundsEffect.I | 28 +++++ panda/src/pgraph/showBoundsEffect.cxx | 140 +++++++++++++++++++++++++ panda/src/pgraph/showBoundsEffect.h | 74 +++++++++++++ 18 files changed, 503 insertions(+), 18 deletions(-) create mode 100644 panda/src/pgraph/showBoundsEffect.I create mode 100644 panda/src/pgraph/showBoundsEffect.cxx create mode 100644 panda/src/pgraph/showBoundsEffect.h diff --git a/panda/src/dgraph/qpdataNode.h b/panda/src/dgraph/qpdataNode.h index 0c0b870485..2eba9a68c1 100644 --- a/panda/src/dgraph/qpdataNode.h +++ b/panda/src/dgraph/qpdataNode.h @@ -84,7 +84,7 @@ PUBLISHED: void write_outputs(ostream &out) const; void write_connections(ostream &out) const; - //protected: +protected: int define_input(const string &name, TypeHandle data_type); int define_output(const string &name, TypeHandle data_type); diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index 57ea817845..8e7ee7609e 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -54,6 +54,7 @@ qpsceneGraphReducer.I qpsceneGraphReducer.h \ selectiveChildNode.I selectiveChildNode.h \ qpsequenceNode.I qpsequenceNode.h \ + showBoundsEffect.I showBoundsEffect.h \ texMatrixAttrib.I texMatrixAttrib.h \ textureApplyAttrib.I textureApplyAttrib.h \ textureAttrib.I textureAttrib.h \ @@ -112,6 +113,7 @@ qpsceneGraphReducer.cxx \ selectiveChildNode.cxx \ qpsequenceNode.cxx \ + showBoundsEffect.cxx \ texMatrixAttrib.cxx \ textureApplyAttrib.cxx \ textureAttrib.cxx \ @@ -172,6 +174,7 @@ qpsceneGraphReducer.I qpsceneGraphReducer.h \ selectiveChildNode.I selectiveChildNode.h \ qpsequenceNode.I qpsequenceNode.h \ + showBoundsEffect.I showBoundsEffect.h \ texMatrixAttrib.I texMatrixAttrib.h \ textureApplyAttrib.I textureApplyAttrib.h \ textureAttrib.I textureAttrib.h \ diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index aa69b3b011..e9b8993ff5 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -52,6 +52,7 @@ #include "renderState.h" #include "selectiveChildNode.h" #include "qpsequenceNode.h" +#include "showBoundsEffect.h" #include "texMatrixAttrib.h" #include "textureApplyAttrib.h" #include "textureAttrib.h" @@ -128,6 +129,7 @@ init_libpgraph() { RenderState::init_type(); SelectiveChildNode::init_type(); qpSequenceNode::init_type(); + ShowBoundsEffect::init_type(); TexMatrixAttrib::init_type(); TextureApplyAttrib::init_type(); TextureAttrib::init_type(); @@ -166,6 +168,7 @@ init_libpgraph() { RenderModeAttrib::register_with_read_factory(); RenderState::register_with_read_factory(); qpSequenceNode::register_with_read_factory(); + ShowBoundsEffect::register_with_read_factory(); TexMatrixAttrib::register_with_read_factory(); TextureApplyAttrib::register_with_read_factory(); TextureAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index 9ba14418c0..925f067e56 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -115,8 +115,8 @@ is_in_view_impl() { // actually culling an object we simply force it to be drawn in // red wireframe. _view_frustum = (GeometricBoundingVolume *)NULL; - CPT(RenderState) fake_effect = get_fake_view_frustum_cull_effect(); - _state = _state->compose(fake_effect); + CPT(RenderState) fake_state = get_fake_view_frustum_cull_state(); + _state = _state->compose(fake_state); } else if ((result & BoundingVolume::IF_all) != 0) { // The node and its descendants are completely enclosed within @@ -140,24 +140,24 @@ is_in_view_impl() { //////////////////////////////////////////////////////////////////// -// Function: CullTraverserData::get_fake_view_frustum_cull_effect +// Function: CullTraverserData::get_fake_view_frustum_cull_state // Access: Private, Static // Description: Returns a RenderState for rendering stuff in red // wireframe, strictly for the fake_view_frustum_cull // effect. //////////////////////////////////////////////////////////////////// CPT(RenderState) CullTraverserData:: -get_fake_view_frustum_cull_effect() { +get_fake_view_frustum_cull_state() { // Once someone asks for this pointer, we hold its reference count // and never free it. - static CPT(RenderState) effect = (const RenderState *)NULL; - if (effect == (const RenderState *)NULL) { - effect = RenderState::make + static CPT(RenderState) state = (const RenderState *)NULL; + if (state == (const RenderState *)NULL) { + state = RenderState::make (ColorAttrib::make_flat(Colorf(1.0f, 0.0f, 0.0f, 1.0f)), TextureAttrib::make_off(), RenderModeAttrib::make(RenderModeAttrib::M_wireframe), 1000); } - return effect; + return state; } diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h index c89fa55986..1d7d474d1a 100644 --- a/panda/src/pgraph/cullTraverserData.h +++ b/panda/src/pgraph/cullTraverserData.h @@ -77,7 +77,7 @@ public: private: bool is_in_view_impl(); - static CPT(RenderState) get_fake_view_frustum_cull_effect(); + static CPT(RenderState) get_fake_view_frustum_cull_state(); }; #include "cullTraverserData.I" diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index e13d4c015a..d8c2cb7063 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -45,6 +45,23 @@ CullableObject(const CullTraverserData &data, _next(next) { } + +//////////////////////////////////////////////////////////////////// +// Function: CullableObject::Constructor +// Access: Public +// Description: Creates a CullableObject based the indicated geom, +// with the indicated render state and transform. +//////////////////////////////////////////////////////////////////// +INLINE CullableObject:: +CullableObject(Geom *geom, const RenderState *state, + const TransformState *transform, + CullableObject *next) : + _geom(geom), + _state(state), + _transform(transform), + _next(next) +{ +} //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index 658ce1e852..96024b0f50 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -42,7 +42,10 @@ public: INLINE CullableObject(const CullTraverserData &data, qpGeomNode *geom_node, int i, CullableObject *next = NULL); - + INLINE CullableObject(Geom *geom, const RenderState *state, + const TransformState *transform, + CullableObject *next = NULL); + private: INLINE CullableObject(const CullableObject ©); INLINE void operator = (const CullableObject ©); diff --git a/panda/src/pgraph/pgraph_composite2.cxx b/panda/src/pgraph/pgraph_composite2.cxx index 2f35a97c0d..ab1fdf91a4 100644 --- a/panda/src/pgraph/pgraph_composite2.cxx +++ b/panda/src/pgraph/pgraph_composite2.cxx @@ -22,6 +22,7 @@ #include "qpsceneGraphReducer.cxx" #include "selectiveChildNode.cxx" #include "qpsequenceNode.cxx" +#include "showBoundsEffect.cxx" #include "test_pgraph.cxx" #include "texMatrixAttrib.cxx" #include "textureApplyAttrib.cxx" diff --git a/panda/src/pgraph/qpcullTraverser.cxx b/panda/src/pgraph/qpcullTraverser.cxx index 63c04af876..3fcce17610 100644 --- a/panda/src/pgraph/qpcullTraverser.cxx +++ b/panda/src/pgraph/qpcullTraverser.cxx @@ -25,6 +25,11 @@ #include "dcast.h" #include "qpgeomNode.h" #include "config_pgraph.h" +#include "boundingSphere.h" +#include "geomSphere.h" +#include "colorAttrib.h" +#include "renderModeAttrib.h" +#include "cullFaceAttrib.h" TypeHandle qpCullTraverser::_type_handle; @@ -89,11 +94,19 @@ traverse(CullTraverserData &data) { // optimization, we should tag nodes with these properties as // being "fancy", and skip this processing for non-fancy nodes. if (data.is_in_view(_camera_mask)) { - data.apply_transform_and_state(this); - PandaNode *node = data.node(); - const FogAttrib *fog = node->get_state()->get_fog(); + const RenderEffects *node_effects = node->get_effects(); + if (node_effects->has_show_bounds()) { + // If we should show the bounding volume for this node, make it + // up now. + show_bounds(data); + } + + data.apply_transform_and_state(this); + + const RenderState *node_state = node->get_state(); + const FogAttrib *fog = node_state->get_fog(); if (fog != (const FogAttrib *)NULL && fog->get_fog() != (qpFog *)NULL) { // If we just introduced a FogAttrib here, call adjust_to_camera() // now. This maybe isn't the perfect time to call it, but it's @@ -160,6 +173,104 @@ traverse_below(const CullTraverserData &data) { } } +//////////////////////////////////////////////////////////////////// +// Function: qpCullTraverser::show_bounds +// Access: Private +// Description: Draws an appropriate visualization of the node's +// external bounding volume. +//////////////////////////////////////////////////////////////////// +void qpCullTraverser:: +show_bounds(CullTraverserData &data) { + PandaNode *node = data.node(); + + PT(Geom) bounds_viz = make_bounds_viz(node->get_bound()); + if (bounds_viz != (Geom *)NULL) { + CullableObject *outer_viz = + new CullableObject(bounds_viz, get_bounds_outer_viz_state(), + data._render_transform); + _cull_handler->record_object(outer_viz); + + CullableObject *inner_viz = + new CullableObject(bounds_viz, get_bounds_inner_viz_state(), + data._render_transform); + _cull_handler->record_object(inner_viz); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpCullTraverser::make_bounds_viz +// Access: Private +// Description: Returns an appropriate visualization of the indicated +// bounding volume. +//////////////////////////////////////////////////////////////////// +PT(Geom) qpCullTraverser:: +make_bounds_viz(const BoundingVolume &vol) { + PT(Geom) geom; + if (vol.is_infinite()) { + // No way to draw an infinite bounding volume. + + } else if (vol.is_of_type(BoundingSphere::get_class_type())) { + const BoundingSphere *sphere = DCAST(BoundingSphere, &vol); + + geom = new GeomSphere; + PTA_Vertexf verts; + LPoint3f center = sphere->get_center(); + verts.push_back(center); + center[0] += sphere->get_radius(); + verts.push_back(center); + geom->set_coords(verts); + geom->set_num_prims(1); + + } else { + pgraph_cat.warning() + << "Don't know how to draw a representation of " + << vol.get_class_type() << "\n"; + } + + return geom; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpCullTraverser::get_bounds_outer_viz_state +// Access: Private, Static +// Description: Returns a RenderState for rendering the outside +// surfaces of the bounding volume visualizations. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) qpCullTraverser:: +get_bounds_outer_viz_state() { + // Once someone asks for this pointer, we hold its reference count + // and never free it. + static CPT(RenderState) state = (const RenderState *)NULL; + if (state == (const RenderState *)NULL) { + state = RenderState::make + (ColorAttrib::make_flat(Colorf(0.3f, 1.0f, 0.5f, 1.0f)), + RenderModeAttrib::make(RenderModeAttrib::M_wireframe), + CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise)); + } + return state; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpCullTraverser::get_bounds_inner_viz_state +// Access: Private, Static +// Description: Returns a RenderState for rendering the inside +// surfaces of the bounding volume visualizations. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) qpCullTraverser:: +get_bounds_inner_viz_state() { + // Once someone asks for this pointer, we hold its reference count + // and never free it. + static CPT(RenderState) state = (const RenderState *)NULL; + if (state == (const RenderState *)NULL) { + state = RenderState::make + (ColorAttrib::make_flat(Colorf(0.15f, 0.5f, 0.25f, 1.0f)), + RenderModeAttrib::make(RenderModeAttrib::M_wireframe), + CullFaceAttrib::make(CullFaceAttrib::M_cull_counter_clockwise)); + } + return state; +} + + //////////////////////////////////////////////////////////////////// // Function: qpCullTraverser::start_decal // Access: Private @@ -233,10 +344,17 @@ start_decal(const CullTraverserData &data) { CullableObject *qpCullTraverser:: r_get_decals(CullTraverserData &data, CullableObject *decals) { if (data.is_in_view(_camera_mask)) { - data.apply_transform_and_state(this); - PandaNode *node = data.node(); + const RenderEffects *node_effects = node->get_effects(); + if (node_effects->has_show_bounds()) { + // If we should show the bounding volume for this node, make it + // up now. + show_bounds(data); + } + + data.apply_transform_and_state(this); + // First, visit all of the node's children. int num_children = node->get_num_children(); if (node->has_selective_visibility()) { diff --git a/panda/src/pgraph/qpcullTraverser.h b/panda/src/pgraph/qpcullTraverser.h index 38c6681ce1..c287b1f9d8 100644 --- a/panda/src/pgraph/qpcullTraverser.h +++ b/panda/src/pgraph/qpcullTraverser.h @@ -21,6 +21,7 @@ #include "pandabase.h" +#include "geom.h" #include "renderState.h" #include "transformState.h" #include "geometricBoundingVolume.h" @@ -73,6 +74,11 @@ public: void traverse_below(const CullTraverserData &data); private: + void show_bounds(CullTraverserData &data); + PT(Geom) make_bounds_viz(const BoundingVolume &vol); + CPT(RenderState) get_bounds_outer_viz_state(); + CPT(RenderState) get_bounds_inner_viz_state(); + void start_decal(const CullTraverserData &data); CullableObject *r_get_decals(CullTraverserData &data, CullableObject *decals); diff --git a/panda/src/pgraph/qpnodePath.cxx b/panda/src/pgraph/qpnodePath.cxx index 876d4c7108..b25d735edb 100644 --- a/panda/src/pgraph/qpnodePath.cxx +++ b/panda/src/pgraph/qpnodePath.cxx @@ -33,6 +33,7 @@ #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "billboardEffect.h" +#include "showBoundsEffect.h" #include "transparencyAttrib.h" #include "materialPool.h" #include "look_at.h" @@ -2423,7 +2424,7 @@ prepare_scene(GraphicsStateGuardianBase *gsg, bool force_retained_mode) { void qpNodePath:: show_bounds() { nassertv_always(!is_empty()); - nassertv(false); + node()->set_effect(ShowBoundsEffect::make()); } //////////////////////////////////////////////////////////////////// @@ -2435,7 +2436,7 @@ show_bounds() { void qpNodePath:: hide_bounds() { nassertv_always(!is_empty()); - nassertv(false); + node()->clear_effect(ShowBoundsEffect::get_class_type()); } //////////////////////////////////////////////////////////////////// @@ -2452,6 +2453,28 @@ get_bounds() const { return node()->get_bound().make_copy(); } +//////////////////////////////////////////////////////////////////// +// Function: qpNodePath::force_recompute_bounds +// Access: Published +// Description: Forces the recomputing of all the bounding volumes at +// every node in the subgraph beginning at this node and +// below. +// +// This should not normally need to be called, since the +// bounding volumes are supposed to be recomputed +// automatically when necessary. It may be useful when +// debugging, to verify that the bounding volumes have +// not become inadvertently stale; it may also be useful +// to force animated characters to update their bounding +// volumes (which does not presently happen +// automatically). +//////////////////////////////////////////////////////////////////// +void qpNodePath:: +force_recompute_bounds() { + nassertv_always(!is_empty()); + r_force_recompute_bounds(node()); +} + //////////////////////////////////////////////////////////////////// // Function: qpNodePath::write_bounds // Access: Published @@ -2902,6 +2925,33 @@ r_adjust_all_priorities(PandaNode *node, int adjustment) { } } +//////////////////////////////////////////////////////////////////// +// Function: qpNodePath::r_force_recompute_bounds +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void qpNodePath:: +r_force_recompute_bounds(PandaNode *node) { + if (node->is_geom_node()) { + qpGeomNode *gnode; + DCAST_INTO_V(gnode, node); + + int num_geoms = gnode->get_num_geoms(); + for (int i = 0; i < num_geoms; i++) { + gnode->get_geom(i)->mark_bound_stale(); + } + } + + node->mark_bound_stale(); + + // Now consider children. + PandaNode::Children cr = node->get_children(); + int num_children = cr.get_num_children(); + for (int i = 0; i < num_children; i++) { + r_force_recompute_bounds(cr.get_child(i)); + } +} + //////////////////////////////////////////////////////////////////// // Function: qpNodePath::r_calc_tight_bounds // Access: Private diff --git a/panda/src/pgraph/qpnodePath.h b/panda/src/pgraph/qpnodePath.h index ef6797480a..0c2be06a0c 100644 --- a/panda/src/pgraph/qpnodePath.h +++ b/panda/src/pgraph/qpnodePath.h @@ -483,6 +483,7 @@ PUBLISHED: void show_bounds(); void hide_bounds(); PT(BoundingVolume) get_bounds() const; + void force_recompute_bounds(); void write_bounds(ostream &out) const; bool calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point); @@ -515,6 +516,7 @@ private: void r_adjust_all_priorities(PandaNode *node, int adjustment); + void r_force_recompute_bounds(PandaNode *node); void r_calc_tight_bounds(PandaNode *node, LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const TransformState *transform); diff --git a/panda/src/pgraph/renderEffects.I b/panda/src/pgraph/renderEffects.I index 396bc2b6d5..0be1e528cb 100644 --- a/panda/src/pgraph/renderEffects.I +++ b/panda/src/pgraph/renderEffects.I @@ -180,3 +180,24 @@ has_decal() const { } return ((_flags & F_has_decal) != 0); } + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::has_show_bounds +// Access: Public +// Description: This function is provided as an optimization, to +// speed up the render-time checking for the existance +// of a ShowBoundsEffect on this state. It returns true +// if a ShowBoundsEffect exists, false otherwise. Note +// that since there is no additional information stored +// on the ShowBoundsEffect, there's no point in +// returning it if it exists. +//////////////////////////////////////////////////////////////////// +INLINE bool RenderEffects:: +has_show_bounds() const { + if ((_flags & F_checked_show_bounds) == 0) { + // We pretend this function is const, even though it transparently + // modifies the internal show_bounds cache. + ((RenderEffects *)this)->determine_show_bounds(); + } + return ((_flags & F_has_show_bounds) != 0); +} diff --git a/panda/src/pgraph/renderEffects.cxx b/panda/src/pgraph/renderEffects.cxx index 9aa197f5a6..c10c93f712 100644 --- a/panda/src/pgraph/renderEffects.cxx +++ b/panda/src/pgraph/renderEffects.cxx @@ -19,6 +19,7 @@ #include "renderEffects.h" #include "billboardEffect.h" #include "decalEffect.h" +#include "showBoundsEffect.h" #include "config_pgraph.h" #include "bamReader.h" #include "bamWriter.h" @@ -459,6 +460,20 @@ determine_decal() { _flags |= F_checked_decal; } +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::determine_show_bounds +// Access: Private +// Description: This is the private implementation of has_show_bounds(). +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +determine_show_bounds() { + const RenderEffect *effect = get_effect(ShowBoundsEffect::get_class_type()); + if (effect != (const RenderEffect *)NULL) { + _flags |= F_has_show_bounds; + } + _flags |= F_checked_show_bounds; +} + //////////////////////////////////////////////////////////////////// // Function: RenderEffects::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h index 43c8a016ad..e82f11a91e 100644 --- a/panda/src/pgraph/renderEffects.h +++ b/panda/src/pgraph/renderEffects.h @@ -88,11 +88,13 @@ PUBLISHED: public: INLINE const BillboardEffect *get_billboard() const; INLINE bool has_decal() const; + INLINE bool has_show_bounds() const; private: static CPT(RenderEffects) return_new(RenderEffects *state); void determine_billboard(); void determine_decal(); + void determine_show_bounds(); private: typedef pset > States; @@ -131,6 +133,8 @@ private: F_checked_billboard = 0x0001, F_checked_decal = 0x0002, F_has_decal = 0x0004, + F_checked_show_bounds = 0x0008, + F_has_show_bounds = 0x0010, }; short _flags; diff --git a/panda/src/pgraph/showBoundsEffect.I b/panda/src/pgraph/showBoundsEffect.I new file mode 100644 index 0000000000..c932abb59e --- /dev/null +++ b/panda/src/pgraph/showBoundsEffect.I @@ -0,0 +1,28 @@ +// Filename: showBoundsEffect.I +// Created by: drose (25Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::Constructor +// Access: Private +// Description: Use ShowBoundsEffect::make() to construct a new +// ShowBoundsEffect object. +//////////////////////////////////////////////////////////////////// +INLINE ShowBoundsEffect:: +ShowBoundsEffect() { +} diff --git a/panda/src/pgraph/showBoundsEffect.cxx b/panda/src/pgraph/showBoundsEffect.cxx new file mode 100644 index 0000000000..c5d15c6a00 --- /dev/null +++ b/panda/src/pgraph/showBoundsEffect.cxx @@ -0,0 +1,140 @@ +// Filename: showBoundsEffect.cxx +// Created by: drose (25Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "showBoundsEffect.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" + +TypeHandle ShowBoundsEffect::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::make +// Access: Published, Static +// Description: Constructs a new ShowBoundsEffect object. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffect) ShowBoundsEffect:: +make() { + ShowBoundsEffect *effect = new ShowBoundsEffect; + return return_new(effect); +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::safe_to_combine +// Access: Public, Virtual +// Description: Returns true if this kind of effect can safely be +// combined with sibling nodes that share the exact same +// effect, or false if this is not a good idea. +//////////////////////////////////////////////////////////////////// +bool ShowBoundsEffect:: +safe_to_combine() const { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::compare_to_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived ShowBoundsEffect +// types to return a unique number indicating whether +// this ShowBoundsEffect is equivalent to the other one. +// +// This should return 0 if the two ShowBoundsEffect objects +// are equivalent, a number less than zero if this one +// should be sorted before the other one, and a number +// greater than zero otherwise. +// +// This will only be called with two ShowBoundsEffect +// objects whose get_type() functions return the same. +//////////////////////////////////////////////////////////////////// +int ShowBoundsEffect:: +compare_to_impl(const RenderEffect *other) const { + // All ShowBoundsEffects are equivalent--there are no properties to + // store. + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::make_default_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived ShowBoundsEffect +// types to specify what the default property for a +// ShowBoundsEffect of this type should be. +// +// This should return a newly-allocated ShowBoundsEffect of +// the same type that corresponds to whatever the +// standard default for this kind of ShowBoundsEffect is. +//////////////////////////////////////////////////////////////////// +RenderEffect *ShowBoundsEffect:: +make_default_impl() const { + return new ShowBoundsEffect; +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// ShowBoundsEffect. +//////////////////////////////////////////////////////////////////// +void ShowBoundsEffect:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void ShowBoundsEffect:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderEffect::write_datagram(manager, dg); +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type ShowBoundsEffect is encountered +// in the Bam file. It should create the ShowBoundsEffect +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *ShowBoundsEffect:: +make_from_bam(const FactoryParams ¶ms) { + ShowBoundsEffect *effect = new ShowBoundsEffect; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + effect->fillin(scan, manager); + + return effect; +} + +//////////////////////////////////////////////////////////////////// +// Function: ShowBoundsEffect::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new ShowBoundsEffect. +//////////////////////////////////////////////////////////////////// +void ShowBoundsEffect:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderEffect::fillin(scan, manager); +} diff --git a/panda/src/pgraph/showBoundsEffect.h b/panda/src/pgraph/showBoundsEffect.h new file mode 100644 index 0000000000..87900d0856 --- /dev/null +++ b/panda/src/pgraph/showBoundsEffect.h @@ -0,0 +1,74 @@ +// Filename: showBoundsEffect.h +// Created by: drose (25Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef SHOWBOUNDSEFFECT_H +#define SHOWBOUNDSEFFECT_H + +#include "pandabase.h" + +#include "renderEffect.h" + +//////////////////////////////////////////////////////////////////// +// Class : ShowBoundsEffect +// Description : Applied to a GeomNode to cause a visible bounding +// volume to be drawn for this node. This is generally +// used only during development to help identify +// bounding volume issues. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA ShowBoundsEffect : public RenderEffect { +private: + INLINE ShowBoundsEffect(); + +PUBLISHED: + static CPT(RenderEffect) make(); + +protected: + virtual bool safe_to_combine() const; + virtual int compare_to_impl(const RenderEffect *other) const; + virtual RenderEffect *make_default_impl() const; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderEffect::init_type(); + register_type(_type_handle, "ShowBoundsEffect", + RenderEffect::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "showBoundsEffect.I" + +#endif +