Panda3D
|
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 ©); 00071 void operator = (const GeomPrimitive ©); 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 ©); 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 ©); 00332 INLINE void operator = (const GeomPrimitivePipelineReader ©); 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