Jim Wilson:

This update adds the ability to do multiple texture transforms (Steve B. thinks supporting them at the plib level would be inefficient, which is probably true).

Removed units (e.g. "_m") from texture translation property and variable names since the texture translation values are dimensionless.

Added the ability to specify a scroll factor for stepped texture animation that needs to scroll smoothly when approaching the step interval (e.g. odometer movement).
This commit is contained in:
ehofman
2003-07-10 09:49:29 +00:00
parent 8871655a9b
commit 4c78e887e1
3 changed files with 205 additions and 22 deletions

View File

@@ -438,9 +438,9 @@ SGTexRotateAnimation::SGTexRotateAnimation( 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);
_center[0] = props->getFloatValue("center/x", 0);
_center[1] = props->getFloatValue("center/y", 0);
_center[2] = props->getFloatValue("center/z", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
@@ -477,15 +477,16 @@ 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)),
_offset(props->getDoubleValue("offset", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_step(props->getDoubleValue("step",0.0)),
_scroll(props->getDoubleValue("scroll",0.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))
_has_min(props->hasValue("min")),
_min(props->getDoubleValue("min")),
_has_max(props->hasValue("max")),
_max(props->getDoubleValue("max")),
_position(props->getDoubleValue("starting-position", 0))
{
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
@@ -503,24 +504,164 @@ SGTexTranslateAnimation::update()
{
if (_table == 0) {
if(_step > 0) {
double scrollval = 0.0;
if(_scroll > 0) {
// calculate scroll amount (for odometer like movement)
double remainder = _step - fmod(fabs(_prop->getDoubleValue()), _step);
if (remainder < _scroll) {
scrollval = (_scroll - remainder) / _scroll * _step;
}
}
// apply stepping of input value
if(_prop->getDoubleValue() > 0)
_position_m = ((floor(_prop->getDoubleValue()/_step) * _step) + _offset_m) * _factor;
_position = ((floor(_prop->getDoubleValue()/_step) * _step) + _offset + scrollval) * _factor;
else
_position_m = ((ceil(_prop->getDoubleValue()/_step) * _step) + _offset_m) * _factor;
_position = ((ceil(_prop->getDoubleValue()/_step) * _step) + _offset + scrollval) * _factor;
} else {
_position_m = (_prop->getDoubleValue() + _offset_m) * _factor;
_position = (_prop->getDoubleValue() + _offset) * _factor;
}
if (_has_min && _position_m < _min_m)
_position_m = _min_m;
if (_has_max && _position_m > _max_m)
_position_m = _max_m;
if (_has_min && _position < _min)
_position = _min;
if (_has_max && _position > _max)
_position = _max;
} else {
_position_m = _table->interpolate(_prop->getDoubleValue());
_position = _table->interpolate(_prop->getDoubleValue());
}
set_translation(_matrix, _position_m, _axis);
set_translation(_matrix, _position, _axis);
((ssgTexTrans *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexMultipleAnimation
////////////////////////////////////////////////////////////////////////
SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true))
{
int i;
// Load animations
vector<SGPropertyNode_ptr> transform_nodes = props->getChildren("transform");
_transform = new TexTransform [transform_nodes.size()];
_num_transforms = 0;
for (i = 0; i < transform_nodes.size(); i++) {
SGPropertyNode_ptr transform_props = transform_nodes[i];
if (!strcmp("textranslate",transform_props->getStringValue("subtype", 0))) {
// transform is a translation
_transform[i].subtype = 0;
_transform[i].prop = (SGPropertyNode *)prop_root->getNode(transform_props->getStringValue("property", "/null"), true);
_transform[i].offset = transform_props->getDoubleValue("offset", 0.0);
_transform[i].factor = transform_props->getDoubleValue("factor", 1.0);
_transform[i].step = transform_props->getDoubleValue("step",0.0);
_transform[i].scroll = transform_props->getDoubleValue("scroll",0.0);
_transform[i].table = read_interpolation_table(transform_props);
_transform[i].has_min = transform_props->hasValue("min");
_transform[i].min = transform_props->getDoubleValue("min");
_transform[i].has_max = transform_props->hasValue("max");
_transform[i].max = transform_props->getDoubleValue("max");
_transform[i].position = transform_props->getDoubleValue("starting-position", 0);
_transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0);
_transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0);
_transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_transform[i].axis);
_num_transforms++;
} else if (!strcmp("texrotate",transform_nodes[i]->getStringValue("subtype", 0))) {
// transform is a rotation
_transform[i].subtype = 1;
_transform[i].prop = (SGPropertyNode *)prop_root->getNode(transform_props->getStringValue("property", "/null"), true);
_transform[i].offset = transform_props->getDoubleValue("offset-deg", 0.0);
_transform[i].factor = transform_props->getDoubleValue("factor", 1.0);
_transform[i].table = read_interpolation_table(transform_props);
_transform[i].has_min = transform_props->hasValue("min-deg");
_transform[i].min = transform_props->getDoubleValue("min-deg");
_transform[i].has_max = transform_props->hasValue("max-deg");
_transform[i].max = transform_props->getDoubleValue("max-deg");
_transform[i].position = transform_props->getDoubleValue("starting-position-deg", 0);
_transform[i].center[0] = transform_props->getFloatValue("center/x", 0);
_transform[i].center[1] = transform_props->getFloatValue("center/y", 0);
_transform[i].center[2] = transform_props->getFloatValue("center/z", 0);
_transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0);
_transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0);
_transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_transform[i].axis);
_num_transforms++;
}
}
}
SGTexMultipleAnimation::~SGTexMultipleAnimation ()
{
// delete _table;
delete _transform;
}
void
SGTexMultipleAnimation::update()
{
int i;
sgMat4 tmatrix;
sgMakeIdentMat4(tmatrix);
for (i = 0; i < _num_transforms; i++) {
if(_transform[i].subtype == 0) {
// subtype 0 is translation
if (_transform[i].table == 0) {
if(_transform[i].step > 0) {
double scrollval = 0.0;
if(_transform[i].scroll > 0) {
// calculate scroll amount (for odometer like movement)
double remainder = _transform[i].step - fmod(fabs(_transform[i].prop->getDoubleValue()), _transform[i].step);
if (remainder < _transform[i].scroll) {
scrollval = (_transform[i].scroll - remainder) / _transform[i].scroll * _transform[i].step;
}
}
// apply stepping of input value
if(_transform[i].prop->getDoubleValue() > 0)
_transform[i].position = ((floor(_transform[i].prop->getDoubleValue()/_transform[i].step) * _transform[i].step) + _transform[i].offset) * _transform[i].factor;
else
_transform[i].position = ((ceil(_transform[i].prop->getDoubleValue()/_transform[i].step) * _transform[i].step) + _transform[i].offset) * _transform[i].factor;
} else {
_transform[i].position = (_transform[i].prop->getDoubleValue() + _transform[i].offset) * _transform[i].factor;
}
if (_transform[i].has_min && _transform[i].position < _transform[i].min)
_transform[i].position = _transform[i].min;
if (_transform[i].has_max && _transform[i].position > _transform[i].max)
_transform[i].position = _transform[i].max;
} else {
_transform[i].position = _transform[i].table->interpolate(_transform[i].prop->getDoubleValue());
}
set_translation(_transform[i].matrix, _transform[i].position, _transform[i].axis);
sgPreMultMat4(tmatrix, _transform[i].matrix);
} else if (_transform[i].subtype == 1) {
// subtype 1 is rotation
if (_transform[i].table == 0) {
_transform[i].position = _transform[i].prop->getDoubleValue() * _transform[i].factor + _transform[i].offset;
if (_transform[i].has_min && _transform[i].position < _transform[i].min)
_transform[i].position = _transform[i].min;
if (_transform[i].has_max && _transform[i].position > _transform[i].max)
_transform[i].position = _transform[i].max;
} else {
_transform[i].position = _transform[i].table->interpolate(_transform[i].prop->getDoubleValue());
}
set_rotation(_transform[i].matrix, _transform[i].position, _transform[i].center, _transform[i].axis);
sgPreMultMat4(tmatrix, _transform[i].matrix);
}
}
((ssgTexTrans *)_branch)->setTransform(tmatrix);
}
// end of animation.cxx

