Jim Wilson:

1. Added support for defining arbitrary rotation axes using (x1,y1,z1), (x2,y2,z2).  The center is calculated automatically (midpoint on line) or you may specify an alternate "center" using the current scheme.  This makes it about  100 times easier to animate flaps, ailerons, etc.

2. Added support for plib's ssgTexTrans.  This will allow more sophisticated 3D instrument features by allowing the texture mapping itself to be animated. Included function for "texrotate" and "textranslate".  They configure the same as the geometry, except the arbitrary axis definition is not necessary (textures are flat).
This commit is contained in:
ehofman
2003-06-08 13:19:34 +00:00
parent 17df7141ae
commit 17e2478522
3 changed files with 205 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
// animation.hxx - classes to manage model animation.
// animation.cxx - classes to manage model animation.
// Written by David Megginson, started 2002.
//
// This file is in the Public Domain, and comes with no warranty.
@@ -221,12 +221,34 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root,
_position_deg(props->getDoubleValue("starting-position-deg", 0)),
_last_time_sec( sim_time_sec )
{
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
_center[0] = 0;
_center[1] = 0;
_center[2] = 0;
if (props->hasValue("axis/x1-m")) {
double x1,y1,z1,x2,y2,z2;
x1 = props->getFloatValue("axis/x1-m");
y1 = props->getFloatValue("axis/y1-m");
z1 = props->getFloatValue("axis/z1-m");
x2 = props->getFloatValue("axis/x2-m");
y2 = props->getFloatValue("axis/y2-m");
z2 = props->getFloatValue("axis/z2-m");
_center[0] = (x1+x2)/2;
_center[1]= (y1+y2)/2;
_center[2] = (z1+z2)/2;
float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
_axis[0] = (x2-x1)/vector_length;
_axis[1] = (y2-y1)/vector_length;
_axis[2] = (z2-z1)/vector_length;
} else {
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
}
if (props->hasValue("center/x-m")) {
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
}
sgNormalizeVec3(_axis);
}
@@ -299,13 +321,35 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root,
_max_deg(props->getDoubleValue("max-deg")),
_position_deg(props->getDoubleValue("starting-position-deg", 0))
{
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
_center[0] = 0;
_center[1] = 0;
_center[2] = 0;
if (props->hasValue("axis/x1-m")) {
double x1,y1,z1,x2,y2,z2;
x1 = props->getFloatValue("axis/x1-m");
y1 = props->getFloatValue("axis/y1-m");
z1 = props->getFloatValue("axis/z1-m");
x2 = props->getFloatValue("axis/x2-m");
y2 = props->getFloatValue("axis/y2-m");
z2 = props->getFloatValue("axis/z2-m");
_center[0] = (x1+x2)/2;
_center[1]= (y1+y2)/2;
_center[2] = (z1+z2)/2;
float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
_axis[0] = (x2-x1)/vector_length;
_axis[1] = (y2-y1)/vector_length;
_axis[2] = (z2-z1)/vector_length;
} else {
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
}
if (props->hasValue("center/x-m")) {
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
}
sgNormalizeVec3(_axis);
}
SGRotateAnimation::~SGRotateAnimation ()
@@ -376,4 +420,97 @@ SGTranslateAnimation::update()
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexRotateAnimation
////////////////////////////////////////////////////////////////////////
SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_offset_deg(props->getDoubleValue("offset-deg", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_table(read_interpolation_table(props)),
_has_min(props->hasValue("min-deg")),
_min_deg(props->getDoubleValue("min-deg")),
_has_max(props->hasValue("max-deg")),
_max_deg(props->getDoubleValue("max-deg")),
_position_deg(props->getDoubleValue("starting-position-deg", 0))
{
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
}
SGTexRotateAnimation::~SGTexRotateAnimation ()
{
delete _table;
}
void
SGTexRotateAnimation::update()
{
if (_table == 0) {
_position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
if (_has_min && _position_deg < _min_deg)
_position_deg = _min_deg;
if (_has_max && _position_deg > _max_deg)
_position_deg = _max_deg;
} else {
_position_deg = _table->interpolate(_prop->getDoubleValue());
}
set_rotation(_matrix, _position_deg, _center, _axis);
((ssgTexTrans *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexTranslateAnimation
////////////////////////////////////////////////////////////////////////
SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_offset_m(props->getDoubleValue("offset-m", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_table(read_interpolation_table(props)),
_has_min(props->hasValue("min-m")),
_min_m(props->getDoubleValue("min-m")),
_has_max(props->hasValue("max-m")),
_max_m(props->getDoubleValue("max-m")),
_position_m(props->getDoubleValue("starting-position-m", 0))
{
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
}
SGTexTranslateAnimation::~SGTexTranslateAnimation ()
{
delete _table;
}
void
SGTexTranslateAnimation::update()
{
if (_table == 0) {
_position_m = (_prop->getDoubleValue() + _offset_m) * _factor;
if (_has_min && _position_m < _min_m)
_position_m = _min_m;
if (_has_max && _position_m > _max_m)
_position_m = _max_m;
} else {
_position_m = _table->interpolate(_prop->getDoubleValue());
}
set_translation(_matrix, _position_m, _axis);
((ssgTexTrans *)_branch)->setTransform(_matrix);
}
// end of animation.cxx

View File

@@ -220,5 +220,55 @@ private:
sgVec3 _axis;
};
/**
* Animation to rotate texture mappings around a center point.
*
* This animation rotates to a specific position.
*/
class SGTexRotateAnimation : public SGAnimation
{
public:
SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
virtual ~SGTexRotateAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _offset_deg;
double _factor;
SGInterpTable * _table;
bool _has_min;
double _min_deg;
bool _has_max;
double _max_deg;
double _position_deg;
sgMat4 _matrix;
sgVec3 _center;
sgVec3 _axis;
};
/**
* Animation to slide texture mappings along an axis.
*/
class SGTexTranslateAnimation : public SGAnimation
{
public:
SGTexTranslateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGTexTranslateAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _offset_m;
double _factor;
SGInterpTable * _table;
bool _has_min;
double _min_m;
bool _has_max;
double _max_m;
double _position_m;
sgMat4 _matrix;
sgVec3 _axis;
};
#endif // _SG_ANIMATION_HXX

View File

@@ -121,6 +121,10 @@ sgMakeAnimation( ssgBranch * model,
animation = new SGRotateAnimation(prop_root, node);
} else if (!strcmp("translate", type)) {
animation = new SGTranslateAnimation(prop_root, node);
} else if (!strcmp("texrotate", type)) {
animation = new SGTexRotateAnimation(prop_root, node);
} else if (!strcmp("textranslate", type)) {
animation = new SGTexTranslateAnimation(prop_root, node);
} else {
animation = new SGNullAnimation(node);
SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);