00001 // Filename: transformState.I 00002 // Created by: drose (25Feb02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: TransformState::Composition::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE TransformState::Composition:: 00026 Composition() { 00027 } 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: TransformState::Composition::Copy Constructor 00031 // Access: Public 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 INLINE TransformState::Composition:: 00035 Composition(const TransformState::Composition ©) : 00036 _result(copy._result) 00037 { 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: TransformState::make_pos 00042 // Access: Published, Static 00043 // Description: Makes a new TransformState with the specified 00044 // components. 00045 //////////////////////////////////////////////////////////////////// 00046 INLINE CPT(TransformState) TransformState:: 00047 make_pos(const LVecBase3f &pos) { 00048 return make_pos_hpr_scale(pos, 00049 LVecBase3f(0.0f, 0.0f, 0.0f), 00050 LVecBase3f(1.0f, 1.0f, 1.0f)); 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: TransformState::make_hpr 00055 // Access: Published, Static 00056 // Description: Makes a new TransformState with the specified 00057 // components. 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE CPT(TransformState) TransformState:: 00060 make_hpr(const LVecBase3f &hpr) { 00061 return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00062 hpr, 00063 LVecBase3f(1.0f, 1.0f, 1.0f)); 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: TransformState::make_quat 00068 // Access: Published, Static 00069 // Description: Makes a new TransformState with the specified 00070 // components. 00071 //////////////////////////////////////////////////////////////////// 00072 INLINE CPT(TransformState) TransformState:: 00073 make_quat(const LQuaternionf &quat) { 00074 return make_pos_quat_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00075 quat, 00076 LVecBase3f(1.0f, 1.0f, 1.0f)); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: TransformState::make_pos_hpr 00081 // Access: Published, Static 00082 // Description: Makes a new TransformState with the specified 00083 // components. 00084 //////////////////////////////////////////////////////////////////// 00085 INLINE CPT(TransformState) TransformState:: 00086 make_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) { 00087 return make_pos_hpr_scale(pos, hpr, 00088 LVecBase3f(1.0, 1.0f, 1.0f)); 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: TransformState::make_scale 00093 // Access: Published, Static 00094 // Description: Makes a new TransformState with the specified 00095 // components. 00096 //////////////////////////////////////////////////////////////////// 00097 INLINE CPT(TransformState) TransformState:: 00098 make_scale(float scale) { 00099 return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00100 LVecBase3f(0.0f, 0.0f, 0.0f), 00101 LVecBase3f(scale, scale, scale)); 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: TransformState::make_scale 00106 // Access: Published, Static 00107 // Description: Makes a new TransformState with the specified 00108 // components. 00109 //////////////////////////////////////////////////////////////////// 00110 INLINE CPT(TransformState) TransformState:: 00111 make_scale(const LVecBase3f &scale) { 00112 return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f), 00113 LVecBase3f(0.0f, 0.0f, 0.0f), 00114 scale); 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: TransformState::is_identity 00119 // Access: Published 00120 // Description: Returns true if the transform represents the identity 00121 // matrix, false otherwise. 00122 //////////////////////////////////////////////////////////////////// 00123 INLINE bool TransformState:: 00124 is_identity() const { 00125 return ((_flags & F_is_identity) != 0); 00126 } 00127 00128 //////////////////////////////////////////////////////////////////// 00129 // Function: TransformState::is_invalid 00130 // Access: Published 00131 // Description: Returns true if the transform represents an invalid 00132 // matrix, for instance the result of inverting a 00133 // singular matrix, or false if the transform is valid. 00134 //////////////////////////////////////////////////////////////////// 00135 INLINE bool TransformState:: 00136 is_invalid() const { 00137 return ((_flags & F_is_invalid) != 0); 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: TransformState::is_singular 00142 // Access: Published 00143 // Description: Returns true if the transform represents a singular 00144 // transform (that is, it has a zero scale, and it 00145 // cannot be inverted), or false otherwise. 00146 //////////////////////////////////////////////////////////////////// 00147 INLINE bool TransformState:: 00148 is_singular() const { 00149 check_singular(); 00150 return ((_flags & F_is_singular) != 0); 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: TransformState::has_components 00155 // Access: Published 00156 // Description: Returns true if the transform can be described by 00157 // separate pos, hpr, and scale components. Most 00158 // transforms we use in everyday life can be so 00159 // described, but some kinds of transforms (for 00160 // instance, those involving a skew) cannot. 00161 // 00162 // This is not related to whether the transform was 00163 // originally described componentwise. Even a transform 00164 // that was constructed with a 4x4 may return true here 00165 // if the matrix is a simple affine matrix with no skew. 00166 // 00167 // If this returns true, you may safely call get_hpr() 00168 // and get_scale() to retrieve the components. (You 00169 // may always safely call get_pos() whether this returns 00170 // true or false.) 00171 //////////////////////////////////////////////////////////////////// 00172 INLINE bool TransformState:: 00173 has_components() const { 00174 check_components(); 00175 return ((_flags & F_has_components) != 0); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: TransformState::components_given 00180 // Access: Published 00181 // Description: Returns true if the transform was specified 00182 // componentwise, or false if it was specified with a 00183 // general 4x4 matrix. If this is true, the components 00184 // returned by get_pos() and get_scale() will be exactly 00185 // those that were set; otherwise, these functions will 00186 // return computed values. If this is true, the 00187 // rotation may have been set either with a hpr trio or 00188 // with a quaternion; hpr_given() or quat_given() can 00189 // resolve the difference. 00190 //////////////////////////////////////////////////////////////////// 00191 INLINE bool TransformState:: 00192 components_given() const { 00193 return ((_flags & F_components_given) != 0); 00194 } 00195 00196 //////////////////////////////////////////////////////////////////// 00197 // Function: TransformState::hpr_given 00198 // Access: Published 00199 // Description: Returns true if the rotation was specified via a trio 00200 // of Euler angles, false otherwise. If this is true, 00201 // get_hpr() will be exactly as set; otherwise, it will 00202 // return a computed value. 00203 //////////////////////////////////////////////////////////////////// 00204 INLINE bool TransformState:: 00205 hpr_given() const { 00206 return ((_flags & F_hpr_given) != 0); 00207 } 00208 00209 //////////////////////////////////////////////////////////////////// 00210 // Function: TransformState::quat_given 00211 // Access: Published 00212 // Description: Returns true if the rotation was specified via a 00213 // quaternion, false otherwise. If this is true, 00214 // get_quat() will be exactly as set; otherwise, it will 00215 // return a computed value. 00216 //////////////////////////////////////////////////////////////////// 00217 INLINE bool TransformState:: 00218 quat_given() const { 00219 return ((_flags & F_quat_given) != 0); 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: TransformState::has_pos 00224 // Access: Published 00225 // Description: Returns true if the transform's pos component can be 00226 // extracted out separately. This is generally always 00227 // true, unless the transform is invalid 00228 // (i.e. is_invalid() returns true). 00229 //////////////////////////////////////////////////////////////////// 00230 INLINE bool TransformState:: 00231 has_pos() const { 00232 return !is_invalid(); 00233 } 00234 00235 //////////////////////////////////////////////////////////////////// 00236 // Function: TransformState::has_hpr 00237 // Access: Published 00238 // Description: Returns true if the transform's rotation component 00239 // can be extracted out separately and described as a 00240 // set of Euler angles. This is generally true only 00241 // when has_components() is true. 00242 //////////////////////////////////////////////////////////////////// 00243 INLINE bool TransformState:: 00244 has_hpr() const { 00245 return has_components(); 00246 } 00247 00248 //////////////////////////////////////////////////////////////////// 00249 // Function: TransformState::has_quat 00250 // Access: Published 00251 // Description: Returns true if the transform's rotation component 00252 // can be extracted out separately and described as a 00253 // quaternion. This is generally true only when 00254 // has_components() is true. 00255 //////////////////////////////////////////////////////////////////// 00256 INLINE bool TransformState:: 00257 has_quat() const { 00258 return has_components(); 00259 } 00260 00261 //////////////////////////////////////////////////////////////////// 00262 // Function: TransformState::has_scale 00263 // Access: Published 00264 // Description: Returns true if the transform's scale component 00265 // can be extracted out separately. This is generally 00266 // true only when has_components() is true. 00267 //////////////////////////////////////////////////////////////////// 00268 INLINE bool TransformState:: 00269 has_scale() const { 00270 return has_components(); 00271 } 00272 00273 //////////////////////////////////////////////////////////////////// 00274 // Function: TransformState::has_uniform_scale 00275 // Access: Published 00276 // Description: Returns true if the scale is uniform across all three 00277 // axes (and therefore can be expressed as a single 00278 // number), or false if the transform has a different 00279 // scale in different dimensions. 00280 //////////////////////////////////////////////////////////////////// 00281 INLINE bool TransformState:: 00282 has_uniform_scale() const { 00283 check_components(); 00284 return (_flags & F_uniform_scale) != 0; 00285 } 00286 00287 //////////////////////////////////////////////////////////////////// 00288 // Function: TransformState::has_mat 00289 // Access: Published 00290 // Description: Returns true if the transform can be described as a 00291 // matrix. This is generally always true, unless 00292 // is_invalid() is true. 00293 //////////////////////////////////////////////////////////////////// 00294 INLINE bool TransformState:: 00295 has_mat() const { 00296 return !is_invalid(); 00297 } 00298 00299 //////////////////////////////////////////////////////////////////// 00300 // Function: TransformState::get_pos 00301 // Access: Published 00302 // Description: Returns the pos component of the transform. It is an 00303 // error to call this if has_pos() returned false. 00304 //////////////////////////////////////////////////////////////////// 00305 INLINE const LVecBase3f &TransformState:: 00306 get_pos() const { 00307 check_components(); 00308 nassertr(has_pos(), _pos); 00309 return _pos; 00310 } 00311 00312 //////////////////////////////////////////////////////////////////// 00313 // Function: TransformState::get_hpr 00314 // Access: Published 00315 // Description: Returns the rotation component of the transform as a 00316 // trio of Euler angles. It is an error to call this if 00317 // has_components() returned false. 00318 //////////////////////////////////////////////////////////////////// 00319 INLINE const LVecBase3f &TransformState:: 00320 get_hpr() const { 00321 check_hpr(); 00322 nassertr(!is_invalid(), _hpr); 00323 // nassertr(has_hpr(), _hpr); 00324 return _hpr; 00325 } 00326 00327 //////////////////////////////////////////////////////////////////// 00328 // Function: TransformState::get_quat 00329 // Access: Published 00330 // Description: Returns the rotation component of the transform as a 00331 // quaternion. It is an error to call this if 00332 // has_components() returned false. 00333 //////////////////////////////////////////////////////////////////// 00334 INLINE const LQuaternionf &TransformState:: 00335 get_quat() const { 00336 check_quat(); 00337 nassertr(!is_invalid(), _quat); 00338 // nassertr(has_quat(), _quat); 00339 return _quat; 00340 } 00341 00342 //////////////////////////////////////////////////////////////////// 00343 // Function: TransformState::get_scale 00344 // Access: Published 00345 // Description: Returns the scale component of the transform. It is an 00346 // error to call this if has_components() returned 00347 // false. 00348 //////////////////////////////////////////////////////////////////// 00349 INLINE const LVecBase3f &TransformState:: 00350 get_scale() const { 00351 check_components(); 00352 nassertr(!is_invalid(), _scale); 00353 // nassertr(has_scale(), _scale); 00354 return _scale; 00355 } 00356 00357 //////////////////////////////////////////////////////////////////// 00358 // Function: TransformState::get_uniform_scale 00359 // Access: Published 00360 // Description: Returns the scale component of the transform, as a 00361 // single number. It is an error to call this if 00362 // has_uniform_scale() returned false. 00363 //////////////////////////////////////////////////////////////////// 00364 INLINE float TransformState:: 00365 get_uniform_scale() const { 00366 check_components(); 00367 nassertr(has_uniform_scale(), _scale[0]); 00368 return _scale[0]; 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: TransformState::get_mat 00373 // Access: Published 00374 // Description: Returns the matrix that describes the transform. 00375 //////////////////////////////////////////////////////////////////// 00376 INLINE const LMatrix4f &TransformState:: 00377 get_mat() const { 00378 nassertr(has_mat(), LMatrix4f::ident_mat()); 00379 check_mat(); 00380 return _mat; 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: TransformState::check_singular 00385 // Access: Private 00386 // Description: Ensures that we know whether the matrix is singular. 00387 //////////////////////////////////////////////////////////////////// 00388 INLINE void TransformState:: 00389 check_singular() const { 00390 // This pretends to be a const function, even though it's not, 00391 // because it only updates a transparent cache value. 00392 if ((_flags & F_singular_known) == 0) { 00393 ((TransformState *)this)->calc_singular(); 00394 } 00395 } 00396 00397 //////////////////////////////////////////////////////////////////// 00398 // Function: TransformState::check_components 00399 // Access: Private 00400 // Description: Ensures that we know the components of the transform 00401 // (or that we know they cannot be derived). 00402 //////////////////////////////////////////////////////////////////// 00403 INLINE void TransformState:: 00404 check_components() const { 00405 // This pretends to be a const function, even though it's not, 00406 // because it only updates a transparent cache value. 00407 if ((_flags & F_components_known) == 0) { 00408 ((TransformState *)this)->calc_components(); 00409 } 00410 } 00411 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: TransformState::check_hpr 00414 // Access: Private 00415 // Description: Ensures that we know the hpr of the transform 00416 // (or that we know they cannot be derived). 00417 //////////////////////////////////////////////////////////////////// 00418 INLINE void TransformState:: 00419 check_hpr() const { 00420 // This pretends to be a const function, even though it's not, 00421 // because it only updates a transparent cache value. 00422 if ((_flags & F_hpr_known) == 0) { 00423 ((TransformState *)this)->calc_hpr(); 00424 } 00425 } 00426 00427 //////////////////////////////////////////////////////////////////// 00428 // Function: TransformState::check_quat 00429 // Access: Private 00430 // Description: Ensures that we know the quat of the transform 00431 // (or that we know they cannot be derived). 00432 //////////////////////////////////////////////////////////////////// 00433 INLINE void TransformState:: 00434 check_quat() const { 00435 // This pretends to be a const function, even though it's not, 00436 // because it only updates a transparent cache value. 00437 if ((_flags & F_quat_known) == 0) { 00438 ((TransformState *)this)->calc_quat(); 00439 } 00440 } 00441 00442 //////////////////////////////////////////////////////////////////// 00443 // Function: TransformState::check_mat 00444 // Access: Private 00445 // Description: Ensures that we know the overall matrix. 00446 //////////////////////////////////////////////////////////////////// 00447 INLINE void TransformState:: 00448 check_mat() const { 00449 // This pretends to be a const function, even though it's not, 00450 // because it only updates a transparent cache value. 00451 if ((_flags & F_mat_known) == 0) { 00452 ((TransformState *)this)->calc_mat(); 00453 } 00454 } 00455 00456 //////////////////////////////////////////////////////////////////// 00457 // Function: TransformState::check_uniform_scale 00458 // Access: Private 00459 // Description: Should be called immediately after _scale (and 00460 // F_has_components) is set, this checks for a uniform 00461 // scale and sets the bit appropriately. 00462 //////////////////////////////////////////////////////////////////// 00463 INLINE void TransformState:: 00464 check_uniform_scale() { 00465 if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) && 00466 IS_NEARLY_EQUAL(_scale[0], _scale[2])) { 00467 _flags |= F_uniform_scale; 00468 } 00469 } 00470 00471 //////////////////////////////////////////////////////////////////// 00472 // Function: TransformState::set_destructing 00473 // Access: Private 00474 // Description: This function should only be called from the 00475 // destructor; it indicates that this TransformState 00476 // object is beginning destruction. It is only used as 00477 // a sanity check, and is only meaningful when NDEBUG is 00478 // not defined. 00479 //////////////////////////////////////////////////////////////////// 00480 INLINE void TransformState:: 00481 set_destructing() { 00482 #ifndef NDEBUG 00483 _flags |= F_is_destructing; 00484 #endif 00485 } 00486 00487 //////////////////////////////////////////////////////////////////// 00488 // Function: TransformState::is_destructing 00489 // Access: Private 00490 // Description: Returns true if the TransformState object is 00491 // currently within its destructor 00492 // (i.e. set_destructing() has been called). This is 00493 // only used as a sanity check, and is only meaningful 00494 // when NDEBUG is not defined. 00495 //////////////////////////////////////////////////////////////////// 00496 INLINE bool TransformState:: 00497 is_destructing() const { 00498 #ifndef NDEBUG 00499 return (_flags & F_is_destructing) != 0; 00500 #else 00501 return false; 00502 #endif 00503 } 00504 00505 //////////////////////////////////////////////////////////////////// 00506 // Function: EventStoreTransform::Constructor 00507 // Access: Public 00508 // Description: 00509 //////////////////////////////////////////////////////////////////// 00510 INLINE EventStoreTransform:: 00511 EventStoreTransform(const TransformState *value) : 00512 _value(value) 00513 { 00514 } 00515 00516 //////////////////////////////////////////////////////////////////// 00517 // Function: EventStoreTransform::set_value 00518 // Access: Public 00519 // Description: 00520 //////////////////////////////////////////////////////////////////// 00521 INLINE void EventStoreTransform:: 00522 set_value(const TransformState *value) { 00523 _value = value; 00524 } 00525 00526 //////////////////////////////////////////////////////////////////// 00527 // Function: EventStoreTransform::get_value 00528 // Access: Public 00529 // Description: 00530 //////////////////////////////////////////////////////////////////// 00531 INLINE const TransformState *EventStoreTransform:: 00532 get_value() const { 00533 return _value; 00534 }