3 * Copyright (C) 2006-2007 Mathias Froehlich
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
25 #include <simgear/props/condition.hxx>
26 #include <simgear/props/props.hxx>
27 #include <simgear/math/interpolater.hxx>
28 #include <simgear/math/SGMath.hxx>
29 #include <simgear/scene/model/persparam.hxx>
31 /// Expression tree implementation.
34 class SGExpression : public SGReferenced {
36 virtual ~SGExpression() {}
37 virtual void eval(T&) const = 0;
40 { T value; eval(value); return value; }
42 virtual bool isConst() const { return false; }
43 virtual SGExpression* simplify();
46 /// Constant value expression
48 class SGConstExpression : public SGExpression<T> {
50 SGConstExpression(const T& value = T()) : _value(value)
52 void setValue(const T& value)
54 const T& getValue() const
56 virtual void eval(T& value) const
58 virtual bool isConst() const { return true; }
65 SGExpression<T>::simplify()
68 return new SGConstExpression<T>(getValue());
73 class SGUnaryExpression : public SGExpression<T> {
75 const SGExpression<T>* getOperand() const
76 { return _expression; }
77 SGExpression<T>* getOperand()
78 { return _expression; }
79 void setOperand(SGExpression<T>* expression)
82 expression = new SGConstExpression<T>(T());
83 _expression = expression;
85 virtual bool isConst() const
86 { return getOperand()->isConst(); }
87 virtual SGExpression<T>* simplify()
89 _expression = _expression->simplify();
90 return SGExpression<T>::simplify();
94 SGUnaryExpression(SGExpression<T>* expression = 0)
95 { setOperand(expression); }
98 SGSharedPtr<SGExpression<T> > _expression;
102 class SGBinaryExpression : public SGExpression<T> {
104 const SGExpression<T>* getOperand(unsigned i) const
105 { return _expressions[i]; }
106 SGExpression<T>* getOperand(unsigned i)
107 { return _expressions[i]; }
108 void setOperand(unsigned i, SGExpression<T>* expression)
111 expression = new SGConstExpression<T>(T());
114 _expressions[i] = expression;
117 virtual bool isConst() const
118 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
119 virtual SGExpression<T>* simplify()
121 _expressions[0] = _expressions[0]->simplify();
122 _expressions[1] = _expressions[1]->simplify();
123 return SGExpression<T>::simplify();
127 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
128 { setOperand(0, expr0); setOperand(1, expr1); }
131 SGSharedPtr<SGExpression<T> > _expressions[2];
135 class SGNaryExpression : public SGExpression<T> {
137 unsigned getNumOperands() const
138 { return _expressions.size(); }
139 const SGExpression<T>* getOperand(unsigned i) const
140 { return _expressions[i]; }
141 SGExpression<T>* getOperand(unsigned i)
142 { return _expressions[i]; }
143 unsigned addOperand(SGExpression<T>* expression)
147 _expressions.push_back(expression);
148 return _expressions.size() - 1;
151 virtual bool isConst() const
153 for (unsigned i = 0; i < _expressions.size(); ++i)
154 if (!_expressions[i]->isConst())
158 virtual SGExpression<T>* simplify()
160 for (unsigned i = 0; i < _expressions.size(); ++i)
161 _expressions[i] = _expressions[i]->simplify();
162 return SGExpression<T>::simplify();
168 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
169 { addOperand(expr0); addOperand(expr1); }
172 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
179 class SGPropertyExpression : public SGExpression<T> {
181 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
183 void setPropertyNode(const SGPropertyNode* prop)
185 virtual void eval(T& value) const
188 void doEval(float& value) const
189 { if (_prop) value = _prop->getFloatValue(); }
190 void doEval(double& value) const
191 { if (_prop) value = _prop->getDoubleValue(); }
192 void doEval(int& value) const
193 { if (_prop) value = _prop->getIntValue(); }
194 void doEval(long& value) const
195 { if (_prop) value = _prop->getLongValue(); }
196 void doEval(bool& value) const
197 { if (_prop) value = _prop->getBoolValue(); }
198 SGSharedPtr<const SGPropertyNode> _prop;
202 class SGAbsExpression : public SGUnaryExpression<T> {
204 SGAbsExpression(SGExpression<T>* expr = 0)
205 : SGUnaryExpression<T>(expr)
208 virtual void eval(T& value) const
209 { value = getOperand()->getValue(); if (value <= 0) value = -value; }
211 using SGUnaryExpression<T>::getOperand;
215 class SGACosExpression : public SGUnaryExpression<T> {
217 SGACosExpression(SGExpression<T>* expr = 0)
218 : SGUnaryExpression<T>(expr)
221 virtual void eval(T& value) const
222 { value = acos(SGMisc<T>::clip(getOperand()->getValue(), -1, 1)); }
224 using SGUnaryExpression<T>::getOperand;
228 class SGASinExpression : public SGUnaryExpression<T> {
230 SGASinExpression(SGExpression<T>* expr = 0)
231 : SGUnaryExpression<T>(expr)
234 virtual void eval(T& value) const
235 { value = asin(SGMisc<T>::clip(getOperand()->getValue(), -1, 1)); }
237 using SGUnaryExpression<T>::getOperand;
241 class SGATanExpression : public SGUnaryExpression<T> {
243 SGATanExpression(SGExpression<T>* expr = 0)
244 : SGUnaryExpression<T>(expr)
247 virtual void eval(T& value) const
248 { value = atan(getOperand()->getValue()); }
250 using SGUnaryExpression<T>::getOperand;
254 class SGCeilExpression : public SGUnaryExpression<T> {
256 SGCeilExpression(SGExpression<T>* expr = 0)
257 : SGUnaryExpression<T>(expr)
260 virtual void eval(T& value) const
261 { value = ceil(getOperand()->getValue()); }
263 using SGUnaryExpression<T>::getOperand;
267 class SGCosExpression : public SGUnaryExpression<T> {
269 SGCosExpression(SGExpression<T>* expr = 0)
270 : SGUnaryExpression<T>(expr)
273 virtual void eval(T& value) const
274 { value = cos(getOperand()->getValue()); }
276 using SGUnaryExpression<T>::getOperand;
280 class SGCoshExpression : public SGUnaryExpression<T> {
282 SGCoshExpression(SGExpression<T>* expr = 0)
283 : SGUnaryExpression<T>(expr)
286 virtual void eval(T& value) const
287 { value = cosh(getOperand()->getValue()); }
289 using SGUnaryExpression<T>::getOperand;
293 class SGExpExpression : public SGUnaryExpression<T> {
295 SGExpExpression(SGExpression<T>* expr = 0)
296 : SGUnaryExpression<T>(expr)
299 virtual void eval(T& value) const
300 { value = exp(getOperand()->getValue()); }
302 using SGUnaryExpression<T>::getOperand;
306 class SGFloorExpression : public SGUnaryExpression<T> {
308 SGFloorExpression(SGExpression<T>* expr = 0)
309 : SGUnaryExpression<T>(expr)
312 virtual void eval(T& value) const
313 { value = floor(getOperand()->getValue()); }
315 using SGUnaryExpression<T>::getOperand;
319 class SGLogExpression : public SGUnaryExpression<T> {
321 SGLogExpression(SGExpression<T>* expr = 0)
322 : SGUnaryExpression<T>(expr)
325 virtual void eval(T& value) const
326 { value = log(getOperand()->getValue()); }
328 using SGUnaryExpression<T>::getOperand;
332 class SGLog10Expression : public SGUnaryExpression<T> {
334 SGLog10Expression(SGExpression<T>* expr = 0)
335 : SGUnaryExpression<T>(expr)
338 virtual void eval(T& value) const
339 { value = log10(getOperand()->getValue()); }
341 using SGUnaryExpression<T>::getOperand;
345 class SGSinExpression : public SGUnaryExpression<T> {
347 SGSinExpression(SGExpression<T>* expr = 0)
348 : SGUnaryExpression<T>(expr)
351 virtual void eval(T& value) const
352 { value = sin(getOperand()->getValue()); }
354 using SGUnaryExpression<T>::getOperand;
358 class SGSinhExpression : public SGUnaryExpression<T> {
360 SGSinhExpression(SGExpression<T>* expr = 0)
361 : SGUnaryExpression<T>(expr)
364 virtual void eval(T& value) const
365 { value = sinh(getOperand()->getValue()); }
367 using SGUnaryExpression<T>::getOperand;
371 class SGSqrExpression : public SGUnaryExpression<T> {
373 SGSqrExpression(SGExpression<T>* expr = 0)
374 : SGUnaryExpression<T>(expr)
377 virtual void eval(T& value) const
378 { value = getOperand()->getValue(); value = value*value; }
380 using SGUnaryExpression<T>::getOperand;
384 class SGSqrtExpression : public SGUnaryExpression<T> {
386 SGSqrtExpression(SGExpression<T>* expr = 0)
387 : SGUnaryExpression<T>(expr)
390 virtual void eval(T& value) const
391 { value = sqrt(getOperand()->getValue()); }
393 using SGUnaryExpression<T>::getOperand;
397 class SGTanExpression : public SGUnaryExpression<T> {
399 SGTanExpression(SGExpression<T>* expr = 0)
400 : SGUnaryExpression<T>(expr)
403 virtual void eval(T& value) const
404 { value = tan(getOperand()->getValue()); }
406 using SGUnaryExpression<T>::getOperand;
410 class SGTanhExpression : public SGUnaryExpression<T> {
412 SGTanhExpression(SGExpression<T>* expr = 0)
413 : SGUnaryExpression<T>(expr)
416 virtual void eval(T& value) const
417 { value = tanh(getOperand()->getValue()); }
419 using SGUnaryExpression<T>::getOperand;
423 class SGScaleExpression : public SGUnaryExpression<T> {
425 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
426 : SGUnaryExpression<T>(expr), _scale(scale)
428 void setScale(const T& scale)
430 const T& getScale() const
433 virtual void eval(T& value) const
434 { value = _scale * getOperand()->getValue(); }
436 virtual SGExpression<T>* simplify()
439 return getOperand()->simplify();
440 return SGUnaryExpression<T>::simplify();
443 using SGUnaryExpression<T>::getOperand;
449 class SGBiasExpression : public SGUnaryExpression<T> {
451 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
452 : SGUnaryExpression<T>(expr), _bias(bias)
455 void setBias(const T& bias)
457 const T& getBias() const
460 virtual void eval(T& value) const
461 { value = _bias + getOperand()->getValue(); }
463 virtual SGExpression<T>* simplify()
466 return getOperand()->simplify();
467 return SGUnaryExpression<T>::simplify();
470 using SGUnaryExpression<T>::getOperand;
476 class SGInterpTableExpression : public SGUnaryExpression<T> {
478 SGInterpTableExpression(SGExpression<T>* expr,
479 const SGInterpTable* interpTable) :
480 SGUnaryExpression<T>(expr),
481 _interpTable(interpTable)
484 virtual void eval(T& value) const
487 value = _interpTable->interpolate(getOperand()->getValue());
490 using SGUnaryExpression<T>::getOperand;
492 SGSharedPtr<SGInterpTable const> _interpTable;
496 class SGClipExpression : public SGUnaryExpression<T> {
498 SGClipExpression(SGExpression<T>* expr)
499 : SGUnaryExpression<T>(expr),
500 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
501 _clipMax(SGLimits<T>::max())
503 SGClipExpression(SGExpression<T>* expr,
504 const T& clipMin, const T& clipMax)
505 : SGUnaryExpression<T>(expr),
510 void setClipMin(const T& clipMin)
511 { _clipMin = clipMin; }
512 const T& getClipMin() const
515 void setClipMax(const T& clipMax)
516 { _clipMax = clipMax; }
517 const T& getClipMax() const
520 virtual void eval(T& value) const
522 value = SGMisc<T>::clip(getOperand()->getValue(), _clipMin, _clipMax);
525 virtual SGExpression<T>* simplify()
527 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
528 _clipMax >= SGLimits<T>::max())
529 return getOperand()->simplify();
530 return SGUnaryExpression<T>::simplify();
533 using SGUnaryExpression<T>::getOperand;
540 class SGStepExpression : public SGUnaryExpression<T> {
542 SGStepExpression(SGExpression<T>* expr = 0,
543 const T& step = T(1), const T& scroll = T(0))
544 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
547 void setStep(const T& step)
549 const T& getStep() const
552 void setScroll(const T& scroll)
553 { _scroll = scroll; }
554 const T& getScroll() const
557 virtual void eval(T& value) const
558 { value = apply_mods(getOperand()->getValue()); }
560 using SGUnaryExpression<T>::getOperand;
563 T apply_mods(T property) const
569 // calculate scroll amount (for odometer like movement)
570 T remainder = _step - fmod(fabs(property), _step);
571 if (remainder < _scroll) {
572 scrollval = (_scroll - remainder) / _scroll * _step;
575 // apply stepping of input value
577 modprop = ((floor(property/_step) * _step) + scrollval);
579 modprop = ((ceil(property/_step) * _step) + scrollval);
591 class SGEnableExpression : public SGUnaryExpression<T> {
593 SGEnableExpression(SGExpression<T>* expr = 0,
594 SGCondition* enable = 0,
595 const T& disabledValue = T(0))
596 : SGUnaryExpression<T>(expr),
598 _disabledValue(disabledValue)
601 const T& getDisabledValue() const
602 { return _disabledValue; }
603 void setDisabledValue(const T& disabledValue)
604 { _disabledValue = disabledValue; }
606 virtual void eval(T& value) const
609 value = getOperand()->getValue();
611 value = _disabledValue;
614 virtual SGExpression<T>* simplify()
617 return getOperand()->simplify();
618 return SGUnaryExpression<T>::simplify();
621 using SGUnaryExpression<T>::getOperand;
623 SGSharedPtr<SGCondition> _enable;
628 class SGAtan2Expression : public SGBinaryExpression<T> {
630 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
631 : SGBinaryExpression<T>(expr0, expr1)
633 virtual void eval(T& value) const
634 { value = atan2(getOperand(0)->getValue(), getOperand(1)->getValue()); }
635 using SGBinaryExpression<T>::getOperand;
639 class SGDivExpression : public SGBinaryExpression<T> {
641 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
642 : SGBinaryExpression<T>(expr0, expr1)
644 virtual void eval(T& value) const
645 { value = getOperand(0)->getValue() / getOperand(1)->getValue(); }
646 using SGBinaryExpression<T>::getOperand;
650 class SGModExpression : public SGBinaryExpression<T> {
652 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
653 : SGBinaryExpression<T>(expr0, expr1)
655 virtual void eval(T& value) const
656 { value = mod(getOperand(0)->getValue(), getOperand(1)->getValue()); }
657 using SGBinaryExpression<T>::getOperand;
659 int mod(const int& v0, const int& v1) const
661 float mod(const float& v0, const float& v1) const
662 { return fmod(v0, v1); }
663 double mod(const double& v0, const double& v1) const
664 { return fmod(v0, v1); }
668 class SGPowExpression : public SGBinaryExpression<T> {
670 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
671 : SGBinaryExpression<T>(expr0, expr1)
673 virtual void eval(T& value) const
674 { value = pow(getOperand(0)->getValue(), getOperand(1)->getValue()); }
675 using SGBinaryExpression<T>::getOperand;
679 class SGSumExpression : public SGNaryExpression<T> {
683 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
684 : SGNaryExpression<T>(expr0, expr1)
686 virtual void eval(T& value) const
689 unsigned sz = SGNaryExpression<T>::getNumOperands();
690 for (unsigned i = 0; i < sz; ++i)
691 value += getOperand(i)->getValue();
693 using SGNaryExpression<T>::getValue;
694 using SGNaryExpression<T>::getOperand;
698 class SGProductExpression : public SGNaryExpression<T> {
700 SGProductExpression()
702 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
703 : SGNaryExpression<T>(expr0, expr1)
705 virtual void eval(T& value) const
708 unsigned sz = SGNaryExpression<T>::getNumOperands();
709 for (unsigned i = 0; i < sz; ++i)
710 value *= getOperand(i)->getValue();
712 using SGNaryExpression<T>::getValue;
713 using SGNaryExpression<T>::getOperand;
717 class SGMinExpression : public SGNaryExpression<T> {
721 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
722 : SGNaryExpression<T>(expr0, expr1)
724 virtual void eval(T& value) const
726 unsigned sz = SGNaryExpression<T>::getNumOperands();
730 value = getOperand(0)->getValue();
731 for (unsigned i = 1; i < sz; ++i)
732 value = SGMisc<T>::min(value, getOperand(i)->getValue());
734 using SGNaryExpression<T>::getOperand;
738 class SGMaxExpression : public SGNaryExpression<T> {
742 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
743 : SGNaryExpression<T>(expr0, expr1)
745 virtual void eval(T& value) const
747 unsigned sz = SGNaryExpression<T>::getNumOperands();
751 value = getOperand(0)->getValue();
752 for (unsigned i = 1; i < sz; ++i)
753 value = SGMisc<T>::max(value, getOperand(i)->getValue());
755 using SGNaryExpression<T>::getOperand;
758 typedef SGExpression<int> SGExpressioni;
759 typedef SGExpression<float> SGExpressionf;
760 typedef SGExpression<double> SGExpressiond;
761 typedef SGExpression<bool> SGExpressionb;
764 * Global function to make an expression out of properties.
768 <clipMax>79</clipMax>
772 <property>sim/model/whatever-rad</property>
774 <property>sim/model/someother-deg</property>
780 will evaluate to an expression:
782 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
786 SGReadIntExpression(SGPropertyNode *inputRoot,
787 const SGPropertyNode *configNode);
790 SGReadFloatExpression(SGPropertyNode *inputRoot,
791 const SGPropertyNode *configNode);
793 SGExpression<double>*
794 SGReadDoubleExpression(SGPropertyNode *inputRoot,
795 const SGPropertyNode *configNode);
798 SGReadBoolExpression(SGPropertyNode *inputRoot,
799 const SGPropertyNode *configNode);
801 #endif // _SG_EXPRESSION_HXX