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 \
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)

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 "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<SGTranslateAnimation::Transform*>(node);
SGTranslateTransform* transform;
transform = static_cast<SGTranslateTransform*>(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<SGRotateAnimation::Transform*>(node);
transform->setAngle(_animationValue->getValue());
SGRotateTransform* transform;
transform = static_cast<SGRotateTransform*>(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<SGRotateAnimation::Transform*>(node);
SGRotateTransform* transform;
transform = static_cast<SGRotateTransform*>(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<SGScaleAnimation::Transform*>(node);
SGScaleTransform* transform;
transform = static_cast<SGScaleTransform*>(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);

View File

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