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