diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index d3eaff3f..70b01db6 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -13,7 +13,10 @@ include_HEADERS = \ placement.hxx \ placementtrans.hxx \ SGMaterialAnimation.hxx \ - SGOffsetTransform.hxx + SGOffsetTransform.hxx \ + SGRotateTransform.hxx \ + SGScaleTransform.hxx \ + SGTranslateTransform.hxx libsgmodel_a_SOURCES = \ animation.cxx \ @@ -25,6 +28,9 @@ libsgmodel_a_SOURCES = \ placementtrans.cxx \ shadanim.cxx \ SGMaterialAnimation.cxx \ - SGOffsetTransform.cxx + SGOffsetTransform.cxx \ + SGRotateTransform.cxx \ + SGScaleTransform.cxx \ + SGTranslateTransform.cxx INCLUDES = -I$(top_srcdir) diff --git a/simgear/scene/model/SGRotateTransform.cxx b/simgear/scene/model/SGRotateTransform.cxx new file mode 100644 index 00000000..84fb15d0 --- /dev/null +++ b/simgear/scene/model/SGRotateTransform.cxx @@ -0,0 +1,122 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "SGRotateTransform.hxx" + +static void +set_rotation (osg::Matrix &matrix, double position_rad, + const SGVec3d ¢er, const SGVec3d &axis) +{ + double temp_angle = -position_rad; + + double s = sin(temp_angle); + double c = cos(temp_angle); + double t = 1 - c; + + // axis was normalized at load time + // hint to the compiler to put these into FP registers + double x = axis[0]; + double y = axis[1]; + double z = axis[2]; + + matrix(0, 0) = t * x * x + c ; + matrix(0, 1) = t * y * x - s * z ; + matrix(0, 2) = t * z * x + s * y ; + matrix(0, 3) = 0; + + matrix(1, 0) = t * x * y + s * z ; + matrix(1, 1) = t * y * y + c ; + matrix(1, 2) = t * z * y - s * x ; + matrix(1, 3) = 0; + + matrix(2, 0) = t * x * z - s * y ; + matrix(2, 1) = t * y * z + s * x ; + matrix(2, 2) = t * z * z + c ; + matrix(2, 3) = 0; + + // hint to the compiler to put these into FP registers + x = center[0]; + y = center[1]; + z = center[2]; + + matrix(3, 0) = x - x*matrix(0, 0) - y*matrix(1, 0) - z*matrix(2, 0); + matrix(3, 1) = y - x*matrix(0, 1) - y*matrix(1, 1) - z*matrix(2, 1); + matrix(3, 2) = z - x*matrix(0, 2) - y*matrix(1, 2) - z*matrix(2, 2); + matrix(3, 3) = 1; +} + +SGRotateTransform::SGRotateTransform() : + _center(0, 0, 0), + _axis(0, 0, 0), + _angleRad(0) +{ + setReferenceFrame(RELATIVE_RF); +} + +bool +SGRotateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + // This is the fast path, optimize a bit + if (_referenceFrame == RELATIVE_RF) { + // FIXME optimize + osg::Matrix tmp; + set_rotation(tmp, _angleRad, _center, _axis); + matrix.preMult(tmp); + } else { + osg::Matrix tmp; + set_rotation(tmp, _angleRad, _center, _axis); + matrix = tmp; + } + return true; +} + +bool +SGRotateTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + if (_referenceFrame == RELATIVE_RF) { + // FIXME optimize + osg::Matrix tmp; + set_rotation(tmp, -_angleRad, _center, _axis); + matrix.postMult(tmp); + } else { + // FIXME optimize + osg::Matrix tmp; + set_rotation(tmp, -_angleRad, _center, _axis); + matrix = tmp; + } + return true; +} + +osg::BoundingSphere +SGRotateTransform::computeBound() const +{ + osg::BoundingSphere bs = osg::Group::computeBound(); + osg::BoundingSphere centerbs(_center.osg(), bs.radius()); + centerbs.expandBy(bs); + return centerbs; +} + diff --git a/simgear/scene/model/SGRotateTransform.hxx b/simgear/scene/model/SGRotateTransform.hxx new file mode 100644 index 00000000..22611ed4 --- /dev/null +++ b/simgear/scene/model/SGRotateTransform.hxx @@ -0,0 +1,69 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef SG_ROTATE_TRANSFORM_HXX +#define SG_ROTATE_TRANSFORM_HXX + +#include +#include + +class SGRotateTransform : public osg::Transform { +public: + SGRotateTransform(); + + void setCenter(const SGVec3f& center) + { setCenter(toVec3d(center)); } + void setCenter(const SGVec3d& center) + { _center = center; dirtyBound(); } + const SGVec3d& getCenter() const + { return _center; } + + void setAxis(const SGVec3f& axis) + { setAxis(toVec3d(axis)); } + void setAxis(const SGVec3d& axis) + { _axis = axis; dirtyBound(); } + const SGVec3d& getAxis() const + { return _axis; } + + void setAngleRad(double angle) + { _angleRad = angle; } + double getAngleRad() const + { return _angleRad; } + + void setAngleDeg(double angle) + { _angleRad = SGMiscd::deg2rad(angle); } + double getAngleDeg() const + { return SGMiscd::rad2deg(_angleRad); } + + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + + virtual osg::BoundingSphere computeBound() const; + +private: + SGVec3d _center; + SGVec3d _axis; + double _angleRad; +}; + +#endif diff --git a/simgear/scene/model/SGScaleTransform.cxx b/simgear/scene/model/SGScaleTransform.cxx new file mode 100644 index 00000000..f8d4ca31 --- /dev/null +++ b/simgear/scene/model/SGScaleTransform.cxx @@ -0,0 +1,109 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "SGScaleTransform.hxx" + +SGScaleTransform::SGScaleTransform() : + _center(0, 0, 0), + _scaleFactor(1, 1, 1), + _boundScale(1) +{ + setReferenceFrame(RELATIVE_RF); +} + +bool +SGScaleTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + osg::Matrix transform; + transform(0,0) = _scaleFactor[0]; + transform(1,1) = _scaleFactor[1]; + transform(2,2) = _scaleFactor[2]; + transform(3,0) = _center[0]*(1 - _scaleFactor[0]); + transform(3,1) = _center[1]*(1 - _scaleFactor[1]); + transform(3,2) = _center[2]*(1 - _scaleFactor[2]); + if (_referenceFrame == RELATIVE_RF) + matrix.preMult(transform); + else + matrix = transform; + return true; +} + +bool +SGScaleTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + if (fabs(_scaleFactor[0]) < SGLimitsd::min()) + return false; + if (fabs(_scaleFactor[1]) < SGLimitsd::min()) + return false; + if (fabs(_scaleFactor[2]) < SGLimitsd::min()) + return false; + SGVec3d rScaleFactor(1/_scaleFactor[0], + 1/_scaleFactor[1], + 1/_scaleFactor[2]); + osg::Matrix transform; + transform(0,0) = rScaleFactor[0]; + transform(1,1) = rScaleFactor[1]; + transform(2,2) = rScaleFactor[2]; + transform(3,0) = _center[0]*(1 - rScaleFactor[0]); + transform(3,1) = _center[1]*(1 - rScaleFactor[1]); + transform(3,2) = _center[2]*(1 - rScaleFactor[2]); + if (_referenceFrame == RELATIVE_RF) + matrix.postMult(transform); + else + matrix = transform; + return true; +} + +osg::BoundingSphere +SGScaleTransform::computeBound() const +{ + osg::BoundingSphere bs = osg::Group::computeBound(); + _boundScale = normI(_scaleFactor); + bs.radius() *= _boundScale; + return bs; +} diff --git a/simgear/scene/model/SGScaleTransform.hxx b/simgear/scene/model/SGScaleTransform.hxx new file mode 100644 index 00000000..03b1c8a0 --- /dev/null +++ b/simgear/scene/model/SGScaleTransform.hxx @@ -0,0 +1,73 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef SG_SCALE_TRANSFORM_HXX +#define SG_SCALE_TRANSFORM_HXX + +#include +#include + +class SGScaleTransform : public osg::Transform { +public: + SGScaleTransform(); + + void setCenter(const SGVec3f& center) + { setCenter(toVec3d(center)); } + void setCenter(const SGVec3d& center) + { _center = center; dirtyBound(); } + const SGVec3d& getCenter() const + { return _center; } + + void setScaleFactor(const SGVec3d& scaleFactor) + { + double boundScale = normI(scaleFactor); + if (_boundScale < boundScale || 5*boundScale < _boundScale) { + _boundScale = boundScale; + dirtyBound(); + } + _scaleFactor = scaleFactor; + } + void setScaleFactor(double scaleFactor) + { + double boundScale = fabs(scaleFactor); + if (_boundScale < boundScale || 5*boundScale < _boundScale) { + _boundScale = boundScale; + dirtyBound(); + } + _scaleFactor = SGVec3d(scaleFactor, scaleFactor, scaleFactor); + } + const SGVec3d& getScaleFactor() const + { return _scaleFactor; } + + + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + virtual osg::BoundingSphere computeBound() const; + +private: + SGVec3d _center; + SGVec3d _scaleFactor; + mutable double _boundScale; +}; + +#endif diff --git a/simgear/scene/model/SGTranslateTransform.cxx b/simgear/scene/model/SGTranslateTransform.cxx new file mode 100644 index 00000000..c7d0f978 --- /dev/null +++ b/simgear/scene/model/SGTranslateTransform.cxx @@ -0,0 +1,83 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "SGTranslateTransform.hxx" + +static inline void +set_translation (osg::Matrix &matrix, double position_m, const SGVec3d &axis) +{ + SGVec3d xyz = axis * position_m; + matrix.makeIdentity(); + matrix(3, 0) = xyz[0]; + matrix(3, 1) = xyz[1]; + matrix(3, 2) = xyz[2]; +} + +SGTranslateTransform::SGTranslateTransform() : + _axis(0, 0, 0), + _value(0) +{ + setReferenceFrame(RELATIVE_RF); +} + +bool +SGTranslateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + if (_referenceFrame == RELATIVE_RF) { + osg::Matrix tmp; + set_translation(tmp, _value, _axis); + matrix.preMult(tmp); + } else { + osg::Matrix tmp; + set_translation(tmp, _value, _axis); + matrix = tmp; + } + return true; +} + +bool +SGTranslateTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const +{ + if (_referenceFrame == RELATIVE_RF) { + osg::Matrix tmp; + set_translation(tmp, -_value, _axis); + matrix.postMult(tmp); + } else { + osg::Matrix tmp; + set_translation(tmp, -_value, _axis); + matrix = tmp; + } + return true; +} + +osg::BoundingSphere +SGTranslateTransform::computeBound() const +{ + osg::BoundingSphere bs = osg::Group::computeBound(); + bs._center += _axis.osg()*_value; + return bs; +} diff --git a/simgear/scene/model/SGTranslateTransform.hxx b/simgear/scene/model/SGTranslateTransform.hxx new file mode 100644 index 00000000..e4bd8f1d --- /dev/null +++ b/simgear/scene/model/SGTranslateTransform.hxx @@ -0,0 +1,53 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef SG_TRANSLATE_TRANSFORM_HXX +#define SG_TRANSLATE_TRANSFORM_HXX + +#include +#include + +class SGTranslateTransform : public osg::Transform { +public: + SGTranslateTransform(); + + void setAxis(const SGVec3d& axis) + { _axis = axis; dirtyBound(); } + const SGVec3d& getAxis() const + { return _axis; } + + void setValue(double value) + { _value = value; dirtyBound(); } + double getValue() const + { return _value; } + + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const; + virtual osg::BoundingSphere computeBound() const; + +private: + SGVec3d _axis; + double _value; +}; + +#endif diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 31d08622..5e3ed63f 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -36,7 +36,10 @@ #include "animation.hxx" #include "model.hxx" +#include "SGTranslateTransform.hxx" #include "SGMaterialAnimation.hxx" +#include "SGRotateTransform.hxx" +#include "SGScaleTransform.hxx" //////////////////////////////////////////////////////////////////////// @@ -711,39 +714,6 @@ SGGroupAnimation::createAnimationGroup(osg::Group& parent) // Implementation of translate animation //////////////////////////////////////////////////////////////////////// -class SGTranslateAnimation::Transform : public osg::Transform { -public: - Transform() : - _axis(0, 0, 0), - _value(0) - { setReferenceFrame(RELATIVE_RF); } - void setAxis(const SGVec3d& axis) - { _axis = axis; dirtyBound(); } - void setValue(double value) - { _value = value; dirtyBound(); } - virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - assert(_referenceFrame == RELATIVE_RF); - osg::Matrix tmp; - set_translation(tmp, _value, _axis); - matrix.preMult(tmp); - return true; - } - virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - assert(_referenceFrame == RELATIVE_RF); - osg::Matrix tmp; - set_translation(tmp, -_value, _axis); - matrix.postMult(tmp); - return true; - } -private: - SGVec3d _axis; - double _value; -}; - class SGTranslateAnimation::UpdateCallback : public osg::NodeCallback { public: UpdateCallback(SGCondition const* condition, @@ -754,8 +724,8 @@ public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!_condition || _condition->test()) { - SGTranslateAnimation::Transform* transform; - transform = static_cast(node); + SGTranslateTransform* transform; + transform = static_cast(node); transform->setValue(_animationValue->getValue()); } traverse(node, nv); @@ -786,7 +756,7 @@ SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode, osg::Group* SGTranslateAnimation::createAnimationGroup(osg::Group& parent) { - Transform* transform = new Transform; + SGTranslateTransform* transform = new SGTranslateTransform; transform->setName("translate animation"); if (_animationValue) { UpdateCallback* uc = new UpdateCallback(_condition, _animationValue); @@ -803,53 +773,6 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent) // Implementation of rotate/spin animation //////////////////////////////////////////////////////////////////////// -class SGRotateAnimation::Transform : public osg::Transform { -public: - Transform() - { setReferenceFrame(RELATIVE_RF); } - void setCenter(const SGVec3d& center) - { _center = center; dirtyBound(); } - void setAxis(const SGVec3d& axis) - { _axis = axis; dirtyBound(); } - void setAngle(double angle) - { _angle = angle; } - double getAngle() const - { return _angle; } - virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - // This is the fast path, optimize a bit - assert(_referenceFrame == RELATIVE_RF); - // FIXME optimize - osg::Matrix tmp; - set_rotation(tmp, _angle, _center, _axis); - matrix.preMult(tmp); - return true; - } - virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - assert(_referenceFrame == RELATIVE_RF); - // FIXME optimize - osg::Matrix tmp; - set_rotation(tmp, -_angle, _center, _axis); - matrix.postMult(tmp); - return true; - } - virtual osg::BoundingSphere computeBound() const - { - osg::BoundingSphere bs = osg::Group::computeBound(); - osg::BoundingSphere centerbs(_center.osg(), bs.radius()); - centerbs.expandBy(bs); - return centerbs; - } - -private: - SGVec3d _center; - SGVec3d _axis; - double _angle; -}; - class SGRotateAnimation::UpdateCallback : public osg::NodeCallback { public: UpdateCallback(SGCondition const* condition, @@ -860,9 +783,9 @@ public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!_condition || _condition->test()) { - SGRotateAnimation::Transform* transform; - transform = static_cast(node); - transform->setAngle(_animationValue->getValue()); + SGRotateTransform* transform; + transform = static_cast(node); + transform->setAngleDeg(_animationValue->getValue()); } traverse(node, nv); } @@ -882,8 +805,8 @@ public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!_condition || _condition->test()) { - SGRotateAnimation::Transform* transform; - transform = static_cast(node); + SGRotateTransform* transform; + transform = static_cast(node); double t = nv->getFrameStamp()->getReferenceTime(); double dt = 0; @@ -891,10 +814,10 @@ public: dt = t - _lastTime; _lastTime = t; double velocity_rpms = _animationValue->getValue()/60; - double angle = transform->getAngle(); + double angle = transform->getAngleDeg(); angle += dt*velocity_rpms*360; angle -= 360*floor(angle/360); - transform->setAngle(angle); + transform->setAngleDeg(angle); } traverse(node, nv); } @@ -944,7 +867,7 @@ SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode, SGPropert osg::Group* SGRotateAnimation::createAnimationGroup(osg::Group& parent) { - Transform* transform = new Transform; + SGRotateTransform* transform = new SGRotateTransform; transform->setName("rotate animation"); if (_isSpin) { SpinUpdateCallback* uc; @@ -956,7 +879,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent) } transform->setCenter(_center); transform->setAxis(_axis); - transform->setAngle(_initialValue); + transform->setAngleDeg(_initialValue); parent.addChild(transform); return transform; } @@ -966,83 +889,6 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent) // Implementation of scale animation //////////////////////////////////////////////////////////////////////// -class SGScaleAnimation::Transform : public osg::Transform { -public: - Transform() : - _center(0, 0, 0), - _scaleFactor(1, 1, 1), - _boundScale(0) - { - setReferenceFrame(RELATIVE_RF); - } - void setCenter(const SGVec3d& center) - { - _center = center; - dirtyBound(); - } - void setScaleFactor(const SGVec3d& scaleFactor) - { - if (_boundScale < normI(scaleFactor)) - dirtyBound(); - _scaleFactor = scaleFactor; - } - void setScaleFactor(double scaleFactor) - { - if (_boundScale < fabs(scaleFactor)) - dirtyBound(); - _scaleFactor = SGVec3d(scaleFactor, scaleFactor, scaleFactor); - } - virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - assert(_referenceFrame == RELATIVE_RF); - osg::Matrix transform; - transform(0,0) = _scaleFactor[0]; - transform(1,1) = _scaleFactor[1]; - transform(2,2) = _scaleFactor[2]; - transform(3,0) = _center[0]*(1 - _scaleFactor[0]); - transform(3,1) = _center[1]*(1 - _scaleFactor[1]); - transform(3,2) = _center[2]*(1 - _scaleFactor[2]); - matrix.preMult(transform); - return true; - } - virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, - osg::NodeVisitor* nv) const - { - assert(_referenceFrame == RELATIVE_RF); - if (fabs(_scaleFactor[0]) < SGLimitsd::min()) - return false; - if (fabs(_scaleFactor[1]) < SGLimitsd::min()) - return false; - if (fabs(_scaleFactor[2]) < SGLimitsd::min()) - return false; - SGVec3d rScaleFactor(1/_scaleFactor[0], - 1/_scaleFactor[1], - 1/_scaleFactor[2]); - osg::Matrix transform; - transform(0,0) = rScaleFactor[0]; - transform(1,1) = rScaleFactor[1]; - transform(2,2) = rScaleFactor[2]; - transform(3,0) = _center[0]*(1 - rScaleFactor[0]); - transform(3,1) = _center[1]*(1 - rScaleFactor[1]); - transform(3,2) = _center[2]*(1 - rScaleFactor[2]); - matrix.postMult(transform); - return true; - } - virtual osg::BoundingSphere computeBound() const - { - osg::BoundingSphere bs = osg::Group::computeBound(); - _boundScale = normI(_scaleFactor); - bs.radius() *= _boundScale; - return bs; - } - -private: - SGVec3d _center; - SGVec3d _scaleFactor; - mutable double _boundScale; -}; - class SGScaleAnimation::UpdateCallback : public osg::NodeCallback { public: UpdateCallback(const SGCondition* condition, @@ -1056,8 +902,8 @@ public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!_condition || _condition->test()) { - SGScaleAnimation::Transform* transform; - transform = static_cast(node); + SGScaleTransform* transform; + transform = static_cast(node); SGVec3d scale(_animationValue[0]->getValue(), _animationValue[1]->getValue(), _animationValue[2]->getValue()); @@ -1150,7 +996,7 @@ SGScaleAnimation::SGScaleAnimation(const SGPropertyNode* configNode, osg::Group* SGScaleAnimation::createAnimationGroup(osg::Group& parent) { - Transform* transform = new Transform; + SGScaleTransform* transform = new SGScaleTransform; transform->setName("scale animation"); transform->setCenter(_center); transform->setScaleFactor(_initialValue); diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index cc6a7b0e..4f3007df 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -147,7 +147,6 @@ public: virtual osg::Group* createAnimationGroup(osg::Group& parent); private: class UpdateCallback; - class Transform; SGSharedPtr _condition; SGSharedPtr _animationValue; SGVec3d _axis; @@ -167,7 +166,6 @@ public: private: class UpdateCallback; class SpinUpdateCallback; - class Transform; SGSharedPtr _condition; SGSharedPtr _animationValue; SGVec3d _axis; @@ -188,7 +186,6 @@ public: virtual osg::Group* createAnimationGroup(osg::Group& parent); private: class UpdateCallback; - class Transform; SGSharedPtr _condition; SGSharedPtr _animationValue[3]; SGVec3d _initialValue;