diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index 3515bef04a..3376d4c7d2 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -377,7 +377,7 @@ r_copy_char(PandaNode *dest, const PandaNode *source, //////////////////////////////////////////////////////////////////// PT(Geom) Character:: copy_geom(const Geom *source, const Character *from) { - if (source->is_of_type(qpGeom::get_class_type())) { + if (source->is_qpgeom()) { CPT(qpGeom) qpsource = DCAST(qpGeom, source); CPT(qpGeomVertexFormat) format = qpsource->get_vertex_data()->get_format(); if (format->get_animation().get_animation_type() == qpGeom::AT_none) { diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index 38eb3eee44..9ccbd339a1 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/panda/src/collide/collisionTraverser.cxx @@ -741,7 +741,7 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom, ci = _colliders.find(entry.get_from_node_path()); nassertv(ci != _colliders.end()); - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { const qpGeom *qpgeom = DCAST(qpGeom, geom); if (qpgeom->get_primitive_type() == qpGeom::PT_polygons) { const qpGeomVertexData *data =qpgeom->get_vertex_data(); diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index be46ce9e5d..b375a7d258 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -601,7 +601,7 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { const LMatrix3f &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv; - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, geom); // Iterate through all the vertices in the Geom. @@ -812,7 +812,7 @@ make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera, //////////////////////////////////////////////////////////////////// PT(Geom) ProjectionScreen:: make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4f &rel_mat) { - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { PT(qpGeom) new_geom = new qpGeom(*DCAST(qpGeom, geom)); qpGeomVertexRewriter vertex(new_geom->modify_vertex_data(), diff --git a/panda/src/egg2pg/config_egg2pg.cxx b/panda/src/egg2pg/config_egg2pg.cxx index 5f96edc02d..1fd314035c 100644 --- a/panda/src/egg2pg/config_egg2pg.cxx +++ b/panda/src/egg2pg/config_egg2pg.cxx @@ -62,6 +62,14 @@ ConfigVariableDouble egg_flatten_radius "the user to specify what should be considered \"small\". Set " "it to 0.0 to disable this feature.")); +ConfigVariableBool egg_unify +("egg-unify", true, + PRC_DESC("When this is true, then in addition to flattening the scene graph " + "nodes, the egg loader will also as many Geoms as possible within " + "a given node into a single Geom. This has theoretical performance " + "benefits, especially on higher-end graphics cards, but it also " + "slightly slows down egg loading.")); + ConfigVariableBool egg_combine_geoms ("egg-combine-geoms", false, PRC_DESC("Set this true to combine sibling GeomNodes into a single GeomNode, " diff --git a/panda/src/egg2pg/config_egg2pg.h b/panda/src/egg2pg/config_egg2pg.h index bb5e9ecae4..64739136a5 100644 --- a/panda/src/egg2pg/config_egg2pg.h +++ b/panda/src/egg2pg/config_egg2pg.h @@ -41,6 +41,7 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_filters; extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_clamp; extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_decals; extern EXPCL_PANDAEGG ConfigVariableBool egg_flatten; +extern EXPCL_PANDAEGG ConfigVariableBool egg_unify; extern EXPCL_PANDAEGG ConfigVariableDouble egg_flatten_radius; extern EXPCL_PANDAEGG ConfigVariableBool egg_combine_geoms; extern EXPCL_PANDAEGG ConfigVariableBool egg_show_collision_solids; diff --git a/panda/src/egg2pg/load_egg_file.cxx b/panda/src/egg2pg/load_egg_file.cxx index 20b9e4b581..7754feb36c 100644 --- a/panda/src/egg2pg/load_egg_file.cxx +++ b/panda/src/egg2pg/load_egg_file.cxx @@ -48,9 +48,14 @@ load_from_loader(EggLoader &loader) { } int num_reduced = gr.flatten(loader._root, combine_siblings_bits); - // gr.collect_vertex_data(loader._root); - // gr.unify(loader._root); egg2pg_cat.info() << "Flattened " << num_reduced << " nodes.\n"; + if (egg_unify) { + gr.collect_vertex_data(loader._root); + gr.unify(loader._root); + if (egg2pg_cat.is_debug()) { + egg2pg_cat.debug() << "Unified.\n"; + } + } } return loader._root; diff --git a/panda/src/express/dcast.T b/panda/src/express/dcast.T index 80693fc68d..599287d862 100644 --- a/panda/src/express/dcast.T +++ b/panda/src/express/dcast.T @@ -54,7 +54,7 @@ _dcast_get_typehandle(WantType *) { template INLINE WantType * _dcast(WantType *, TypedObject *ptr) { -#ifndef NDEBUG +#ifdef DO_DCAST TypeHandle want_handle = _dcast_get_typehandle((WantType *)0); if (!_dcast_verify(want_handle, sizeof(WantType), ptr)) { return (WantType *)NULL; @@ -75,7 +75,7 @@ _dcast(WantType *, TypedObject *ptr) { template INLINE const WantType * _dcast(WantType *, const TypedObject *ptr) { -#ifndef NDEBUG +#ifdef DO_DCAST TypeHandle want_handle = _dcast_get_typehandle((WantType *)0); if (!_dcast_verify(want_handle, sizeof(WantType), ptr)) { return (const WantType *)NULL; diff --git a/panda/src/express/dcast.cxx b/panda/src/express/dcast.cxx index 1a609de337..559dbd068f 100644 --- a/panda/src/express/dcast.cxx +++ b/panda/src/express/dcast.cxx @@ -24,7 +24,7 @@ #endif -#ifndef NDEBUG +#ifdef DO_DCAST //////////////////////////////////////////////////////////////////// // Function: _dcast_verify // Description: This function performs the actual check that the @@ -67,5 +67,6 @@ _dcast_verify(TypeHandle want_handle, size_t want_size, return true; } -#endif // NDEBUG +#endif // DO_DCAST + diff --git a/panda/src/express/dcast.h b/panda/src/express/dcast.h index 4eef5bb90c..acbbd1d17d 100644 --- a/panda/src/express/dcast.h +++ b/panda/src/express/dcast.h @@ -68,12 +68,12 @@ INLINE WantType *_dcast_ref(WantType *&, TypedObject *ptr); template INLINE const WantType *_dcast_ref(WantType *&, const TypedObject *ptr); -#ifndef NDEBUG +#ifdef DO_DCAST // _dcast_verify performs the actual verification. EXPCL_PANDAEXPRESS bool _dcast_verify(TypeHandle want_handle, size_t want_size, const TypedObject *ptr); -#endif // NDEBUG +#endif // DO_DCAST #define DCAST_INTO_V(to_pointer, from_pointer) \ { \ diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index c32ea7f856..1b66b0a064 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2846,7 +2846,7 @@ GeomContext *CLP(GraphicsStateGuardian):: prepare_geom(Geom *geom) { // Temporary test until the experimental Geom rewrite becomes the // actual Geom implementation. - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { CLP(GeomContext) *ggc = new CLP(GeomContext)(geom); return ggc; diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index ded68ae0e6..e5c9d52c89 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -567,6 +567,18 @@ is_dynamic() const { return (_vindex != (ushort*)0L); } +//////////////////////////////////////////////////////////////////// +// Function: Geom::is_qpgeom +// Access: Published, Virtual +// Description: Returns true if this is a new-style qpGeom class, +// false otherwise. Temporary until the experimental +// Geom rewrite becomes the actual Geom implementation. +//////////////////////////////////////////////////////////////////// +bool Geom:: +is_qpgeom() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: Geom::prepare // Access: Published diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index a972e674f1..ee1ac63f86 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -171,6 +171,9 @@ public: PUBLISHED: virtual bool is_dynamic() const; + // Temporary. + virtual bool is_qpgeom() const; + INLINE GeomBindType get_binding(int attr) const; INLINE bool has_any_texcoords() const; INLINE bool has_texcoords(const InternalName *name) const; diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index ed98d28273..ceabfc3a1a 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -105,6 +105,18 @@ make_copy() const { return new qpGeom(*this); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::is_qpgeom +// Access: Published, Virtual +// Description: Returns true if this is a new-style qpGeom class, +// false otherwise. Temporary until the experimental +// Geom rewrite becomes the actual Geom implementation. +//////////////////////////////////////////////////////////////////// +bool qpGeom:: +is_qpgeom() const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::set_usage_hint // Access: Published diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index e8b9907a2f..62f7d27ef3 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -66,6 +66,7 @@ PUBLISHED: // Temporary. virtual Geom *make_copy() const; + virtual bool is_qpgeom() const; INLINE PrimitiveType get_primitive_type() const; INLINE ShadeModel get_shade_model() const; diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index f8e46c2ec6..27366be567 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -809,7 +809,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name, const GeomInfo &geom_info = (*gi); const Geom *orig_geom = geom_info._geom_node->get_geom(geom_info._index); - if (orig_geom->is_of_type(qpGeom::get_class_type())) { + if (orig_geom->is_qpgeom()) { PT(qpGeom) geom = new qpGeom(*DCAST(qpGeom, orig_geom)); PT(qpGeomVertexData) vdata = geom->modify_vertex_data(); vdata->set_usage_hint(qpGeom::UH_stream); diff --git a/panda/src/particlesystem/spriteParticleRenderer.cxx b/panda/src/particlesystem/spriteParticleRenderer.cxx index a328e07441..4aba06fd74 100644 --- a/panda/src/particlesystem/spriteParticleRenderer.cxx +++ b/panda/src/particlesystem/spriteParticleRenderer.cxx @@ -147,7 +147,7 @@ set_from_node(const NodePath &node_path, bool size_from_texels) { TexCoordf min_uv, max_uv; Vertexf min_xyz, max_xyz; - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { const qpGeom *qpgeom = DCAST(qpGeom, geom); qpGeomVertexReader texcoord(qpgeom->get_vertex_data()); qpGeomVertexReader vertex(qpgeom->get_vertex_data()); diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 13ca1e9a9e..2325c5fd3a 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -46,7 +46,7 @@ munge_geom(GraphicsStateGuardianBase *gsg, if (_geom != (Geom *)NULL) { // Temporary test and dcast until the experimental Geom rewrite // becomes the actual Geom rewrite. - if (_geom->is_of_type(qpGeom::get_class_type())) { + if (_geom->is_qpgeom()) { _munger = munger; CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom); _munged_data = qpgeom->get_vertex_data(); diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 729ec35fff..e64924c52f 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -354,7 +354,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const Geom *geom = get_geom(i); // Temporary test until the experimental Geom rewrite is final. - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { const qpGeom *qpgeom = DCAST(qpGeom, geom); qpgeom->calc_tight_bounds(min_point, max_point, found_any, qpgeom->get_vertex_data()->animate_vertices(), @@ -481,11 +481,11 @@ unify() { const GeomEntry &entry = (*gi); bool unified = false; - if (entry._geom->is_of_type(qpGeom::get_class_type())) { + if (entry._geom->is_qpgeom()) { Geoms::iterator gj; for (gj = new_geoms.begin(); gj != new_geoms.end() && !unified; ++gj) { GeomEntry &new_entry = (*gj); - if (new_entry._geom->is_of_type(qpGeom::get_class_type())) { + if (new_entry._geom->is_qpgeom()) { if (entry._state == new_entry._state) { // Both states match, so try to combine the primitives. if (DCAST(qpGeom, new_entry._geom)->copy_primitives_from @@ -512,7 +512,7 @@ unify() { // Finally, go back through and unify the resulting geom(s). for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) { const GeomEntry &entry = (*gi); - if (entry._geom->is_of_type(qpGeom::get_class_type())) { + if (entry._geom->is_qpgeom()) { DCAST(qpGeom, entry._geom)->unify_in_place(); } } diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index ae93830838..8719d1e0cc 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -71,7 +71,7 @@ transform_vertices(Geom *geom, const LMatrix4f &mat) { nassertr(geom != (Geom *)NULL, false); - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceVertices sv; @@ -212,7 +212,7 @@ transform_texcoords(Geom *geom, const InternalName *from_name, bool transformed = false; nassertr(geom != (Geom *)NULL, false); - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceTexCoords st; @@ -331,7 +331,7 @@ bool GeomTransformer:: set_color(Geom *geom, const Colorf &color) { bool transformed = false; - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceColors sc; @@ -411,7 +411,7 @@ transform_colors(Geom *geom, const LVecBase4f &scale) { nassertr(geom != (Geom *)NULL, false); - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceColors sc; @@ -763,7 +763,7 @@ collect_vertex_data(GeomNode *node, int collect_bits) { GeomNode::Geoms::iterator gi; for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) { GeomNode::GeomEntry &entry = (*gi); - if (entry._geom->is_of_type(qpGeom::get_class_type())) { + if (entry._geom->is_qpgeom()) { PT(qpGeom) new_geom = DCAST(qpGeom, entry._geom->make_copy()); entry._geom = new_geom; diff --git a/panda/src/pgraph/sceneGraphReducer.cxx b/panda/src/pgraph/sceneGraphReducer.cxx index f8bb863cdd..09171e0c9d 100644 --- a/panda/src/pgraph/sceneGraphReducer.cxx +++ b/panda/src/pgraph/sceneGraphReducer.cxx @@ -684,7 +684,7 @@ r_make_nonindexed(PandaNode *node, int nonindexed_bits) { GeomNode *geom_node = DCAST(GeomNode, node); int num_geoms = geom_node->get_num_geoms(); for (int i = 0; i < num_geoms; ++i) { - if (geom_node->get_geom(i)->is_of_type(qpGeom::get_class_type())) { + if (geom_node->get_geom(i)->is_qpgeom()) { const qpGeom *geom = DCAST(qpGeom, geom_node->get_geom(i)); // Check whether the geom is animated or dynamic, and skip it diff --git a/panda/src/text/staticTextFont.cxx b/panda/src/text/staticTextFont.cxx index 27cfc41aeb..8d5017420c 100644 --- a/panda/src/text/staticTextFont.cxx +++ b/panda/src/text/staticTextFont.cxx @@ -196,7 +196,7 @@ find_character_gsets(PandaNode *root, CPT(Geom) &ch, for (int i = 0; i < geode->get_num_geoms(); i++) { const Geom *geom = geode->get_geom(i); - if (geom->is_of_type(qpGeom::get_class_type())) { + if (geom->is_qpgeom()) { CPT(qpGeom) qpgeom = DCAST(qpGeom, geom); bool found_points = false; diff --git a/panda/src/text/textGlyph.I b/panda/src/text/textGlyph.I index 14c0ecae69..13563c55e5 100644 --- a/panda/src/text/textGlyph.I +++ b/panda/src/text/textGlyph.I @@ -83,7 +83,7 @@ get_geom(qpGeom::UsageHint usage_hint) const { // it is also critical for the DynamicTextGlyph, which depends on // this behavior to properly count references to this glyph. PT(Geom) new_geom = _geom->make_copy(); - if (new_geom->is_of_type(qpGeom::get_class_type())) { + if (new_geom->is_qpgeom()) { qpGeom *qpgeom = DCAST(qpGeom, new_geom); qpgeom->set_usage_hint(usage_hint); if (qpgeom->get_vertex_data()->get_usage_hint() != usage_hint) {