From 3a88955760cf0f8f39513c4ebc91c14a54aa8abd Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 20 Apr 2005 20:24:21 +0000 Subject: [PATCH] unify() --- panda/src/gobj/qpgeom.I | 27 ++++++++++-- panda/src/gobj/qpgeom.cxx | 67 +++++++++++++++++++++++++++++ panda/src/gobj/qpgeom.h | 2 + panda/src/gobj/qpgeomLines.cxx | 8 ++-- panda/src/gobj/qpgeomLinestrips.cxx | 8 ++-- panda/src/gobj/qpgeomPoints.cxx | 8 ++-- panda/src/gobj/qpgeomTriangles.cxx | 8 ++-- panda/src/gobj/qpgeomTrifans.cxx | 8 ++-- panda/src/gobj/qpgeomTristrips.cxx | 8 ++-- 9 files changed, 122 insertions(+), 22 deletions(-) diff --git a/panda/src/gobj/qpgeom.I b/panda/src/gobj/qpgeom.I index 6fc44fddef..dfa5eafecd 100644 --- a/panda/src/gobj/qpgeom.I +++ b/panda/src/gobj/qpgeom.I @@ -20,10 +20,13 @@ //////////////////////////////////////////////////////////////////// // Function: qpGeom::get_primitive_type // Access: Published -// Description: Returns the primitive type that is common to all -// GeomPrimitives added within the Geom. All nested -// primitives within a particular Geom must be the same -// type. +// Description: Returns the fundamental primitive type that is common +// to all GeomPrimitives added within the Geom. All +// nested primitives within a particular Geom must be +// the same type (that is, you can mix triangles and +// tristrips, because they are both the same fundamental +// type PT_polygons, but you cannot mix triangles and +// points withn the same Geom). //////////////////////////////////////////////////////////////////// INLINE qpGeom::PrimitiveType qpGeom:: get_primitive_type() const { @@ -165,6 +168,22 @@ rotate() const { return new_geom; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::unify +// Access: Published +// Description: Unifies all of the primitives contained within this +// Geom into a single primitive object. This may +// require decomposing the primitives if, for instance, +// the Geom contains both triangle strips and triangle +// fans. +//////////////////////////////////////////////////////////////////// +INLINE CPT(qpGeom) qpGeom:: +unify() const { + PT(qpGeom) new_geom = new qpGeom(*this); + new_geom->unify_in_place(); + return new_geom; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::get_modified // Access: Published diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 3a8fd5f22f..2ee7d16bd5 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -448,6 +448,73 @@ rotate_in_place() { nassertv(all_is_valid); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::unify_in_place +// Access: Published +// Description: Unifies all of the primitives contained within this +// Geom into a single primitive object. This may +// require decomposing the primitives if, for instance, +// the Geom contains both triangle strips and triangle +// fans. +//////////////////////////////////////////////////////////////////// +void qpGeom:: +unify_in_place() { + if (get_num_primitives() <= 1) { + // If we don't have more than one primitive to start with, no need + // to do anything. + return; + } + + clear_cache(); + CDWriter cdata(_cycler); + + PT(qpGeomPrimitive) new_prim; + + Primitives::const_iterator pi; + for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) { + CPT(qpGeomPrimitive) primitive = (*pi); + if (new_prim == (qpGeomPrimitive *)NULL) { + // The first primitive type we come across is copied directly. + new_prim = primitive->make_copy(); + } else { + // Thereafter, we must try to merge primitives. If they are not + // the same type, we have to decompose both of them. + if (new_prim->get_type() != primitive->get_type()) { + CPT(qpGeomPrimitive) decomposed = new_prim->decompose(); + new_prim = (qpGeomPrimitive *)decomposed.p(); + primitive = primitive->decompose(); + + nassertv(new_prim->get_type() == primitive->get_type()); + } + + // Now simply copy in the vertices. + int num_primitives = primitive->get_num_primitives(); + for (int pi = 0; pi < num_primitives; ++pi) { + int start = primitive->get_primitive_start(pi); + int end = primitive->get_primitive_end(pi); + for (int vi = start; vi < end; ++vi) { + new_prim->add_vertex(primitive->get_vertex(vi)); + } + new_prim->close_primitive(); + } + } + } + + // At the end of the day, we have just one primitive, which becomes + // the one primitive in our list of primitives. + nassertv(new_prim->check_valid(cdata->_data)); + + // The new primitive, naturally, inherits the Geom's overall shade + // model. + new_prim->set_shade_model(cdata->_shade_model); + + cdata->_primitives.clear(); + cdata->_primitives.push_back(new_prim); + + cdata->_modified = qpGeom::get_next_modified(); + reset_geom_rendering(cdata); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::get_num_bytes // Access: Published diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index ea503ec99e..adbf866154 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -90,9 +90,11 @@ PUBLISHED: INLINE CPT(qpGeom) decompose() const; INLINE CPT(qpGeom) rotate() const; + INLINE CPT(qpGeom) unify() const; void decompose_in_place(); void rotate_in_place(); + void unify_in_place(); int get_num_bytes() const; INLINE UpdateSeq get_modified() const; diff --git a/panda/src/gobj/qpgeomLines.cxx b/panda/src/gobj/qpgeomLines.cxx index 17ba50c15a..0ef0ed60cb 100644 --- a/panda/src/gobj/qpgeomLines.cxx +++ b/panda/src/gobj/qpgeomLines.cxx @@ -69,9 +69,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomLines:: get_primitive_type() const { diff --git a/panda/src/gobj/qpgeomLinestrips.cxx b/panda/src/gobj/qpgeomLinestrips.cxx index 56243b67aa..b28db229bf 100644 --- a/panda/src/gobj/qpgeomLinestrips.cxx +++ b/panda/src/gobj/qpgeomLinestrips.cxx @@ -71,9 +71,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomLinestrips:: get_primitive_type() const { diff --git a/panda/src/gobj/qpgeomPoints.cxx b/panda/src/gobj/qpgeomPoints.cxx index 415aa1523d..b3dcf0b606 100644 --- a/panda/src/gobj/qpgeomPoints.cxx +++ b/panda/src/gobj/qpgeomPoints.cxx @@ -69,9 +69,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomPoints:: get_primitive_type() const { diff --git a/panda/src/gobj/qpgeomTriangles.cxx b/panda/src/gobj/qpgeomTriangles.cxx index 45fb05a8bf..0f679443a3 100644 --- a/panda/src/gobj/qpgeomTriangles.cxx +++ b/panda/src/gobj/qpgeomTriangles.cxx @@ -70,9 +70,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomTriangles:: get_primitive_type() const { diff --git a/panda/src/gobj/qpgeomTrifans.cxx b/panda/src/gobj/qpgeomTrifans.cxx index 8de3d06b79..2eafff97b2 100644 --- a/panda/src/gobj/qpgeomTrifans.cxx +++ b/panda/src/gobj/qpgeomTrifans.cxx @@ -70,9 +70,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomTrifans:: get_primitive_type() const { diff --git a/panda/src/gobj/qpgeomTristrips.cxx b/panda/src/gobj/qpgeomTristrips.cxx index 0f3b0eb7e7..54e123ed60 100644 --- a/panda/src/gobj/qpgeomTristrips.cxx +++ b/panda/src/gobj/qpgeomTristrips.cxx @@ -71,9 +71,11 @@ make_copy() const { // Access: Public, Virtual // Description: Returns the fundamental rendering type of this // primitive: whether it is points, lines, or polygons. -// This is used primarily to set up the appropriate -// antialiasing settings when AntialiasAttrib::M_auto is -// in effect. +// +// This is used to set up the appropriate antialiasing +// settings when AntialiasAttrib::M_auto is in effect; +// it also implies the type of primitive that will be +// produced when decompose() is called. //////////////////////////////////////////////////////////////////// qpGeomPrimitive::PrimitiveType qpGeomTristrips:: get_primitive_type() const {