+ traverse(node, nv);
+ }
+public:
+ SGSharedPtr<SGCondition const> _condition;
+ SGSharedPtr<SGExpressiond const> _animationValue[3];
+};
+
+SGScaleAnimation::SGScaleAnimation(const SGPropertyNode* configNode,
+ SGPropertyNode* modelRoot) :
+ SGAnimation(configNode, modelRoot)
+{
+ _condition = getCondition();
+
+ // default offset/factor for all directions
+ double offset = configNode->getDoubleValue("offset", 0);
+ double factor = configNode->getDoubleValue("factor", 1);
+
+ SGSharedPtr<SGExpressiond> inPropExpr;
+
+ std::string inputPropertyName;
+ inputPropertyName = configNode->getStringValue("property", "");
+ 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) {
+ 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)) {
+ 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 {
+ 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);
+ _initialValue[0] += configNode->getDoubleValue("x-offset", offset);
+ _initialValue[1] = configNode->getDoubleValue("y-starting-scale", 1);
+ _initialValue[1] *= configNode->getDoubleValue("y-factor", factor);
+ _initialValue[1] += configNode->getDoubleValue("y-offset", offset);
+ _initialValue[2] = configNode->getDoubleValue("z-starting-scale", 1);
+ _initialValue[2] *= configNode->getDoubleValue("z-factor", factor);
+ _initialValue[2] += configNode->getDoubleValue("z-offset", offset);
+ _center[0] = configNode->getDoubleValue("center/x-m", 0);
+ _center[1] = configNode->getDoubleValue("center/y-m", 0);
+ _center[2] = configNode->getDoubleValue("center/z-m", 0);