Panda3D
 All Classes Functions Variables Enumerations
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 
160  PT(GeomVertexData)
161  replace_column(InternalName *name, int num_components,
162  NumericType numeric_type, Contents contents) const;
163 
164  void output(ostream &out) const;
165  void write(ostream &out, int indent_level = 0) const;
166  void describe_vertex(ostream &out, int row) const;
167 
168  void clear_cache();
169  void clear_cache_stage();
170 
171 public:
172  static INLINE PN_uint32 pack_abcd(unsigned int a, unsigned int b,
173  unsigned int c, unsigned int d);
174  static INLINE unsigned int unpack_abcd_a(PN_uint32 data);
175  static INLINE unsigned int unpack_abcd_b(PN_uint32 data);
176  static INLINE unsigned int unpack_abcd_c(PN_uint32 data);
177  static INLINE unsigned int unpack_abcd_d(PN_uint32 data);
178 
179 private:
180  static void bytewise_copy(unsigned char *to, int to_stride,
181  const unsigned char *from, int from_stride,
182  const GeomVertexColumn *from_type,
183  int num_records);
184  static void
185  packed_argb_to_uint8_rgba(unsigned char *to, int to_stride,
186  const unsigned char *from, int from_stride,
187  int num_records);
188  static void
189  uint8_rgba_to_packed_argb(unsigned char *to, int to_stride,
190  const unsigned char *from, int from_stride,
191  int num_records);
192 
194  INLINE static int
195  add_transform(TransformTable *table, const VertexTransform *transform,
196  TransformMap &already_added);
197 
198 private:
199  string _name;
200 
202 
203  // The pipelined data with each CacheEntry.
204  class EXPCL_PANDA_GOBJ CDataCache : public CycleData {
205  public:
206  INLINE CDataCache();
207  INLINE CDataCache(const CDataCache &copy);
208  ALLOC_DELETED_CHAIN(CDataCache);
209  virtual CycleData *make_copy() const;
210  virtual TypeHandle get_parent_type() const {
211  return GeomVertexData::get_class_type();
212  }
213 
214  CPT(GeomVertexData) _result;
215 
216  public:
217  static TypeHandle get_class_type() {
218  return _type_handle;
219  }
220  static void init_type() {
221  register_type(_type_handle, "GeomVertexData::CDataCache");
222  }
223 
224  private:
225  static TypeHandle _type_handle;
226  };
229 
230 public:
231  // The CacheKey class separates out just the part of CacheEntry that
232  // is used to key the cache entry within the map. We have this as a
233  // separate class so we can easily look up a new entry in the map,
234  // without having to execute the relatively expensive CacheEntry
235  // constructor.
236  class EXPCL_PANDA_GOBJ CacheKey {
237  public:
238  INLINE CacheKey(const GeomVertexFormat *modifier);
239  INLINE CacheKey(const CacheKey &copy);
240 #ifdef USE_MOVE_SEMANTICS
241  INLINE CacheKey(CacheKey &&from) NOEXCEPT;
242 #endif
243 
244  INLINE bool operator < (const CacheKey &other) const;
245 
246  CPT(GeomVertexFormat) _modifier;
247  };
248  // It is not clear why MSVC7 needs this class to be public.
249  class EXPCL_PANDA_GOBJ CacheEntry : public GeomCacheEntry {
250  public:
251  INLINE CacheEntry(GeomVertexData *source,
252  const GeomVertexFormat *modifier);
253  INLINE CacheEntry(GeomVertexData *source, const CacheKey &key);
254 #ifdef USE_MOVE_SEMANTICS
255  INLINE CacheEntry(GeomVertexData *source, CacheKey &&key) NOEXCEPT;
256 #endif
257  ALLOC_DELETED_CHAIN(CacheEntry);
258 
259  virtual void evict_callback();
260  virtual void output(ostream &out) const;
261 
262  GeomVertexData *_source; // A back pointer to the containing data.
263  CacheKey _key;
264 
266 
267  public:
268  static TypeHandle get_class_type() {
269  return _type_handle;
270  }
271  static void init_type() {
272  GeomCacheEntry::init_type();
273  register_type(_type_handle, "GeomVertexData::CacheEntry",
274  GeomCacheEntry::get_class_type());
275  }
276 
277  private:
278  static TypeHandle _type_handle;
279  };
281 
282 private:
283  // This is the data that must be cycled between pipeline stages.
284  class EXPCL_PANDA_GOBJ CData : public CycleData {
285  public:
286  INLINE CData();
287  INLINE CData(const CData &copy);
288  ALLOC_DELETED_CHAIN(CData);
289  virtual CycleData *make_copy() const;
290  virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
291  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
292  virtual void fillin(DatagramIterator &scan, BamReader *manager);
293  virtual TypeHandle get_parent_type() const {
294  return GeomVertexData::get_class_type();
295  }
296 
297  UsageHint _usage_hint;
298  CPT(GeomVertexFormat) _format;
299  Arrays _arrays;
300  CPT(TransformTable) _transform_table;
301  COWPT(TransformBlendTable) _transform_blend_table;
302  CPT(SliderTable) _slider_table;
303  PT(GeomVertexData) _animated_vertices;
304  UpdateSeq _animated_vertices_modified;
305  UpdateSeq _modified;
306 
307  public:
308  static TypeHandle get_class_type() {
309  return _type_handle;
310  }
311  static void init_type() {
312  register_type(_type_handle, "GeomVertexData::CData");
313  }
314 
315  private:
316  static TypeHandle _type_handle;
317  };
318 
319  PipelineCycler<CData> _cycler;
320  typedef CycleDataLockedReader<CData> CDLockedReader;
321  typedef CycleDataReader<CData> CDReader;
322  typedef CycleDataWriter<CData> CDWriter;
323  typedef CycleDataStageReader<CData> CDStageReader;
324  typedef CycleDataStageWriter<CData> CDStageWriter;
325 
326  Cache _cache;
327  LightMutex _cache_lock;
328 
329 private:
330  void update_animated_vertices(CData *cdata, Thread *current_thread);
331  void do_transform_point_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
332  const LMatrix4 &mat, int begin_row, int end_row);
333  void do_transform_vector_column(const GeomVertexFormat *format, GeomVertexRewriter &data,
334  const LMatrix4 &mat, int begin_row, int end_row);
335  static void table_xform_point3f(unsigned char *datat, size_t num_rows,
336  size_t stride, const LMatrix4f &matf);
337  static void table_xform_normal3f(unsigned char *datat, size_t num_rows,
338  size_t stride, const LMatrix4f &matf);
339  static void table_xform_vector3f(unsigned char *datat, size_t num_rows,
340  size_t stride, const LMatrix4f &matf);
341  static void table_xform_vecbase4f(unsigned char *datat, size_t num_rows,
342  size_t stride, const LMatrix4f &matf);
343 
344  static PStatCollector _convert_pcollector;
345  static PStatCollector _scale_color_pcollector;
346  static PStatCollector _set_color_pcollector;
347  static PStatCollector _animation_pcollector;
348 
349  PStatCollector _char_pcollector;
350  PStatCollector _skinning_pcollector;
351  PStatCollector _morphs_pcollector;
352  PStatCollector _blends_pcollector;
353 
354 public:
355  static void register_with_read_factory();
356  virtual void write_datagram(BamWriter *manager, Datagram &dg);
357  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
358  virtual bool require_fully_complete() const;
359 
360  virtual void finalize(BamReader *manager);
361 
362 protected:
363  static TypedWritable *make_from_bam(const FactoryParams &params);
364  void fillin(DatagramIterator &scan, BamReader *manager);
365 
366 public:
367  static TypeHandle get_class_type() {
368  return _type_handle;
369  }
370  static void init_type() {
371  CopyOnWriteObject::init_type();
372  register_type(_type_handle, "GeomVertexData",
373  CopyOnWriteObject::get_class_type());
374  CDataCache::init_type();
375  CacheEntry::init_type();
376  CData::init_type();
377  }
378  virtual TypeHandle get_type() const {
379  return get_class_type();
380  }
381  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
382 
383 private:
384  static TypeHandle _type_handle;
385 
386  friend class CacheEntry;
387  friend class GeomVertexDataPipelineBase;
388  friend class GeomVertexDataPipelineReader;
389  friend class GeomVertexDataPipelineWriter;
390 };
391 
392 ////////////////////////////////////////////////////////////////////
393 // Class : GeomVertexDataPipelineBase
394 // Description : The common code from
395 // GeomVertexDataPipelineReader and
396 // GeomVertexDataPipelineWriter.
397 ////////////////////////////////////////////////////////////////////
398 class EXPCL_PANDA_GOBJ GeomVertexDataPipelineBase : public GeomEnums {
399 protected:
401  Thread *current_thread,
402  GeomVertexData::CData *cdata);
403 
404 public:
405  INLINE ~GeomVertexDataPipelineBase();
406 
407 public:
408  INLINE Thread *get_current_thread() const;
409 
410  INLINE const GeomVertexFormat *get_format() const;
411  INLINE bool has_column(const InternalName *name) const;
412 
413  INLINE UsageHint get_usage_hint() const;
414  INLINE int get_num_arrays() const;
415  INLINE CPT(GeomVertexArrayData) get_array(int i) const;
416  INLINE const TransformTable *get_transform_table() const;
417  INLINE CPT(TransformBlendTable) get_transform_blend_table() const;
418  INLINE const SliderTable *get_slider_table() const;
419  int get_num_bytes() const;
420  INLINE UpdateSeq get_modified() const;
421 
422 protected:
423  PT(GeomVertexData) _object;
424  Thread *_current_thread;
425  GeomVertexData::CData *_cdata;
426 };
427 
428 ////////////////////////////////////////////////////////////////////
429 // Class : GeomVertexDataPipelineReader
430 // Description : Encapsulates the data from a GeomVertexData,
431 // pre-fetched for one stage of the pipeline.
432 ////////////////////////////////////////////////////////////////////
434 public:
435  INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, Thread *current_thread);
436 private:
437  INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader &copy);
438  INLINE void operator = (const GeomVertexDataPipelineReader &copy);
439 
440 public:
441  INLINE ~GeomVertexDataPipelineReader();
442  ALLOC_DELETED_CHAIN(GeomVertexDataPipelineReader);
443 
444  INLINE const GeomVertexData *get_object() const;
445 
446  INLINE void check_array_readers() const;
447  INLINE const GeomVertexArrayDataHandle *get_array_reader(int i) const;
448  int get_num_rows() const;
449 
450  bool get_array_info(const InternalName *name,
451  const GeomVertexArrayDataHandle *&array_reader,
452  int &num_values, NumericType &numeric_type,
453  int &start, int &stride) const;
454 
455  bool get_array_info(const InternalName *name,
456  const GeomVertexArrayDataHandle *&array_reader,
457  int &num_values, NumericType &numeric_type,
458  int &start, int &stride, int &divisor,
459  int &num_elements, int &element_stride) const;
460 
461  INLINE bool has_vertex() const;
462  INLINE bool is_vertex_transformed() const;
463  bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
464  int &num_values, NumericType &numeric_type,
465  int &start, int &stride) const;
466 
467  INLINE bool has_normal() const;
468  bool get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
469  NumericType &numeric_type,
470  int &start, int &stride) const;
471 
472  INLINE bool has_color() const;
473  bool get_color_info(const GeomVertexArrayDataHandle *&array_reader,
474  int &num_values, NumericType &numeric_type,
475  int &start, int &stride) const;
476 
477 private:
478  void make_array_readers();
479  void delete_array_readers();
480 
481  bool _got_array_readers;
483  ArrayReaders _array_readers;
484 
485 public:
486  static TypeHandle get_class_type() {
487  return _type_handle;
488  }
489  static void init_type() {
490  register_type(_type_handle, "GeomVertexDataPipelineReader");
491  }
492 
493 private:
494  static TypeHandle _type_handle;
495 };
496 
497 ////////////////////////////////////////////////////////////////////
498 // Class : GeomVertexDataPipelineWriter
499 // Description : Encapsulates the data from a GeomVertexData,
500 // pre-fetched for one stage of the pipeline.
501 ////////////////////////////////////////////////////////////////////
503 public:
504  INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, bool force_to_0,
505  Thread *current_thread);
506 private:
507  INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter &copy);
508  INLINE void operator = (const GeomVertexDataPipelineWriter &copy);
509 
510 public:
511  INLINE ~GeomVertexDataPipelineWriter();
512  ALLOC_DELETED_CHAIN(GeomVertexDataPipelineWriter);
513 
514  INLINE GeomVertexData *get_object() const;
515 
516  INLINE void check_array_writers() const;
517  INLINE GeomVertexArrayDataHandle *get_array_writer(int i) const;
518 
519  PT(GeomVertexArrayData) modify_array(int i);
520  void set_array(int i, const GeomVertexArrayData *array);
521 
522  int get_num_rows() const;
523  bool set_num_rows(int n);
524  bool unclean_set_num_rows(int n);
525  bool reserve_num_rows(int n);
526 
527 private:
528  void make_array_writers();
529  void delete_array_writers();
530 
531  bool _force_to_0;
532  bool _got_array_writers;
534  ArrayWriters _array_writers;
535 
536 public:
537  static TypeHandle get_class_type() {
538  return _type_handle;
539  }
540  static void init_type() {
541  register_type(_type_handle, "GeomVertexDataPipelineWriter");
542  }
543 
544 private:
545  static TypeHandle _type_handle;
546 };
547 
548 INLINE ostream &operator << (ostream &out, const GeomVertexData &obj);
549 
550 #include "geomVertexData.I"
551 
552 #endif
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
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
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 int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager-&gt;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. ...
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
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.