Panda3D
geomVertexData.h
1 // Filename: geomVertexData.h
2 // Created by: drose (06Mar05)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef GEOMVERTEXDATA_H
16 #define GEOMVERTEXDATA_H
17 
18 #include "pandabase.h"
19 #include "copyOnWriteObject.h"
20 #include "copyOnWritePointer.h"
21 #include "geomVertexFormat.h"
22 #include "geomVertexColumn.h"
23 #include "geomVertexArrayData.h"
24 #include "geomEnums.h"
25 #include "geomCacheEntry.h"
26 #include "transformTable.h"
27 #include "transformBlendTable.h"
28 #include "sliderTable.h"
29 #include "internalName.h"
30 #include "cycleData.h"
31 #include "cycleDataLockedReader.h"
32 #include "cycleDataReader.h"
33 #include "cycleDataWriter.h"
34 #include "cycleDataStageReader.h"
35 #include "cycleDataStageWriter.h"
36 #include "pipelineCycler.h"
37 #include "pStatCollector.h"
38 #include "pointerTo.h"
39 #include "pmap.h"
40 #include "pvector.h"
41 #include "deletedChain.h"
42 
43 class FactoryParams;
44 class GeomVertexColumn;
45 class GeomVertexRewriter;
46 
47 ////////////////////////////////////////////////////////////////////
48 // Class : GeomVertexData
49 // Description : This defines the actual numeric vertex data stored in
50 // a Geom, in the structure defined by a particular
51 // GeomVertexFormat object.
52 //
53 // The data consists of one or more arrays, each of
54 // which in turn consists of a series of rows, one per
55 // vertex. All arrays should have the same number of
56 // rows; each vertex is defined by the column data from
57 // a particular row across all arrays.
58 //
59 // Often, there will be only one array per Geom, and the
60 // various columns defined in the GeomVertexFormat will
61 // be interleaved within that array. However, it is
62 // also possible to have multiple different arrays, with
63 // a certain subset of the total columns defined in each
64 // array.
65 //
66 // However the data is distributed, the effect is of a
67 // single table of vertices, where each vertex is
68 // represented by one row of the table.
69 //
70 // In general, application code should not attempt to
71 // directly manipulate the vertex data through this
72 // structure; instead, use the GeomVertexReader,
73 // GeomVertexWriter, and GeomVertexRewriter objects to
74 // read and write vertex data at a high level.
75 ////////////////////////////////////////////////////////////////////
76 class EXPCL_PANDA_GOBJ GeomVertexData : public CopyOnWriteObject, public GeomEnums {
77 private:
79 protected:
80  virtual PT(CopyOnWriteObject) make_cow_copy();
81 
82 PUBLISHED:
83  GeomVertexData(const string &name,
84  const GeomVertexFormat *format,
85  UsageHint usage_hint);
86  GeomVertexData(const GeomVertexData &copy);
87  GeomVertexData(const GeomVertexData &copy,
88  const GeomVertexFormat *format);
89  void operator = (const GeomVertexData &copy);
90  virtual ~GeomVertexData();
91  ALLOC_DELETED_CHAIN(GeomVertexData);
92 
93  int compare_to(const GeomVertexData &other) const;
94 
95  INLINE const string &get_name() const;
96  void set_name(const string &name);
97 
98  INLINE UsageHint get_usage_hint() const;
99  void set_usage_hint(UsageHint usage_hint);
100 
101  INLINE const GeomVertexFormat *get_format() const;
102  void set_format(const GeomVertexFormat *format);
103  void unclean_set_format(const GeomVertexFormat *format);
104 
105  INLINE bool has_column(const InternalName *name) const;
106 
107  INLINE int get_num_rows() const;
108  INLINE bool set_num_rows(int n);
109  INLINE bool unclean_set_num_rows(int n);
110  INLINE bool reserve_num_rows(int n);
111  void clear_rows();
112 
113  INLINE int get_num_arrays() const;
114  INLINE CPT(GeomVertexArrayData) get_array(int i) const;
115  MAKE_SEQ(get_arrays, get_num_arrays, get_array);
116  INLINE PT(GeomVertexArrayData) modify_array(int i);
117  INLINE void set_array(int i, const GeomVertexArrayData *array);
118 
119  INLINE const TransformTable *get_transform_table() const;
120  void set_transform_table(const TransformTable *table);
121  INLINE void clear_transform_table();
122 
123  INLINE CPT(TransformBlendTable) get_transform_blend_table() const;
124  PT(TransformBlendTable) modify_transform_blend_table();
125  void set_transform_blend_table(const TransformBlendTable *table);
126  INLINE void clear_transform_blend_table();
127 
128  INLINE const SliderTable *get_slider_table() const;
129  void set_slider_table(const SliderTable *table);
130  INLINE void clear_slider_table();
131 
132  INLINE int get_num_bytes() const;
133  INLINE UpdateSeq get_modified(Thread *current_thread = Thread::get_current_thread()) const;
134 
135  bool request_resident() const;
136 
137  void copy_from(const GeomVertexData *source, bool keep_data_objects,
138  Thread *current_thread = Thread::get_current_thread());
139  void copy_row_from(int dest_row, const GeomVertexData *source,
140  int source_row, Thread *current_thread);
141  CPT(GeomVertexData) convert_to(const GeomVertexFormat *new_format) const;
142  CPT(GeomVertexData)
143  scale_color(const LVecBase4 &color_scale) const;
144  CPT(GeomVertexData)
145  scale_color(const LVecBase4 &color_scale, int num_components,
146  NumericType numeric_type, Contents contents) const;
147  CPT(GeomVertexData)
148  set_color(const LColor &color) const;
149  CPT(GeomVertexData)
150  set_color(const LColor &color, int num_components,
151  NumericType numeric_type, Contents contents) const;
152 
153  CPT(GeomVertexData) reverse_normals() const;
154 
155  CPT(GeomVertexData) animate_vertices(bool force, Thread *current_thread) const;
156  void clear_animated_vertices();
157  void transform_vertices(const LMatrix4 &mat);
158  void transform_vertices(const LMatrix4 &mat, int begin_row, int end_row);
159  void transform_vertices(const LMatrix4 &mat, const SparseArray &rows);
160 
161  PT(GeomVertexData)
162  replace_column(InternalName *name, int num_components,
163  NumericType numeric_type, Contents contents) const;
164 
165  void output(ostream &out) const;
166  void write(ostream &out, int indent_level = 0) const;
167  void describe_vertex(ostream &out, int row) const;
168 
169  void clear_cache();
170  void clear_cache_stage();
171 
172 public:
173  static INLINE PN_uint32 pack_abcd(unsigned int a, unsigned int b,
174  unsigned int c, unsigned int d);
175  static INLINE unsigned int unpack_abcd_a(PN_uint32 data);
176  static INLINE unsigned int unpack_abcd_b(PN_uint32 data);
177  static INLINE unsigned int unpack_abcd_c(PN_uint32 data);
178  static INLINE unsigned int unpack_abcd_d(PN_uint32 data);
179 
180 private:
181  static void bytewise_copy(unsigned char *to, int to_stride,
182  const unsigned char *from, int from_stride,
183  const GeomVertexColumn *from_type,
184  int num_records);
185  static void
186  packed_argb_to_uint8_rgba(unsigned char *to, int to_stride,
187  const unsigned char *from, int from_stride,
188  int num_records);
189  static void
190  uint8_rgba_to_packed_argb(unsigned char *to, int to_stride,
191  const unsigned char *from, int from_stride,
192  int num_records);
193 
195  INLINE static int
196  add_transform(TransformTable *table, const VertexTransform *transform,
197  TransformMap &already_added);
198 
199 private:
200  string _name;
201 
203 
204  // The pipelined data with each CacheEntry.
205  class EXPCL_PANDA_GOBJ CDataCache : public CycleData {
206  public:
207  INLINE CDataCache();
208  INLINE CDataCache(const CDataCache &copy);
209  ALLOC_DELETED_CHAIN(CDataCache);
210  virtual CycleData *make_copy() const;
211  virtual TypeHandle get_parent_type() const {
212  return GeomVertexData::get_class_type();
213  }
214 
215  CPT(GeomVertexData) _result;
216 
217  public:
218  static TypeHandle get_class_type() {
219  return _type_handle;
220  }
221  static void init_type() {
222  register_type(_type_handle, "GeomVertexData::CDataCache");
223  }
224 
225  private:
226  static TypeHandle _type_handle;
227  };
230 
231 public:
232  // The CacheKey class separates out just the part of CacheEntry that
233  // is used to key the cache entry within the map. We have this as a
234  // separate class so we can easily look up a new entry in the map,
235  // without having to execute the relatively expensive CacheEntry
236  // constructor.
237  class EXPCL_PANDA_GOBJ CacheKey {
238  public:
239  INLINE CacheKey(const GeomVertexFormat *modifier);
240  INLINE CacheKey(const CacheKey &copy);
241 #ifdef USE_MOVE_SEMANTICS
242  INLINE CacheKey(CacheKey &&from) NOEXCEPT;
243 #endif
244 
245  INLINE bool operator < (const CacheKey &other) const;
246 
247  CPT(GeomVertexFormat) _modifier;
248  };
249  // It is not clear why MSVC7 needs this class to be public.
250  class EXPCL_PANDA_GOBJ CacheEntry : public GeomCacheEntry {
251  public:
252  INLINE CacheEntry(GeomVertexData *source,
253  const GeomVertexFormat *modifier);
254  INLINE CacheEntry(GeomVertexData *source, const CacheKey &key);
255 #ifdef USE_MOVE_SEMANTICS
256  INLINE CacheEntry(GeomVertexData *source, CacheKey &&key) NOEXCEPT;
257 #endif
258  ALLOC_DELETED_CHAIN(CacheEntry);
259 
260  virtual void evict_callback();
261  virtual void output(ostream &out) const;
262 
263  GeomVertexData *_source; // A back pointer to the containing data.
264  CacheKey _key;
265 
267 
268  public:
269  static TypeHandle get_class_type() {
270  return _type_handle;
271  }
272  static void init_type() {
273  GeomCacheEntry::init_type();
274  register_type(_type_handle, "GeomVertexData::CacheEntry",
275  GeomCacheEntry::get_class_type());
276  }
277 
278  private:
279  static TypeHandle _type_handle;
280  };
282 
283 private:
284  // This is the data that must be cycled between pipeline stages.
285  class EXPCL_PANDA_GOBJ CData : public CycleData {
286  public:
287  INLINE CData();
288  INLINE CData(const CData &copy);
289  ALLOC_DELETED_CHAIN(CData);
290  virtual CycleData *make_copy() const;
291  virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
292  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
293  virtual void fillin(DatagramIterator &scan, BamReader *manager);
294  virtual TypeHandle get_parent_type() const {
295  return GeomVertexData::get_class_type();
296  }
297 
298  UsageHint _usage_hint;
299  CPT(GeomVertexFormat) _format;
300  Arrays _arrays;
301  CPT(TransformTable) _transform_table;
302  COWPT(TransformBlendTable) _transform_blend_table;
303  CPT(SliderTable) _slider_table;
304  PT(GeomVertexData) _animated_vertices;
305  UpdateSeq _animated_vertices_modified;
306  UpdateSeq _modified;
307 
308  public:
309  static TypeHandle get_class_type() {
310  return _type_handle;
311  }
312  static void init_type() {
313  register_type(_type_handle, "GeomVertexData::CData");
314  }
315 
316  private:
317  static TypeHandle _type_handle;
318  };
319 
320  PipelineCycler<CData> _cycler;
326 
327  Cache _cache;
328  LightMutex _cache_lock;
329 
330 private:
331  void update_animated_vertices(CData *cdata, Thread *current_thread);
332  void do_transform_point_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
333  const LMatrix4 &mat, int begin_row, int end_row);
334  void do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
335  const LMatrix4 &mat, int begin_row, int end_row);
336  static void table_xform_point3f(unsigned char *datat, size_t num_rows,
337  size_t stride, const LMatrix4f &matf);
338  static void table_xform_normal3f(unsigned char *datat, size_t num_rows,
339  size_t stride, const LMatrix4f &matf);
340  static void table_xform_vector3f(unsigned char *datat, size_t num_rows,
341  size_t stride, const LMatrix4f &matf);
342  static void table_xform_vecbase4f(unsigned char *datat, size_t num_rows,
343  size_t stride, const LMatrix4f &matf);
344 
345  static PStatCollector _convert_pcollector;
346  static PStatCollector _scale_color_pcollector;
347  static PStatCollector _set_color_pcollector;
348  static PStatCollector _animation_pcollector;
349 
350  PStatCollector _char_pcollector;
351  PStatCollector _skinning_pcollector;
352  PStatCollector _morphs_pcollector;
353  PStatCollector _blends_pcollector;
354 
355 public:
356  static void register_with_read_factory();
357  virtual void write_datagram(BamWriter *manager, Datagram &dg);
358  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
359  virtual bool require_fully_complete() const;
360 
361  virtual void finalize(BamReader *manager);
362 
363 protected:
364  static TypedWritable *make_from_bam(const FactoryParams &params);
365  void fillin(DatagramIterator &scan, BamReader *manager);
366 
367 public:
368  static TypeHandle get_class_type() {
369  return _type_handle;
370  }
371  static void init_type() {
372  CopyOnWriteObject::init_type();
373  register_type(_type_handle, "GeomVertexData",
374  CopyOnWriteObject::get_class_type());
375  CDataCache::init_type();
376  CacheEntry::init_type();
377  CData::init_type();
378  }
379  virtual TypeHandle get_type() const {
380  return get_class_type();
381  }
382  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
383 
384 private:
385  static TypeHandle _type_handle;
386 
387  friend class CacheEntry;
388  friend class GeomVertexDataPipelineBase;
389  friend class GeomVertexDataPipelineReader;
390  friend class GeomVertexDataPipelineWriter;
391 };
392 
393 ////////////////////////////////////////////////////////////////////
394 // Class : GeomVertexDataPipelineBase
395 // Description : The common code from
396 // GeomVertexDataPipelineReader and
397 // GeomVertexDataPipelineWriter.
398 ////////////////////////////////////////////////////////////////////
399 class EXPCL_PANDA_GOBJ GeomVertexDataPipelineBase : public GeomEnums {
400 protected:
402  Thread *current_thread,
403  GeomVertexData::CData *cdata);
404 
405 public:
406  INLINE ~GeomVertexDataPipelineBase();
407 
408 public:
409  INLINE Thread *get_current_thread() const;
410 
411  INLINE const GeomVertexFormat *get_format() const;
412  INLINE bool has_column(const InternalName *name) const;
413 
414  INLINE UsageHint get_usage_hint() const;
415  INLINE int get_num_arrays() const;
416  INLINE CPT(GeomVertexArrayData) get_array(int i) const;
417  INLINE const TransformTable *get_transform_table() const;
418  INLINE CPT(TransformBlendTable) get_transform_blend_table() const;
419  INLINE const SliderTable *get_slider_table() const;
420  int get_num_bytes() const;
421  INLINE UpdateSeq get_modified() const;
422 
423 protected:
424  PT(GeomVertexData) _object;
425  Thread *_current_thread;
426  GeomVertexData::CData *_cdata;
427 };
428 
429 ////////////////////////////////////////////////////////////////////
430 // Class : GeomVertexDataPipelineReader
431 // Description : Encapsulates the data from a GeomVertexData,
432 // pre-fetched for one stage of the pipeline.
433 ////////////////////////////////////////////////////////////////////
435 public:
436  INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, Thread *current_thread);
437 private:
438  INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader &copy);
439  INLINE void operator = (const GeomVertexDataPipelineReader &copy);
440 
441 public:
442  INLINE ~GeomVertexDataPipelineReader();
443  ALLOC_DELETED_CHAIN(GeomVertexDataPipelineReader);
444 
445  INLINE const GeomVertexData *get_object() const;
446 
447  INLINE void check_array_readers() const;
448  INLINE const GeomVertexArrayDataHandle *get_array_reader(int i) const;
449  int get_num_rows() const;
450 
451  bool get_array_info(const InternalName *name,
452  const GeomVertexArrayDataHandle *&array_reader,
453  int &num_values, NumericType &numeric_type,
454  int &start, int &stride) const;
455 
456  bool get_array_info(const InternalName *name,
457  const GeomVertexArrayDataHandle *&array_reader,
458  int &num_values, NumericType &numeric_type,
459  int &start, int &stride, int &divisor,
460  int &num_elements, int &element_stride) const;
461 
462  INLINE bool has_vertex() const;
463  INLINE bool is_vertex_transformed() const;
464  bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
465  int &num_values, NumericType &numeric_type,
466  int &start, int &stride) const;
467 
468  INLINE bool has_normal() const;
469  bool get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
470  NumericType &numeric_type,
471  int &start, int &stride) const;
472 
473  INLINE bool has_color() const;
474  bool get_color_info(const GeomVertexArrayDataHandle *&array_reader,
475  int &num_values, NumericType &numeric_type,
476  int &start, int &stride) const;
477 
478 private:
479  void make_array_readers();
480  void delete_array_readers();
481 
482  bool _got_array_readers;
484  ArrayReaders _array_readers;
485 
486 public:
487  static TypeHandle get_class_type() {
488  return _type_handle;
489  }
490  static void init_type() {
491  register_type(_type_handle, "GeomVertexDataPipelineReader");
492  }
493 
494 private:
495  static TypeHandle _type_handle;
496 };
497 
498 ////////////////////////////////////////////////////////////////////
499 // Class : GeomVertexDataPipelineWriter
500 // Description : Encapsulates the data from a GeomVertexData,
501 // pre-fetched for one stage of the pipeline.
502 ////////////////////////////////////////////////////////////////////
504 public:
505  INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0,
506  Thread *current_thread);
507 private:
508  INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter &copy);
509  INLINE void operator = (const GeomVertexDataPipelineWriter &copy);
510 
511 public:
512  INLINE ~GeomVertexDataPipelineWriter();
513  ALLOC_DELETED_CHAIN(GeomVertexDataPipelineWriter);
514 
515  INLINE GeomVertexData *get_object() const;
516 
517  INLINE void check_array_writers() const;
518  INLINE GeomVertexArrayDataHandle *get_array_writer(int i) const;
519 
520  PT(GeomVertexArrayData) modify_array(int i);
521  void set_array(int i, const GeomVertexArrayData *array);
522 
523  int get_num_rows() const;
524  bool set_num_rows(int n);
525  bool unclean_set_num_rows(int n);
526  bool reserve_num_rows(int n);
527 
528 private:
529  void make_array_writers();
530  void delete_array_writers();
531 
532  bool _force_to_0;
533  bool _got_array_writers;
535  ArrayWriters _array_writers;
536 
537 public:
538  static TypeHandle get_class_type() {
539  return _type_handle;
540  }
541  static void init_type() {
542  register_type(_type_handle, "GeomVertexDataPipelineWriter");
543  }
544 
545 private:
546  static TypeHandle _type_handle;
547 };
548 
549 INLINE ostream &operator << (ostream &out, const GeomVertexData &obj);
550 
551 #include "geomVertexData.I"
552 
553 #endif
This class records a set of integers, where each integer is either present or not present in the set...
Definition: sparseArray.h:49
The common code from GeomVertexDataPipelineReader and GeomVertexDataPipelineWriter.
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
This class exists just to provide scoping for the various enumerated types used by Geom...
Definition: geomEnums.h:27
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
virtual TypeHandle get_parent_type() const
Returns the type of the container that owns the CycleData.
Definition: cycleData.cxx:91
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is our own Panda specialization on the default STL list.
Definition: plist.h:38
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This defines how a single column is interleaved within a vertex array stored within a Geom...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
A lightweight class that represents a single element that may be timed and/or counted via stats...
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
Definition: sliderTable.h:42
virtual void write_datagram(BamWriter *, Datagram &) const
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: cycleData.cxx:34
This is an abstract base class that holds a pointer to some transform, computed in some arbitrary way...
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual void evict_callback()
Called when the entry is evicted from the cache, this should clean up the owning object appropriately...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
Definition: cycleData.cxx:55
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class&#39;s make_from_bam() method to read in all...
Definition: cycleData.cxx:68
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:79
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
Stores the total set of VertexTransforms that the vertices in a particular GeomVertexData object migh...
A thread; that is, a lightweight process.
Definition: thread.h:51
This structure collects together the different combinations of transforms and blend amounts used by a...
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This object contains a single cache entry in the GeomCacheManager.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This is a sequence number that increments monotonically.
Definition: updateSeq.h:43
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:45
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter, combined together into one convenient package.
This is the data for one array of a GeomVertexData structure.