Panda3D
geom.I
1 // Filename: geom.I
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 
16 ////////////////////////////////////////////////////////////////////
17 // Function: Geom::get_primitive_type
18 // Access: Published
19 // Description: Returns the fundamental primitive type that is common
20 // to all GeomPrimitives added within the Geom. All
21 // nested primitives within a particular Geom must be
22 // the same type (that is, you can mix triangles and
23 // tristrips, because they are both the same fundamental
24 // type PT_polygons, but you cannot mix triangles and
25 // points withn the same Geom).
26 ////////////////////////////////////////////////////////////////////
27 INLINE Geom::PrimitiveType Geom::
29  CDReader cdata(_cycler);
30  return cdata->_primitive_type;
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: Geom::get_shade_model
35 // Access: Published
36 // Description: Returns the shade model common to all of the
37 // individual GeomPrimitives that have been added to the
38 // geom.
39 ////////////////////////////////////////////////////////////////////
40 INLINE Geom::ShadeModel Geom::
41 get_shade_model() const {
42  CDReader cdata(_cycler);
43  return cdata->_shade_model;
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: Geom::get_geom_rendering
48 // Access: Published
49 // Description: Returns the set of GeomRendering bits that represent
50 // the rendering properties required to properly render
51 // this Geom.
52 ////////////////////////////////////////////////////////////////////
53 INLINE int Geom::
55  CDReader cdata(_cycler);
56  return cdata->_geom_rendering;
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: Geom::get_usage_hint
61 // Access: Published
62 // Description: Returns the minimum (i.e. most dynamic) usage_hint
63 // among all of the individual GeomPrimitives that have
64 // been added to the geom.
65 ////////////////////////////////////////////////////////////////////
66 INLINE Geom::UsageHint Geom::
67 get_usage_hint() const {
68  CDLockedReader cdata(_cycler);
69  if (!cdata->_got_usage_hint) {
70  CDWriter cdataw(((Geom *)this)->_cycler, cdata, false);
71  ((Geom *)this)->reset_usage_hint(cdataw);
72  return cdataw->_usage_hint;
73  }
74  return cdata->_usage_hint;
75 }
76 
77 ////////////////////////////////////////////////////////////////////
78 // Function: Geom::get_vertex_data
79 // Access: Published
80 // Description: Returns a const pointer to the GeomVertexData,
81 // for application code to directly examine (but not
82 // modify) the geom's underlying data.
83 ////////////////////////////////////////////////////////////////////
84 INLINE CPT(GeomVertexData) Geom::
85 get_vertex_data(Thread *current_thread) const {
86  CDReader cdata(_cycler, current_thread);
87  return cdata->_data.get_read_pointer();
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: Geom::is_empty
92 // Access: Published
93 // Description: Returns true if there appear to be no vertices to be
94 // rendered by this Geom, false if has some actual data.
95 ////////////////////////////////////////////////////////////////////
96 INLINE bool Geom::
97 is_empty() const {
98  CDReader cdata(_cycler);
99  return cdata->_primitives.empty();
100 }
101 
102 ////////////////////////////////////////////////////////////////////
103 // Function: Geom::get_num_primitives
104 // Access: Published
105 // Description: Returns the number of GeomPrimitive objects stored
106 // within the Geom, each of which represents a number of
107 // primitives of a particular type.
108 ////////////////////////////////////////////////////////////////////
109 INLINE int Geom::
110 get_num_primitives() const {
111  CDReader cdata(_cycler);
112  return cdata->_primitives.size();
113 }
114 
115 ////////////////////////////////////////////////////////////////////
116 // Function: Geom::get_primitive
117 // Access: Published
118 // Description: Returns a const pointer to the ith GeomPrimitive
119 // object stored within the Geom. Use this call only to
120 // inspect the ith object; use modify_primitive() or
121 // set_primitive() if you want to modify it.
122 ////////////////////////////////////////////////////////////////////
123 INLINE CPT(GeomPrimitive) Geom::
124 get_primitive(int i) const {
125  CDReader cdata(_cycler);
126  nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
127  return cdata->_primitives[i].get_read_pointer();
128 }
129 
130 ////////////////////////////////////////////////////////////////////
131 // Function: Geom::modify_primitive
132 // Access: Published
133 // Description: Returns a modifiable pointer to the ith GeomPrimitive
134 // object stored within the Geom, so application code
135 // can directly manipulate the properties of this
136 // primitive.
137 //
138 // Don't call this in a downstream thread unless you
139 // don't mind it blowing away other changes you might
140 // have recently made in an upstream thread.
141 ////////////////////////////////////////////////////////////////////
142 INLINE PT(GeomPrimitive) Geom::
143 modify_primitive(int i) {
144  Thread *current_thread = Thread::get_current_thread();
145  CDWriter cdata(_cycler, true, current_thread);
146  nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
147  cdata->_got_usage_hint = false;
148  cdata->_modified = Geom::get_next_modified();
149  clear_cache_stage(current_thread);
150  return cdata->_primitives[i].get_write_pointer();
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: Geom::decompose
155 // Access: Published
156 // Description: Decomposes all of the primitives within this Geom,
157 // returning the result. See
158 // GeomPrimitive::decompose().
159 ////////////////////////////////////////////////////////////////////
160 INLINE PT(Geom) Geom::
161 decompose() const {
162  PT(Geom) new_geom = make_copy();
163  new_geom->decompose_in_place();
164  return new_geom;
165 }
166 
167 ////////////////////////////////////////////////////////////////////
168 // Function: Geom::doubleside
169 // Access: Published
170 // Description: Doublesides all of the primitives within this Geom,
171 // returning the result. See
172 // GeomPrimitive::doubleside().
173 ////////////////////////////////////////////////////////////////////
174 INLINE PT(Geom) Geom::
175 doubleside() const {
176  PT(Geom) new_geom = make_copy();
177  new_geom->doubleside_in_place();
178  return new_geom;
179 }
180 
181 ////////////////////////////////////////////////////////////////////
182 // Function: Geom::reverse
183 // Access: Published
184 // Description: Reverses all of the primitives within this Geom,
185 // returning the result. See
186 // GeomPrimitive::reverse().
187 ////////////////////////////////////////////////////////////////////
188 INLINE PT(Geom) Geom::
189 reverse() const {
190  PT(Geom) new_geom = make_copy();
191  new_geom->reverse_in_place();
192  return new_geom;
193 }
194 
195 ////////////////////////////////////////////////////////////////////
196 // Function: Geom::rotate
197 // Access: Published
198 // Description: Rotates all of the primitives within this Geom,
199 // returning the result. See
200 // GeomPrimitive::rotate().
201 ////////////////////////////////////////////////////////////////////
202 INLINE PT(Geom) Geom::
203 rotate() const {
204  PT(Geom) new_geom = make_copy();
205  new_geom->rotate_in_place();
206  return new_geom;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: Geom::unify
211 // Access: Published
212 // Description: Unifies all of the primitives contained within this
213 // Geom into a single (or as few as possible, within the
214 // constraints of max_indices) primitive objects. This
215 // may require decomposing the primitives if, for
216 // instance, the Geom contains both triangle strips and
217 // triangle fans.
218 //
219 // max_indices represents the maximum number of indices
220 // that will be put in any one GeomPrimitive. If
221 // preserve_order is true, then the primitives will not
222 // be reordered during the operation, even if this
223 // results in a suboptimal result.
224 ////////////////////////////////////////////////////////////////////
225 INLINE PT(Geom) Geom::
226 unify(int max_indices, bool preserve_order) const {
227  PT(Geom) new_geom = make_copy();
228  new_geom->unify_in_place(max_indices, preserve_order);
229  return new_geom;
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: Geom::make_points
234 // Access: Published
235 // Description: Returns a new Geom with points at all the vertices.
236 // See GeomPrimitive::make_points().
237 ////////////////////////////////////////////////////////////////////
238 INLINE PT(Geom) Geom::
239 make_points() const {
240  PT(Geom) new_geom = make_copy();
241  new_geom->make_points_in_place();
242  return new_geom;
243 }
244 
245 ////////////////////////////////////////////////////////////////////
246 // Function: Geom::make_lines
247 // Access: Published
248 // Description: Returns a new Geom with lines at all the edges.
249 // See GeomPrimitive::make_lines().
250 ////////////////////////////////////////////////////////////////////
251 INLINE PT(Geom) Geom::
252 make_lines() const {
253  PT(Geom) new_geom = make_copy();
254  new_geom->make_lines_in_place();
255  return new_geom;
256 }
257 
258 ////////////////////////////////////////////////////////////////////
259 // Function: Geom::make_patches
260 // Access: Published
261 // Description: Returns a new Geom with each primitive converted
262 // into a patch. Calls decompose() first.
263 ////////////////////////////////////////////////////////////////////
264 INLINE PT(Geom) Geom::
265 make_patches() const {
266  PT(Geom) new_geom = make_copy();
267  new_geom->make_patches_in_place();
268  return new_geom;
269 }
270 
271 ////////////////////////////////////////////////////////////////////
272 // Function: Geom::get_modified
273 // Access: Published
274 // Description: Returns a sequence number which is guaranteed to
275 // change at least every time any of the primitives in
276 // the Geom is modified, or the set of primitives is
277 // modified. However, this does not include
278 // modifications to the vertex data, which should be
279 // tested separately.
280 ////////////////////////////////////////////////////////////////////
281 INLINE UpdateSeq Geom::
282 get_modified(Thread *current_thread) const {
283  CDReader cdata(_cycler, current_thread);
284  return cdata->_modified;
285 }
286 
287 ////////////////////////////////////////////////////////////////////
288 // Function: Geom::mark_bounds_stale
289 // Access: Published
290 // Description: Marks the bounding volume of the Geom as stale so
291 // that it should be recomputed. Usually it is not
292 // necessary to call this explicitly.
293 ////////////////////////////////////////////////////////////////////
294 INLINE void Geom::
295 mark_bounds_stale() const {
296  CDWriter cdata(((Geom *)this)->_cycler, false);
297  ((Geom *)this)->mark_internal_bounds_stale(cdata);
298 }
299 
300 ////////////////////////////////////////////////////////////////////
301 // Function: Geom::set_bounds_type
302 // Access: Published
303 // Description: Specifies the desired type of bounding volume that
304 // will be created for this Geom. This is normally
305 // BoundingVolume::BT_default, which means to set the
306 // type according to the config variable "bounds-type".
307 //
308 // If this is BT_sphere or BT_box, a BoundingSphere or
309 // BoundingBox is explicitly created. If it is BT_best,
310 // a BoundingBox is created.
311 //
312 // This affects the implicit bounding volume only. If
313 // an explicit bounding volume is set on the Geom with
314 // set_bounds(), that bounding volume type is used.
315 // (This is different behavior from the similar method
316 // on PandaNode.)
317 ////////////////////////////////////////////////////////////////////
318 INLINE void Geom::
319 set_bounds_type(BoundingVolume::BoundsType bounds_type) {
320  CDWriter cdata(_cycler, true);
321  cdata->_bounds_type = bounds_type;
322  mark_internal_bounds_stale(cdata);
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: Geom::get_bounds_type
327 // Access: Published
328 // Description: Returns the bounding volume type set with
329 // set_bounds_type().
330 ////////////////////////////////////////////////////////////////////
331 INLINE BoundingVolume::BoundsType Geom::
333  CDReader cdata(_cycler);
334  return cdata->_bounds_type;
335 }
336 
337 ////////////////////////////////////////////////////////////////////
338 // Function: Geom::set_bounds
339 // Access: Published
340 // Description: Resets the bounding volume so that it is the
341 // indicated volume. When it is explicitly set, the
342 // bounding volume will no longer be automatically
343 // computed; call clear_bounds() if you would like to
344 // return the bounding volume to its default behavior.
345 //
346 // Don't call this in a downstream thread unless you
347 // don't mind it blowing away other changes you might
348 // have recently made in an upstream thread.
349 ////////////////////////////////////////////////////////////////////
350 INLINE void Geom::
351 set_bounds(const BoundingVolume *volume) {
352  CDWriter cdata(_cycler, true);
353  if (volume == NULL) {
354  cdata->_user_bounds = NULL;
355  } else {
356  cdata->_user_bounds = volume->make_copy();
357  }
358 }
359 
360 ////////////////////////////////////////////////////////////////////
361 // Function: Geom::clear_bounds
362 // Access: Published
363 // Description: Reverses the effect of a previous call to
364 // set_bounds(), and allows the bounding volume to be
365 // automatically computed once more based on the
366 // vertices.
367 //
368 // Don't call this in a downstream thread unless you
369 // don't mind it blowing away other changes you might
370 // have recently made in an upstream thread.
371 ////////////////////////////////////////////////////////////////////
372 INLINE void Geom::
374  CDWriter cdata(_cycler, true);
375  cdata->_user_bounds = NULL;
376  mark_internal_bounds_stale(cdata);
377 }
378 
379 ////////////////////////////////////////////////////////////////////
380 // Function: Geom::calc_tight_bounds
381 // Access: Public
382 // Description: Expands min_point and max_point to include all of the
383 // vertices in the Geom, if any. found_any is set true
384 // if any points are found. It is the caller's
385 // responsibility to initialize min_point, max_point,
386 // and found_any before calling this function.
387 //
388 // This version of the method allows the Geom to specify
389 // an alternate vertex data table (for instance, if the
390 // vertex data has already been munged), and also allows
391 // the result to be computed in any coordinate space by
392 // specifying a transform matrix.
393 ////////////////////////////////////////////////////////////////////
394 INLINE void Geom::
395 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
396  bool &found_any,
397  const GeomVertexData *vertex_data,
398  bool got_mat, const LMatrix4 &mat,
399  Thread *current_thread) const {
400  CDReader cdata(_cycler, current_thread);
401 
402  PN_stdfloat sq_radius;
403  do_calc_tight_bounds(min_point, max_point, sq_radius, found_any,
404  vertex_data, got_mat, mat,
405  InternalName::get_vertex(),
406  cdata, current_thread);
407 }
408 
409 ////////////////////////////////////////////////////////////////////
410 // Function: Geom::calc_tight_bounds
411 // Access: Public, Virtual
412 // Description: Expands min_point and max_point to include all of the
413 // vertices in the Geom, if any. found_any is set true
414 // if any points are found. It is the caller's
415 // responsibility to initialize min_point, max_point,
416 // and found_any before calling this function.
417 //
418 // This version of the method assumes the Geom will use
419 // its own vertex data, and the results are computed in
420 // the Geom's own coordinate space.
421 ////////////////////////////////////////////////////////////////////
422 INLINE void Geom::
423 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
424  bool &found_any, Thread *current_thread) const {
425 
426  calc_tight_bounds(min_point, max_point, found_any,
427  get_vertex_data(current_thread), false,
429  current_thread);
430 }
431 
432 ////////////////////////////////////////////////////////////////////
433 // Function: Geom::calc_tight_bounds
434 // Access: Public
435 // Description: Similar to calc_tight_bounds(), for UV coordinates or
436 // other named columns.
437 ////////////////////////////////////////////////////////////////////
438 INLINE void Geom::
439 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
440  bool &found_any,
441  const GeomVertexData *vertex_data,
442  bool got_mat, const LMatrix4 &mat,
443  const InternalName *column_name,
444  Thread *current_thread) const {
445  CDReader cdata(_cycler, current_thread);
446 
447  PN_stdfloat sq_radius;
448  do_calc_tight_bounds(min_point, max_point, sq_radius, found_any,
449  vertex_data, got_mat, mat,
450  column_name, cdata, current_thread);
451 }
452 
453 ////////////////////////////////////////////////////////////////////
454 // Function: Geom::mark_internal_bounds_stale
455 // Access: Private
456 // Description: Should be called to mark the internal bounding
457 // volume stale, so that recompute_internal_bounds()
458 // will be called when the bounding volume is next
459 // requested.
460 ////////////////////////////////////////////////////////////////////
461 INLINE void Geom::
462 mark_internal_bounds_stale(CData *cdata) {
463  cdata->_internal_bounds_stale = true;
464 }
465 
466 ////////////////////////////////////////////////////////////////////
467 // Function: Geom::CDataCache::Constructor
468 // Access: Public
469 // Description:
470 ////////////////////////////////////////////////////////////////////
471 INLINE Geom::CDataCache::
472 CDataCache() :
473  _source(NULL),
474  _geom_result(NULL),
475  _data_result(NULL)
476 {
477 }
478 
479 ////////////////////////////////////////////////////////////////////
480 // Function: Geom::CDataCache::Copy Constructor
481 // Access: Public
482 // Description:
483 ////////////////////////////////////////////////////////////////////
484 INLINE Geom::CDataCache::
485 CDataCache(const Geom::CDataCache &copy) :
486  _source(copy._source),
487  _geom_result(copy._geom_result),
488  _data_result(copy._data_result)
489 {
490  if (_geom_result != _source && _geom_result != (Geom *)NULL) {
491  _geom_result->ref();
492  }
493 }
494 
495 ////////////////////////////////////////////////////////////////////
496 // Function: Geom::CDataCache::set_result
497 // Access: Public
498 // Description: Stores the geom_result and data_result on the cache,
499 // upping and/or dropping the reference count
500 // appropriately.
501 ////////////////////////////////////////////////////////////////////
502 INLINE void Geom::CDataCache::
503 set_result(const Geom *geom_result, const GeomVertexData *data_result) {
504  if (geom_result != _geom_result) {
505  if (_geom_result != _source && _geom_result != (Geom *)NULL) {
506  unref_delete(_geom_result);
507  }
508  _geom_result = geom_result;
509  if (_geom_result != _source && _geom_result != (Geom *)NULL) {
510  _geom_result->ref();
511  }
512  }
513  _data_result = data_result;
514 }
515 
516 ////////////////////////////////////////////////////////////////////
517 // Function: Geom::CacheKey::Constructor
518 // Access: Public
519 // Description:
520 ////////////////////////////////////////////////////////////////////
521 INLINE Geom::CacheKey::
522 CacheKey(const GeomVertexData *source_data, const GeomMunger *modifier) :
523  _source_data(source_data),
524  _modifier(modifier)
525 {
526 }
527 
528 ////////////////////////////////////////////////////////////////////
529 // Function: Geom::CacheKey::Copy Constructor
530 // Access: Public
531 // Description:
532 ////////////////////////////////////////////////////////////////////
533 INLINE Geom::CacheKey::
534 CacheKey(const CacheKey &copy) :
535  _source_data(copy._source_data),
536  _modifier(copy._modifier)
537 {
538 }
539 
540 #ifdef USE_MOVE_SEMANTICS
541 ////////////////////////////////////////////////////////////////////
542 // Function: Geom::CacheKey::Copy Constructor
543 // Access: Public
544 // Description:
545 ////////////////////////////////////////////////////////////////////
546 INLINE Geom::CacheKey::
547 CacheKey(CacheKey &&from) NOEXCEPT :
548  _source_data(move(from._source_data)),
549  _modifier(move(from._modifier))
550 {
551 }
552 #endif // USE_MOVE_SEMANTICS
553 
554 ////////////////////////////////////////////////////////////////////
555 // Function: Geom::CacheKey::operator <
556 // Access: Public
557 // Description: Provides a unique ordering within the map.
558 ////////////////////////////////////////////////////////////////////
559 INLINE bool Geom::CacheKey::
560 operator < (const CacheKey &other) const {
561  if (_modifier != other._modifier) {
562  int compare = _modifier->geom_compare_to(*other._modifier);
563  if (compare != 0) {
564  return (compare < 0);
565  }
566  }
567  if (_source_data != other._source_data) {
568  return (_source_data < other._source_data);
569  }
570  return 0;
571 }
572 
573 ////////////////////////////////////////////////////////////////////
574 // Function: Geom::CacheEntry::Constructor
575 // Access: Public
576 // Description:
577 ////////////////////////////////////////////////////////////////////
578 INLINE Geom::CacheEntry::
579 CacheEntry(Geom *source, const GeomVertexData *source_data,
580  const GeomMunger *modifier) :
581  _source(source),
582  _key(source_data, modifier)
583 {
584 }
585 
586 ////////////////////////////////////////////////////////////////////
587 // Function: Geom::CacheEntry::Copy Constructor
588 // Access: Public
589 // Description:
590 ////////////////////////////////////////////////////////////////////
591 INLINE Geom::CacheEntry::
592 CacheEntry(Geom *source, const Geom::CacheKey &key) :
593  _source(source),
594  _key(key)
595 {
596 }
597 
598 #ifdef USE_MOVE_SEMANTICS
599 ////////////////////////////////////////////////////////////////////
600 // Function: Geom::CacheEntry::Move Constructor
601 // Access: Public
602 // Description:
603 ////////////////////////////////////////////////////////////////////
604 INLINE Geom::CacheEntry::
605 CacheEntry(Geom *source, Geom::CacheKey &&key) NOEXCEPT :
606  _source(source),
607  _key(move(key))
608 {
609 }
610 #endif // USE_MOVE_SEMANTICS
611 
612 ////////////////////////////////////////////////////////////////////
613 // Function: Geom::CData::Constructor
614 // Access: Public
615 // Description:
616 ////////////////////////////////////////////////////////////////////
617 INLINE Geom::CData::
618 CData() :
619  _primitive_type(PT_none),
620  _shade_model(SM_uniform),
621  _geom_rendering(0),
622  _usage_hint(UH_unspecified),
623  _got_usage_hint(false),
624  _nested_vertices(0),
625  _internal_bounds_stale(true),
626  _bounds_type(BoundingVolume::BT_default)
627 {
628 }
629 
630 ////////////////////////////////////////////////////////////////////
631 // Function: Geom::CData::Copy Constructor
632 // Access: Public
633 // Description:
634 ////////////////////////////////////////////////////////////////////
635 INLINE Geom::CData::
636 CData(const Geom::CData &copy) :
637  _data(copy._data),
638  _primitives(copy._primitives),
639  _primitive_type(copy._primitive_type),
640  _shade_model(copy._shade_model),
641  _geom_rendering(copy._geom_rendering),
642  _usage_hint(copy._usage_hint),
643  _got_usage_hint(copy._got_usage_hint),
644  _modified(copy._modified),
645  _internal_bounds(copy._internal_bounds),
646  _nested_vertices(copy._nested_vertices),
647  _internal_bounds_stale(copy._internal_bounds_stale),
648  _bounds_type(copy._bounds_type),
649  _user_bounds(copy._user_bounds)
650 {
651 }
652 
653 ////////////////////////////////////////////////////////////////////
654 // Function: GeomPipelineReader::Constructor
655 // Access: Public
656 // Description:
657 ////////////////////////////////////////////////////////////////////
658 INLINE GeomPipelineReader::
659 GeomPipelineReader(const Geom *object, Thread *current_thread) :
660  _object(object),
661  _current_thread(current_thread),
662  _cdata(object->_cycler.read_unlocked(current_thread))
663 {
664 #ifdef _DEBUG
665  nassertv(_object->test_ref_count_nonzero());
666 #endif // _DEBUG
667 #ifdef DO_PIPELINING
668  _cdata->ref();
669 #endif // DO_PIPELINING
670 }
671 
672 ////////////////////////////////////////////////////////////////////
673 // Function: GeomPipelineReader::Copy Constructor
674 // Access: Private
675 // Description: Don't attempt to copy these objects.
676 ////////////////////////////////////////////////////////////////////
677 INLINE GeomPipelineReader::
678 GeomPipelineReader(const GeomPipelineReader &) {
679  nassertv(false);
680 }
681 
682 ////////////////////////////////////////////////////////////////////
683 // Function: GeomPipelineReader::Copy Assignment Operator
684 // Access: Private
685 // Description: Don't attempt to copy these objects.
686 ////////////////////////////////////////////////////////////////////
687 INLINE void GeomPipelineReader::
688 operator = (const GeomPipelineReader &) {
689  nassertv(false);
690 }
691 
692 ////////////////////////////////////////////////////////////////////
693 // Function: GeomPipelineReader::Destructor
694 // Access: Public
695 // Description:
696 ////////////////////////////////////////////////////////////////////
697 INLINE GeomPipelineReader::
698 ~GeomPipelineReader() {
699 #ifdef _DEBUG
700  nassertv(_object->test_ref_count_nonzero());
701 #endif // _DEBUG
702  // _object->_cycler.release_read(_cdata);
703 
704 #ifdef DO_PIPELINING
705  unref_delete((CycleData *)_cdata);
706 #endif // DO_PIPELINING
707 
708 #ifdef _DEBUG
709  _object = NULL;
710  _cdata = NULL;
711 #endif // _DEBUG
712 }
713 
714 ////////////////////////////////////////////////////////////////////
715 // Function: GeomPipelineReader::get_object
716 // Access: Public
717 // Description:
718 ////////////////////////////////////////////////////////////////////
719 INLINE const Geom *GeomPipelineReader::
720 get_object() const {
721  return _object;
722 }
723 
724 ////////////////////////////////////////////////////////////////////
725 // Function: GeomPipelineReader::get_current_thread
726 // Access: Public
727 // Description:
728 ////////////////////////////////////////////////////////////////////
729 INLINE Thread *GeomPipelineReader::
730 get_current_thread() const {
731  return _current_thread;
732 }
733 
734 ////////////////////////////////////////////////////////////////////
735 // Function: GeomPipelineReader::get_primitive_type
736 // Access: Public
737 // Description:
738 ////////////////////////////////////////////////////////////////////
739 INLINE GeomPipelineReader::PrimitiveType GeomPipelineReader::
740 get_primitive_type() const {
741  return _cdata->_primitive_type;
742 }
743 
744 ////////////////////////////////////////////////////////////////////
745 // Function: GeomPipelineReader::get_shade_model
746 // Access: Public
747 // Description:
748 ////////////////////////////////////////////////////////////////////
749 INLINE GeomPipelineReader::ShadeModel GeomPipelineReader::
750 get_shade_model() const {
751  return _cdata->_shade_model;
752 }
753 
754 ////////////////////////////////////////////////////////////////////
755 // Function: GeomPipelineReader::get_geom_rendering
756 // Access: Public
757 // Description:
758 ////////////////////////////////////////////////////////////////////
759 INLINE int GeomPipelineReader::
760 get_geom_rendering() const {
761  return _cdata->_geom_rendering;
762 }
763 
764 ////////////////////////////////////////////////////////////////////
765 // Function: GeomPipelineReader::get_usage_hint
766 // Access: Public
767 // Description:
768 ////////////////////////////////////////////////////////////////////
769 INLINE GeomPipelineReader::UsageHint GeomPipelineReader::
770 get_usage_hint() const {
771  nassertr(_cdata->_got_usage_hint, UH_static);
772  return _cdata->_usage_hint;
773 }
774 
775 ////////////////////////////////////////////////////////////////////
776 // Function: GeomPipelineReader::get_vertex_data
777 // Access: Public
778 // Description:
779 ////////////////////////////////////////////////////////////////////
780 INLINE CPT(GeomVertexData) GeomPipelineReader::
781 get_vertex_data() const {
782  return _cdata->_data.get_read_pointer();
783 }
784 
785 ////////////////////////////////////////////////////////////////////
786 // Function: GeomPipelineReader::get_num_primitives
787 // Access: Public
788 // Description:
789 ////////////////////////////////////////////////////////////////////
790 INLINE int GeomPipelineReader::
791 get_num_primitives() const {
792  return _cdata->_primitives.size();
793 }
794 
795 ////////////////////////////////////////////////////////////////////
796 // Function: GeomPipelineReader::get_primitive
797 // Access: Public
798 // Description:
799 ////////////////////////////////////////////////////////////////////
800 INLINE CPT(GeomPrimitive) GeomPipelineReader::
801 get_primitive(int i) const {
802  nassertr(i >= 0 && i < (int)_cdata->_primitives.size(), NULL);
803  return _cdata->_primitives[i].get_read_pointer();
804 }
805 
806 ////////////////////////////////////////////////////////////////////
807 // Function: GeomPipelineReader::get_modified
808 // Access: Public
809 // Description:
810 ////////////////////////////////////////////////////////////////////
811 INLINE UpdateSeq GeomPipelineReader::
812 get_modified() const {
813  return _cdata->_modified;
814 }
815 
816 ////////////////////////////////////////////////////////////////////
817 // Function: GeomPipelineReader::prepare_now
818 // Access: Public
819 // Description: Creates a context for the geom on the particular
820 // GSG, if it does not already exist. Returns the new
821 // (or old) GeomContext. This assumes that the
822 // GraphicsStateGuardian is the currently active
823 // rendering context and that it is ready to accept new
824 // geoms. If this is not necessarily the case, you
825 // should use prepare() instead.
826 //
827 // Normally, this is not called directly except by the
828 // GraphicsStateGuardian; a geom does not need to be
829 // explicitly prepared by the user before it may be
830 // rendered.
831 ////////////////////////////////////////////////////////////////////
832 INLINE GeomContext *GeomPipelineReader::
833 prepare_now(PreparedGraphicsObjects *prepared_objects,
834  GraphicsStateGuardianBase *gsg) const {
835  return ((Geom *)_object.p())->prepare_now(prepared_objects, gsg);
836 }
837 
838 INLINE ostream &
839 operator << (ostream &out, const Geom &obj) {
840  obj.output(out);
841  return out;
842 }
static const LMatrix4f & ident_mat()
Returns an identity matrix.
Definition: lmatrix.h:903
This is a special class object that holds all the information returned by a particular GSG to indicat...
Definition: geomContext.h:39
BoundingVolume::BoundsType get_bounds_type() const
Returns the bounding volume type set with set_bounds_type().
Definition: geom.I:332
UsageHint get_usage_hint() const
Returns the minimum (i.e.
Definition: geom.I:67
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition: geomMunger.h:57
void set_bounds(const BoundingVolume *volume)
Resets the bounding volume so that it is the indicated volume.
Definition: geom.I:351
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:63
PrimitiveType get_primitive_type() const
Returns the fundamental primitive type that is common to all GeomPrimitives added within the Geom...
Definition: geom.I:28
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
void clear_bounds()
Reverses the effect of a previous call to set_bounds(), and allows the bounding volume to be automati...
Definition: geom.I:373
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Definition: geom.h:401
A table of objects that are saved within the graphics context for reference by handle later...
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 ...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
void clear_cache_stage(Thread *current_thread)
Removes all of the previously-cached results of munge_geom(), at the current pipeline stage and upstr...
Definition: geom.cxx:1156
virtual Geom * make_copy() const
Returns a newly-allocated Geom that is a shallow copy of this one.
Definition: geom.cxx:118
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(...
A container for geometry primitives.
Definition: geom.h:58
GeomContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the geom on the particular GSG, if it does not already exist.
Definition: geom.cxx:1269
int get_geom_rendering() const
Returns the set of GeomRendering bits that represent the rendering properties required to properly re...
Definition: geom.I:54
bool operator<(const CacheKey &other) const
Provides a unique ordering within the map.
Definition: geom.I:560
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
void ref() const
Explicitly increments the reference count.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
const CycleDataType * read_unlocked(Thread *current_thread) const
See PipelineCyclerBase::read_unlocked().
ShadeModel get_shade_model() const
Returns the shade model common to all of the individual GeomPrimitives that have been added to the ge...
Definition: geom.I:41
A thread; that is, a lightweight process.
Definition: thread.h:51
static UpdateSeq get_next_modified()
Returns a monotonically increasing sequence.
Definition: geom.cxx:1324
This is a sequence number that increments monotonically.
Definition: updateSeq.h:43
void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any, const GeomVertexData *vertex_data, bool got_mat, const LMatrix4 &mat, Thread *current_thread) const
Expands min_point and max_point to include all of the vertices in the Geom, if any.
Definition: geom.I:395