View File

@@ -260,17 +260,57 @@ public:
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _offset_m;
double _offset;
double _factor;
double _step;
double _scroll;
SGInterpTable * _table;
bool _has_min;
double _min_m;
double _min;
bool _has_max;
double _max_m;
double _position_m;
double _max;
double _position;
sgMat4 _matrix;
sgVec3 _axis;
};
/**
* Classes for handling multiple types of Texture translations on one object
*/
class SGTexMultipleAnimation : public SGAnimation
{
public:
SGTexMultipleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGTexMultipleAnimation ();
virtual void update();
private:
class TexTransform
{
public:
SGPropertyNode_ptr prop;
int subtype; // 0=translation, 1=rotation
double offset;
double factor;
double step;
double scroll;
SGInterpTable * table;
bool has_min;
double min;
bool has_max;
double max;
double position;
sgMat4 matrix;
sgVec3 center;
sgVec3 axis;
};
SGPropertyNode_ptr _prop;
TexTransform* _transform;
int _num_transforms;
};
#endif // _SG_ANIMATION_HXX

View File

@@ -125,6 +125,8 @@ sgMakeAnimation( ssgBranch * model,
animation = new SGTexRotateAnimation(prop_root, node);
} else if (!strcmp("textranslate", type)) {
animation = new SGTexTranslateAnimation(prop_root, node);
} else if (!strcmp("texmultiple", type)) {
animation = new SGTexMultipleAnimation(prop_root, node);
} else {
animation = new SGNullAnimation(node);
SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);