| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- // Filename: transformState.I
- // Created by: drose (25Feb02)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
- //
- // All use of this software is subject to the terms of the Panda 3d
- // Software license. You should have received a copy of this license
- // along with this source code; you will also find a current copy of
- // the license at http://etc.cmu.edu/panda3d/docs/license/ .
- //
- // To contact the maintainers of this program write to
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::Composition::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- INLINE TransformState::Composition::
- Composition() {
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::Composition::Copy Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- INLINE TransformState::Composition::
- Composition(const TransformState::Composition ©) :
- _result(copy._result)
- {
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_pos
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_pos(const LVecBase3f &pos) {
- return make_pos_hpr_scale(pos,
- LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(1.0f, 1.0f, 1.0f));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_hpr
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_hpr(const LVecBase3f &hpr) {
- return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
- hpr,
- LVecBase3f(1.0f, 1.0f, 1.0f));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_quat
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_quat(const LQuaternionf &quat) {
- return make_pos_quat_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
- quat,
- LVecBase3f(1.0f, 1.0f, 1.0f));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_pos_hpr
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) {
- return make_pos_hpr_scale(pos, hpr,
- LVecBase3f(1.0, 1.0f, 1.0f));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_scale
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_scale(float scale) {
- return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(scale, scale, scale));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_scale
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_scale(const LVecBase3f &scale) {
- return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(0.0f, 0.0f, 0.0f),
- scale);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_shear
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_shear(const LVecBase3f &shear) {
- return make_pos_hpr_scale_shear(LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(0.0f, 0.0f, 0.0f),
- LVecBase3f(1.0f, 1.0f, 1.0f),
- shear);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_pos_hpr_scale
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_pos_hpr_scale(const LVecBase3f &pos, const LVecBase3f &hpr,
- const LVecBase3f &scale) {
- return make_pos_hpr_scale_shear(pos, hpr, scale, LVecBase3f::zero());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::make_pos_quat_scale
- // Access: Published, Static
- // Description: Makes a new TransformState with the specified
- // components.
- ////////////////////////////////////////////////////////////////////
- INLINE CPT(TransformState) TransformState::
- make_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat,
- const LVecBase3f &scale) {
- return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3f::zero());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::is_identity
- // Access: Published
- // Description: Returns true if the transform represents the identity
- // matrix, false otherwise.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- is_identity() const {
- return ((_flags & F_is_identity) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::is_invalid
- // Access: Published
- // Description: Returns true if the transform represents an invalid
- // matrix, for instance the result of inverting a
- // singular matrix, or false if the transform is valid.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- is_invalid() const {
- return ((_flags & F_is_invalid) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::is_singular
- // Access: Published
- // Description: Returns true if the transform represents a singular
- // transform (that is, it has a zero scale, and it
- // cannot be inverted), or false otherwise.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- is_singular() const {
- check_singular();
- return ((_flags & F_is_singular) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_components
- // Access: Published
- // Description: Returns true if the transform can be described by
- // separate pos, hpr, and scale components. Most
- // transforms we use in everyday life can be so
- // described, but some kinds of transforms (for
- // instance, those involving a skew) cannot.
- //
- // This is not related to whether the transform was
- // originally described componentwise. Even a transform
- // that was constructed with a 4x4 may return true here
- // if the matrix is a simple affine matrix with no skew.
- //
- // If this returns true, you may safely call get_hpr()
- // and get_scale() to retrieve the components. (You
- // may always safely call get_pos() whether this returns
- // true or false.)
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_components() const {
- check_components();
- return ((_flags & F_has_components) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::components_given
- // Access: Published
- // Description: Returns true if the transform was specified
- // componentwise, or false if it was specified with a
- // general 4x4 matrix. If this is true, the components
- // returned by get_pos() and get_scale() will be exactly
- // those that were set; otherwise, these functions will
- // return computed values. If this is true, the
- // rotation may have been set either with a hpr trio or
- // with a quaternion; hpr_given() or quat_given() can
- // resolve the difference.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- components_given() const {
- return ((_flags & F_components_given) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::hpr_given
- // Access: Published
- // Description: Returns true if the rotation was specified via a trio
- // of Euler angles, false otherwise. If this is true,
- // get_hpr() will be exactly as set; otherwise, it will
- // return a computed value.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- hpr_given() const {
- return ((_flags & F_hpr_given) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::quat_given
- // Access: Published
- // Description: Returns true if the rotation was specified via a
- // quaternion, false otherwise. If this is true,
- // get_quat() will be exactly as set; otherwise, it will
- // return a computed value.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- quat_given() const {
- return ((_flags & F_quat_given) != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_pos
- // Access: Published
- // Description: Returns true if the transform's pos component can be
- // extracted out separately. This is generally always
- // true, unless the transform is invalid
- // (i.e. is_invalid() returns true).
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_pos() const {
- return !is_invalid();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_hpr
- // Access: Published
- // Description: Returns true if the transform's rotation component
- // can be extracted out separately and described as a
- // set of Euler angles. This is generally true only
- // when has_components() is true.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_hpr() const {
- return has_components();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_quat
- // Access: Published
- // Description: Returns true if the transform's rotation component
- // can be extracted out separately and described as a
- // quaternion. This is generally true only when
- // has_components() is true.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_quat() const {
- return has_components();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_scale
- // Access: Published
- // Description: Returns true if the transform's scale component
- // can be extracted out separately. This is generally
- // true only when has_components() is true.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_scale() const {
- return has_components();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_uniform_scale
- // Access: Published
- // Description: Returns true if the scale is uniform across all three
- // axes (and therefore can be expressed as a single
- // number), or false if the transform has a different
- // scale in different dimensions.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_uniform_scale() const {
- check_components();
- return (_flags & F_uniform_scale) != 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_shear
- // Access: Published
- // Description: Returns true if the transform's shear component
- // can be extracted out separately. This is generally
- // true only when has_components() is true.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_shear() const {
- return has_components();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_nonzero_shear
- // Access: Published
- // Description: Returns true if the shear component is non-zero,
- // false if it is zero or if the matrix cannot be
- // decomposed.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_nonzero_shear() const {
- check_components();
- return (_flags & F_has_nonzero_shear) != 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::has_mat
- // Access: Published
- // Description: Returns true if the transform can be described as a
- // matrix. This is generally always true, unless
- // is_invalid() is true.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- has_mat() const {
- return !is_invalid();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_pos
- // Access: Published
- // Description: Returns the pos component of the transform. It is an
- // error to call this if has_pos() returned false.
- ////////////////////////////////////////////////////////////////////
- INLINE const LVecBase3f &TransformState::
- get_pos() const {
- check_components();
- nassertr(has_pos(), _pos);
- return _pos;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_hpr
- // Access: Published
- // Description: Returns the rotation component of the transform as a
- // trio of Euler angles. It is an error to call this if
- // has_components() returned false.
- ////////////////////////////////////////////////////////////////////
- INLINE const LVecBase3f &TransformState::
- get_hpr() const {
- check_hpr();
- nassertr(!is_invalid(), _hpr);
- // nassertr(has_hpr(), _hpr);
- return _hpr;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_quat
- // Access: Published
- // Description: Returns the rotation component of the transform as a
- // quaternion. It is an error to call this if
- // has_components() returned false.
- ////////////////////////////////////////////////////////////////////
- INLINE const LQuaternionf &TransformState::
- get_quat() const {
- check_quat();
- nassertr(!is_invalid(), _quat);
- // nassertr(has_quat(), _quat);
- return _quat;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_scale
- // Access: Published
- // Description: Returns the scale component of the transform. It is an
- // error to call this if has_components() returned
- // false.
- ////////////////////////////////////////////////////////////////////
- INLINE const LVecBase3f &TransformState::
- get_scale() const {
- check_components();
- nassertr(!is_invalid(), _scale);
- // nassertr(has_scale(), _scale);
- return _scale;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_uniform_scale
- // Access: Published
- // Description: Returns the scale component of the transform, as a
- // single number. It is an error to call this if
- // has_uniform_scale() returned false.
- ////////////////////////////////////////////////////////////////////
- INLINE float TransformState::
- get_uniform_scale() const {
- check_components();
- nassertr(has_uniform_scale(), _scale[0]);
- return _scale[0];
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_shear
- // Access: Published
- // Description: Returns the shear component of the transform. It is
- // an error to call this if has_components() returned
- // false.
- ////////////////////////////////////////////////////////////////////
- INLINE const LVecBase3f &TransformState::
- get_shear() const {
- check_components();
- nassertr(!is_invalid(), _shear);
- return _shear;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::get_mat
- // Access: Published
- // Description: Returns the matrix that describes the transform.
- ////////////////////////////////////////////////////////////////////
- INLINE const LMatrix4f &TransformState::
- get_mat() const {
- nassertr(has_mat(), LMatrix4f::ident_mat());
- check_mat();
- return _mat;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_singular
- // Access: Private
- // Description: Ensures that we know whether the matrix is singular.
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_singular() const {
- // This pretends to be a const function, even though it's not,
- // because it only updates a transparent cache value.
- if ((_flags & F_singular_known) == 0) {
- ((TransformState *)this)->calc_singular();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_components
- // Access: Private
- // Description: Ensures that we know the components of the transform
- // (or that we know they cannot be derived).
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_components() const {
- // This pretends to be a const function, even though it's not,
- // because it only updates a transparent cache value.
- if ((_flags & F_components_known) == 0) {
- ((TransformState *)this)->calc_components();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_hpr
- // Access: Private
- // Description: Ensures that we know the hpr of the transform
- // (or that we know they cannot be derived).
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_hpr() const {
- // This pretends to be a const function, even though it's not,
- // because it only updates a transparent cache value.
- if ((_flags & F_hpr_known) == 0) {
- ((TransformState *)this)->calc_hpr();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_quat
- // Access: Private
- // Description: Ensures that we know the quat of the transform
- // (or that we know they cannot be derived).
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_quat() const {
- // This pretends to be a const function, even though it's not,
- // because it only updates a transparent cache value.
- if ((_flags & F_quat_known) == 0) {
- ((TransformState *)this)->calc_quat();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_mat
- // Access: Private
- // Description: Ensures that we know the overall matrix.
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_mat() const {
- // This pretends to be a const function, even though it's not,
- // because it only updates a transparent cache value.
- if ((_flags & F_mat_known) == 0) {
- ((TransformState *)this)->calc_mat();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::check_uniform_scale
- // Access: Private
- // Description: Should be called immediately after _scale (and
- // F_has_components) is set, this checks for a uniform
- // scale (as well as a non-zero shear) and sets the bit
- // appropriately.
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- check_uniform_scale() {
- if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) &&
- IS_NEARLY_EQUAL(_scale[0], _scale[2])) {
- _flags |= F_uniform_scale;
- }
- if (!_shear.almost_equal(LVecBase3f::zero())) {
- _flags |= F_has_nonzero_shear;
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::set_destructing
- // Access: Private
- // Description: This function should only be called from the
- // destructor; it indicates that this TransformState
- // object is beginning destruction. It is only used as
- // a sanity check, and is only meaningful when NDEBUG is
- // not defined.
- ////////////////////////////////////////////////////////////////////
- INLINE void TransformState::
- set_destructing() {
- #ifndef NDEBUG
- _flags |= F_is_destructing;
- #endif
- }
- ////////////////////////////////////////////////////////////////////
- // Function: TransformState::is_destructing
- // Access: Private
- // Description: Returns true if the TransformState object is
- // currently within its destructor
- // (i.e. set_destructing() has been called). This is
- // only used as a sanity check, and is only meaningful
- // when NDEBUG is not defined.
- ////////////////////////////////////////////////////////////////////
- INLINE bool TransformState::
- is_destructing() const {
- #ifndef NDEBUG
- return (_flags & F_is_destructing) != 0;
- #else
- return false;
- #endif
- }
|