diff --git a/panda/src/gobj/geom.I b/panda/src/gobj/geom.I index f34df85a75..acf7b61745 100644 --- a/panda/src/gobj/geom.I +++ b/panda/src/gobj/geom.I @@ -242,6 +242,19 @@ make_points() const { return new_geom; } +//////////////////////////////////////////////////////////////////// +// Function: Geom::make_patches +// Access: Published +// Description: Returns a new Geom with each primitive converted +// into a patch. Calls decompose() first. +//////////////////////////////////////////////////////////////////// +INLINE PT(Geom) Geom:: +make_patches() const { + PT(Geom) new_geom = make_copy(); + new_geom->make_patches_in_place(); + return new_geom; +} + //////////////////////////////////////////////////////////////////// // Function: Geom::get_modified // Access: Published diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 1a4251e5f6..da20e629b4 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -788,6 +788,43 @@ make_points_in_place() { nassertv(all_is_valid); } +//////////////////////////////////////////////////////////////////// +// Function: Geom::make_patches_in_place +// Access: Published +// Description: Replaces the GeomPrimitives within this Geom with +// corresponding GeomPatches. See +// GeomPrimitive::make_patches(). +// +// Don't call this in a downstream thread unless you +// don't mind it blowing away other changes you might +// have recently made in an upstream thread. +//////////////////////////////////////////////////////////////////// +void Geom:: +make_patches_in_place() { + Thread *current_thread = Thread::get_current_thread(); + CDWriter cdata(_cycler, true, current_thread); + +#ifndef NDEBUG + bool all_is_valid = true; +#endif + Primitives::iterator pi; + for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) { + CPT(GeomPrimitive) new_prim = (*pi).get_read_pointer()->make_patches(); + (*pi) = (GeomPrimitive *)new_prim.p(); + +#ifndef NDEBUG + if (!new_prim->check_valid(cdata->_data.get_read_pointer())) { + all_is_valid = false; + } +#endif + } + + cdata->_modified = Geom::get_next_modified(); + reset_geom_rendering(cdata); + clear_cache_stage(current_thread); + + nassertv(all_is_valid); +} //////////////////////////////////////////////////////////////////// // Function: Geom::copy_primitives_from diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index 075c92c765..af0eca41a0 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -102,6 +102,7 @@ PUBLISHED: INLINE PT(Geom) rotate() const; INLINE PT(Geom) unify(int max_indices, bool preserve_order) const; INLINE PT(Geom) make_points() const; + INLINE PT(Geom) make_patches() const; void decompose_in_place(); void doubleside_in_place(); @@ -109,6 +110,7 @@ PUBLISHED: void rotate_in_place(); void unify_in_place(int max_indices, bool preserve_order); void make_points_in_place(); + void make_patches_in_place(); virtual bool copy_primitives_from(const Geom *other); diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index 99271ffe4c..86d07499d0 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -991,6 +991,41 @@ make_points() const { return points; } +//////////////////////////////////////////////////////////////////// +// Function: GeomPrimitive::make_patches +// Access: Published +// Description: Decomposes a complex primitive type into a simpler +// primitive type, for instance triangle strips to +// triangles, puts these in a new GeomPatches objectand returns a pointer to the new primitive +// definition. If the decomposition cannot be +// performed, this might return the original object. +// +// This method is useful for application code that wants +// to iterate through the set of triangles on the +// primitive without having to write handlers for each +// possible kind of primitive type. +//////////////////////////////////////////////////////////////////// +CPT(GeomPrimitive) GeomPrimitive:: +make_patches() const { + if (is_exact_type(GeomPatches::get_class_type())) { + return this; + } + + CPT(GeomPrimitive) prim = decompose_impl(); + int num_vertices_per_patch = prim->get_num_vertices_per_primitive(); + + PT(GeomPrimitive) patches = new GeomPatches(num_vertices_per_patch, get_usage_hint()); + + if (prim->is_indexed()) { + patches->set_vertices(prim->get_vertices()); + } else { + patches->set_nonindexed_vertices(prim->get_first_vertex(), + prim->get_num_vertices()); + } + + return patches; +} + //////////////////////////////////////////////////////////////////// // Function: GeomPrimitive::get_num_bytes // Access: Published diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index 655ec5867e..18213be302 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -133,6 +133,7 @@ PUBLISHED: CPT(GeomPrimitive) reverse() const; CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const; CPT(GeomPrimitive) make_points() const; + CPT(GeomPrimitive) make_patches() const; int get_num_bytes() const; INLINE int get_data_size_bytes() const; @@ -232,14 +233,14 @@ private: // itself from the other's list. typedef pmap Contexts; Contexts _contexts; - + // This is the data that must be cycled between pipeline stages. class EXPCL_PANDA_GOBJ CData : public CycleData { public: INLINE CData(); INLINE CData(const CData ©); ALLOC_DELETED_CHAIN(CData); - + virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; virtual int complete_pointers(TypedWritable **plist, BamReader *manager); @@ -247,7 +248,7 @@ private: virtual TypeHandle get_parent_type() const { return GeomPrimitive::get_class_type(); } - + ShadeModel _shade_model; int _first_vertex; int _num_vertices; @@ -258,11 +259,11 @@ private: COWPT(GeomVertexArrayData) _mins; COWPT(GeomVertexArrayData) _maxs; UpdateSeq _modified; - + bool _got_minmax; unsigned int _min_vertex; unsigned int _max_vertex; - + public: static TypeHandle get_class_type() { return _type_handle; @@ -270,7 +271,7 @@ private: static void init_type() { register_type(_type_handle, "GeomPrimitive::CData"); } - + private: static TypeHandle _type_handle; @@ -282,7 +283,7 @@ private: typedef CycleDataWriter CDWriter; typedef CycleDataStageReader CDStageReader; typedef CycleDataStageWriter CDStageWriter; - + private: static PStatCollector _decompose_pcollector; static PStatCollector _doubleside_pcollector; @@ -360,7 +361,7 @@ public: INLINE CPTA_int get_ends() const; INLINE CPT(GeomVertexArrayData) get_mins() const; INLINE CPT(GeomVertexArrayData) get_maxs() const; - + private: CPT(GeomPrimitive) _object; Thread *_current_thread;