Panda3D
|
00001 // Filename: transformState.I 00002 // Created by: drose (25Feb02) 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: TransformState::operator < 00018 // Access: Published 00019 // Description: Provides an arbitrary ordering among all unique 00020 // TransformStates, so we can store the essentially 00021 // different ones in a big set and throw away the rest. 00022 // 00023 // This is the same as sorts_less(), except the 00024 // uniquify_matrix value is implicit from the Config.prc 00025 // file. 00026 //////////////////////////////////////////////////////////////////// 00027 INLINE bool TransformState:: 00028 operator < (const TransformState &other) const { 00029 return sorts_less(other, uniquify_matrix); 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: TransformState::get_hash 00034 // Access: Published 00035 // Description: Returns a suitable hash value for phash_map. 00036 //////////////////////////////////////////////////////////////////// 00037 INLINE size_t TransformState:: 00038 get_hash() const { 00039 check_hash(); 00040 return _hash; 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: TransformState::make_pos 00045 // Access: Published, Static 00046 // Description: Makes a new TransformState with the specified 00047 // components. 00048 //////////////////////////////////////////////////////////////////// 00049 INLINE CPT(TransformState) TransformState:: 00050 make_pos(const LVecBase3f &pos) { 00051 return make_pos_hpr_scale(pos, 00052 LVecBase3f(0.0f, 0.0f, 0.0f), 00053 LVecBase3f(1.0f, 1.0f, 1.0f)); 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: TransformState::make_hpr 00058 // Access: Published, Static 00059 // Description: Makes a new TransformState with the specified 00060 // components. 00061 //////////////////////////////////////////////////////////////////// 00062 INLINE CPT(TransformState) TransformState:: 00063 make_hpr(const LVecBase3f &hpr) { 00064 return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00065 hpr, 00066 LVecBase3f(1.0f, 1.0f, 1.0f)); 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: TransformState::make_quat 00071 // Access: Published, Static 00072 // Description: Makes a new TransformState with the specified 00073 // components. 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE CPT(TransformState) TransformState:: 00076 make_quat(const LQuaternionf &quat) { 00077 return make_pos_quat_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00078 quat, 00079 LVecBase3f(1.0f, 1.0f, 1.0f)); 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: TransformState::make_pos_hpr 00084 // Access: Published, Static 00085 // Description: Makes a new TransformState with the specified 00086 // components. 00087 //////////////////////////////////////////////////////////////////// 00088 INLINE CPT(TransformState) TransformState:: 00089 make_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) { 00090 return make_pos_hpr_scale(pos, hpr, 00091 LVecBase3f(1.0, 1.0f, 1.0f)); 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: TransformState::make_scale 00096 // Access: Published, Static 00097 // Description: Makes a new TransformState with the specified 00098 // components. 00099 //////////////////////////////////////////////////////////////////// 00100 INLINE CPT(TransformState) TransformState:: 00101 make_scale(float scale) { 00102 // We actually map this 3-d uniform make_scale() to the 2-d 00103 // version--might as well call it a 2-d scale. 00104 return make_scale2d(scale); 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: TransformState::make_scale 00109 // Access: Published, Static 00110 // Description: Makes a new TransformState with the specified 00111 // components. 00112 //////////////////////////////////////////////////////////////////// 00113 INLINE CPT(TransformState) TransformState:: 00114 make_scale(const LVecBase3f &scale) { 00115 return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00116 LVecBase3f(0.0f, 0.0f, 0.0f), 00117 scale); 00118 } 00119 00120 //////////////////////////////////////////////////////////////////// 00121 // Function: TransformState::make_shear 00122 // Access: Published, Static 00123 // Description: Makes a new TransformState with the specified 00124 // components. 00125 //////////////////////////////////////////////////////////////////// 00126 INLINE CPT(TransformState) TransformState:: 00127 make_shear(const LVecBase3f &shear) { 00128 return make_pos_hpr_scale_shear(LVecBase3f(0.0f, 0.0f, 0.0f), 00129 LVecBase3f(0.0f, 0.0f, 0.0f), 00130 LVecBase3f(1.0f, 1.0f, 1.0f), 00131 shear); 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: TransformState::make_pos_hpr_scale 00136 // Access: Published, Static 00137 // Description: Makes a new TransformState with the specified 00138 // components. 00139 //////////////////////////////////////////////////////////////////// 00140 INLINE CPT(TransformState) TransformState:: 00141 make_pos_hpr_scale(const LVecBase3f &pos, const LVecBase3f &hpr, 00142 const LVecBase3f &scale) { 00143 return make_pos_hpr_scale_shear(pos, hpr, scale, LVecBase3f::zero()); 00144 } 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: TransformState::make_pos_quat_scale 00148 // Access: Published, Static 00149 // Description: Makes a new TransformState with the specified 00150 // components. 00151 //////////////////////////////////////////////////////////////////// 00152 INLINE CPT(TransformState) TransformState:: 00153 make_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat, 00154 const LVecBase3f &scale) { 00155 return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3f::zero()); 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: TransformState::make_pos2d 00160 // Access: Published, Static 00161 // Description: Makes a new 2-d TransformState with the specified 00162 // components. 00163 //////////////////////////////////////////////////////////////////// 00164 INLINE CPT(TransformState) TransformState:: 00165 make_pos2d(const LVecBase2f &pos) { 00166 return make_pos_rotate_scale2d(pos, 0.0f, LVecBase2f(1.0f, 1.0f)); 00167 } 00168 00169 //////////////////////////////////////////////////////////////////// 00170 // Function: TransformState::make_rotate2d 00171 // Access: Published, Static 00172 // Description: Makes a new 2-d TransformState with the specified 00173 // components. 00174 //////////////////////////////////////////////////////////////////// 00175 INLINE CPT(TransformState) TransformState:: 00176 make_rotate2d(float rotate) { 00177 return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), rotate, 00178 LVecBase2f(1.0f, 1.0f)); 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: TransformState::make_pos_rotate2d 00183 // Access: Published, Static 00184 // Description: Makes a new 2-d TransformState with the specified 00185 // components. 00186 //////////////////////////////////////////////////////////////////// 00187 INLINE CPT(TransformState) TransformState:: 00188 make_pos_rotate2d(const LVecBase2f &pos, float rotate) { 00189 return make_pos_rotate_scale2d(pos, rotate, 00190 LVecBase2f(1.0, 1.0f)); 00191 } 00192 00193 //////////////////////////////////////////////////////////////////// 00194 // Function: TransformState::make_scale2d 00195 // Access: Published, Static 00196 // Description: Makes a new 2-d TransformState with the specified 00197 // components. 00198 //////////////////////////////////////////////////////////////////// 00199 INLINE CPT(TransformState) TransformState:: 00200 make_scale2d(float scale) { 00201 return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), 0.0f, 00202 LVecBase2f(scale, scale)); 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: TransformState::make_scale2d 00207 // Access: Published, Static 00208 // Description: Makes a new 2-d TransformState with the specified 00209 // components. 00210 //////////////////////////////////////////////////////////////////// 00211 INLINE CPT(TransformState) TransformState:: 00212 make_scale2d(const LVecBase2f &scale) { 00213 return make_pos_rotate_scale2d(LVecBase2f(0.0f, 0.0f), 0.0f, scale); 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: TransformState::make_shear2d 00218 // Access: Published, Static 00219 // Description: Makes a new 2-d TransformState with the specified 00220 // components. 00221 //////////////////////////////////////////////////////////////////// 00222 INLINE CPT(TransformState) TransformState:: 00223 make_shear2d(float shear) { 00224 return make_pos_rotate_scale_shear2d(LVecBase2f(0.0f, 0.0f), 0.0f, 00225 LVecBase2f(1.0f, 1.0f), shear); 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: TransformState::make_pos_rotate_scale2d 00230 // Access: Published, Static 00231 // Description: Makes a new 2-d TransformState with the specified 00232 // components. 00233 //////////////////////////////////////////////////////////////////// 00234 INLINE CPT(TransformState) TransformState:: 00235 make_pos_rotate_scale2d(const LVecBase2f &pos, float rotate, 00236 const LVecBase2f &scale) { 00237 return make_pos_rotate_scale_shear2d(pos, rotate, scale, 0.0f); 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: TransformState::is_identity 00242 // Access: Published 00243 // Description: Returns true if the transform represents the identity 00244 // matrix, false otherwise. 00245 //////////////////////////////////////////////////////////////////// 00246 INLINE bool TransformState:: 00247 is_identity() const { 00248 return ((_flags & F_is_identity) != 0); 00249 } 00250 00251 //////////////////////////////////////////////////////////////////// 00252 // Function: TransformState::is_invalid 00253 // Access: Published 00254 // Description: Returns true if the transform represents an invalid 00255 // matrix, for instance the result of inverting a 00256 // singular matrix, or false if the transform is valid. 00257 //////////////////////////////////////////////////////////////////// 00258 INLINE bool TransformState:: 00259 is_invalid() const { 00260 return ((_flags & F_is_invalid) != 0); 00261 } 00262 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: TransformState::is_singular 00265 // Access: Published 00266 // Description: Returns true if the transform represents a singular 00267 // transform (that is, it has a zero scale, and it 00268 // cannot be inverted), or false otherwise. 00269 //////////////////////////////////////////////////////////////////// 00270 INLINE bool TransformState:: 00271 is_singular() const { 00272 check_singular(); 00273 return ((_flags & F_is_singular) != 0); 00274 } 00275 00276 //////////////////////////////////////////////////////////////////// 00277 // Function: TransformState::is_2d 00278 // Access: Published 00279 // Description: Returns true if the transform has been constructed 00280 // entirely using the 2-d transform operations, 00281 // e.g. make_pos2d(), and therefore operates strictly in 00282 // two-dimensional space on X and Y only. 00283 //////////////////////////////////////////////////////////////////// 00284 INLINE bool TransformState:: 00285 is_2d() const { 00286 return ((_flags & F_is_2d) != 0); 00287 } 00288 00289 //////////////////////////////////////////////////////////////////// 00290 // Function: TransformState::has_components 00291 // Access: Published 00292 // Description: Returns true if the transform can be described by 00293 // separate pos, hpr, and scale components. Most 00294 // transforms we use in everyday life can be so 00295 // described, but some kinds of transforms (for 00296 // instance, those involving a skew) cannot. 00297 // 00298 // This is not related to whether the transform was 00299 // originally described componentwise. Even a transform 00300 // that was constructed with a 4x4 may return true here 00301 // if the matrix is a simple affine matrix with no skew. 00302 // 00303 // If this returns true, you may safely call get_hpr() 00304 // and get_scale() to retrieve the components. (You 00305 // may always safely call get_pos() whether this returns 00306 // true or false.) 00307 //////////////////////////////////////////////////////////////////// 00308 INLINE bool TransformState:: 00309 has_components() const { 00310 check_components(); 00311 return ((_flags & F_has_components) != 0); 00312 } 00313 00314 //////////////////////////////////////////////////////////////////// 00315 // Function: TransformState::components_given 00316 // Access: Published 00317 // Description: Returns true if the transform was specified 00318 // componentwise, or false if it was specified with a 00319 // general 4x4 matrix. If this is true, the components 00320 // returned by get_pos() and get_scale() will be exactly 00321 // those that were set; otherwise, these functions will 00322 // return computed values. If this is true, the 00323 // rotation may have been set either with a hpr trio or 00324 // with a quaternion; hpr_given() or quat_given() can 00325 // resolve the difference. 00326 //////////////////////////////////////////////////////////////////// 00327 INLINE bool TransformState:: 00328 components_given() const { 00329 return ((_flags & F_components_given) != 0); 00330 } 00331 00332 //////////////////////////////////////////////////////////////////// 00333 // Function: TransformState::hpr_given 00334 // Access: Published 00335 // Description: Returns true if the rotation was specified via a trio 00336 // of Euler angles, false otherwise. If this is true, 00337 // get_hpr() will be exactly as set; otherwise, it will 00338 // return a computed value. 00339 //////////////////////////////////////////////////////////////////// 00340 INLINE bool TransformState:: 00341 hpr_given() const { 00342 return ((_flags & F_hpr_given) != 0); 00343 } 00344 00345 //////////////////////////////////////////////////////////////////// 00346 // Function: TransformState::quat_given 00347 // Access: Published 00348 // Description: Returns true if the rotation was specified via a 00349 // quaternion, false otherwise. If this is true, 00350 // get_quat() will be exactly as set; otherwise, it will 00351 // return a computed value. 00352 //////////////////////////////////////////////////////////////////// 00353 INLINE bool TransformState:: 00354 quat_given() const { 00355 return ((_flags & F_quat_given) != 0); 00356 } 00357 00358 //////////////////////////////////////////////////////////////////// 00359 // Function: TransformState::has_pos 00360 // Access: Published 00361 // Description: Returns true if the transform's pos component can be 00362 // extracted out separately. This is generally always 00363 // true, unless the transform is invalid 00364 // (i.e. is_invalid() returns true). 00365 //////////////////////////////////////////////////////////////////// 00366 INLINE bool TransformState:: 00367 has_pos() const { 00368 return !is_invalid(); 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: TransformState::has_hpr 00373 // Access: Published 00374 // Description: Returns true if the transform's rotation component 00375 // can be extracted out separately and described as a 00376 // set of Euler angles. This is generally true only 00377 // when has_components() is true. 00378 //////////////////////////////////////////////////////////////////// 00379 INLINE bool TransformState:: 00380 has_hpr() const { 00381 return has_components(); 00382 } 00383 00384 //////////////////////////////////////////////////////////////////// 00385 // Function: TransformState::has_quat 00386 // Access: Published 00387 // Description: Returns true if the transform's rotation component 00388 // can be extracted out separately and described as a 00389 // quaternion. This is generally true only when 00390 // has_components() is true. 00391 //////////////////////////////////////////////////////////////////// 00392 INLINE bool TransformState:: 00393 has_quat() const { 00394 return has_components(); 00395 } 00396 00397 //////////////////////////////////////////////////////////////////// 00398 // Function: TransformState::has_scale 00399 // Access: Published 00400 // Description: Returns true if the transform's scale component 00401 // can be extracted out separately. This is generally 00402 // true only when has_components() is true. 00403 //////////////////////////////////////////////////////////////////// 00404 INLINE bool TransformState:: 00405 has_scale() const { 00406 return has_components(); 00407 } 00408 00409 //////////////////////////////////////////////////////////////////// 00410 // Function: TransformState::has_identity_scale 00411 // Access: Published 00412 // Description: Returns true if the scale is uniform 1.0, or false if 00413 // the scale has some real value. 00414 //////////////////////////////////////////////////////////////////// 00415 INLINE bool TransformState:: 00416 has_identity_scale() const { 00417 check_components(); 00418 return (_flags & F_identity_scale) != 0; 00419 } 00420 00421 //////////////////////////////////////////////////////////////////// 00422 // Function: TransformState::has_uniform_scale 00423 // Access: Published 00424 // Description: Returns true if the scale is uniform across all three 00425 // axes (and therefore can be expressed as a single 00426 // number), or false if the transform has a different 00427 // scale in different dimensions. 00428 //////////////////////////////////////////////////////////////////// 00429 INLINE bool TransformState:: 00430 has_uniform_scale() const { 00431 check_components(); 00432 return (_flags & F_uniform_scale) != 0; 00433 } 00434 00435 //////////////////////////////////////////////////////////////////// 00436 // Function: TransformState::has_shear 00437 // Access: Published 00438 // Description: Returns true if the transform's shear component 00439 // can be extracted out separately. This is generally 00440 // true only when has_components() is true. 00441 //////////////////////////////////////////////////////////////////// 00442 INLINE bool TransformState:: 00443 has_shear() const { 00444 return has_components(); 00445 } 00446 00447 //////////////////////////////////////////////////////////////////// 00448 // Function: TransformState::has_nonzero_shear 00449 // Access: Published 00450 // Description: Returns true if the shear component is non-zero, 00451 // false if it is zero or if the matrix cannot be 00452 // decomposed. 00453 //////////////////////////////////////////////////////////////////// 00454 INLINE bool TransformState:: 00455 has_nonzero_shear() const { 00456 check_components(); 00457 return (_flags & F_has_nonzero_shear) != 0; 00458 } 00459 00460 //////////////////////////////////////////////////////////////////// 00461 // Function: TransformState::has_mat 00462 // Access: Published 00463 // Description: Returns true if the transform can be described as a 00464 // matrix. This is generally always true, unless 00465 // is_invalid() is true. 00466 //////////////////////////////////////////////////////////////////// 00467 INLINE bool TransformState:: 00468 has_mat() const { 00469 return !is_invalid(); 00470 } 00471 00472 //////////////////////////////////////////////////////////////////// 00473 // Function: TransformState::get_pos 00474 // Access: Published 00475 // Description: Returns the pos component of the transform. It is an 00476 // error to call this if has_pos() returned false. 00477 //////////////////////////////////////////////////////////////////// 00478 INLINE const LPoint3f &TransformState:: 00479 get_pos() const { 00480 check_components(); 00481 nassertr(has_pos(), _pos); 00482 return _pos; 00483 } 00484 00485 //////////////////////////////////////////////////////////////////// 00486 // Function: TransformState::get_hpr 00487 // Access: Published 00488 // Description: Returns the rotation component of the transform as a 00489 // trio of Euler angles. It is an error to call this if 00490 // has_components() returned false. 00491 //////////////////////////////////////////////////////////////////// 00492 INLINE const LVecBase3f &TransformState:: 00493 get_hpr() const { 00494 check_hpr(); 00495 nassertr(!is_invalid(), _hpr); 00496 return _hpr; 00497 } 00498 00499 //////////////////////////////////////////////////////////////////// 00500 // Function: TransformState::get_quat 00501 // Access: Published 00502 // Description: Returns the rotation component of the transform as a 00503 // quaternion. The return value will be normalized if a 00504 // normalized quaternion was given to the constructor 00505 // (or if the quaternion was computed implicitly); it 00506 // will be non-normalized if a non-normalized quaternion 00507 // was given to the constructor. See also 00508 // get_norm_quat(). 00509 // 00510 // It is an error to call this if has_components() 00511 // returned false. 00512 //////////////////////////////////////////////////////////////////// 00513 INLINE const LQuaternionf &TransformState:: 00514 get_quat() const { 00515 check_quat(); 00516 nassertr(!is_invalid(), _quat); 00517 return _quat; 00518 } 00519 00520 //////////////////////////////////////////////////////////////////// 00521 // Function: TransformState::get_norm_quat 00522 // Access: Published 00523 // Description: Returns the rotation component of the transform as a 00524 // quaternion. Unlike the result of get_quat(), the 00525 // return value of this method is guaranteed to be 00526 // normalized. It is an error to call this if 00527 // has_components() returned false. 00528 //////////////////////////////////////////////////////////////////// 00529 INLINE const LQuaternionf &TransformState:: 00530 get_norm_quat() const { 00531 check_norm_quat(); 00532 nassertr(!is_invalid(), _norm_quat); 00533 return _norm_quat; 00534 } 00535 00536 //////////////////////////////////////////////////////////////////// 00537 // Function: TransformState::get_scale 00538 // Access: Published 00539 // Description: Returns the scale component of the transform. It is an 00540 // error to call this if has_components() returned 00541 // false. 00542 //////////////////////////////////////////////////////////////////// 00543 INLINE const LVecBase3f &TransformState:: 00544 get_scale() const { 00545 check_components(); 00546 nassertr(!is_invalid(), _scale); 00547 return _scale; 00548 } 00549 00550 //////////////////////////////////////////////////////////////////// 00551 // Function: TransformState::get_uniform_scale 00552 // Access: Published 00553 // Description: Returns the scale component of the transform, as a 00554 // single number. It is an error to call this if 00555 // has_uniform_scale() returned false. 00556 //////////////////////////////////////////////////////////////////// 00557 INLINE float TransformState:: 00558 get_uniform_scale() const { 00559 check_components(); 00560 nassertr(has_uniform_scale(), _scale[0]); 00561 return _scale[0]; 00562 } 00563 00564 //////////////////////////////////////////////////////////////////// 00565 // Function: TransformState::get_shear 00566 // Access: Published 00567 // Description: Returns the shear component of the transform. It is 00568 // an error to call this if has_components() returned 00569 // false. 00570 //////////////////////////////////////////////////////////////////// 00571 INLINE const LVecBase3f &TransformState:: 00572 get_shear() const { 00573 check_components(); 00574 nassertr(!is_invalid(), _shear); 00575 return _shear; 00576 } 00577 00578 //////////////////////////////////////////////////////////////////// 00579 // Function: TransformState::get_mat 00580 // Access: Published 00581 // Description: Returns the matrix that describes the transform. 00582 //////////////////////////////////////////////////////////////////// 00583 INLINE const LMatrix4f &TransformState:: 00584 get_mat() const { 00585 nassertr(has_mat(), LMatrix4f::ident_mat()); 00586 check_mat(); 00587 return _mat; 00588 } 00589 00590 //////////////////////////////////////////////////////////////////// 00591 // Function: TransformState::get_pos2d 00592 // Access: Published 00593 // Description: Returns the pos component of the 2-d transform. It 00594 // is an error to call this if has_pos() or is_2d() 00595 // returned false. 00596 //////////////////////////////////////////////////////////////////// 00597 INLINE LVecBase2f TransformState:: 00598 get_pos2d() const { 00599 check_components(); 00600 nassertr(has_pos() && is_2d(), LVecBase2f::zero()); 00601 return LVecBase2f(_pos[0], _pos[1]); 00602 } 00603 00604 //////////////////////////////////////////////////////////////////// 00605 // Function: TransformState::get_rotate2d 00606 // Access: Published 00607 // Description: Returns the rotation component of the 2-d transform 00608 // as an angle in degrees clockwise about the origin. 00609 // It is an error to call this if has_components() or 00610 // is_2d() returned false. 00611 //////////////////////////////////////////////////////////////////// 00612 INLINE float TransformState:: 00613 get_rotate2d() const { 00614 check_hpr(); 00615 nassertr(!is_invalid() && is_2d(), 0); 00616 switch (get_default_coordinate_system()) { 00617 default: 00618 case CS_zup_right: 00619 return _hpr[0]; 00620 case CS_zup_left: 00621 return -_hpr[0]; 00622 case CS_yup_right: 00623 return -_hpr[2]; 00624 case CS_yup_left: 00625 return _hpr[2]; 00626 } 00627 } 00628 00629 //////////////////////////////////////////////////////////////////// 00630 // Function: TransformState::get_scale2d 00631 // Access: Published 00632 // Description: Returns the scale component of the 2-d transform. It 00633 // is an error to call this if has_components() or 00634 // is_2d() returned false. 00635 //////////////////////////////////////////////////////////////////// 00636 INLINE LVecBase2f TransformState:: 00637 get_scale2d() const { 00638 check_components(); 00639 nassertr(!is_invalid() && is_2d(), LVecBase2f::zero()); 00640 return LVecBase2f(_scale[0], _scale[1]); 00641 } 00642 00643 //////////////////////////////////////////////////////////////////// 00644 // Function: TransformState::get_shear2d 00645 // Access: Published 00646 // Description: Returns the shear component of the 2-d transform. It 00647 // is an error to call this if has_components() or 00648 // is_2d() returned false. 00649 //////////////////////////////////////////////////////////////////// 00650 INLINE float TransformState:: 00651 get_shear2d() const { 00652 check_components(); 00653 nassertr(!is_invalid() && is_2d(), 0.0f); 00654 return _shear[0]; 00655 } 00656 00657 //////////////////////////////////////////////////////////////////// 00658 // Function: TransformState::get_mat3 00659 // Access: Published 00660 // Description: Returns the 3x3 matrix that describes the 2-d 00661 // transform. It is an error to call this if is_2d() 00662 // returned false. 00663 //////////////////////////////////////////////////////////////////// 00664 INLINE LMatrix3f TransformState:: 00665 get_mat3() const { 00666 nassertr(has_mat() && is_2d(), LMatrix3f::ident_mat()); 00667 check_mat(); 00668 return LMatrix3f(_mat(0, 0), _mat(0, 1), _mat(0, 3), 00669 _mat(1, 0), _mat(1, 1), _mat(1, 3), 00670 _mat(3, 0), _mat(3, 1), _mat(3, 3)); 00671 } 00672 00673 //////////////////////////////////////////////////////////////////// 00674 // Function: TransformState::get_inverse 00675 // Access: Published 00676 // Description: Returns the inverse of this transform. If you are 00677 // going to immediately compose this result with another 00678 // TransformState, it is faster to do it in one 00679 // operation with invert_compose(). 00680 //////////////////////////////////////////////////////////////////// 00681 INLINE CPT(TransformState) TransformState:: 00682 get_inverse() const { 00683 return invert_compose(TransformState::make_identity()); 00684 } 00685 00686 //////////////////////////////////////////////////////////////////// 00687 // Function: TransformState::get_unique 00688 // Access: Published 00689 // Description: Returns the pointer to the unique TransformState in 00690 // the cache that is equivalent to this one. This may 00691 // be the same pointer as this object, or it may be a 00692 // different pointer; but it will be an equivalent 00693 // object, and it will be a shared pointer. This may be 00694 // called from time to time to improve cache benefits. 00695 //////////////////////////////////////////////////////////////////// 00696 INLINE CPT(TransformState) TransformState:: 00697 get_unique() const { 00698 return return_unique((TransformState *)this); 00699 } 00700 00701 //////////////////////////////////////////////////////////////////// 00702 // Function: TransformState::get_geom_rendering 00703 // Access: Published 00704 // Description: Returns the union of the Geom::GeomRendering bits 00705 // that will be required once this TransformState is 00706 // applied to a geom which includes the indicated 00707 // geom_rendering bits. The RenderState's 00708 // get_geom_rendering() should already have been 00709 // applied. 00710 //////////////////////////////////////////////////////////////////// 00711 INLINE int TransformState:: 00712 get_geom_rendering(int geom_rendering) const { 00713 if ((geom_rendering & GeomEnums::GR_point_perspective) != 0) { 00714 if (!has_identity_scale()) { 00715 geom_rendering |= GeomEnums::GR_point_scale; 00716 } 00717 } 00718 00719 return geom_rendering; 00720 } 00721 00722 //////////////////////////////////////////////////////////////////// 00723 // Function: TransformState::cache_ref 00724 // Access: Published 00725 // Description: Overrides this method to update PStats appropriately. 00726 //////////////////////////////////////////////////////////////////// 00727 INLINE void TransformState:: 00728 cache_ref() const { 00729 #ifdef DO_PSTATS 00730 int old_referenced_bits = get_referenced_bits(); 00731 NodeCachedReferenceCount::cache_ref(); 00732 consider_update_pstats(old_referenced_bits); 00733 #else // DO_PSTATS 00734 NodeCachedReferenceCount::cache_ref(); 00735 #endif // DO_PSTATS 00736 } 00737 00738 //////////////////////////////////////////////////////////////////// 00739 // Function: TransformState::cache_unref 00740 // Access: Published 00741 // Description: Overrides this method to update PStats appropriately. 00742 //////////////////////////////////////////////////////////////////// 00743 INLINE bool TransformState:: 00744 cache_unref() const { 00745 #ifdef DO_PSTATS 00746 int old_referenced_bits = get_referenced_bits(); 00747 bool result = do_cache_unref(); 00748 consider_update_pstats(old_referenced_bits); 00749 return result; 00750 #else // DO_PSTATS 00751 return do_cache_unref(); 00752 #endif // DO_PSTATS 00753 } 00754 00755 //////////////////////////////////////////////////////////////////// 00756 // Function: TransformState::node_ref 00757 // Access: Published 00758 // Description: Overrides this method to update PStats appropriately. 00759 //////////////////////////////////////////////////////////////////// 00760 INLINE void TransformState:: 00761 node_ref() const { 00762 #ifdef DO_PSTATS 00763 int old_referenced_bits = get_referenced_bits(); 00764 NodeCachedReferenceCount::node_ref(); 00765 consider_update_pstats(old_referenced_bits); 00766 #else // DO_PSTATS 00767 NodeCachedReferenceCount::node_ref(); 00768 #endif // DO_PSTATS 00769 } 00770 00771 //////////////////////////////////////////////////////////////////// 00772 // Function: TransformState::node_unref 00773 // Access: Published 00774 // Description: Overrides this method to update PStats appropriately. 00775 //////////////////////////////////////////////////////////////////// 00776 INLINE bool TransformState:: 00777 node_unref() const { 00778 #ifdef DO_PSTATS 00779 int old_referenced_bits = get_referenced_bits(); 00780 bool result = do_node_unref(); 00781 consider_update_pstats(old_referenced_bits); 00782 return result; 00783 #else // DO_PSTATS 00784 return do_node_unref(); 00785 #endif // DO_PSTATS 00786 } 00787 00788 //////////////////////////////////////////////////////////////////// 00789 // Function: TransformState::get_composition_cache_num_entries 00790 // Access: Published 00791 // Description: Returns the number of entries in the composition 00792 // cache for this TransformState. This is the number of 00793 // other TransformStates whose composition with this one 00794 // has been cached. This number is not useful for any 00795 // practical reason other than performance analysis. 00796 //////////////////////////////////////////////////////////////////// 00797 INLINE int TransformState:: 00798 get_composition_cache_num_entries() const { 00799 LightReMutexHolder holder(*_states_lock); 00800 return _composition_cache.get_num_entries(); 00801 } 00802 00803 //////////////////////////////////////////////////////////////////// 00804 // Function: TransformState::get_invert_composition_cache_num_entries 00805 // Access: Published 00806 // Description: Returns the number of entries in the 00807 // invert_composition cache for this TransformState. 00808 // This is similar to the composition cache, but it 00809 // records cache entries for the invert_compose() 00810 // operation. See get_composition_cache_num_entries(). 00811 //////////////////////////////////////////////////////////////////// 00812 INLINE int TransformState:: 00813 get_invert_composition_cache_num_entries() const { 00814 LightReMutexHolder holder(*_states_lock); 00815 return _invert_composition_cache.get_num_entries(); 00816 } 00817 00818 //////////////////////////////////////////////////////////////////// 00819 // Function: TransformState::get_composition_cache_size 00820 // Access: Published 00821 // Description: Returns the number of slots in the composition 00822 // cache for this TransformState. You may use this as 00823 // an upper bound when walking through all of the 00824 // composition cache results via 00825 // get_composition_cache_source() or result(). 00826 // 00827 // This has no practical value other than for examining 00828 // the cache for performance analysis. 00829 //////////////////////////////////////////////////////////////////// 00830 INLINE int TransformState:: 00831 get_composition_cache_size() const { 00832 LightReMutexHolder holder(*_states_lock); 00833 return _composition_cache.get_size(); 00834 } 00835 00836 //////////////////////////////////////////////////////////////////// 00837 // Function: TransformState::get_composition_cache_source 00838 // Access: Published 00839 // Description: Returns the source TransformState of the nth element 00840 // in the composition cache. Returns NULL if there 00841 // doesn't happen to be an entry in the nth element. 00842 // See get_composition_cache_result(). 00843 // 00844 // This has no practical value other than for examining 00845 // the cache for performance analysis. 00846 //////////////////////////////////////////////////////////////////// 00847 INLINE const TransformState *TransformState:: 00848 get_composition_cache_source(int n) const { 00849 LightReMutexHolder holder(*_states_lock); 00850 if (!_composition_cache.has_element(n)) { 00851 return NULL; 00852 } 00853 return _composition_cache.get_key(n); 00854 } 00855 00856 //////////////////////////////////////////////////////////////////// 00857 // Function: TransformState::get_composition_cache_result 00858 // Access: Published 00859 // Description: Returns the result TransformState of the nth element 00860 // in the composition cache. Returns NULL if there 00861 // doesn't happen to be an entry in the nth element. 00862 // 00863 // In general, 00864 // a->compose(a->get_composition_cache_source(n)) == 00865 // a->get_composition_cache_result(n). 00866 // 00867 // This has no practical value other than for examining 00868 // the cache for performance analysis. 00869 //////////////////////////////////////////////////////////////////// 00870 INLINE const TransformState *TransformState:: 00871 get_composition_cache_result(int n) const { 00872 LightReMutexHolder holder(*_states_lock); 00873 if (!_composition_cache.has_element(n)) { 00874 return NULL; 00875 } 00876 return _composition_cache.get_data(n)._result; 00877 } 00878 00879 //////////////////////////////////////////////////////////////////// 00880 // Function: TransformState::get_invert_composition_cache_size 00881 // Access: Published 00882 // Description: Returns the number of slots in the composition 00883 // cache for this TransformState. You may use this as 00884 // an upper bound when walking through all of the 00885 // composition cache results via 00886 // get_invert_composition_cache_source() or result(). 00887 // 00888 // This has no practical value other than for examining 00889 // the cache for performance analysis. 00890 //////////////////////////////////////////////////////////////////// 00891 INLINE int TransformState:: 00892 get_invert_composition_cache_size() const { 00893 LightReMutexHolder holder(*_states_lock); 00894 return _invert_composition_cache.get_size(); 00895 } 00896 00897 //////////////////////////////////////////////////////////////////// 00898 // Function: TransformState::get_invert_composition_cache_source 00899 // Access: Published 00900 // Description: Returns the source TransformState of the nth element 00901 // in the invert composition cache. Returns NULL if 00902 // there doesn't happen to be an entry in the nth 00903 // element. See get_invert_composition_cache_result(). 00904 // 00905 // This has no practical value other than for examining 00906 // the cache for performance analysis. 00907 //////////////////////////////////////////////////////////////////// 00908 INLINE const TransformState *TransformState:: 00909 get_invert_composition_cache_source(int n) const { 00910 LightReMutexHolder holder(*_states_lock); 00911 if (!_invert_composition_cache.has_element(n)) { 00912 return NULL; 00913 } 00914 return _invert_composition_cache.get_key(n); 00915 } 00916 00917 //////////////////////////////////////////////////////////////////// 00918 // Function: TransformState::get_invert_composition_cache_result 00919 // Access: Published 00920 // Description: Returns the result TransformState of the nth element 00921 // in the invert composition cache. Returns NULL if 00922 // there doesn't happen to be an entry in the nth 00923 // element. 00924 // 00925 // In general, 00926 // a->invert_compose(a->get_invert_composition_cache_source(n)) 00927 // == a->get_invert_composition_cache_result(n). 00928 // 00929 // This has no practical value other than for examining 00930 // the cache for performance analysis. 00931 //////////////////////////////////////////////////////////////////// 00932 INLINE const TransformState *TransformState:: 00933 get_invert_composition_cache_result(int n) const { 00934 LightReMutexHolder holder(*_states_lock); 00935 if (!_invert_composition_cache.has_element(n)) { 00936 return NULL; 00937 } 00938 return _invert_composition_cache.get_data(n)._result; 00939 } 00940 00941 //////////////////////////////////////////////////////////////////// 00942 // Function: TransformState::flush_level 00943 // Access: Public, Static 00944 // Description: Flushes the PStatCollectors used during traversal. 00945 //////////////////////////////////////////////////////////////////// 00946 INLINE void TransformState:: 00947 flush_level() { 00948 _node_counter.flush_level(); 00949 _cache_counter.flush_level(); 00950 } 00951 00952 //////////////////////////////////////////////////////////////////// 00953 // Function: TransformState::do_node_unref 00954 // Access: Private 00955 // Description: Reimplements NodeReferenceCount::node_unref(). We do 00956 // this because we have a non-virtual unref() method. 00957 //////////////////////////////////////////////////////////////////// 00958 INLINE bool TransformState:: 00959 do_node_unref() const { 00960 node_unref_only(); 00961 return unref(); 00962 } 00963 00964 //////////////////////////////////////////////////////////////////// 00965 // Function: TransformState::do_cache_unref 00966 // Access: Private 00967 // Description: Reimplements 00968 // CachedTypedWritableReferenceCount::cache_unref(). We 00969 // do this because we have a non-virtual unref() method. 00970 //////////////////////////////////////////////////////////////////// 00971 INLINE bool TransformState:: 00972 do_cache_unref() const { 00973 cache_unref_only(); 00974 return unref(); 00975 } 00976 00977 //////////////////////////////////////////////////////////////////// 00978 // Function: TransformState::check_hash 00979 // Access: Private 00980 // Description: Ensures that we know the hash value. 00981 //////////////////////////////////////////////////////////////////// 00982 INLINE void TransformState:: 00983 check_hash() const { 00984 // This pretends to be a const function, even though it's not, 00985 // because it only updates a transparent cache value. 00986 if ((_flags & F_hash_known) == 0) { 00987 ((TransformState *)this)->calc_hash(); 00988 } 00989 } 00990 00991 //////////////////////////////////////////////////////////////////// 00992 // Function: TransformState::check_singular 00993 // Access: Private 00994 // Description: Ensures that we know whether the matrix is singular. 00995 //////////////////////////////////////////////////////////////////// 00996 INLINE void TransformState:: 00997 check_singular() const { 00998 // This pretends to be a const function, even though it's not, 00999 // because it only updates a transparent cache value. 01000 if ((_flags & F_singular_known) == 0) { 01001 ((TransformState *)this)->calc_singular(); 01002 } 01003 } 01004 01005 //////////////////////////////////////////////////////////////////// 01006 // Function: TransformState::check_components 01007 // Access: Private 01008 // Description: Ensures that we know the components of the transform 01009 // (or that we know they cannot be derived). 01010 //////////////////////////////////////////////////////////////////// 01011 INLINE void TransformState:: 01012 check_components() const { 01013 // This pretends to be a const function, even though it's not, 01014 // because it only updates a transparent cache value. 01015 if ((_flags & F_components_known) == 0) { 01016 ((TransformState *)this)->calc_components(); 01017 } 01018 } 01019 01020 //////////////////////////////////////////////////////////////////// 01021 // Function: TransformState::check_hpr 01022 // Access: Private 01023 // Description: Ensures that we know the hpr of the transform 01024 // (or that we know they cannot be derived). 01025 //////////////////////////////////////////////////////////////////// 01026 INLINE void TransformState:: 01027 check_hpr() const { 01028 // This pretends to be a const function, even though it's not, 01029 // because it only updates a transparent cache value. 01030 if ((_flags & F_hpr_known) == 0) { 01031 ((TransformState *)this)->calc_hpr(); 01032 } 01033 } 01034 01035 //////////////////////////////////////////////////////////////////// 01036 // Function: TransformState::check_quat 01037 // Access: Private 01038 // Description: Ensures that we know the quat of the transform 01039 // (or that we know they cannot be derived). 01040 //////////////////////////////////////////////////////////////////// 01041 INLINE void TransformState:: 01042 check_quat() const { 01043 // This pretends to be a const function, even though it's not, 01044 // because it only updates a transparent cache value. 01045 if ((_flags & F_quat_known) == 0) { 01046 ((TransformState *)this)->calc_quat(); 01047 } 01048 } 01049 01050 //////////////////////////////////////////////////////////////////// 01051 // Function: TransformState::check_norm_quat 01052 // Access: Private 01053 // Description: Ensures that we know the normalized quat of the transform 01054 // (or that we know they cannot be derived). 01055 //////////////////////////////////////////////////////////////////// 01056 INLINE void TransformState:: 01057 check_norm_quat() const { 01058 // This pretends to be a const function, even though it's not, 01059 // because it only updates a transparent cache value. 01060 if ((_flags & F_norm_quat_known) == 0) { 01061 ((TransformState *)this)->calc_norm_quat(); 01062 } 01063 } 01064 01065 //////////////////////////////////////////////////////////////////// 01066 // Function: TransformState::check_mat 01067 // Access: Private 01068 // Description: Ensures that we know the overall matrix. 01069 //////////////////////////////////////////////////////////////////// 01070 INLINE void TransformState:: 01071 check_mat() const { 01072 // This pretends to be a const function, even though it's not, 01073 // because it only updates a transparent cache value. 01074 if ((_flags & F_mat_known) == 0) { 01075 ((TransformState *)this)->calc_mat(); 01076 } 01077 } 01078 01079 //////////////////////////////////////////////////////////////////// 01080 // Function: TransformState::calc_hash 01081 // Access: Private 01082 // Description: Computes the hash value. 01083 //////////////////////////////////////////////////////////////////// 01084 INLINE void TransformState:: 01085 calc_hash() { 01086 LightMutexHolder holder(_lock); 01087 do_calc_hash(); 01088 } 01089 01090 //////////////////////////////////////////////////////////////////// 01091 // Function: TransformState::calc_components 01092 // Access: Private 01093 // Description: Derives the components from the matrix, if possible. 01094 //////////////////////////////////////////////////////////////////// 01095 INLINE void TransformState:: 01096 calc_components() { 01097 LightMutexHolder holder(_lock); 01098 do_calc_components(); 01099 } 01100 01101 //////////////////////////////////////////////////////////////////// 01102 // Function: TransformState::calc_hpr 01103 // Access: Private 01104 // Description: Derives the hpr, from the matrix if necessary, or 01105 // from the quat. 01106 //////////////////////////////////////////////////////////////////// 01107 INLINE void TransformState:: 01108 calc_hpr() { 01109 LightMutexHolder holder(_lock); 01110 do_calc_hpr(); 01111 } 01112 01113 //////////////////////////////////////////////////////////////////// 01114 // Function: TransformState::calc_mat 01115 // Access: Private 01116 // Description: Computes the matrix from the components. 01117 //////////////////////////////////////////////////////////////////// 01118 INLINE void TransformState:: 01119 calc_mat() { 01120 LightMutexHolder holder(_lock); 01121 do_calc_mat(); 01122 } 01123 01124 //////////////////////////////////////////////////////////////////// 01125 // Function: TransformState::check_uniform_scale 01126 // Access: Private 01127 // Description: Should be called immediately after _scale (and 01128 // F_has_components) is set, this checks for a 01129 // identity and/or uniform scale (as well as a non-zero 01130 // shear) and sets the bit appropriately. 01131 // 01132 // It does not matter whether the lock is or is not held 01133 // before calling this method. 01134 //////////////////////////////////////////////////////////////////// 01135 INLINE void TransformState:: 01136 check_uniform_scale() { 01137 if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) && 01138 IS_NEARLY_EQUAL(_scale[0], _scale[2])) { 01139 _flags |= F_uniform_scale; 01140 if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) { 01141 _flags |= F_identity_scale; 01142 } 01143 } 01144 01145 if (!_shear.almost_equal(LVecBase3f::zero())) { 01146 _flags |= F_has_nonzero_shear; 01147 } 01148 } 01149 01150 //////////////////////////////////////////////////////////////////// 01151 // Function: TransformState::check_uniform_scale2d 01152 // Access: Private 01153 // Description: Should be called immediately after _scale (and 01154 // F_has_components) is set, for a known 2-d scale, this 01155 // checks for a identity and/or uniform scale (as well 01156 // as a non-zero shear) and sets the bit appropriately. 01157 // 01158 // It does not matter whether the lock is or is not held 01159 // before calling this method. 01160 //////////////////////////////////////////////////////////////////// 01161 INLINE void TransformState:: 01162 check_uniform_scale2d() { 01163 if (IS_NEARLY_EQUAL(_scale[0], _scale[1])) { 01164 _scale[2] = _scale[0]; 01165 _flags |= F_uniform_scale; 01166 if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) { 01167 _flags |= F_identity_scale; 01168 } 01169 } 01170 01171 if (!_shear.almost_equal(LVecBase3f::zero())) { 01172 _flags |= F_has_nonzero_shear; 01173 } 01174 } 01175 01176 //////////////////////////////////////////////////////////////////// 01177 // Function: TransformState::set_destructing 01178 // Access: Private 01179 // Description: This function should only be called from the 01180 // destructor; it indicates that this TransformState 01181 // object is beginning destruction. It is only used as 01182 // a sanity check, and is only meaningful when NDEBUG is 01183 // not defined. 01184 //////////////////////////////////////////////////////////////////// 01185 INLINE void TransformState:: 01186 set_destructing() { 01187 #ifndef NDEBUG 01188 _flags |= F_is_destructing; 01189 #endif 01190 } 01191 01192 //////////////////////////////////////////////////////////////////// 01193 // Function: TransformState::is_destructing 01194 // Access: Private 01195 // Description: Returns true if the TransformState object is 01196 // currently within its destructor 01197 // (i.e. set_destructing() has been called). This is 01198 // only used as a sanity check, and is only meaningful 01199 // when NDEBUG is not defined. 01200 //////////////////////////////////////////////////////////////////// 01201 INLINE bool TransformState:: 01202 is_destructing() const { 01203 #ifndef NDEBUG 01204 return (_flags & F_is_destructing) != 0; 01205 #else 01206 return false; 01207 #endif 01208 } 01209 01210 //////////////////////////////////////////////////////////////////// 01211 // Function: TransformState::consider_update_pstats 01212 // Access: Private 01213 // Description: Calls update_pstats() if the state of the referenced 01214 // bits has changed from the indicated value. 01215 //////////////////////////////////////////////////////////////////// 01216 INLINE void TransformState:: 01217 consider_update_pstats(int old_referenced_bits) const { 01218 #ifdef DO_PSTATS 01219 int new_referenced_bits = get_referenced_bits(); 01220 if (old_referenced_bits != new_referenced_bits) { 01221 update_pstats(old_referenced_bits, new_referenced_bits); 01222 } 01223 #endif // DO_PSTATS 01224 } 01225 01226 //////////////////////////////////////////////////////////////////// 01227 // Function: TransformState::Composition::Constructor 01228 // Access: Public 01229 // Description: 01230 //////////////////////////////////////////////////////////////////// 01231 INLINE TransformState::Composition:: 01232 Composition() { 01233 } 01234 01235 //////////////////////////////////////////////////////////////////// 01236 // Function: TransformState::Composition::Copy Constructor 01237 // Access: Public 01238 // Description: 01239 //////////////////////////////////////////////////////////////////// 01240 INLINE TransformState::Composition:: 01241 Composition(const TransformState::Composition ©) : 01242 _result(copy._result) 01243 { 01244 } 01245 01246 //////////////////////////////////////////////////////////////////// 01247 // Function: TransformState::CompositionCycleDescEntry::Constructor 01248 // Access: Public 01249 // Description: 01250 //////////////////////////////////////////////////////////////////// 01251 INLINE TransformState::CompositionCycleDescEntry:: 01252 CompositionCycleDescEntry(const TransformState *obj, 01253 const TransformState *result, 01254 bool inverted) : 01255 _obj(obj), 01256 _result(result), 01257 _inverted(inverted) 01258 { 01259 }