Panda3D
geom.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file geom.h
10  * @author drose
11  * @date 2005-03-06
12  */
13 
14 #ifndef GEOM_H
15 #define GEOM_H
16 
17 #include "pandabase.h"
18 #include "copyOnWriteObject.h"
19 #include "copyOnWritePointer.h"
20 #include "cycleData.h"
21 #include "cycleDataLockedReader.h"
22 #include "cycleDataReader.h"
23 #include "cycleDataWriter.h"
24 #include "cycleDataStageReader.h"
25 #include "cycleDataStageWriter.h"
26 #include "pipelineCycler.h"
27 #include "geomVertexData.h"
28 #include "geomPrimitive.h"
29 #include "geomMunger.h"
30 #include "geomEnums.h"
31 #include "geomCacheEntry.h"
32 #include "textureStage.h"
33 #include "updateSeq.h"
34 #include "pointerTo.h"
35 #include "indirectLess.h"
36 #include "pset.h"
37 #include "pmap.h"
38 #include "boundingVolume.h"
39 #include "pStatCollector.h"
40 #include "deletedChain.h"
41 #include "lightMutex.h"
42 
43 class GeomContext;
45 
46 /**
47  * A container for geometry primitives. This class associates one or more
48  * GeomPrimitive objects with a table of vertices defined by a GeomVertexData
49  * object. All of the primitives stored in a particular Geom are drawn from
50  * the same set of vertices (each primitive uses a subset of all of the
51  * vertices in the table), and all of them must be rendered at the same time,
52  * in the same graphics state.
53  */
54 class EXPCL_PANDA_GOBJ Geom : public CopyOnWriteObject, public GeomEnums {
55 protected:
56  virtual PT(CopyOnWriteObject) make_cow_copy();
57 
58 PUBLISHED:
59  explicit Geom(const GeomVertexData *data);
60 
61 protected:
62  Geom(const Geom &copy);
63 
64 PUBLISHED:
65  void operator = (const Geom &copy);
66  virtual ~Geom();
67  ALLOC_DELETED_CHAIN(Geom);
68 
69  virtual Geom *make_copy() const;
70 
71  INLINE PrimitiveType get_primitive_type() const;
72  INLINE ShadeModel get_shade_model() const;
73  INLINE int get_geom_rendering() const;
74  MAKE_PROPERTY(primitive_type, get_primitive_type);
75  MAKE_PROPERTY(shade_model, get_shade_model);
76  MAKE_PROPERTY(geom_rendering, get_geom_rendering);
77 
78  UsageHint get_usage_hint() const;
79  void set_usage_hint(UsageHint usage_hint);
80  //MAKE_PROPERTY(usage_hint, get_usage_hint, set_usage_hint);
81 
82  INLINE CPT(GeomVertexData) get_vertex_data(Thread *current_thread = Thread::get_current_thread()) const;
83  PT(GeomVertexData) modify_vertex_data();
84  void set_vertex_data(const GeomVertexData *data);
85  void offset_vertices(const GeomVertexData *data, int offset);
86  int make_nonindexed(bool composite_only);
87 
88  CPT(GeomVertexData) get_animated_vertex_data(bool force, Thread *current_thread) const;
89 
90  INLINE bool is_empty() const;
91 
92  INLINE size_t get_num_primitives() const;
93  INLINE CPT(GeomPrimitive) get_primitive(size_t i) const;
94  MAKE_SEQ(get_primitives, get_num_primitives, get_primitive);
95  INLINE PT(GeomPrimitive) modify_primitive(size_t i);
96  void set_primitive(size_t i, const GeomPrimitive *primitive);
97  void insert_primitive(size_t i, const GeomPrimitive *primitive);
98  INLINE void add_primitive(const GeomPrimitive *primitive);
99  void remove_primitive(size_t i);
100  void clear_primitives();
101  MAKE_SEQ_PROPERTY(primitives, get_num_primitives, get_primitive, set_primitive, remove_primitive, insert_primitive);
102 
103  INLINE PT(Geom) decompose() const;
104  INLINE PT(Geom) doubleside() const;
105  INLINE PT(Geom) reverse() const;
106  INLINE PT(Geom) rotate() const;
107  INLINE PT(Geom) unify(int max_indices, bool preserve_order) const;
108  INLINE PT(Geom) make_points() const;
109  INLINE PT(Geom) make_lines() const;
110  INLINE PT(Geom) make_patches() const;
111  INLINE PT(Geom) make_adjacency() const;
112 
113  void decompose_in_place();
114  void doubleside_in_place();
115  void reverse_in_place();
116  void rotate_in_place();
117  void unify_in_place(int max_indices, bool preserve_order);
118  void make_points_in_place();
119  void make_lines_in_place();
120  void make_patches_in_place();
121  void make_adjacency_in_place();
122 
123  virtual bool copy_primitives_from(const Geom *other);
124 
125  int get_num_bytes() const;
126  INLINE UpdateSeq get_modified(Thread *current_thread = Thread::get_current_thread()) const;
127  MAKE_PROPERTY(num_bytes, get_num_bytes);
128  MAKE_PROPERTY(modified, get_modified);
129 
130  bool request_resident() const;
131 
132  void transform_vertices(const LMatrix4 &mat);
133  bool check_valid() const;
134  bool check_valid(const GeomVertexData *vertex_data) const;
135 
136  CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
137  int get_nested_vertices(Thread *current_thread = Thread::get_current_thread()) const;
138  INLINE void mark_bounds_stale() const;
139  INLINE void set_bounds_type(BoundingVolume::BoundsType bounds_type);
140  INLINE BoundingVolume::BoundsType get_bounds_type() const;
141  INLINE void set_bounds(const BoundingVolume *volume);
142  INLINE void clear_bounds();
143  MAKE_PROPERTY(bounds_type, get_bounds_type, set_bounds_type);
144 
145  virtual void output(std::ostream &out) const;
146  virtual void write(std::ostream &out, int indent_level = 0) const;
147 
148  void clear_cache();
149  void clear_cache_stage(Thread *current_thread);
150 
151  void prepare(PreparedGraphicsObjects *prepared_objects);
152  bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
153  bool release(PreparedGraphicsObjects *prepared_objects);
154  int release_all();
155 
156  GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
158 
159 public:
160  bool draw(GraphicsStateGuardianBase *gsg,
161  const GeomVertexData *vertex_data,
162  bool force, Thread *current_thread) const;
163 
164  INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
165  bool &found_any,
166  const GeomVertexData *vertex_data,
167  bool got_mat, const LMatrix4 &mat,
168  Thread *current_thread) const;
169  INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
170  bool &found_any, Thread *current_thread) const;
171  INLINE void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
172  bool &found_any,
173  const GeomVertexData *vertex_data,
174  bool got_mat, const LMatrix4 &mat,
175  const InternalName *column_name,
176  Thread *current_thread) const;
177 
178  static UpdateSeq get_next_modified();
179 
180 private:
181  class CData;
182 
183  INLINE void mark_internal_bounds_stale(CData *cdata);
184  void compute_internal_bounds(CData *cdata, Thread *current_thread) const;
185 
186  void do_calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
187  PN_stdfloat &sq_center_dist, bool &found_any,
188  const GeomVertexData *vertex_data,
189  bool got_mat, const LMatrix4 &mat,
190  const InternalName *column_name,
191  const CData *cdata, Thread *current_thread) const;
192 
193  void do_calc_sphere_radius(const LPoint3 &center,
194  PN_stdfloat &sq_radius, bool &found_any,
195  const GeomVertexData *vertex_data,
196  const CData *cdata, Thread *current_thread) const;
197 
198  void clear_prepared(PreparedGraphicsObjects *prepared_objects);
199  bool check_will_be_valid(const GeomVertexData *vertex_data) const;
200 
201  void reset_geom_rendering(CData *cdata);
202 
203  void combine_primitives(GeomPrimitive *a_prim, CPT(GeomPrimitive) b_prim,
204  Thread *current_thread);
205 
206 private:
207  typedef pvector<COWPT(GeomPrimitive) > Primitives;
208 
209  // We have to use reference-counting pointers here instead of having
210  // explicit cleanup in the GeomVertexFormat destructor, because the cache
211  // needs to be stored in the CycleData, which makes accurate cleanup more
212  // difficult. We use the GeomCacheManager class to avoid cache bloat.
213 
214  // Note: the above comment is no longer true. The cache is not stored in
215  // the CycleData, which just causes problems; instead, we cycle each
216  // individual CacheEntry as needed. Need to investigate if we could
217  // simplify the cache system now.
218 
219  // The pipelined data with each CacheEntry.
220  class EXPCL_PANDA_GOBJ CDataCache : public CycleData {
221  public:
222  INLINE CDataCache();
223  INLINE CDataCache(const CDataCache &copy);
224  virtual ~CDataCache();
225  ALLOC_DELETED_CHAIN(CDataCache);
226  virtual CycleData *make_copy() const;
227  virtual TypeHandle get_parent_type() const {
228  return Geom::get_class_type();
229  }
230 
231  INLINE void set_result(const Geom *geom_result, const GeomVertexData *data_result);
232 
233  Geom *_source; // A back pointer to the containing Geom
234  const Geom *_geom_result; // ref-counted if not NULL and not same as _source
235  CPT(GeomVertexData) _data_result;
236 
237  public:
238  static TypeHandle get_class_type() {
239  return _type_handle;
240  }
241  static void init_type() {
242  register_type(_type_handle, "Geom::CDataCache");
243  }
244 
245  private:
246  static TypeHandle _type_handle;
247  };
248  typedef CycleDataReader<CDataCache> CDCacheReader;
249  typedef CycleDataWriter<CDataCache> CDCacheWriter;
250 
251 public:
252  // The CacheKey class separates out just the part of CacheEntry that is used
253  // to key the cache entry within the map. We have this as a separate class
254  // so we can easily look up a new entry in the map, without having to
255  // execute the relatively expensive CacheEntry constructor.
256  class CacheKey {
257  public:
258  INLINE CacheKey(const GeomVertexData *source_data,
259  const GeomMunger *modifier);
260  INLINE CacheKey(const CacheKey &copy);
261  INLINE CacheKey(CacheKey &&from) noexcept;
262 
263  INLINE bool operator < (const CacheKey &other) const;
264 
265  CPT(GeomVertexData) _source_data;
266  CPT(GeomMunger) _modifier;
267  };
268  // It is not clear why MSVC7 needs this class to be public.
269  class CacheEntry : public GeomCacheEntry {
270  public:
271  INLINE CacheEntry(Geom *source,
272  const GeomVertexData *source_data,
273  const GeomMunger *modifier);
274  INLINE CacheEntry(Geom *source, const CacheKey &key);
275  INLINE CacheEntry(Geom *source, CacheKey &&key) noexcept;
276 
277  ALLOC_DELETED_CHAIN(CacheEntry);
278 
279  virtual void evict_callback();
280  virtual void output(std::ostream &out) const;
281 
282  Geom *_source; // A back pointer to the containing Geom
283  CacheKey _key;
284 
286 
287  public:
288  static TypeHandle get_class_type() {
289  return _type_handle;
290  }
291  static void init_type() {
292  GeomCacheEntry::init_type();
293  register_type(_type_handle, "Geom::CacheEntry",
294  GeomCacheEntry::get_class_type());
295  }
296 
297  private:
298  static TypeHandle _type_handle;
299  };
300  typedef pmap<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > Cache;
301 
302 private:
303  // This is the data that must be cycled between pipeline stages.
304  class EXPCL_PANDA_GOBJ CData : public CycleData {
305  public:
306  INLINE CData();
307  INLINE CData(GeomVertexData *data);
308 
309  ALLOC_DELETED_CHAIN(CData);
310  virtual CycleData *make_copy() const;
311  virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
312  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
313  virtual void fillin(DatagramIterator &scan, BamReader *manager);
314  virtual TypeHandle get_parent_type() const {
315  return Geom::get_class_type();
316  }
317 
318  COWPT(GeomVertexData) _data;
319  Primitives _primitives;
320  PrimitiveType _primitive_type;
321  ShadeModel _shade_model;
322  int _geom_rendering;
323  UpdateSeq _modified;
324 
325  CPT(BoundingVolume) _internal_bounds;
326  int _nested_vertices;
327  bool _internal_bounds_stale;
328  BoundingVolume::BoundsType _bounds_type;
329  CPT(BoundingVolume) _user_bounds;
330 
331  public:
332  static TypeHandle get_class_type() {
333  return _type_handle;
334  }
335  static void init_type() {
336  register_type(_type_handle, "Geom::CData");
337  }
338 
339  private:
340  static TypeHandle _type_handle;
341  };
342 
343  PipelineCycler<CData> _cycler;
344  typedef CycleDataLockedReader<CData> CDLockedReader;
345  typedef CycleDataReader<CData> CDReader;
346  typedef CycleDataWriter<CData> CDWriter;
347  typedef CycleDataStageReader<CData> CDStageReader;
348  typedef CycleDataStageWriter<CData> CDStageWriter;
349 
350  Cache _cache;
351  LightMutex _cache_lock;
352 
353  // This works just like the Texture contexts: each Geom keeps a record of
354  // all the PGO objects that hold the Geom, and vice-versa.
356  Contexts _contexts;
357 
358  static UpdateSeq _next_modified;
359  static PStatCollector _draw_primitive_setup_pcollector;
360 
361 public:
362  static void register_with_read_factory();
363  virtual void write_datagram(BamWriter *manager, Datagram &dg);
364 
365  virtual void finalize(BamReader *manager);
366 
367 protected:
368  static TypedWritable *make_from_bam(const FactoryParams &params);
369  void fillin(DatagramIterator &scan, BamReader *manager);
370 
371 public:
372  static TypeHandle get_class_type() {
373  return _type_handle;
374  }
375  static void init_type() {
376  CopyOnWriteObject::init_type();
377  register_type(_type_handle, "Geom",
378  CopyOnWriteObject::get_class_type());
379  CDataCache::init_type();
380  CacheEntry::init_type();
381  CData::init_type();
382  }
383  virtual TypeHandle get_type() const {
384  return get_class_type();
385  }
386  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
387 
388 private:
389  static TypeHandle _type_handle;
390 
391  friend class CacheEntry;
392  friend class GeomMunger;
393  friend class GeomContext;
394  friend class GeomPipelineReader;
395  friend class PreparedGraphicsObjects;
396 };
397 
398 /**
399  * Encapsulates the data from a Geom, pre-fetched for one stage of the
400  * pipeline.
401  *
402  * Does not hold a reference to the Geom. The caller must ensure that the
403  * Geom persists for at least the lifetime of the GeomPipelineReader.
404  */
405 class EXPCL_PANDA_GOBJ GeomPipelineReader : public GeomEnums {
406 public:
407  INLINE GeomPipelineReader(Thread *current_thread);
408  INLINE GeomPipelineReader(const Geom *object, Thread *current_thread);
409  GeomPipelineReader(const GeomPipelineReader &copy) = delete;
410  INLINE ~GeomPipelineReader();
411 
412  ALLOC_DELETED_CHAIN(GeomPipelineReader);
413 
414  GeomPipelineReader &operator = (const GeomPipelineReader &copy) = delete;
415 
416  INLINE void set_object(const Geom *object);
417  INLINE const Geom *get_object() const;
418  INLINE Thread *get_current_thread() const;
419 
420  INLINE PrimitiveType get_primitive_type() const;
421  INLINE ShadeModel get_shade_model() const;
422  INLINE int get_geom_rendering() const;
423  INLINE CPT(GeomVertexData) get_vertex_data() const;
424  INLINE int get_num_primitives() const;
425  INLINE CPT(GeomPrimitive) get_primitive(int i) const;
426 
427  INLINE UpdateSeq get_modified() const;
428 
429  bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
430 
431  INLINE GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
432  GraphicsStateGuardianBase *gsg) const;
433 
434  bool draw(GraphicsStateGuardianBase *gsg,
435  const GeomVertexDataPipelineReader *data_reader,
436  bool force) const;
437 
438 private:
439  const Geom *_object;
440  Thread *_current_thread;
441  const Geom::CData *_cdata;
442 
443 public:
444  static TypeHandle get_class_type() {
445  return _type_handle;
446  }
447  static void init_type() {
448  register_type(_type_handle, "GeomPipelineReader");
449  }
450 
451 private:
452  static TypeHandle _type_handle;
453 };
454 
455 INLINE std::ostream &operator << (std::ostream &out, const Geom &obj);
456 
457 #include "geom.I"
458 
459 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: geomContext.h:34
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition: geomMunger.h:50
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:47
This class exists just to provide scoping for the various enumerated types used by Geom,...
Definition: geomEnums.h:24
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual TypeHandle get_parent_type() const
Returns the type of the container that owns the CycleData.
Definition: cycleData.cxx:76
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is our own Panda specialization on the default STL list.
Definition: plist.h:35
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Definition: geom.h:405
A table of objects that are saved within the graphics context for reference by handle later.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
An STL function object class, this is intended to be used on any ordered collection of pointers to cl...
Definition: indirectLess.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats.
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:32
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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(...
A container for geometry primitives.
Definition: geom.h:54
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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:48
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Encodes a string name in a hash table, mapping it to a pointer.
Definition: internalName.h:38
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
Definition: cycleData.cxx:58
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:39
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.