Modified Files:

simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
Added Files:
	simgear/scene/model/SGRotateTransform.cxx
	simgear/scene/model/SGRotateTransform.hxx
	simgear/scene/model/SGScaleTransform.cxx
	simgear/scene/model/SGScaleTransform.hxx
	simgear/scene/model/SGTranslateTransform.cxx
	simgear/scene/model/SGTranslateTransform.hxx:
	Factor out some useful classes.
This commit is contained in:
frohlich 2007-05-28 07:13:07 +00:00
parent f32e037c58
commit 487701a143
9 changed files with 535 additions and 177 deletions

View File

@ -13,7 +13,10 @@ include_HEADERS = \
placement.hxx \ placement.hxx \
placementtrans.hxx \ placementtrans.hxx \
SGMaterialAnimation.hxx \ SGMaterialAnimation.hxx \
SGOffsetTransform.hxx SGOffsetTransform.hxx \
SGRotateTransform.hxx \
SGScaleTransform.hxx \
SGTranslateTransform.hxx
libsgmodel_a_SOURCES = \ libsgmodel_a_SOURCES = \
animation.cxx \ animation.cxx \
@ -25,6 +28,9 @@ libsgmodel_a_SOURCES = \
placementtrans.cxx \ placementtrans.cxx \
shadanim.cxx \ shadanim.cxx \
SGMaterialAnimation.cxx \ SGMaterialAnimation.cxx \
SGOffsetTransform.cxx SGOffsetTransform.cxx \
SGRotateTransform.cxx \
SGScaleTransform.cxx \
SGTranslateTransform.cxx
INCLUDES = -I$(top_srcdir) INCLUDES = -I$(top_srcdir)

View File

@ -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 <simgear_config.h>
#endif
#include "SGRotateTransform.hxx"
static void
set_rotation (osg::Matrix &matrix, double position_rad,
const SGVec3d &center, 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;
}

View File

@ -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 <osg/Transform>
#include <simgear/math/SGMath.hxx>
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

View File

@ -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 <simgear_config.h>
#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;
}

View File

@ -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 <osg/Transform>
#include <simgear/math/SGMath.hxx>
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

View File

@ -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 <simgear_config.h>
#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;
}

View File

@ -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 <osg/Transform>
#include <simgear/math/SGMath.hxx>
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

View File

