Panda3D
|
00001 // Filename: geomVertexData.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 GEOMVERTEXDATA_H 00016 #define GEOMVERTEXDATA_H 00017 00018 #include "pandabase.h" 00019 #include "copyOnWriteObject.h" 00020 #include "copyOnWritePointer.h" 00021 #include "geomVertexFormat.h" 00022 #include "geomVertexColumn.h" 00023 #include "geomVertexArrayData.h" 00024 #include "geomEnums.h" 00025 #include "geomCacheEntry.h" 00026 #include "transformTable.h" 00027 #include "transformBlendTable.h" 00028 #include "sliderTable.h" 00029 #include "internalName.h" 00030 #include "cycleData.h" 00031 #include "cycleDataLockedReader.h" 00032 #include "cycleDataReader.h" 00033 #include "cycleDataWriter.h" 00034 #include "cycleDataStageReader.h" 00035 #include "cycleDataStageWriter.h" 00036 #include "pipelineCycler.h" 00037 #include "pStatCollector.h" 00038 #include "pointerTo.h" 00039 #include "pmap.h" 00040 #include "pvector.h" 00041 #include "deletedChain.h" 00042 00043 class FactoryParams; 00044 class GeomVertexColumn; 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Class : GeomVertexData 00048 // Description : This defines the actual numeric vertex data stored in 00049 // a Geom, in the structure defined by a particular 00050 // GeomVertexFormat object. 00051 // 00052 // The data consists of one or more arrays, each of 00053 // which in turn consists of a series of rows, one per 00054 // vertex. All arrays should have the same number of 00055 // rows; each vertex is defined by the column data from 00056 // a particular row across all arrays. 00057 // 00058 // Often, there will be only one array per Geom, and the 00059 // various columns defined in the GeomVertexFormat will 00060 // be interleaved within that array. However, it is 00061 // also possible to have multiple different arrays, with 00062 // a certain subset of the total columns defined in each 00063 // array. 00064 // 00065 // However the data is distributed, the effect is of a 00066 // single table of vertices, where each vertex is 00067 // represented by one row of the table. 00068 // 00069 // In general, application code should not attempt to 00070 // directly manipulate the vertex data through this 00071 // structure; instead, use the GeomVertexReader, 00072 // GeomVertexWriter, and GeomVertexRewriter objects to 00073 // read and write vertex data at a high level. 00074 //////////////////////////////////////////////////////////////////// 00075 class EXPCL_PANDA_GOBJ GeomVertexData : public CopyOnWriteObject, public GeomEnums { 00076 private: 00077 GeomVertexData(); 00078 protected: 00079 virtual PT(CopyOnWriteObject) make_cow_copy(); 00080 00081 PUBLISHED: 00082 GeomVertexData(const string &name, 00083 const GeomVertexFormat *format, 00084 UsageHint usage_hint); 00085 GeomVertexData(const GeomVertexData ©); 00086 GeomVertexData(const GeomVertexData ©, 00087 const GeomVertexFormat *format); 00088 void operator = (const GeomVertexData ©); 00089 virtual ~GeomVertexData(); 00090 ALLOC_DELETED_CHAIN(GeomVertexData); 00091 00092 int compare_to(const GeomVertexData &other) const; 00093 00094 INLINE const string &get_name() const; 00095 void set_name(const string &name); 00096 00097 INLINE UsageHint get_usage_hint() const; 00098 void set_usage_hint(UsageHint usage_hint); 00099 00100 INLINE const GeomVertexFormat *get_format() const; 00101 void set_format(const GeomVertexFormat *format); 00102 00103 INLINE bool has_column(const InternalName *name) const; 00104 00105 INLINE int get_num_rows() const; 00106 INLINE bool set_num_rows(int n); 00107 INLINE bool unclean_set_num_rows(int n); 00108 void clear_rows(); 00109 00110 INLINE int get_num_arrays() const; 00111 INLINE CPT(GeomVertexArrayData) get_array(int i) const; 00112 MAKE_SEQ(get_arrays, get_num_arrays, get_array); 00113 INLINE PT(GeomVertexArrayData) modify_array(int i); 00114 INLINE void set_array(int i, const GeomVertexArrayData *array); 00115 00116 INLINE const TransformTable *get_transform_table() const; 00117 void set_transform_table(const TransformTable *table); 00118 INLINE void clear_transform_table(); 00119 00120 INLINE CPT(TransformBlendTable) get_transform_blend_table() const; 00121 PT(TransformBlendTable) modify_transform_blend_table(); 00122 void set_transform_blend_table(const TransformBlendTable *table); 00123 INLINE void clear_transform_blend_table(); 00124 00125 INLINE const SliderTable *get_slider_table() const; 00126 void set_slider_table(const SliderTable *table); 00127 INLINE void clear_slider_table(); 00128 00129 INLINE int get_num_bytes() const; 00130 INLINE UpdateSeq get_modified(Thread *current_thread = Thread::get_current_thread()) const; 00131 00132 bool request_resident() const; 00133 00134 void copy_from(const GeomVertexData *source, bool keep_data_objects, 00135 Thread *current_thread = Thread::get_current_thread()); 00136 void copy_row_from(int dest_row, const GeomVertexData *source, 00137 int source_row, Thread *current_thread); 00138 CPT(GeomVertexData) convert_to(const GeomVertexFormat *new_format) const; 00139 CPT(GeomVertexData) 00140 scale_color(const LVecBase4f &color_scale) const; 00141 CPT(GeomVertexData) 00142 scale_color(const LVecBase4f &color_scale, int num_components, 00143 NumericType numeric_type, Contents contents) const; 00144 CPT(GeomVertexData) 00145 set_color(const Colorf &color) const; 00146 CPT(GeomVertexData) 00147 set_color(const Colorf &color, int num_components, 00148 NumericType numeric_type, Contents contents) const; 00149 00150 CPT(GeomVertexData) reverse_normals() const; 00151 00152 CPT(GeomVertexData) animate_vertices(bool force, Thread *current_thread) const; 00153 void clear_animated_vertices(); 00154 00155 PT(GeomVertexData) 00156 replace_column(InternalName *name, int num_components, 00157 NumericType numeric_type, Contents contents) const; 00158 00159 void output(ostream &out) const; 00160 void write(ostream &out, int indent_level = 0) const; 00161 void describe_vertex(ostream &out, int row) const; 00162 00163 void clear_cache(); 00164 void clear_cache_stage(); 00165 00166 public: 00167 static INLINE PN_uint32 pack_abcd(unsigned int a, unsigned int b, 00168 unsigned int c, unsigned int d); 00169 static INLINE unsigned int unpack_abcd_a(PN_uint32 data); 00170 static INLINE unsigned int unpack_abcd_b(PN_uint32 data); 00171 static INLINE unsigned int unpack_abcd_c(PN_uint32 data); 00172 static INLINE unsigned int unpack_abcd_d(PN_uint32 data); 00173 00174 private: 00175 static void bytewise_copy(unsigned char *to, int to_stride, 00176 const unsigned char *from, int from_stride, 00177 const GeomVertexColumn *from_type, 00178 int num_records); 00179 static void 00180 packed_argb_to_uint8_rgba(unsigned char *to, int to_stride, 00181 const unsigned char *from, int from_stride, 00182 int num_records); 00183 static void 00184 uint8_rgba_to_packed_argb(unsigned char *to, int to_stride, 00185 const unsigned char *from, int from_stride, 00186 int num_records); 00187 00188 typedef pmap<const VertexTransform *, int> TransformMap; 00189 INLINE static int 00190 add_transform(TransformTable *table, const VertexTransform *transform, 00191 TransformMap &already_added); 00192 00193 private: 00194 string _name; 00195 00196 typedef pvector< COWPT(GeomVertexArrayData) > Arrays; 00197 00198 // The pipelined data with each CacheEntry. 00199 class EXPCL_PANDA_GOBJ CDataCache : public CycleData { 00200 public: 00201 INLINE CDataCache(); 00202 INLINE CDataCache(const CDataCache ©); 00203 ALLOC_DELETED_CHAIN(CDataCache); 00204 virtual CycleData *make_copy() const; 00205 virtual TypeHandle get_parent_type() const { 00206 return GeomVertexData::get_class_type(); 00207 } 00208 00209 CPT(GeomVertexData) _result; 00210 00211 public: 00212 static TypeHandle get_class_type() { 00213 return _type_handle; 00214 } 00215 static void init_type() { 00216 register_type(_type_handle, "GeomVertexData::CDataCache"); 00217 } 00218 00219 private: 00220 static TypeHandle _type_handle; 00221 }; 00222 typedef CycleDataReader<CDataCache> CDCacheReader; 00223 typedef CycleDataWriter<CDataCache> CDCacheWriter; 00224 00225 public: 00226 // The CacheKey class separates out just the part of CacheEntry that 00227 // is used to key the cache entry within the map. We have this as a 00228 // separate class so we can easily look up a new entry in the map, 00229 // without having to execute the relatively expensive CacheEntry 00230 // constructor. 00231 class CacheKey { 00232 public: 00233 INLINE CacheKey(const GeomVertexFormat *modifier); 00234 INLINE bool operator < (const CacheKey &other) const; 00235 00236 CPT(GeomVertexFormat) _modifier; 00237 }; 00238 // It is not clear why MSVC7 needs this class to be public. 00239 class CacheEntry : public GeomCacheEntry { 00240 public: 00241 INLINE CacheEntry(GeomVertexData *source, 00242 const GeomVertexFormat *modifier); 00243 ALLOC_DELETED_CHAIN(CacheEntry); 00244 00245 virtual void evict_callback(); 00246 virtual void output(ostream &out) const; 00247 00248 GeomVertexData *_source; // A back pointer to the containing data. 00249 CacheKey _key; 00250 00251 PipelineCycler<CDataCache> _cycler; 00252 00253 public: 00254 static TypeHandle get_class_type() { 00255 return _type_handle; 00256 } 00257 static void init_type() { 00258 register_type(_type_handle, "GeomVertexData::CacheEntry"); 00259 } 00260 00261 private: 00262 static TypeHandle _type_handle; 00263 }; 00264 typedef pmap<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > Cache; 00265 00266 private: 00267 // This is the data that must be cycled between pipeline stages. 00268 class EXPCL_PANDA_GOBJ CData : public CycleData { 00269 public: 00270 INLINE CData(); 00271 INLINE CData(const CData ©); 00272 ALLOC_DELETED_CHAIN(CData); 00273 virtual CycleData *make_copy() const; 00274 virtual void write_datagram(BamWriter *manager, Datagram &dg) const; 00275 virtual int complete_pointers(TypedWritable **plist, BamReader *manager); 00276 virtual void fillin(DatagramIterator &scan, BamReader *manager); 00277 virtual TypeHandle get_parent_type() const { 00278 return GeomVertexData::get_class_type(); 00279 } 00280 00281 UsageHint _usage_hint; 00282 CPT(GeomVertexFormat) _format; 00283 Arrays _arrays; 00284 CPT(TransformTable) _transform_table; 00285 COWPT(TransformBlendTable) _transform_blend_table; 00286 CPT(SliderTable) _slider_table; 00287 PT(GeomVertexData) _animated_vertices; 00288 UpdateSeq _animated_vertices_modified; 00289 UpdateSeq _modified; 00290 00291 public: 00292 static TypeHandle get_class_type() { 00293 return _type_handle; 00294 } 00295 static void init_type() { 00296 register_type(_type_handle, "GeomVertexData::CData"); 00297 } 00298 00299 private: 00300 static TypeHandle _type_handle; 00301 }; 00302 00303 PipelineCycler<CData> _cycler; 00304 typedef CycleDataLockedReader<CData> CDLockedReader; 00305 typedef CycleDataReader<CData> CDReader; 00306 typedef CycleDataWriter<CData> CDWriter; 00307 typedef CycleDataStageReader<CData> CDStageReader; 00308 typedef CycleDataStageWriter<CData> CDStageWriter; 00309 00310 Cache _cache; 00311 LightMutex _cache_lock; 00312 00313 private: 00314 void update_animated_vertices(CData *cdata, Thread *current_thread); 00315 00316 static PStatCollector _convert_pcollector; 00317 static PStatCollector _scale_color_pcollector; 00318 static PStatCollector _set_color_pcollector; 00319 static PStatCollector _animation_pcollector; 00320 00321 PStatCollector _char_pcollector; 00322 PStatCollector _skinning_pcollector; 00323 PStatCollector _morphs_pcollector; 00324 00325 public: 00326 static void register_with_read_factory(); 00327 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00328 virtual int complete_pointers(TypedWritable **plist, BamReader *manager); 00329 virtual bool require_fully_complete() const; 00330 00331 virtual void finalize(BamReader *manager); 00332 00333 protected: 00334 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00335 void fillin(DatagramIterator &scan, BamReader *manager); 00336 00337 public: 00338 static TypeHandle get_class_type() { 00339 return _type_handle; 00340 } 00341 static void init_type() { 00342 CopyOnWriteObject::init_type(); 00343 register_type(_type_handle, "GeomVertexData", 00344 CopyOnWriteObject::get_class_type()); 00345 CDataCache::init_type(); 00346 CacheEntry::init_type(); 00347 CData::init_type(); 00348 } 00349 virtual TypeHandle get_type() const { 00350 return get_class_type(); 00351 } 00352 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00353 00354 private: 00355 static TypeHandle _type_handle; 00356 00357 friend class CacheEntry; 00358 friend class GeomVertexDataPipelineBase; 00359 friend class GeomVertexDataPipelineReader; 00360 friend class GeomVertexDataPipelineWriter; 00361 }; 00362 00363 //////////////////////////////////////////////////////////////////// 00364 // Class : GeomVertexDataPipelineBase 00365 // Description : The common code from 00366 // GeomVertexDataPipelineReader and 00367 // GeomVertexDataPipelineWriter. 00368 //////////////////////////////////////////////////////////////////// 00369 class EXPCL_PANDA_GOBJ GeomVertexDataPipelineBase : public GeomEnums { 00370 protected: 00371 INLINE GeomVertexDataPipelineBase(GeomVertexData *object, 00372 Thread *current_thread, 00373 GeomVertexData::CData *cdata); 00374 00375 public: 00376 INLINE ~GeomVertexDataPipelineBase(); 00377 00378 public: 00379 INLINE Thread *get_current_thread() const; 00380 00381 INLINE const GeomVertexFormat *get_format() const; 00382 INLINE bool has_column(const InternalName *name) const; 00383 00384 INLINE UsageHint get_usage_hint() const; 00385 INLINE int get_num_arrays() const; 00386 INLINE CPT(GeomVertexArrayData) get_array(int i) const; 00387 INLINE const TransformTable *get_transform_table() const; 00388 INLINE CPT(TransformBlendTable) get_transform_blend_table() const; 00389 INLINE const SliderTable *get_slider_table() const; 00390 int get_num_bytes() const; 00391 INLINE UpdateSeq get_modified() const; 00392 00393 protected: 00394 PT(GeomVertexData) _object; 00395 Thread *_current_thread; 00396 GeomVertexData::CData *_cdata; 00397 }; 00398 00399 //////////////////////////////////////////////////////////////////// 00400 // Class : GeomVertexDataPipelineReader 00401 // Description : Encapsulates the data from a GeomVertexData, 00402 // pre-fetched for one stage of the pipeline. 00403 //////////////////////////////////////////////////////////////////// 00404 class EXPCL_PANDA_GOBJ GeomVertexDataPipelineReader : public GeomVertexDataPipelineBase { 00405 public: 00406 INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, Thread *current_thread); 00407 private: 00408 INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©); 00409 INLINE void operator = (const GeomVertexDataPipelineReader ©); 00410 00411 public: 00412 INLINE ~GeomVertexDataPipelineReader(); 00413 ALLOC_DELETED_CHAIN(GeomVertexDataPipelineReader); 00414 00415 INLINE const GeomVertexData *get_object() const; 00416 00417 INLINE void check_array_readers() const; 00418 INLINE const GeomVertexArrayDataHandle *get_array_reader(int i) const; 00419 int get_num_rows() const; 00420 00421 bool get_array_info(const InternalName *name, 00422 const GeomVertexArrayDataHandle *&array_reader, 00423 int &num_values, NumericType &numeric_type, 00424 int &start, int &stride) const; 00425 00426 INLINE bool has_vertex() const; 00427 INLINE bool is_vertex_transformed() const; 00428 bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader, 00429 int &num_values, NumericType &numeric_type, 00430 int &start, int &stride) const; 00431 00432 INLINE bool has_normal() const; 00433 bool get_normal_info(const GeomVertexArrayDataHandle *&array_reader, 00434 NumericType &numeric_type, 00435 int &start, int &stride) const; 00436 00437 INLINE bool has_color() const; 00438 bool get_color_info(const GeomVertexArrayDataHandle *&array_reader, 00439 int &num_values, NumericType &numeric_type, 00440 int &start, int &stride) const; 00441 00442 private: 00443 void make_array_readers(); 00444 void delete_array_readers(); 00445 00446 bool _got_array_readers; 00447 typedef pvector<CPT(GeomVertexArrayDataHandle) > ArrayReaders; 00448 ArrayReaders _array_readers; 00449 00450 public: 00451 static TypeHandle get_class_type() { 00452 return _type_handle; 00453 } 00454 static void init_type() { 00455 register_type(_type_handle, "GeomVertexDataPipelineReader"); 00456 } 00457 00458 private: 00459 static TypeHandle _type_handle; 00460 }; 00461 00462 //////////////////////////////////////////////////////////////////// 00463 // Class : GeomVertexDataPipelineWriter 00464 // Description : Encapsulates the data from a GeomVertexData, 00465 // pre-fetched for one stage of the pipeline. 00466 //////////////////////////////////////////////////////////////////// 00467 class EXPCL_PANDA_GOBJ GeomVertexDataPipelineWriter : public GeomVertexDataPipelineBase { 00468 public: 00469 INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0, 00470 Thread *current_thread); 00471 private: 00472 INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©); 00473 INLINE void operator = (const GeomVertexDataPipelineWriter ©); 00474 00475 public: 00476 INLINE ~GeomVertexDataPipelineWriter(); 00477 ALLOC_DELETED_CHAIN(GeomVertexDataPipelineWriter); 00478 00479 INLINE GeomVertexData *get_object() const; 00480 00481 INLINE void check_array_writers() const; 00482 INLINE GeomVertexArrayDataHandle *get_array_writer(int i) const; 00483 00484 PT(GeomVertexArrayData) modify_array(int i); 00485 void set_array(int i, const GeomVertexArrayData *array); 00486 00487 int get_num_rows() const; 00488 bool set_num_rows(int n); 00489 bool unclean_set_num_rows(int n); 00490 00491 private: 00492 void make_array_writers(); 00493 void delete_array_writers(); 00494 00495 bool _force_to_0; 00496 bool _got_array_writers; 00497 typedef pvector<PT(GeomVertexArrayDataHandle) > ArrayWriters; 00498 ArrayWriters _array_writers; 00499 00500 public: 00501 static TypeHandle get_class_type() { 00502 return _type_handle; 00503 } 00504 static void init_type() { 00505 register_type(_type_handle, "GeomVertexDataPipelineWriter"); 00506 } 00507 00508 private: 00509 static TypeHandle _type_handle; 00510 }; 00511 00512 INLINE ostream &operator << (ostream &out, const GeomVertexData &obj); 00513 00514 #include "geomVertexData.I" 00515 00516 #endif