Panda3D

geomPrimitive.h

00001 // Filename: geomPrimitive.h
00002 // Created by:  drose (06Mar05)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef GEOMPRIMITIVE_H
00016 #define GEOMPRIMITIVE_H
00017 
00018 #include "pandabase.h"
00019 #include "geomEnums.h"
00020 #include "geomVertexArrayData.h"
00021 #include "geomVertexData.h"
00022 #include "copyOnWriteObject.h"
00023 #include "luse.h"
00024 #include "updateSeq.h"
00025 #include "pointerTo.h"
00026 #include "pta_int.h"
00027 #include "pStatCollector.h"
00028 #include "cycleData.h"
00029 #include "cycleDataReader.h"
00030 #include "cycleDataWriter.h"
00031 #include "cycleDataStageReader.h"
00032 #include "cycleDataStageWriter.h"
00033 #include "pipelineCycler.h"
00034 #include "deletedChain.h"
00035 
00036 class PreparedGraphicsObjects;
00037 class IndexBufferContext;
00038 class GraphicsStateGuardianBase;
00039 class FactoryParams;
00040 class GeomPrimitivePipelineReader;
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //       Class : GeomPrimitive
00044 // Description : This is an abstract base class for a family of
00045 //               classes that represent the fundamental geometry
00046 //               primitives that may be stored in a Geom.
00047 //
00048 //               They all have in common the fact that they are
00049 //               defined by tables of vertex data stored in a
00050 //               GeomVertexData object.  Each GeomPrimitive object
00051 //               contains an ordered list of integers, which index
00052 //               into the vertex array defined by the GeomVertexData
00053 //               and define the particular vertices of the
00054 //               GeomVertexData that are used for this primitive.
00055 //
00056 //               The meaning of a given arrangement of vertices is
00057 //               defined by each individual primitive type; for
00058 //               instance, a GeomTriangle renders a triangle from each
00059 //               three consecutive vertices, while a GeomTriangleStrip
00060 //               renders a strip of (n - 2) connected triangles from
00061 //               each sequence of n vertices.
00062 ////////////////////////////////////////////////////////////////////
00063 class EXPCL_PANDA_GOBJ GeomPrimitive : public CopyOnWriteObject, public GeomEnums {
00064 protected:
00065   GeomPrimitive();
00066   virtual PT(CopyOnWriteObject) make_cow_copy();
00067 
00068 PUBLISHED:
00069   GeomPrimitive(UsageHint usage_hint);
00070   GeomPrimitive(const GeomPrimitive &copy);
00071   void operator = (const GeomPrimitive &copy);
00072   virtual ~GeomPrimitive();
00073   ALLOC_DELETED_CHAIN(GeomPrimitive);
00074 
00075   virtual PT(GeomPrimitive) make_copy() const=0;
00076 
00077   virtual PrimitiveType get_primitive_type() const=0;
00078   virtual int get_geom_rendering() const;
00079 
00080   INLINE ShadeModel get_shade_model() const;
00081   INLINE void set_shade_model(ShadeModel shade_model);
00082 
00083   INLINE UsageHint get_usage_hint() const;
00084   void set_usage_hint(UsageHint usage_hint);
00085 
00086   INLINE NumericType get_index_type() const;
00087   void set_index_type(NumericType index_type);
00088 
00089   // The following published methods are provided for safe, high-level
00090   // iteration through the vertices and sub-primitives within the
00091   // GeomPrimitive class.  These work correctly regardless of the
00092   // primitive type and without depending on knowledge about the way
00093   // primitives' lengths are encoded.  You can also safely build up a
00094   // composite primitive using these methods.
00095 
00096   INLINE bool is_composite() const;
00097   INLINE bool is_indexed() const;
00098   INLINE int get_first_vertex() const;
00099   INLINE int get_num_vertices() const;
00100   INLINE int get_vertex(int i) const;
00101   MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
00102   void add_vertex(int vertex);
00103   INLINE void add_vertices(int v1, int v2);
00104   INLINE void add_vertices(int v1, int v2, int v3);
00105   INLINE void add_vertices(int v1, int v2, int v3, int v4);
00106   void add_consecutive_vertices(int start, int num_vertices);
00107   void add_next_vertices(int num_vertices);
00108   bool close_primitive();
00109   void clear_vertices();
00110   void offset_vertices(int offset);
00111   void make_nonindexed(GeomVertexData *dest, const GeomVertexData *source);
00112   void pack_vertices(GeomVertexData *dest, const GeomVertexData *source);
00113   void make_indexed();
00114 
00115   INLINE int get_num_primitives() const;
00116   int get_primitive_start(int n) const;
00117   int get_primitive_end(int n) const;
00118   int get_primitive_num_vertices(int n) const;
00119 
00120   INLINE int get_num_faces() const;
00121   INLINE int get_primitive_num_faces(int n) const;
00122 
00123   INLINE int get_min_vertex() const;
00124   int get_primitive_min_vertex(int n) const;
00125   INLINE int get_max_vertex() const;
00126   int get_primitive_max_vertex(int n) const;
00127 
00128   CPT(GeomPrimitive) decompose() const;
00129   CPT(GeomPrimitive) rotate() const;
00130   CPT(GeomPrimitive) doubleside() const;
00131   CPT(GeomPrimitive) reverse() const;
00132   CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const;
00133   CPT(GeomPrimitive) make_points() const;
00134 
00135   int get_num_bytes() const;
00136   INLINE int get_data_size_bytes() const;
00137   INLINE UpdateSeq get_modified() const;
00138 
00139   bool request_resident() const;
00140 
00141   INLINE bool check_valid(const GeomVertexData *vertex_data) const;
00142 
00143   virtual void output(ostream &out) const;
00144   virtual void write(ostream &out, int indent_level) const;
00145 
00146 PUBLISHED:
00147   // These public methods are not intended for high-level usage.  They
00148   // are public so that low-level code that absolutely needs fast
00149   // access to the primitive data can get to it, but using them
00150   // requires knowledge about how the component primitives are encoded
00151   // within the GeomPrimitive class, and it's easy to screw something
00152   // up.  Also, if too many code samples depend on this internal
00153   // knowledge, it may make it difficult to extend this class later.
00154   // It is recommended that application-level code use the above
00155   // interfaces instead.
00156 
00157   INLINE CPT(GeomVertexArrayData) get_vertices() const;
00158   PT(GeomVertexArrayData) modify_vertices(int num_vertices = -1);
00159   void set_vertices(const GeomVertexArrayData *vertices, int num_vertices = -1);
00160   void set_nonindexed_vertices(int first_vertex, int num_vertices);
00161 
00162   INLINE int get_index_stride() const;
00163 
00164   INLINE CPTA_int get_ends() const;
00165   PTA_int modify_ends();
00166   void set_ends(CPTA_int ends);
00167 
00168   INLINE CPT(GeomVertexArrayData) get_mins() const;
00169   INLINE CPT(GeomVertexArrayData) get_maxs() const;
00170 
00171   void set_minmax(int min_vertex, int max_vertex,
00172                   GeomVertexArrayData *mins, GeomVertexArrayData *maxs);
00173   void clear_minmax();
00174 
00175   virtual int get_num_vertices_per_primitive() const;
00176   virtual int get_min_num_vertices_per_primitive() const;
00177   virtual int get_num_unused_vertices_per_primitive() const;
00178 
00179 public:
00180   void prepare(PreparedGraphicsObjects *prepared_objects);
00181   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
00182 
00183   IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
00184                                   GraphicsStateGuardianBase *gsg);
00185   bool release(PreparedGraphicsObjects *prepared_objects);
00186   int release_all();
00187 
00188   INLINE CPT(GeomVertexArrayFormat) get_index_format() const;
00189   INLINE PT(GeomVertexArrayData) make_index_data() const;
00190 
00191 private:
00192   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
00193   static int get_highest_index_value(NumericType index_type);
00194 
00195 public:
00196   virtual bool draw(GraphicsStateGuardianBase *gsg,
00197                     const GeomPrimitivePipelineReader *reader,
00198                     bool force) const=0;
00199 
00200   void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
00201                          bool &found_any, 
00202                          const GeomVertexData *vertex_data,
00203                          bool got_mat, const LMatrix4f &mat,
00204                          const InternalName *column_name,
00205                          Thread *current_thread) const;
00206 
00207 protected:
00208   virtual CPT(GeomPrimitive) decompose_impl() const;
00209   virtual CPT(GeomVertexArrayData) rotate_impl() const;
00210   virtual CPT(GeomPrimitive) doubleside_impl() const;
00211   virtual CPT(GeomPrimitive) reverse_impl() const;
00212   virtual bool requires_unused_vertices() const;
00213   virtual void append_unused_vertices(GeomVertexArrayData *vertices, 
00214                                       int vertex);
00215 
00216 private:
00217   class CData;
00218 
00219   void recompute_minmax(CData *cdata);
00220   void do_make_indexed(CData *cdata);
00221   void consider_elevate_index_type(CData *cdata, int vertex);
00222   void do_set_index_type(CData *cdata, NumericType index_type);
00223   PT(GeomVertexArrayData) do_modify_vertices(CData *cdata);
00224 
00225 private:
00226   // A GeomPrimitive keeps a list (actually, a map) of all the
00227   // PreparedGraphicsObjects tables that it has been prepared into.
00228   // Each PGO conversely keeps a list (a set) of all the Geoms that
00229   // have been prepared there.  When either destructs, it removes
00230   // itself from the other's list.
00231   typedef pmap<PreparedGraphicsObjects *, IndexBufferContext *> Contexts;
00232   Contexts _contexts;
00233     
00234   // This is the data that must be cycled between pipeline stages.
00235   class EXPCL_PANDA_GOBJ CData : public CycleData {
00236   public:
00237     INLINE CData();
00238     INLINE CData(const CData &copy);
00239     ALLOC_DELETED_CHAIN(CData);
00240     
00241     virtual CycleData *make_copy() const;
00242     virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00243     virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
00244     virtual void fillin(DatagramIterator &scan, BamReader *manager);
00245     virtual TypeHandle get_parent_type() const {
00246       return GeomPrimitive::get_class_type();
00247     }
00248     
00249     ShadeModel _shade_model;
00250     int _first_vertex;
00251     int _num_vertices;
00252     NumericType _index_type;
00253     UsageHint _usage_hint;
00254     COWPT(GeomVertexArrayData) _vertices;
00255     PTA_int _ends;
00256     COWPT(GeomVertexArrayData) _mins;
00257     COWPT(GeomVertexArrayData) _maxs;
00258     UpdateSeq _modified;
00259     
00260     bool _got_minmax;
00261     unsigned int _min_vertex;
00262     unsigned int _max_vertex;
00263     
00264   public:
00265     static TypeHandle get_class_type() {
00266       return _type_handle;
00267     }
00268     static void init_type() {
00269       register_type(_type_handle, "GeomPrimitive::CData");
00270     }
00271     
00272   private:
00273     static TypeHandle _type_handle;
00274 
00275     friend class GeomPrimitive;
00276   };
00277 
00278   PipelineCycler<CData> _cycler;
00279   typedef CycleDataReader<CData> CDReader;
00280   typedef CycleDataWriter<CData> CDWriter;
00281   typedef CycleDataStageReader<CData> CDStageReader;
00282   typedef CycleDataStageWriter<CData> CDStageWriter;
00283   
00284 private:
00285   static PStatCollector _decompose_pcollector;
00286   static PStatCollector _doubleside_pcollector;
00287   static PStatCollector _reverse_pcollector;
00288   static PStatCollector _rotate_pcollector;
00289 
00290 public:
00291   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00292 
00293   virtual void finalize(BamReader *manager);
00294 
00295 protected:
00296   void fillin(DatagramIterator &scan, BamReader *manager);
00297 
00298 public:
00299   static TypeHandle get_class_type() {
00300     return _type_handle;
00301   }
00302   static void init_type() {
00303     CopyOnWriteObject::init_type();
00304     register_type(_type_handle, "GeomPrimitive",
00305                   CopyOnWriteObject::get_class_type());
00306     CData::init_type();
00307   }
00308   virtual TypeHandle get_type() const {
00309     return get_class_type();
00310   }
00311   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00312 
00313 private:
00314   static TypeHandle _type_handle;
00315 
00316   friend class Geom;
00317   friend class PreparedGraphicsObjects;
00318   friend class GeomPrimitivePipelineReader;
00319 };
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //       Class : GeomPrimitivePipelineReader
00323 // Description : Encapsulates the data from a GeomPrimitive,
00324 //               pre-fetched for one stage of the pipeline.
00325 ////////////////////////////////////////////////////////////////////
00326 class EXPCL_PANDA_GOBJ GeomPrimitivePipelineReader : public GeomEnums {
00327 public:
00328   INLINE GeomPrimitivePipelineReader(const GeomPrimitive *object, Thread *current_thread);
00329 private:
00330   INLINE GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader &copy);
00331   INLINE void operator = (const GeomPrimitivePipelineReader &copy);
00332 
00333 public:
00334   INLINE ~GeomPrimitivePipelineReader();
00335   ALLOC_DELETED_CHAIN(GeomPrimitivePipelineReader);
00336 
00337   INLINE const GeomPrimitive *get_object() const;
00338   INLINE Thread *get_current_thread() const;
00339 
00340   void check_minmax() const;
00341 
00342   INLINE ShadeModel get_shade_model() const;
00343   INLINE UsageHint get_usage_hint() const;
00344   INLINE NumericType get_index_type() const;
00345   INLINE bool is_indexed() const;
00346   int get_first_vertex() const;
00347   INLINE int get_num_vertices() const;
00348   int get_vertex(int i) const;
00349   int get_num_primitives() const;
00350   INLINE int get_min_vertex() const;
00351   INLINE int get_max_vertex() const;
00352   INLINE int get_data_size_bytes() const;
00353   INLINE UpdateSeq get_modified() const;
00354   bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
00355   INLINE int get_index_stride() const;
00356   INLINE const GeomVertexArrayDataHandle *get_vertices_reader() const;
00357   INLINE const unsigned char *get_read_pointer(bool force) const;
00358   INLINE CPTA_int get_ends() const;
00359   INLINE CPT(GeomVertexArrayData) get_mins() const;
00360   INLINE CPT(GeomVertexArrayData) get_maxs() const;
00361   
00362 private:
00363   CPT(GeomPrimitive) _object;
00364   Thread *_current_thread;
00365   const GeomPrimitive::CData *_cdata;
00366 
00367   CPT(GeomVertexArrayDataHandle) _vertices_reader;
00368 
00369 public:
00370   static TypeHandle get_class_type() {
00371     return _type_handle;
00372   }
00373   static void init_type() {
00374     register_type(_type_handle, "GeomPrimitivePipelineReader");
00375   }
00376 
00377 private:
00378   static TypeHandle _type_handle;
00379 };
00380 
00381 INLINE ostream &operator << (ostream &out, const GeomPrimitive &obj);
00382 
00383 #include "geomPrimitive.I"
00384 
00385 #endif
 All Classes Functions Variables Enumerations