Panda3D
|
00001 // Filename: geom.I 00002 // Created by: drose (06Mar05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: Geom::get_primitive_type 00018 // Access: Published 00019 // Description: Returns the fundamental primitive type that is common 00020 // to all GeomPrimitives added within the Geom. All 00021 // nested primitives within a particular Geom must be 00022 // the same type (that is, you can mix triangles and 00023 // tristrips, because they are both the same fundamental 00024 // type PT_polygons, but you cannot mix triangles and 00025 // points withn the same Geom). 00026 //////////////////////////////////////////////////////////////////// 00027 INLINE Geom::PrimitiveType Geom:: 00028 get_primitive_type() const { 00029 CDReader cdata(_cycler); 00030 return cdata->_primitive_type; 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: Geom::get_shade_model 00035 // Access: Published 00036 // Description: Returns the shade model common to all of the 00037 // individual GeomPrimitives that have been added to the 00038 // geom. 00039 //////////////////////////////////////////////////////////////////// 00040 INLINE Geom::ShadeModel Geom:: 00041 get_shade_model() const { 00042 CDReader cdata(_cycler); 00043 return cdata->_shade_model; 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: Geom::get_geom_rendering 00048 // Access: Published 00049 // Description: Returns the set of GeomRendering bits that represent 00050 // the rendering properties required to properly render 00051 // this Geom. 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE int Geom:: 00054 get_geom_rendering() const { 00055 CDReader cdata(_cycler); 00056 return cdata->_geom_rendering; 00057 } 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Function: Geom::get_usage_hint 00061 // Access: Published 00062 // Description: Returns the minimum (i.e. most dynamic) usage_hint 00063 // among all of the individual GeomPrimitives that have 00064 // been added to the geom. 00065 //////////////////////////////////////////////////////////////////// 00066 INLINE Geom::UsageHint Geom:: 00067 get_usage_hint() const { 00068 CDLockedReader cdata(_cycler); 00069 if (!cdata->_got_usage_hint) { 00070 CDWriter cdataw(((Geom *)this)->_cycler, cdata, false); 00071 ((Geom *)this)->reset_usage_hint(cdataw); 00072 return cdataw->_usage_hint; 00073 } 00074 return cdata->_usage_hint; 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: Geom::get_vertex_data 00079 // Access: Published 00080 // Description: Returns a const pointer to the GeomVertexData, 00081 // for application code to directly examine (but not 00082 // modify) the geom's underlying data. 00083 //////////////////////////////////////////////////////////////////// 00084 INLINE CPT(GeomVertexData) Geom:: 00085 get_vertex_data(Thread *current_thread) const { 00086 CDReader cdata(_cycler, current_thread); 00087 return cdata->_data.get_read_pointer(); 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: Geom::is_empty 00092 // Access: Published 00093 // Description: Returns true if there appear to be no vertices to be 00094 // rendered by this Geom, false if has some actual data. 00095 //////////////////////////////////////////////////////////////////// 00096 INLINE bool Geom:: 00097 is_empty() const { 00098 CDReader cdata(_cycler); 00099 return (cdata->_data.get_read_pointer()->get_num_rows() == 0 || 00100 cdata->_primitives.empty()); 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: Geom::get_num_primitives 00105 // Access: Published 00106 // Description: Returns the number of GeomPrimitive objects stored 00107 // within the Geom, each of which represents a number of 00108 // primitives of a particular type. 00109 //////////////////////////////////////////////////////////////////// 00110 INLINE int Geom:: 00111 get_num_primitives() const { 00112 CDReader cdata(_cycler); 00113 return cdata->_primitives.size(); 00114 } 00115 00116 //////////////////////////////////////////////////////////////////// 00117 // Function: Geom::get_primitive 00118 // Access: Published 00119 // Description: Returns a const pointer to the ith GeomPrimitive 00120 // object stored within the Geom. Use this call only to 00121 // inspect the ith object; use modify_primitive() or 00122 // set_primitive() if you want to modify it. 00123 //////////////////////////////////////////////////////////////////// 00124 INLINE CPT(GeomPrimitive) Geom:: 00125 get_primitive(int i) const { 00126 CDReader cdata(_cycler); 00127 nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL); 00128 return cdata->_primitives[i].get_read_pointer(); 00129 } 00130 00131 //////////////////////////////////////////////////////////////////// 00132 // Function: Geom::modify_primitive 00133 // Access: Published 00134 // Description: Returns a modifiable pointer to the ith GeomPrimitive 00135 // object stored within the Geom, so application code 00136 // can directly manipulate the properties of this 00137 // primitive. 00138 // 00139 // Don't call this in a downstream thread unless you 00140 // don't mind it blowing away other changes you might 00141 // have recently made in an upstream thread. 00142 //////////////////////////////////////////////////////////////////// 00143 INLINE PT(GeomPrimitive) Geom:: 00144 modify_primitive(int i) { 00145 Thread *current_thread = Thread::get_current_thread(); 00146 CDWriter cdata(_cycler, true, current_thread); 00147 nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL); 00148 cdata->_got_usage_hint = false; 00149 cdata->_modified = Geom::get_next_modified(); 00150 clear_cache_stage(current_thread); 00151 return cdata->_primitives[i].get_write_pointer(); 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: Geom::decompose 00156 // Access: Published 00157 // Description: Decomposes all of the primitives within this Geom, 00158 // returning the result. See 00159 // GeomPrimitive::decompose(). 00160 //////////////////////////////////////////////////////////////////// 00161 INLINE PT(Geom) Geom:: 00162 decompose() const { 00163 PT(Geom) new_geom = make_copy(); 00164 new_geom->decompose_in_place(); 00165 return new_geom; 00166 } 00167 00168 //////////////////////////////////////////////////////////////////// 00169 // Function: Geom::doubleside 00170 // Access: Published 00171 // Description: Doublesides all of the primitives within this Geom, 00172 // returning the result. See 00173 // GeomPrimitive::doubleside(). 00174 //////////////////////////////////////////////////////////////////// 00175 INLINE PT(Geom) Geom:: 00176 doubleside() const { 00177 PT(Geom) new_geom = make_copy(); 00178 new_geom->doubleside_in_place(); 00179 return new_geom; 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: Geom::reverse 00184 // Access: Published 00185 // Description: Reverses all of the primitives within this Geom, 00186 // returning the result. See 00187 // GeomPrimitive::reverse(). 00188 //////////////////////////////////////////////////////////////////// 00189 INLINE PT(Geom) Geom:: 00190 reverse() const { 00191 PT(Geom) new_geom = make_copy(); 00192 new_geom->reverse_in_place(); 00193 return new_geom; 00194 } 00195 00196 //////////////////////////////////////////////////////////////////// 00197 // Function: Geom::rotate 00198 // Access: Published 00199 // Description: Rotates all of the primitives within this Geom, 00200 // returning the result. See 00201 // GeomPrimitive::rotate(). 00202 //////////////////////////////////////////////////////////////////// 00203 INLINE PT(Geom) Geom:: 00204 rotate() const { 00205 PT(Geom) new_geom = make_copy(); 00206 new_geom->rotate_in_place(); 00207 return new_geom; 00208 } 00209 00210 //////////////////////////////////////////////////////////////////// 00211 // Function: Geom::unify 00212 // Access: Published 00213 // Description: Unifies all of the primitives contained within this 00214 // Geom into a single (or as few as possible, within the 00215 // constraints of max_indices) primitive objects. This 00216 // may require decomposing the primitives if, for 00217 // instance, the Geom contains both triangle strips and 00218 // triangle fans. 00219 // 00220 // max_indices represents the maximum number of indices 00221 // that will be put in any one GeomPrimitive. If 00222 // preserve_order is true, then the primitives will not 00223 // be reordered during the operation, even if this 00224 // results in a suboptimal result. 00225 //////////////////////////////////////////////////////////////////// 00226 INLINE PT(Geom) Geom:: 00227 unify(int max_indices, bool preserve_order) const { 00228 PT(Geom) new_geom = make_copy(); 00229 new_geom->unify_in_place(max_indices, preserve_order); 00230 return new_geom; 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: Geom::make_points 00235 // Access: Published 00236 // Description: Returns a new Geom with points at all the vertices. 00237 // See GeomPrimitive::make_points(). 00238 //////////////////////////////////////////////////////////////////// 00239 INLINE PT(Geom) Geom:: 00240 make_points() const { 00241 PT(Geom) new_geom = make_copy(); 00242 new_geom->make_points_in_place(); 00243 return new_geom; 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: Geom::get_modified 00248 // Access: Published 00249 // Description: Returns a sequence number which is guaranteed to 00250 // change at least every time any of the primitives in 00251 // the Geom is modified, or the set of primitives is 00252 // modified. However, this does not include 00253 // modifications to the vertex data, which should be 00254 // tested separately. 00255 //////////////////////////////////////////////////////////////////// 00256 INLINE UpdateSeq Geom:: 00257 get_modified(Thread *current_thread) const { 00258 CDReader cdata(_cycler, current_thread); 00259 return cdata->_modified; 00260 } 00261 00262 //////////////////////////////////////////////////////////////////// 00263 // Function: Geom::mark_bounds_stale 00264 // Access: Published 00265 // Description: Marks the bounding volume of the Geom as stale so 00266 // that it should be recomputed. Usually it is not 00267 // necessary to call this explicitly. 00268 //////////////////////////////////////////////////////////////////// 00269 INLINE void Geom:: 00270 mark_bounds_stale() const { 00271 CDWriter cdata(((Geom *)this)->_cycler, false); 00272 ((Geom *)this)->mark_internal_bounds_stale(cdata); 00273 } 00274 00275 //////////////////////////////////////////////////////////////////// 00276 // Function: Geom::set_bounds_type 00277 // Access: Published 00278 // Description: Specifies the desired type of bounding volume that 00279 // will be created for this Geom. This is normally 00280 // BoundingVolume::BT_default, which means to set the 00281 // type according to the config variable "bounds-type". 00282 // 00283 // If this is BT_sphere or BT_box, a BoundingSphere or 00284 // BoundingBox is explicitly created. If it is BT_best, 00285 // a BoundingBox is created. 00286 // 00287 // This affects the implicit bounding volume only. If 00288 // an explicit bounding volume is set on the Geom with 00289 // set_bounds(), that bounding volume type is used. 00290 // (This is different behavior from the similar method 00291 // on PandaNode.) 00292 //////////////////////////////////////////////////////////////////// 00293 INLINE void Geom:: 00294 set_bounds_type(BoundingVolume::BoundsType bounds_type) { 00295 CDWriter cdata(_cycler, true); 00296 cdata->_bounds_type = bounds_type; 00297 mark_internal_bounds_stale(cdata); 00298 } 00299 00300 //////////////////////////////////////////////////////////////////// 00301 // Function: Geom::get_bounds_type 00302 // Access: Published 00303 // Description: Returns the bounding volume type set with 00304 // set_bounds_type(). 00305 //////////////////////////////////////////////////////////////////// 00306 INLINE BoundingVolume::BoundsType Geom:: 00307 get_bounds_type() const { 00308 CDReader cdata(_cycler); 00309 return cdata->_bounds_type; 00310 } 00311 00312 //////////////////////////////////////////////////////////////////// 00313 // Function: Geom::set_bounds 00314 // Access: Published 00315 // Description: Resets the bounding volume so that it is the 00316 // indicated volume. When it is explicitly set, the 00317 // bounding volume will no longer be automatically 00318 // computed; call clear_bounds() if you would like to 00319 // return the bounding volume to its default behavior. 00320 // 00321 // Don't call this in a downstream thread unless you 00322 // don't mind it blowing away other changes you might 00323 // have recently made in an upstream thread. 00324 //////////////////////////////////////////////////////////////////// 00325 INLINE void Geom:: 00326 set_bounds(const BoundingVolume *volume) { 00327 CDWriter cdata(_cycler, true); 00328 if (volume == NULL) { 00329 cdata->_user_bounds = NULL; 00330 } else { 00331 cdata->_user_bounds = volume->make_copy(); 00332 } 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: Geom::clear_bounds 00337 // Access: Published 00338 // Description: Reverses the effect of a previous call to 00339 // set_bounds(), and allows the bounding volume to be 00340 // automatically computed once more based on the 00341 // vertices. 00342 // 00343 // Don't call this in a downstream thread unless you 00344 // don't mind it blowing away other changes you might 00345 // have recently made in an upstream thread. 00346 //////////////////////////////////////////////////////////////////// 00347 INLINE void Geom:: 00348 clear_bounds() { 00349 CDWriter cdata(_cycler, true); 00350 cdata->_user_bounds = NULL; 00351 mark_internal_bounds_stale(cdata); 00352 } 00353 00354 //////////////////////////////////////////////////////////////////// 00355 // Function: Geom::calc_tight_bounds 00356 // Access: Public 00357 // Description: Expands min_point and max_point to include all of the 00358 // vertices in the Geom, if any. found_any is set true 00359 // if any points are found. It is the caller's 00360 // responsibility to initialize min_point, max_point, 00361 // and found_any before calling this function. 00362 // 00363 // This version of the method allows the Geom to specify 00364 // an alternate vertex data table (for instance, if the 00365 // vertex data has already been munged), and also allows 00366 // the result to be computed in any coordinate space by 00367 // specifying a transform matrix. 00368 //////////////////////////////////////////////////////////////////// 00369 INLINE void Geom:: 00370 calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, 00371 bool &found_any, 00372 const GeomVertexData *vertex_data, 00373 bool got_mat, const LMatrix4f &mat, 00374 Thread *current_thread) const { 00375 CDReader cdata(_cycler, current_thread); 00376 00377 do_calc_tight_bounds(min_point, max_point, found_any, 00378 vertex_data, got_mat, mat, 00379 InternalName::get_vertex(), 00380 cdata, current_thread); 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: Geom::calc_tight_bounds 00385 // Access: Public, Virtual 00386 // Description: Expands min_point and max_point to include all of the 00387 // vertices in the Geom, if any. found_any is set true 00388 // if any points are found. It is the caller's 00389 // responsibility to initialize min_point, max_point, 00390 // and found_any before calling this function. 00391 // 00392 // This version of the method assumes the Geom will use 00393 // its own vertex data, and the results are computed in 00394 // the Geom's own coordinate space. 00395 //////////////////////////////////////////////////////////////////// 00396 INLINE void Geom:: 00397 calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, 00398 bool &found_any, Thread *current_thread) const { 00399 calc_tight_bounds(min_point, max_point, found_any, 00400 get_vertex_data(current_thread), false, 00401 LMatrix4f::ident_mat(), 00402 current_thread); 00403 } 00404 00405 //////////////////////////////////////////////////////////////////// 00406 // Function: Geom::calc_tight_bounds 00407 // Access: Public 00408 // Description: Similar to calc_tight_bounds(), for UV coordinates or 00409 // other named columns. 00410 //////////////////////////////////////////////////////////////////// 00411 INLINE void Geom:: 00412 calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, 00413 bool &found_any, 00414 const GeomVertexData *vertex_data, 00415 bool got_mat, const LMatrix4f &mat, 00416 const InternalName *column_name, 00417 Thread *current_thread) const { 00418 CDReader cdata(_cycler, current_thread); 00419 00420 do_calc_tight_bounds(min_point, max_point, found_any, 00421 vertex_data, got_mat, mat, 00422 column_name, cdata, current_thread); 00423 } 00424 00425 //////////////////////////////////////////////////////////////////// 00426 // Function: Geom::mark_internal_bounds_stale 00427 // Access: Private 00428 // Description: Should be called to mark the internal bounding 00429 // volume stale, so that recompute_internal_bounds() 00430 // will be called when the bounding volume is next 00431 // requested. 00432 //////////////////////////////////////////////////////////////////// 00433 INLINE void Geom:: 00434 mark_internal_bounds_stale(CData *cdata) { 00435 cdata->_internal_bounds_stale = true; 00436 } 00437 00438 //////////////////////////////////////////////////////////////////// 00439 // Function: Geom::CDataCache::Constructor 00440 // Access: Public 00441 // Description: 00442 //////////////////////////////////////////////////////////////////// 00443 INLINE Geom::CDataCache:: 00444 CDataCache() : 00445 _source(NULL), 00446 _geom_result(NULL), 00447 _data_result(NULL) 00448 { 00449 } 00450 00451 //////////////////////////////////////////////////////////////////// 00452 // Function: Geom::CDataCache::Copy Constructor 00453 // Access: Public 00454 // Description: 00455 //////////////////////////////////////////////////////////////////// 00456 INLINE Geom::CDataCache:: 00457 CDataCache(const Geom::CDataCache ©) : 00458 _source(copy._source), 00459 _geom_result(copy._geom_result), 00460 _data_result(copy._data_result) 00461 { 00462 if (_geom_result != _source && _geom_result != (Geom *)NULL) { 00463 _geom_result->ref(); 00464 } 00465 } 00466 00467 //////////////////////////////////////////////////////////////////// 00468 // Function: Geom::CDataCache::set_result 00469 // Access: Public 00470 // Description: Stores the geom_result and data_result on the cache, 00471 // upping and/or dropping the reference count 00472 // appropriately. 00473 //////////////////////////////////////////////////////////////////// 00474 INLINE void Geom::CDataCache:: 00475 set_result(const Geom *geom_result, const GeomVertexData *data_result) { 00476 if (geom_result != _geom_result) { 00477 if (_geom_result != _source && _geom_result != (Geom *)NULL) { 00478 unref_delete(_geom_result); 00479 } 00480 _geom_result = geom_result; 00481 if (_geom_result != _source && _geom_result != (Geom *)NULL) { 00482 _geom_result->ref(); 00483 } 00484 } 00485 _data_result = data_result; 00486 } 00487 00488 //////////////////////////////////////////////////////////////////// 00489 // Function: Geom::CacheKey::Constructor 00490 // Access: Public 00491 // Description: 00492 //////////////////////////////////////////////////////////////////// 00493 INLINE Geom::CacheKey:: 00494 CacheKey(const GeomVertexData *source_data, const GeomMunger *modifier) : 00495 _source_data(source_data), 00496 _modifier(modifier) 00497 { 00498 } 00499 00500 //////////////////////////////////////////////////////////////////// 00501 // Function: Geom::CacheKey::operator < 00502 // Access: Public 00503 // Description: Provides a unique ordering within the map. 00504 //////////////////////////////////////////////////////////////////// 00505 INLINE bool Geom::CacheKey:: 00506 operator < (const CacheKey &other) const { 00507 if (_modifier != other._modifier) { 00508 int compare = _modifier->geom_compare_to(*other._modifier); 00509 if (compare != 0) { 00510 return (compare < 0); 00511 } 00512 } 00513 if (_source_data != other._source_data) { 00514 return (_source_data < other._source_data); 00515 } 00516 return 0; 00517 } 00518 00519 //////////////////////////////////////////////////////////////////// 00520 // Function: Geom::CacheEntry::Constructor 00521 // Access: Public 00522 // Description: 00523 //////////////////////////////////////////////////////////////////// 00524 INLINE Geom::CacheEntry:: 00525 CacheEntry(Geom *source, const GeomVertexData *source_data, 00526 const GeomMunger *modifier) : 00527 _source(source), 00528 _key(source_data, modifier) 00529 { 00530 } 00531 00532 00533 //////////////////////////////////////////////////////////////////// 00534 // Function: Geom::CData::Constructor 00535 // Access: Public 00536 // Description: 00537 //////////////////////////////////////////////////////////////////// 00538 INLINE Geom::CData:: 00539 CData() : 00540 _primitive_type(PT_none), 00541 _shade_model(SM_uniform), 00542 _geom_rendering(0), 00543 _usage_hint(UH_unspecified), 00544 _got_usage_hint(false), 00545 _nested_vertices(0), 00546 _internal_bounds_stale(true), 00547 _bounds_type(BoundingVolume::BT_default) 00548 { 00549 } 00550 00551 //////////////////////////////////////////////////////////////////// 00552 // Function: Geom::CData::Copy Constructor 00553 // Access: Public 00554 // Description: 00555 //////////////////////////////////////////////////////////////////// 00556 INLINE Geom::CData:: 00557 CData(const Geom::CData ©) : 00558 _data(copy._data), 00559 _primitives(copy._primitives), 00560 _primitive_type(copy._primitive_type), 00561 _shade_model(copy._shade_model), 00562 _geom_rendering(copy._geom_rendering), 00563 _usage_hint(copy._usage_hint), 00564 _got_usage_hint(copy._got_usage_hint), 00565 _modified(copy._modified), 00566 _internal_bounds(copy._internal_bounds), 00567 _nested_vertices(copy._nested_vertices), 00568 _internal_bounds_stale(copy._internal_bounds_stale), 00569 _bounds_type(copy._bounds_type), 00570 _user_bounds(copy._user_bounds) 00571 { 00572 } 00573 00574 //////////////////////////////////////////////////////////////////// 00575 // Function: GeomPipelineReader::Constructor 00576 // Access: Public 00577 // Description: 00578 //////////////////////////////////////////////////////////////////// 00579 INLINE GeomPipelineReader:: 00580 GeomPipelineReader(const Geom *object, Thread *current_thread) : 00581 _object(object), 00582 _current_thread(current_thread), 00583 _cdata(object->_cycler.read_unlocked(current_thread)) 00584 { 00585 #ifdef _DEBUG 00586 nassertv(_object->test_ref_count_nonzero()); 00587 #endif // _DEBUG 00588 #ifdef DO_PIPELINING 00589 _cdata->ref(); 00590 #endif // DO_PIPELINING 00591 } 00592 00593 //////////////////////////////////////////////////////////////////// 00594 // Function: GeomPipelineReader::Copy Constructor 00595 // Access: Private 00596 // Description: Don't attempt to copy these objects. 00597 //////////////////////////////////////////////////////////////////// 00598 INLINE GeomPipelineReader:: 00599 GeomPipelineReader(const GeomPipelineReader &) { 00600 nassertv(false); 00601 } 00602 00603 //////////////////////////////////////////////////////////////////// 00604 // Function: GeomPipelineReader::Copy Assignment Operator 00605 // Access: Private 00606 // Description: Don't attempt to copy these objects. 00607 //////////////////////////////////////////////////////////////////// 00608 INLINE void GeomPipelineReader:: 00609 operator = (const GeomPipelineReader &) { 00610 nassertv(false); 00611 } 00612 00613 //////////////////////////////////////////////////////////////////// 00614 // Function: GeomPipelineReader::Destructor 00615 // Access: Public 00616 // Description: 00617 //////////////////////////////////////////////////////////////////// 00618 INLINE GeomPipelineReader:: 00619 ~GeomPipelineReader() { 00620 #ifdef _DEBUG 00621 nassertv(_object->test_ref_count_nonzero()); 00622 #endif // _DEBUG 00623 // _object->_cycler.release_read(_cdata); 00624 00625 #ifdef DO_PIPELINING 00626 unref_delete((CycleData *)_cdata); 00627 #endif // DO_PIPELINING 00628 00629 #ifdef _DEBUG 00630 _object = NULL; 00631 _cdata = NULL; 00632 #endif // _DEBUG 00633 } 00634 00635 //////////////////////////////////////////////////////////////////// 00636 // Function: GeomPipelineReader::get_object 00637 // Access: Public 00638 // Description: 00639 //////////////////////////////////////////////////////////////////// 00640 INLINE const Geom *GeomPipelineReader:: 00641 get_object() const { 00642 return _object; 00643 } 00644 00645 //////////////////////////////////////////////////////////////////// 00646 // Function: GeomPipelineReader::get_current_thread 00647 // Access: Public 00648 // Description: 00649 //////////////////////////////////////////////////////////////////// 00650 INLINE Thread *GeomPipelineReader:: 00651 get_current_thread() const { 00652 return _current_thread; 00653 } 00654 00655 //////////////////////////////////////////////////////////////////// 00656 // Function: GeomPipelineReader::get_primitive_type 00657 // Access: Public 00658 // Description: 00659 //////////////////////////////////////////////////////////////////// 00660 INLINE GeomPipelineReader::PrimitiveType GeomPipelineReader:: 00661 get_primitive_type() const { 00662 return _cdata->_primitive_type; 00663 } 00664 00665 //////////////////////////////////////////////////////////////////// 00666 // Function: GeomPipelineReader::get_shade_model 00667 // Access: Public 00668 // Description: 00669 //////////////////////////////////////////////////////////////////// 00670 INLINE GeomPipelineReader::ShadeModel GeomPipelineReader:: 00671 get_shade_model() const { 00672 return _cdata->_shade_model; 00673 } 00674 00675 //////////////////////////////////////////////////////////////////// 00676 // Function: GeomPipelineReader::get_geom_rendering 00677 // Access: Public 00678 // Description: 00679 //////////////////////////////////////////////////////////////////// 00680 INLINE int GeomPipelineReader:: 00681 get_geom_rendering() const { 00682 return _cdata->_geom_rendering; 00683 } 00684 00685 //////////////////////////////////////////////////////////////////// 00686 // Function: GeomPipelineReader::get_usage_hint 00687 // Access: Public 00688 // Description: 00689 //////////////////////////////////////////////////////////////////// 00690 INLINE GeomPipelineReader::UsageHint GeomPipelineReader:: 00691 get_usage_hint() const { 00692 nassertr(_cdata->_got_usage_hint, UH_static); 00693 return _cdata->_usage_hint; 00694 } 00695 00696 //////////////////////////////////////////////////////////////////// 00697 // Function: GeomPipelineReader::get_vertex_data 00698 // Access: Public 00699 // Description: 00700 //////////////////////////////////////////////////////////////////// 00701 INLINE CPT(GeomVertexData) GeomPipelineReader:: 00702 get_vertex_data() const { 00703 return _cdata->_data.get_read_pointer(); 00704 } 00705 00706 //////////////////////////////////////////////////////////////////// 00707 // Function: GeomPipelineReader::get_num_primitives 00708 // Access: Public 00709 // Description: 00710 //////////////////////////////////////////////////////////////////// 00711 INLINE int GeomPipelineReader:: 00712 get_num_primitives() const { 00713 return _cdata->_primitives.size(); 00714 } 00715 00716 //////////////////////////////////////////////////////////////////// 00717 // Function: GeomPipelineReader::get_primitive 00718 // Access: Public 00719 // Description: 00720 //////////////////////////////////////////////////////////////////// 00721 INLINE CPT(GeomPrimitive) GeomPipelineReader:: 00722 get_primitive(int i) const { 00723 nassertr(i >= 0 && i < (int)_cdata->_primitives.size(), NULL); 00724 return _cdata->_primitives[i].get_read_pointer(); 00725 } 00726 00727 //////////////////////////////////////////////////////////////////// 00728 // Function: GeomPipelineReader::get_modified 00729 // Access: Public 00730 // Description: 00731 //////////////////////////////////////////////////////////////////// 00732 INLINE UpdateSeq GeomPipelineReader:: 00733 get_modified() const { 00734 return _cdata->_modified; 00735 } 00736 00737 INLINE ostream & 00738 operator << (ostream &out, const Geom &obj) { 00739 obj.output(out); 00740 return out; 00741 }