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