Modified Files:

animation.cxx animation.hxx: Make use of the expression stuff.
	Factors out common code with other animations stuff in flightgear.
This commit is contained in:
frohlich
2007-12-26 19:12:04 +00:00
parent 0b1f074bcf
commit c3719f35e3
2 changed files with 249 additions and 377 deletions
+240 -335
View File
@@ -110,36 +110,6 @@ set_translation (osg::Matrix &matrix, double position_m, const SGVec3d &axis)
matrix(3, 2) = xyz[2];
}
/**
* Modify property value by step and scroll settings in texture translations
*/
static double
apply_mods(double property, double step, double scroll, double bias)
{
double modprop;
property += bias;
if(step > 0) {
double scrollval = 0.0;
if(scroll > 0) {
// calculate scroll amount (for odometer like movement)
double remainder = step - fmod(fabs(property), step);
if (remainder < scroll) {
scrollval = (scroll - remainder) / scroll * step;
}
}
// apply stepping of input value
if(property > 0)
modprop = ((floor(property/step) * step) + scrollval);
else
modprop = ((ceil(property/step) * step) + scrollval);
} else {
modprop = property;
}
return modprop;
}
/**
* Read an interpolation table from properties.
*/
@@ -152,202 +122,96 @@ read_interpolation_table(const SGPropertyNode* props)
return new SGInterpTable(table_node);
}
////////////////////////////////////////////////////////////////////////
// Utility value classes
////////////////////////////////////////////////////////////////////////
class SGScaleOffsetValue : public SGDoubleValue {
public:
SGScaleOffsetValue(SGPropertyNode const* propertyNode) :
_propertyNode(propertyNode),
_scale(1),
_offset(0),
_min(-SGLimitsd::max()),
_max(SGLimitsd::max())
{ }
void setScale(double scale)
{ _scale = scale; }
void setOffset(double offset)
{ _offset = offset; }
void setMin(double min)
{ _min = min; }
void setMax(double max)
{ _max = max; }
virtual double getValue() const
{
double value = _propertyNode ? _propertyNode->getDoubleValue() : 0;
return std::min(_max, std::max(_min, _offset + _scale*value));
}
private:
SGSharedPtr<SGPropertyNode const> _propertyNode;
double _scale;
double _offset;
double _min;
double _max;
};
class SGPersScaleOffsetValue : public SGDoubleValue {
public:
SGPersScaleOffsetValue(SGPropertyNode const* propertyNode,
SGPropertyNode const* config,
const char* scalename, const char* offsetname,
double defScale = 1, double defOffset = 0) :
_propertyNode(propertyNode),
_scale(config, scalename, defScale),
_offset(config, offsetname, defOffset),
_min(-SGLimitsd::max()),
_max(SGLimitsd::max())
{ }
void setScale(double scale)
{ _scale = scale; }
void setOffset(double offset)
{ _offset = offset; }
void setMin(double min)
{ _min = min; }
void setMax(double max)
{ _max = max; }
virtual double getValue() const
{
_offset.shuffle();
_scale.shuffle();
double value = _propertyNode ? _propertyNode->getDoubleValue() : 0;
return SGMiscd::clip(_offset + _scale*value, _min, _max);
}
private:
SGSharedPtr<SGPropertyNode const> _propertyNode;
mutable SGPersonalityParameter<double> _scale;
mutable SGPersonalityParameter<double> _offset;
double _min;
double _max;
};
class SGInterpTableValue : public SGDoubleValue {
public:
SGInterpTableValue(SGPropertyNode const* propertyNode,
SGInterpTable const* interpTable) :
_propertyNode(propertyNode),
_interpTable(interpTable)
{ }
virtual double getValue() const
{ return _interpTable->interpolate(_propertyNode ? _propertyNode->getDoubleValue() : 0); }
private:
SGSharedPtr<SGPropertyNode const> _propertyNode;
SGSharedPtr<SGInterpTable const> _interpTable;
};
class SGTexScaleOffsetValue : public SGDoubleValue {
public:
SGTexScaleOffsetValue(const SGPropertyNode* propertyNode) :
_propertyNode(propertyNode),
_scale(1),
_offset(0),
_step(0),
_scroll(0),
_bias(0),
_min(-SGLimitsd::max()),
_max(SGLimitsd::max())
{ }
void setScale(double scale)
{ _scale = scale; }
void setOffset(double offset)
{ _offset = offset; }
void setStep(double step)
{ _step = step; }
void setScroll(double scroll)
{ _scroll = scroll; }
void setBias(double bias)
{ _bias = bias; }
void setMin(double min)
{ _min = min; }
void setMax(double max)
{ _max = max; }
virtual double getValue() const
{
double value = _propertyNode ? _propertyNode->getDoubleValue() : 0;
value = apply_mods(value, _step, _scroll, _bias);
return SGMiscd::clip(_scale*(_offset + value), _min, _max);
}
private:
SGSharedPtr<const SGPropertyNode> _propertyNode;
double _scale;
double _offset;
double _step;
double _scroll;
double _bias;
double _min;
double _max;
};
class SGTexTableValue : public SGDoubleValue {
public:
SGTexTableValue(const SGPropertyNode* propertyNode,
const SGInterpTable* interpTable) :
_propertyNode(propertyNode),
_interpTable(interpTable)
{ }
void setStep(double step)
{ _step = step; }
void setScroll(double scroll)
{ _scroll = scroll; }
void setBias(double bias)
{ _bias = bias; }
virtual double getValue() const
{
double value = _propertyNode ? _propertyNode->getDoubleValue() : 0;
value = apply_mods(value, _step, _scroll, _bias);
return _interpTable->interpolate(value);
}
private:
SGSharedPtr<SGPropertyNode const> _propertyNode;
SGSharedPtr<SGInterpTable const> _interpTable;
double _step;
double _scroll;
double _bias;
};
static std::string
unit_string(const char* value, const char* unit)
{
return std::string(value) + unit;
}
static SGDoubleValue*
class SGPersonalityScaleOffsetExpression : public SGUnaryExpression<double> {
public:
SGPersonalityScaleOffsetExpression(SGExpression<double>* expr,
SGPropertyNode const* config,
const std::string& scalename,
const std::string& offsetname,
double defScale = 1,
double defOffset = 0) :
SGUnaryExpression<double>(expr),
_scale(config, scalename.c_str(), defScale),
_offset(config, offsetname.c_str(), defOffset)
{ }
void setScale(double scale)
{ _scale = scale; }
void setOffset(double offset)
{ _offset = offset; }
virtual void eval(double& value) const
{
_offset.shuffle();
_scale.shuffle();
value = _offset + _scale*getOperand()->getValue();
}
virtual bool isConst() const { return false; }
private:
mutable SGPersonalityParameter<double> _scale;
mutable SGPersonalityParameter<double> _offset;
};
static SGExpressiond*
read_factor_offset(const SGPropertyNode* configNode, SGExpressiond* expr,
const std::string& factor, const std::string& offset)
{
double factorValue = configNode->getDoubleValue(factor, 1);
if (factorValue != 1)
expr = new SGScaleExpression<double>(expr, factorValue);
double offsetValue = configNode->getDoubleValue(offset, 0);
if (offsetValue != 0)
expr = new SGBiasExpression<double>(expr, offsetValue);
return expr;
}
static SGExpressiond*
read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
const char* unit, double defMin, double defMax)
{
std::string inputPropertyName;
inputPropertyName = configNode->getStringValue("property", "");
if (!inputPropertyName.empty()) {
SGPropertyNode* inputProperty;
inputProperty = modelRoot->getNode(inputPropertyName.c_str(), true);
SGInterpTable* interpTable = read_interpolation_table(configNode);
if (interpTable) {
SGInterpTableValue* value;
value = new SGInterpTableValue(inputProperty, interpTable);
return value;
} else {
std::string offset = unit_string("offset", unit);
std::string min = unit_string("min", unit);
std::string max = unit_string("max", unit);
SGExpression<double>* value = 0;
if (configNode->getBoolValue("use-personality", false)) {
SGPersScaleOffsetValue* value;
value = new SGPersScaleOffsetValue(inputProperty, configNode,
"factor", offset.c_str());
value->setMin(configNode->getDoubleValue(min.c_str(), defMin));
value->setMax(configNode->getDoubleValue(max.c_str(), defMax));
return value;
} else {
SGScaleOffsetValue* value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("factor", 1));
value->setOffset(configNode->getDoubleValue(offset.c_str(), 0));
value->setMin(configNode->getDoubleValue(min.c_str(), defMin));
value->setMax(configNode->getDoubleValue(max.c_str(), defMax));
return value;
}
std::string inputPropertyName = configNode->getStringValue("property", "");
if (inputPropertyName.empty()) {
std::string spos = unit_string("starting-position", unit);
double initPos = configNode->getDoubleValue(spos, 0);
value = new SGConstExpression<double>(initPos);
} else {
SGPropertyNode* inputProperty;
inputProperty = modelRoot->getNode(inputPropertyName, true);
value = new SGPropertyExpression<double>(inputProperty);
}
SGInterpTable* interpTable = read_interpolation_table(configNode);
if (interpTable) {
return new SGInterpTableExpression<double>(value, interpTable);
} else {
std::string offset = unit_string("offset", unit);
std::string min = unit_string("min", unit);
std::string max = unit_string("max", unit);
if (configNode->getBoolValue("use-personality", false)) {
value = new SGPersonalityScaleOffsetExpression(value, configNode,
"factor", offset);
} else {
value = read_factor_offset(configNode, value, "factor", offset);
}
double minClip = configNode->getDoubleValue(min, defMin);
double maxClip = configNode->getDoubleValue(max, defMax);
if (minClip > SGMiscd::min(SGLimitsd::min(), -SGLimitsd::max()) ||
maxClip < SGLimitsd::max())
value = new SGClipExpression<double>(value, minClip, maxClip);
return value;
}
return 0;
}
@@ -742,7 +606,7 @@ SGGroupAnimation::createAnimationGroup(osg::Group& parent)
class SGTranslateAnimation::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback(SGCondition const* condition,
SGDoubleValue const* animationValue) :
SGExpressiond const* animationValue) :
_condition(condition),
_animationValue(animationValue)
{ }
@@ -757,7 +621,7 @@ public:
}
public:
SGSharedPtr<SGCondition const> _condition;
SGSharedPtr<SGDoubleValue const> _animationValue;
SGSharedPtr<SGExpressiond const> _animationValue;
};
SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode,
@@ -765,17 +629,20 @@ SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode,
SGAnimation(configNode, modelRoot)
{
_condition = getCondition();
_animationValue = read_value(configNode, modelRoot, "-m",
-SGLimitsd::max(), SGLimitsd::max());
SGSharedPtr<SGExpressiond> value;
value = read_value(configNode, modelRoot, "-m",
-SGLimitsd::max(), SGLimitsd::max());
_animationValue = value->simplify();
if (_animationValue)
_initialValue = _animationValue->getValue();
else
_initialValue = 0;
_axis[0] = configNode->getDoubleValue("axis/x", 0);
_axis[1] = configNode->getDoubleValue("axis/y", 0);
_axis[2] = configNode->getDoubleValue("axis/z", 0);
if (8*SGLimitsd::min() < norm(_axis))
_axis = normalize(_axis);
_initialValue = configNode->getDoubleValue("starting-position-m", 0);
_initialValue *= configNode->getDoubleValue("factor", 1);
_initialValue += configNode->getDoubleValue("offset-m", 0);
}
osg::Group*
@@ -783,7 +650,7 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
{
SGTranslateTransform* transform = new SGTranslateTransform;
transform->setName("translate animation");
if (_animationValue) {
if (_animationValue && !_animationValue->isConst()) {
UpdateCallback* uc = new UpdateCallback(_condition, _animationValue);
transform->setUpdateCallback(uc);
}
@@ -801,7 +668,7 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
class SGRotateAnimation::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback(SGCondition const* condition,
SGDoubleValue const* animationValue) :
SGExpressiond const* animationValue) :
_condition(condition),
_animationValue(animationValue)
{ }
@@ -816,13 +683,13 @@ public:
}
public:
SGSharedPtr<SGCondition const> _condition;
SGSharedPtr<SGDoubleValue const> _animationValue;
SGSharedPtr<SGExpressiond const> _animationValue;
};
class SGRotateAnimation::SpinUpdateCallback : public osg::NodeCallback {
public:
SpinUpdateCallback(SGCondition const* condition,
SGDoubleValue const* animationValue) :
SGExpressiond const* animationValue) :
_condition(condition),
_animationValue(animationValue),
_lastTime(-1)
@@ -848,22 +715,26 @@ public:
}
public:
SGSharedPtr<SGCondition const> _condition;
SGSharedPtr<SGDoubleValue const> _animationValue;
SGSharedPtr<SGExpressiond const> _animationValue;
double _lastTime;
};
SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode, SGPropertyNode* modelRoot) :
SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
SGPropertyNode* modelRoot) :
SGAnimation(configNode, modelRoot)
{
std::string type = configNode->getStringValue("type", "");
_isSpin = (type == "spin");
_condition = getCondition();
_animationValue = read_value(configNode, modelRoot, "-deg",
-SGLimitsd::max(), SGLimitsd::max());
_initialValue = configNode->getDoubleValue("starting-position-deg", 0);
_initialValue *= configNode->getDoubleValue("factor", 1);
_initialValue += configNode->getDoubleValue("offset-deg", 0);
SGSharedPtr<SGExpressiond> value;
value = read_value(configNode, modelRoot, "-deg",
-SGLimitsd::max(), SGLimitsd::max());
_animationValue = value->simplify();
if (_animationValue)
_initialValue = _animationValue->getValue();
else
_initialValue = 0;
_center = SGVec3d::zeros();
if (configNode->hasValue("axis/x1-m")) {
@@ -898,7 +769,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
SpinUpdateCallback* uc;
uc = new SpinUpdateCallback(_condition, _animationValue);
transform->setUpdateCallback(uc);
} else if (_animationValue) {
} else if (_animationValue || !_animationValue->isConst()) {
UpdateCallback* uc = new UpdateCallback(_condition, _animationValue);
transform->setUpdateCallback(uc);
}
@@ -917,7 +788,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
class SGScaleAnimation::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback(const SGCondition* condition,
SGSharedPtr<const SGDoubleValue> animationValue[3]) :
SGSharedPtr<const SGExpressiond> animationValue[3]) :
_condition(condition)
{
_animationValue[0] = animationValue[0];
@@ -938,7 +809,7 @@ public:
}
public:
SGSharedPtr<SGCondition const> _condition;
SGSharedPtr<SGDoubleValue const> _animationValue[3];
SGSharedPtr<SGExpressiond const> _animationValue[3];
};
SGScaleAnimation::SGScaleAnimation(const SGPropertyNode* configNode,
@@ -951,58 +822,69 @@ SGScaleAnimation::SGScaleAnimation(const SGPropertyNode* configNode,
double offset = configNode->getDoubleValue("offset", 0);
double factor = configNode->getDoubleValue("factor", 1);
SGSharedPtr<SGExpressiond> inPropExpr;
std::string inputPropertyName;
inputPropertyName = configNode->getStringValue("property", "");
SGPropertyNode* inputProperty = 0;
if (!inputPropertyName.empty()) {
inputProperty = modelRoot->getNode(inputPropertyName.c_str(), true);
if (inputPropertyName.empty()) {
inPropExpr = new SGConstExpression<double>(0);
} else {
SGPropertyNode* inputProperty;
inputProperty = modelRoot->getNode(inputPropertyName, true);
inPropExpr = new SGPropertyExpression<double>(inputProperty);
}
SGInterpTable* interpTable = read_interpolation_table(configNode);
if (interpTable) {
SGInterpTableValue* value;
value = new SGInterpTableValue(inputProperty, interpTable);
_animationValue[0] = value;
_animationValue[1] = value;
_animationValue[2] = value;
SGSharedPtr<SGExpressiond> value;
value = new SGInterpTableExpression<double>(inPropExpr, interpTable);
_animationValue[0] = value->simplify();
_animationValue[1] = value->simplify();
_animationValue[2] = value->simplify();
} else if (configNode->getBoolValue("use-personality", false)) {
SGPersScaleOffsetValue* value;
value = new SGPersScaleOffsetValue(inputProperty, configNode,
"x-factor", "x-offset",
factor, offset);
value->setMin(configNode->getDoubleValue("x-min", 0));
value->setMax(configNode->getDoubleValue("x-max", SGLimitsd::max()));
_animationValue[0] = value;
value = new SGPersScaleOffsetValue(inputProperty, configNode,
"y-factor", "y-offset",
factor, offset);
value->setMin(configNode->getDoubleValue("y-min", 0));
value->setMax(configNode->getDoubleValue("y-max", SGLimitsd::max()));
_animationValue[1] = value;
value = new SGPersScaleOffsetValue(inputProperty, configNode,
"z-factor", "z-offset",
factor, offset);
value->setMin(configNode->getDoubleValue("z-min", 0));
value->setMax(configNode->getDoubleValue("z-max", SGLimitsd::max()));
_animationValue[2] = value;
SGSharedPtr<SGExpressiond> value;
value = new SGPersonalityScaleOffsetExpression(inPropExpr, configNode,
"x-factor", "x-offset",
factor, offset);
double minClip = configNode->getDoubleValue("x-min", 0);
double maxClip = configNode->getDoubleValue("x-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[0] = value->simplify();
value = new SGPersonalityScaleOffsetExpression(inPropExpr, configNode,
"y-factor", "y-offset",
factor, offset);
minClip = configNode->getDoubleValue("y-min", 0);
maxClip = configNode->getDoubleValue("y-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[1] = value->simplify();
value = new SGPersonalityScaleOffsetExpression(inPropExpr, configNode,
"z-factor", "z-offset",
factor, offset);
minClip = configNode->getDoubleValue("z-min", 0);
maxClip = configNode->getDoubleValue("z-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[2] = value->simplify();
} else {
SGScaleOffsetValue* value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("x-factor", factor));
value->setOffset(configNode->getDoubleValue("x-offset", offset));
value->setMin(configNode->getDoubleValue("x-min", 0));
value->setMax(configNode->getDoubleValue("x-max", SGLimitsd::max()));
_animationValue[0] = value;
value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("y-factor", factor));
value->setOffset(configNode->getDoubleValue("y-offset", offset));
value->setMin(configNode->getDoubleValue("y-min", 0));
value->setMax(configNode->getDoubleValue("y-max", SGLimitsd::max()));
_animationValue[1] = value;
value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("z-factor", factor));
value->setOffset(configNode->getDoubleValue("z-offset", offset));
value->setMin(configNode->getDoubleValue("z-min", 0));
value->setMax(configNode->getDoubleValue("z-max", SGLimitsd::max()));
_animationValue[2] = value;
SGSharedPtr<SGExpressiond> value;
value = read_factor_offset(configNode, inPropExpr, "x-factor", "x-offset");
double minClip = configNode->getDoubleValue("x-min", 0);
double maxClip = configNode->getDoubleValue("x-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[0] = value->simplify();
value = read_factor_offset(configNode, inPropExpr, "y-factor", "y-offset");
minClip = configNode->getDoubleValue("y-min", 0);
maxClip = configNode->getDoubleValue("y-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[1] = value->simplify();
value = read_factor_offset(configNode, inPropExpr, "z-factor", "z-offset");
minClip = configNode->getDoubleValue("z-min", 0);
maxClip = configNode->getDoubleValue("z-max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
_animationValue[2] = value->simplify();
}
_initialValue[0] = configNode->getDoubleValue("x-starting-scale", 1);
_initialValue[0] *= configNode->getDoubleValue("x-factor", factor);
@@ -1335,8 +1217,8 @@ SGBillboardAnimation::createAnimationGroup(osg::Group& parent)
class SGRangeAnimation::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback(const SGCondition* condition,
const SGDoubleValue* minAnimationValue,
const SGDoubleValue* maxAnimationValue,
const SGExpressiond* minAnimationValue,
const SGExpressiond* maxAnimationValue,
double minValue, double maxValue) :
_condition(condition),
_minAnimationValue(minAnimationValue),
@@ -1367,8 +1249,8 @@ public:
private:
SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _minAnimationValue;
SGSharedPtr<const SGDoubleValue> _maxAnimationValue;
SGSharedPtr<const SGExpressiond> _minAnimationValue;
SGSharedPtr<const SGExpressiond> _maxAnimationValue;
double _minStaticValue;
double _maxStaticValue;
};
@@ -1383,18 +1265,23 @@ SGRangeAnimation::SGRangeAnimation(const SGPropertyNode* configNode,
inputPropertyName = configNode->getStringValue("min-property", "");
if (!inputPropertyName.empty()) {
SGPropertyNode* inputProperty;
inputProperty = modelRoot->getNode(inputPropertyName.c_str(), true);
SGScaleOffsetValue* value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("min-factor", 1));
_minAnimationValue = value;
inputProperty = modelRoot->getNode(inputPropertyName, true);
SGSharedPtr<SGExpressiond> value;
value = new SGPropertyExpression<double>(inputProperty);
value = read_factor_offset(configNode, value, "min-factor", "min-offset");
_minAnimationValue = value->simplify();
}
inputPropertyName = configNode->getStringValue("max-property", "");
if (!inputPropertyName.empty()) {
SGPropertyNode* inputProperty;
inputProperty = modelRoot->getNode(inputPropertyName.c_str(), true);
SGScaleOffsetValue* value = new SGScaleOffsetValue(inputProperty);
value->setScale(configNode->getDoubleValue("max-factor", 1));
_maxAnimationValue = value;
SGSharedPtr<SGExpressiond> value;
value = new SGPropertyExpression<double>(inputProperty);
value = read_factor_offset(configNode, value, "max-factor", "max-offset");
_maxAnimationValue = value->simplify();
}
_initialValue[0] = configNode->getDoubleValue("min-m", 0);
@@ -1610,7 +1497,7 @@ private:
class SGBlendAnimation::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback(const SGPropertyNode* configNode, const SGDoubleValue* v) :
UpdateCallback(const SGPropertyNode* configNode, const SGExpressiond* v) :
_prev_value(-1),
_animationValue(v)
{ }
@@ -1626,7 +1513,7 @@ public:
}
public:
double _prev_value;
SGSharedPtr<SGDoubleValue const> _animationValue;
SGSharedPtr<SGExpressiond const> _animationValue;
};
@@ -1889,7 +1776,7 @@ public:
for (i = _transforms.begin(); i != _transforms.end(); ++i)
i->transform->transform(texMat->getMatrix());
}
void appendTransform(Transform* transform, SGDoubleValue* value)
void appendTransform(Transform* transform, SGExpressiond* value)
{
Entry entry = { transform, value };
transform->transform(_matrix);
@@ -1899,7 +1786,7 @@ public:
private:
struct Entry {
SGSharedPtr<Transform> transform;
SGSharedPtr<const SGDoubleValue> value;
SGSharedPtr<const SGExpressiond> value;
};
typedef std::vector<Entry> TransformList;
TransformList _transforms;
@@ -1956,29 +1843,38 @@ SGTexTransformAnimation::appendTexTranslate(const SGPropertyNode* config,
UpdateCallback* updateCallback)
{
std::string propertyName = config->getStringValue("property", "/null");
SGPropertyNode* inputNode;
inputNode = getModelRoot()->getNode(propertyName.c_str(), true);
SGSharedPtr<SGExpressiond> value;
if (getModelRoot()->hasChild(propertyName))
value = new SGPropertyExpression<double>(getModelRoot()->getNode(propertyName));
else
value = new SGConstExpression<double>(0);
SGDoubleValue* animationValue;
SGSharedPtr<SGExpressiond> animationValue;
SGInterpTable* table = read_interpolation_table(config);
if (table) {
SGTexTableValue* value;
value = new SGTexTableValue(inputNode, table);
value->setStep(config->getDoubleValue("step", 0));
value->setScroll(config->getDoubleValue("scroll", 0));
value->setBias(config->getDoubleValue("bias", 0));
animationValue = value;
value = new SGInterpTableExpression<double>(value, table);
double biasValue = config->getDoubleValue("bias", 0);
if (biasValue != 0)
value = new SGBiasExpression<double>(value, biasValue);
value = new SGStepExpression<double>(value,
config->getDoubleValue("step", 0),
config->getDoubleValue("scroll", 0));
animationValue = value->simplify();
} else {
SGTexScaleOffsetValue* value;
value = new SGTexScaleOffsetValue(inputNode);
value->setScale(config->getDoubleValue("factor", 1));
value->setOffset(config->getDoubleValue("offset", 0));
value->setStep(config->getDoubleValue("step", 0));
value->setScroll(config->getDoubleValue("scroll", 0));
value->setBias(config->getDoubleValue("bias", 0));
value->setMin(config->getDoubleValue("min", -SGLimitsd::max()));
value->setMax(config->getDoubleValue("max", SGLimitsd::max()));
animationValue = value;
double biasValue = config->getDoubleValue("bias", 0);
if (biasValue != 0)
value = new SGBiasExpression<double>(value, biasValue);
value = new SGStepExpression<double>(value,
config->getDoubleValue("step", 0),
config->getDoubleValue("scroll", 0));
value = read_factor_offset(config, value, "factor", "offset");
if (config->hasChild("min") || config->hasChild("max")) {
double minClip = config->getDoubleValue("min", -SGLimitsd::max());
double maxClip = config->getDoubleValue("max", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
}
animationValue = value->simplify();
}
SGVec3d axis(config->getDoubleValue("axis/x", 0),
config->getDoubleValue("axis/y", 0),
@@ -1994,29 +1890,38 @@ SGTexTransformAnimation::appendTexRotate(const SGPropertyNode* config,
UpdateCallback* updateCallback)
{
std::string propertyName = config->getStringValue("property", "/null");
SGPropertyNode* inputNode;
inputNode = getModelRoot()->getNode(propertyName.c_str(), true);
SGSharedPtr<SGExpressiond> value;
if (getModelRoot()->hasChild(propertyName))
value = new SGPropertyExpression<double>(getModelRoot()->getNode(propertyName));
else
value = new SGConstExpression<double>(0);
SGDoubleValue* animationValue;
SGSharedPtr<SGExpressiond> animationValue;
SGInterpTable* table = read_interpolation_table(config);
if (table) {
SGTexTableValue* value;
value = new SGTexTableValue(inputNode, table);
value->setStep(config->getDoubleValue("step", 0));
value->setScroll(config->getDoubleValue("scroll", 0));
value->setBias(config->getDoubleValue("bias", 0));
animationValue = value;
value = new SGInterpTableExpression<double>(value, table);
double biasValue = config->getDoubleValue("bias", 0);
if (biasValue != 0)
value = new SGBiasExpression<double>(value, biasValue);
value = new SGStepExpression<double>(value,
config->getDoubleValue("step", 0),
config->getDoubleValue("scroll", 0));
animationValue = value->simplify();
} else {
SGTexScaleOffsetValue* value;
value = new SGTexScaleOffsetValue(inputNode);
value->setScale(config->getDoubleValue("factor", 1));
value->setOffset(config->getDoubleValue("offset-deg", 0));
value->setStep(config->getDoubleValue("step", 0));
value->setScroll(config->getDoubleValue("scroll", 0));
value->setBias(config->getDoubleValue("bias", 0));
value->setMin(config->getDoubleValue("min-deg", -SGLimitsd::max()));
value->setMax(config->getDoubleValue("max-deg", SGLimitsd::max()));
animationValue = value;
double biasValue = config->getDoubleValue("bias", 0);
if (biasValue != 0)
value = new SGBiasExpression<double>(value, biasValue);
value = new SGStepExpression<double>(value,
config->getDoubleValue("step", 0),
config->getDoubleValue("scroll", 0));
value = read_factor_offset(config, value, "factor", "offset-deg");
if (config->hasChild("min-deg") || config->hasChild("max-deg")) {
double minClip = config->getDoubleValue("min-deg", -SGLimitsd::max());
double maxClip = config->getDoubleValue("max-deg", SGLimitsd::max());
value = new SGClipExpression<double>(value, minClip, maxClip);
}
animationValue = value->simplify();
}
SGVec3d axis(config->getDoubleValue("axis/x", 0),
config->getDoubleValue("axis/y", 0),
+9 -42
View File
@@ -11,38 +11,17 @@
# error This library requires C++
#endif
#include <vector>
#include <map>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/ref_ptr>
#include <osg/AlphaFunc>
#include <osg/Group>
#include <osg/Material>
#include <osg/Node>
#include <osg/NodeCallback>
#include <osg/NodeVisitor>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/TexMat>
#include <osgDB/ReaderWriter>
#include <simgear/props/props.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/math/interpolater.hxx>
#include <simgear/scene/model/persparam.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
SG_USING_STD(vector);
SG_USING_STD(map);
// Don't pull in the headers, since we don't need them here.
class SGInterpTable;
class SGCondition;
#include <simgear/props/props.hxx>
#include <simgear/props/condition.hxx>
#include <simgear/structure/SGExpression.hxx>
// Has anyone done anything *really* stupid, like making min and max macros?
#ifdef min
@@ -52,18 +31,6 @@ class SGCondition;
#undef max
#endif
//////////////////////////////////////////////////////////////////////
// Helper classes, FIXME: factor out
//////////////////////////////////////////////////////////////////////
class SGDoubleValue : public SGReferenced {
public:
virtual ~SGDoubleValue() {}
virtual double getValue() const = 0;
};
//////////////////////////////////////////////////////////////////////
// Base class for animation installers
@@ -150,7 +117,7 @@ public:
private:
class UpdateCallback;
SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue;
SGSharedPtr<const SGExpressiond> _animationValue;
SGVec3d _axis;
double _initialValue;
};
@@ -169,7 +136,7 @@ private:
class UpdateCallback;
class SpinUpdateCallback;
SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue;
SGSharedPtr<const SGExpressiond> _animationValue;
SGVec3d _axis;
SGVec3d _center;
double _initialValue;
@@ -189,7 +156,7 @@ public:
private:
class UpdateCallback;
SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _animationValue[3];
SGSharedPtr<const SGExpressiond> _animationValue[3];
SGVec3d _initialValue;
SGVec3d _center;
};
@@ -249,8 +216,8 @@ public:
private:
class UpdateCallback;
SGSharedPtr<const SGCondition> _condition;
SGSharedPtr<const SGDoubleValue> _minAnimationValue;
SGSharedPtr<const SGDoubleValue> _maxAnimationValue;
SGSharedPtr<const SGExpressiond> _minAnimationValue;
SGSharedPtr<const SGExpressiond> _maxAnimationValue;
SGVec2d _initialValue;
};
@@ -294,7 +261,7 @@ public:
private:
class BlendVisitor;
class UpdateCallback;
SGSharedPtr<SGDoubleValue> _animationValue;
SGSharedPtr<SGExpressiond> _animationValue;
};