Panda3D
Loading...
Searching...
No Matches
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"
22#include "cycleDataReader.h"
23#include "cycleDataWriter.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
43class 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 */
54class EXPCL_PANDA_GOBJ Geom : public CopyOnWriteObject, public GeomEnums {
55protected:
56 virtual PT(CopyOnWriteObject) make_cow_copy();
57
58PUBLISHED:
59 explicit Geom(const GeomVertexData *data);
60
61protected:
62 Geom(const Geom &copy);
63
64PUBLISHED:
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 = Thread::get_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
159public:
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
180private:
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
206private:
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
251public:
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
302private:
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
361public:
362 static void register_with_read_factory();
363 virtual void write_datagram(BamWriter *manager, Datagram &dg);
364
365 virtual void finalize(BamReader *manager);
366
367protected:
368 static TypedWritable *make_from_bam(const FactoryParams &params);
369 void fillin(DatagramIterator &scan, BamReader *manager);
370
371public:
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
388private:
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 */
405class EXPCL_PANDA_GOBJ GeomPipelineReader : public GeomEnums {
406public:
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
438private:
439 const Geom *_object;
440 Thread *_current_thread;
441 const Geom::CData *_cdata;
442
443public:
444 static TypeHandle get_class_type() {
445 return _type_handle;
446 }
447 static void init_type() {
448 register_type(_type_handle, "GeomPipelineReader");
449 }
450
451private:
452 static TypeHandle _type_handle;
453};
454
455INLINE 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.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
Definition cycleData.h:50
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
An instance of this class is passed to the Factory when requesting it to do its business and construc...
This object contains a single cache entry in the GeomCacheManager.
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition geomContext.h:34
This class exists just to provide scoping for the various enumerated types used by Geom,...
Definition geomEnums.h:24
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition geomMunger.h:50
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Definition geom.h:405
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition geom.h:54
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
An STL function object class, this is intended to be used on any ordered collection of pointers to cl...
Encodes a string name in a hash table, mapping it to a pointer.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition lightMutex.h:41
A lightweight class that represents a single element that may be timed and/or counted via stats.
A table of objects that are saved within the graphics context for reference by handle later.
A thread; that is, a lightweight process.
Definition thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
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...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
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().
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
This is our own Panda specialization on the default STL list.
Definition plist.h:35
This is our own Panda specialization on the default STL map.
Definition pmap.h:49
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
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.
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.
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.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
This class maintains different copies of a page of data between stages of the graphics pipeline (or a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.