@ -36,7 +36,10 @@
#include "animation.hxx" #include "animation.hxx"
#include "model.hxx" #include "model.hxx"
#include "SGTranslateTransform.hxx"
#include "SGMaterialAnimation.hxx" #include "SGMaterialAnimation.hxx"
#include "SGRotateTransform.hxx"
#include "SGScaleTransform.hxx"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -711,39 +714,6 @@ SGGroupAnimation::createAnimationGroup(osg::Group& parent)
// Implementation of translate animation // 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 { class SGTranslateAnimation::UpdateCallback : public osg::NodeCallback {
public: public:
UpdateCallback(SGCondition const* condition, UpdateCallback(SGCondition const* condition,
@ -754,8 +724,8 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (!_condition || _condition->test()) { if (!_condition || _condition->test()) {
SGTranslateAnimation::Transform* transform; SGTranslateTransform* transform;
transform = static_cast<SGTranslateAnimation::Transform*>(node); transform = static_cast<SGTranslateTransform*>(node);
transform->setValue(_animationValue->getValue()); transform->setValue(_animationValue->getValue());
} }
traverse(node, nv); traverse(node, nv);
@ -786,7 +756,7 @@ SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode,
osg::Group* osg::Group*
SGTranslateAnimation::createAnimationGroup(osg::Group& parent) SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
{ {
Transform* transform = new Transform; SGTranslateTransform* transform = new SGTranslateTransform;
transform->setName("translate animation"); transform->setName("translate animation");
if (_animationValue) { if (_animationValue) {
UpdateCallback* uc = new UpdateCallback(_condition, _animationValue); UpdateCallback* uc = new UpdateCallback(_condition, _animationValue);
@ -803,53 +773,6 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
// Implementation of rotate/spin animation // 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 { class SGRotateAnimation::UpdateCallback : public osg::NodeCallback {
public: public:
UpdateCallback(SGCondition const* condition, UpdateCallback(SGCondition const* condition,
@ -860,9 +783,9 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (!_condition || _condition->test()) { if (!_condition || _condition->test()) {
SGRotateAnimation::Transform* transform; SGRotateTransform* transform;
transform = static_cast<SGRotateAnimation::Transform*>(node); transform = static_cast<SGRotateTransform*>(node);
transform->setAngle(_animationValue->getValue()); transform->setAngleDeg(_animationValue->getValue());
} }
traverse(node, nv); traverse(node, nv);
} }
@ -882,8 +805,8 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (!_condition || _condition->test()) { if (!_condition || _condition->test()) {
SGRotateAnimation::Transform* transform; SGRotateTransform* transform;
transform = static_cast<SGRotateAnimation::Transform*>(node); transform = static_cast<SGRotateTransform*>(node);
double t = nv->getFrameStamp()->getReferenceTime(); double t = nv->getFrameStamp()->getReferenceTime();
double dt = 0; double dt = 0;
@ -891,10 +814,10 @@ public:
dt = t - _lastTime; dt = t - _lastTime;
_lastTime = t; _lastTime = t;
double velocity_rpms = _animationValue->getValue()/60; double velocity_rpms = _animationValue->getValue()/60;
double angle = transform->getAngle(); double angle = transform->getAngleDeg();
angle += dt*velocity_rpms*360; angle += dt*velocity_rpms*360;
angle -= 360*floor(angle/360); angle -= 360*floor(angle/360);
transform->setAngle(angle); transform->setAngleDeg(angle);
} }
traverse(node, nv); traverse(node, nv);
} }
@ -944,7 +867,7 @@ SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode, SGPropert
osg::Group* osg::Group*
SGRotateAnimation::createAnimationGroup(osg::Group& parent) SGRotateAnimation::createAnimationGroup(osg::Group& parent)
{ {
Transform* transform = new Transform; SGRotateTransform* transform = new SGRotateTransform;
transform->setName("rotate animation"); transform->setName("rotate animation");
if (_isSpin) { if (_isSpin) {
SpinUpdateCallback* uc; SpinUpdateCallback* uc;
@ -956,7 +879,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
} }
transform->setCenter(_center); transform->setCenter(_center);
transform->setAxis(_axis); transform->setAxis(_axis);
transform->setAngle(_initialValue); transform->setAngleDeg(_initialValue);
parent.addChild(transform); parent.addChild(transform);
return transform; return transform;
} }
@ -966,83 +889,6 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
// Implementation of scale animation // 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 { class SGScaleAnimation::UpdateCallback : public osg::NodeCallback {
public: public:
UpdateCallback(const SGCondition* condition, UpdateCallback(const SGCondition* condition,
@ -1056,8 +902,8 @@ public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
if (!_condition || _condition->test()) { if (!_condition || _condition->test()) {
SGScaleAnimation::Transform* transform; SGScaleTransform* transform;
transform = static_cast<SGScaleAnimation::Transform*>(node); transform = static_cast<SGScaleTransform*>(node);
SGVec3d scale(_animationValue[0]->getValue(), SGVec3d scale(_animationValue[0]->getValue(),
_animationValue[1]->getValue(), _animationValue[1]->getValue(),
_animationValue[2]->getValue()); _animationValue[2]->getValue());
@ -1150,7 +996,7 @@ SGScaleAnimation::SGScaleAnimation(const SGPropertyNode* configNode,
osg::Group* osg::Group*
SGScaleAnimation::createAnimationGroup(osg::Group& parent) SGScaleAnimation::createAnimationGroup(osg::Group& parent)
{ {
Transform* transform = new Transform; SGScaleTransform* transform = new SGScaleTransform;
transform->setName("scale animation"); transform->setName("scale animation");
transform->setCenter(_center); transform->setCenter(_center);
transform->setScaleFactor(_initialValue); transform->setScaleFactor(_initialValue);

View File

@ -147,7 +147,6 @@ public:
virtual osg::Group* createAnimationGroup(osg::Group& parent); virtual osg::Group* createAnimationGroup(osg::Group& parent);
private: private:
class UpdateCallback; class UpdateCallback;
class Transform;
SGSharedPtr<const SGCondition> _condition; SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue; SGSharedPtr<const SGDoubleValue> _animationValue;
SGVec3d _axis; SGVec3d _axis;
@ -167,7 +166,6 @@ public:
private: private:
class UpdateCallback; class UpdateCallback;
class SpinUpdateCallback; class SpinUpdateCallback;
class Transform;
SGSharedPtr<const SGCondition> _condition; SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue; SGSharedPtr<const SGDoubleValue> _animationValue;
SGVec3d _axis; SGVec3d _axis;
@ -188,7 +186,6 @@ public:
virtual osg::Group* createAnimationGroup(osg::Group& parent); virtual osg::Group* createAnimationGroup(osg::Group& parent);
private: private:
class UpdateCallback; class UpdateCallback;
class Transform;
SGSharedPtr<const SGCondition> _condition; SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue[3]; SGSharedPtr<const SGDoubleValue> _animationValue[3];
SGVec3d _initialValue; SGVec3d _initialValue;