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:
parent
f32e037c58
commit
487701a143
@ -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)
|
||||||
|
122
simgear/scene/model/SGRotateTransform.cxx
Normal file
122
simgear/scene/model/SGRotateTransform.cxx
Normal 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 ¢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;
|
||||||
|
}
|
||||||
|
|
69
simgear/scene/model/SGRotateTransform.hxx
Normal file
69
simgear/scene/model/SGRotateTransform.hxx
Normal 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
|
109
simgear/scene/model/SGScaleTransform.cxx
Normal file
109
simgear/scene/model/SGScaleTransform.cxx
Normal 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;
|
||||||
|
}
|
73
simgear/scene/model/SGScaleTransform.hxx
Normal file
73
simgear/scene/model/SGScaleTransform.hxx
Normal 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
|
83
simgear/scene/model/SGTranslateTransform.cxx
Normal file
83
simgear/scene/model/SGTranslateTransform.cxx
Normal 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;
|
||||||
|
}
|
53
simgear/scene/model/SGTranslateTransform.hxx
Normal file
53
simgear/scene/model/SGTranslateTransform.hxx
Normal 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
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user