Panda3D
 All Classes Functions Variables Enumerations
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   void reserve_num_vertices(int num_vertices);
00109   bool close_primitive();
00110   void clear_vertices();
00111   void offset_vertices(int offset);
00112   void make_nonindexed(GeomVertexData *dest, const GeomVertexData *source);
00113   void pack_vertices(GeomVertexData *dest, const GeomVertexData *source);
00114   void make_indexed();
00115 
00116   INLINE int get_num_primitives() const;
00117   int get_primitive_start(int n) const;
00118   int get_primitive_end(int n) const;
00119   int get_primitive_num_vertices(int n) const;
00120 
00121   INLINE int get_num_faces() const;
00122   INLINE int get_primitive_num_faces(int n) const;
00123 
00124   INLINE int get_min_vertex() const;
00125   int get_primitive_min_vertex(int n) const;
00126   INLINE int get_max_vertex() const;
00127   int get_primitive_max_vertex(int n) const;
00128 
00129   CPT(GeomPrimitive) decompose() const;
00130   CPT(GeomPrimitive) rotate() const;
00131   CPT(GeomPrimitive) doubleside() const;
00132   CPT(GeomPrimitive) reverse() const;
00133   CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const;
00134   CPT(GeomPrimitive) make_points() const;
00135 
00136   int get_num_bytes() const;
00137   INLINE int get_data_size_bytes() const;
00138   INLINE UpdateSeq get_modified() const;
00139 
00140   bool request_resident() const;
00141 
00142   INLINE bool check_valid(const GeomVertexData *vertex_data) const;
00143 
00144   virtual void output(ostream &out) const;
00145   virtual void write(ostream &out, int indent_level) const;
00146 
00147 PUBLISHED:
00148   // These public methods are not intended for high-level usage.  They
00149   // are public so that low-level code that absolutely needs fast
00150   // access to the primitive data can get to it, but using them
00151   // requires knowledge about how the component primitives are encoded
00152   // within the GeomPrimitive class, and it's easy to screw something
00153   // up.  Also, if too many code samples depend on this internal
00154   // knowledge, it may make it difficult to extend this class later.
00155   // It is recommended that application-level code use the above
00156   // interfaces instead.
00157 
00158   INLINE CPT(GeomVertexArrayData) get_vertices() const;
00159   PT(GeomVertexArrayData) modify_vertices(int num_vertices = -1);
00160   void set_vertices(const GeomVertexArrayData *vertices, int num_vertices = -1);
00161   void set_nonindexed_vertices(int first_vertex, int num_vertices);
00162 
00163   INLINE int get_index_stride() const;
00164 
00165   INLINE CPTA_int get_ends() const;
00166   PTA_int modify_ends();
00167   void set_ends(CPTA_int ends);
00168 
00169   INLINE CPT(GeomVertexArrayData) get_mins() const;
00170   INLINE CPT(GeomVertexArrayData) get_maxs() const;
00171 
00172   void set_minmax(int min_vertex, int max_vertex,
00173                   GeomVertexArrayData *mins, GeomVertexArrayData *maxs);
00174   void clear_minmax();
00175 
00176   virtual int get_num_vertices_per_primitive() const;
00177   virtual int get_min_num_vertices_per_primitive() const;
00178   virtual int get_num_unused_vertices_per_primitive() const;
00179 
00180 public:
00181   void prepare(PreparedGraphicsObjects *prepared_objects);
00182   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
00183 
00184   IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
00185                                   GraphicsStateGuardianBase *gsg);
00186   bool release(PreparedGraphicsObjects *prepared_objects);
00187   int release_all();
00188 
00189   CPT(GeomVertexArrayFormat) get_index_format() const;
00190   INLINE PT(GeomVertexArrayData) make_index_data() const;
00191 
00192 private:
00193   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
00194   static int get_highest_index_value(NumericType index_type);
00195 
00196 public:
00197   virtual bool draw(GraphicsStateGuardianBase *gsg,
00198                     const GeomPrimitivePipelineReader *reader,
00199                     bool force) const=0;
00200 
00201   void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
00202                          bool &found_any, 
00203                          const GeomVertexData *vertex_data,
00204                          bool got_mat, const LMatrix4 &mat,
00205                          const InternalName *column_name,
00206                          Thread *current_thread) const;
00207 
00208 protected:
00209   virtual CPT(GeomPrimitive) decompose_impl() const;
00210   virtual CPT(GeomVertexArrayData) rotate_impl() const;
00211   virtual CPT(GeomPrimitive) doubleside_impl() const;
00212   virtual CPT(GeomPrimitive) reverse_impl() const;
00213   virtual bool requires_unused_vertices() const;
00214   virtual void append_unused_vertices(GeomVertexArrayData *vertices, 
00215                                       int vertex);
00216 
00217 private:
00218   class CData;
00219 
00220   void recompute_minmax(CData *cdata);
00221   void do_make_indexed(CData *cdata);
00222   void consider_elevate_index_type(CData *cdata, int vertex);
00223   void do_set_index_type(CData *cdata, NumericType index_type);
00224   PT(GeomVertexArrayData) do_modify_vertices(CData *cdata);
00225 
00226 private:
00227   // A GeomPrimitive keeps a list (actually, a map) of all the
00228   // PreparedGraphicsObjects tables that it has been prepared into.
00229   // Each PGO conversely keeps a list (a set) of all the Geoms that
00230   // have been prepared there.  When either destructs, it removes
00231   // itself from the other's list.
00232   typedef pmap<PreparedGraphicsObjects *, IndexBufferContext *> Contexts;
00233   Contexts _contexts;
00234     
00235   // This is the data that must be cycled between pipeline stages.
00236   class EXPCL_PANDA_GOBJ CData : public CycleData {
00237   public:
00238     INLINE CData();
00239     INLINE CData(const CData &copy);
00240     ALLOC_DELETED_CHAIN(CData);
00241     
00242     virtual CycleData *make_copy() const;
00243     virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00244     virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
00245     virtual void fillin(DatagramIterator &scan, BamReader *manager);
00246     virtual TypeHandle get_parent_type() const {
00247       return GeomPrimitive::get_class_type();
00248     }
00249     
00250     ShadeModel _shade_model;
00251     int _first_vertex;
00252     int _num_vertices;
00253     NumericType _index_type;
00254     UsageHint _usage_hint;
00255     COWPT(GeomVertexArrayData) _vertices;
00256     PTA_int _ends;
00257     COWPT(GeomVertexArrayData) _mins;
00258     COWPT(GeomVertexArrayData) _maxs;
00259     UpdateSeq _modified;
00260     
00261     bool _got_minmax;
00262     unsigned int _min_vertex;
00263     unsigned int _max_vertex;
00264     
00265   public:
00266     static TypeHandle get_class_type() {
00267       return _type_handle;
00268     }
00269     static void init_type() {
00270       register_type(_type_handle, "GeomPrimitive::CData");
00271     }
00272     
00273   private:
00274     static TypeHandle _type_handle;
00275 
00276     friend class GeomPrimitive;
00277   };
00278 
00279   PipelineCycler<CData> _cycler;
00280   typedef CycleDataReader<CData> CDReader;
00281   typedef CycleDataWriter<CData> CDWriter;
00282   typedef CycleDataStageReader<CData> CDStageReader;
00283   typedef CycleDataStageWriter<CData> CDStageWriter;
00284   
00285 private:
00286   static PStatCollector _decompose_pcollector;
00287   static PStatCollector _doubleside_pcollector;
00288   static PStatCollector _reverse_pcollector;
00289   static PStatCollector _rotate_pcollector;
00290 
00291 public:
00292   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00293 
00294   virtual void finalize(BamReader *manager);
00295 
00296 protected:
00297   void fillin(DatagramIterator &scan, BamReader *manager);
00298 
00299 public:
00300   static TypeHandle get_class_type() {
00301     return _type_handle;
00302   }
00303   static void init_type() {
00304     CopyOnWriteObject::init_type();
00305     register_type(_type_handle, "GeomPrimitive",
00306                   CopyOnWriteObject::get_class_type());
00307     CData::init_type();
00308   }
00309   virtual TypeHandle get_type() const {
00310     return get_class_type();
00311   }
00312   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00313 
00314 private:
00315   static TypeHandle _type_handle;
00316 
00317   friend class Geom;
00318   friend class PreparedGraphicsObjects;
00319   friend class GeomPrimitivePipelineReader;
00320 };
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //       Class : GeomPrimitivePipelineReader
00324 // Description : Encapsulates the data from a GeomPrimitive,
00325 //               pre-fetched for one stage of the pipeline.
00326 ////////////////////////////////////////////////////////////////////
00327 class EXPCL_PANDA_GOBJ GeomPrimitivePipelineReader : public GeomEnums {
00328 public:
00329   INLINE GeomPrimitivePipelineReader(const GeomPrimitive *object, Thread *current_thread);
00330 private:
00331   INLINE GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader &copy);
00332   INLINE void operator = (const GeomPrimitivePipelineReader &copy);
00333 
00334 public:
00335   INLINE ~GeomPrimitivePipelineReader();
00336   ALLOC_DELETED_CHAIN(GeomPrimitivePipelineReader);
00337 
00338   INLINE const GeomPrimitive *get_object() const;
00339   INLINE Thread *get_current_thread() const;
00340 
00341   void check_minmax() const;
00342 
00343   INLINE ShadeModel get_shade_model() const;
00344   INLINE UsageHint get_usage_hint() const;
00345   INLINE NumericType get_index_type() const;
00346   INLINE bool is_indexed() const;
00347   int get_first_vertex() const;
00348   INLINE int get_num_vertices() const;
00349   int get_vertex(int i) const;
00350   int get_num_primitives() const;
00351   INLINE int get_min_vertex() const;
00352   INLINE int get_max_vertex() const;
00353   INLINE int get_data_size_bytes() const;
00354   INLINE UpdateSeq get_modified() const;
00355   bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
00356   INLINE int get_index_stride() const;
00357   INLINE const GeomVertexArrayDataHandle *get_vertices_reader() const;
00358   INLINE const unsigned char *get_read_pointer(bool force) const;
00359   INLINE CPTA_int get_ends() const;
00360   INLINE CPT(GeomVertexArrayData) get_mins() const;
00361   INLINE CPT(GeomVertexArrayData) get_maxs() const;
00362   
00363 private:
00364   CPT(GeomPrimitive) _object;
00365   Thread *_current_thread;
00366   const GeomPrimitive::CData *_cdata;
00367 
00368   CPT(GeomVertexArrayDataHandle) _vertices_reader;
00369 
00370 public:
00371   static TypeHandle get_class_type() {
00372     return _type_handle;
00373   }
00374   static void init_type() {
00375     register_type(_type_handle, "GeomPrimitivePipelineReader");
00376   }
00377 
00378 private:
00379   static TypeHandle _type_handle;
00380 };
00381 
00382 INLINE ostream &operator << (ostream &out, const GeomPrimitive &obj);
00383 
00384 #include "geomPrimitive.I"
00385 
00386 #endif
 All Classes Functions Variables Enumerations