2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #if !defined (INCLUDED_EXPRESSION_H)
23 #define INCLUDED_EXPRESSION_H
25 #include <math/matrix.h>
27 template<typename Value>
32 typedef Value value_type;
34 Literal(const Value& value)
38 const value_type& eval() const
44 template<typename Value>
45 inline Literal<Value> float_literal(const Value& value)
47 return Literal<Value>(value);
50 template<typename Expression>
51 inline float float_for_expression(const Expression& expression)
53 return expression.eval();
57 template<typename First, typename Second>
63 typedef typename First::value_type value_type;
65 ScalarDivided(const First& first_, const Second& second_) : first(first_), second(second_)
68 value_type eval() const
70 return static_cast<value_type>(first.eval() / second.eval());
74 template<typename First, typename Second>
75 inline ScalarDivided<First, Second> float_divided(const First& first, const Second& second)
77 return ScalarDivided<First, Second>(first, second);
80 template<typename First>
81 inline ScalarDivided<Literal<typename First::value_type>, First> float_reciprocal(const First& first)
83 typedef typename First::value_type first_value_type;
84 return ScalarDivided<Literal<first_value_type>, First>(float_literal(first_value_type(1.0)), first);
87 template<typename First>
92 typedef typename First::value_type value_type;
94 SquareRoot(const First& first_) : first(first_)
97 value_type eval() const
99 return static_cast<value_type>(sqrt(first.eval()));
103 template<typename First>
104 inline SquareRoot<First> float_square_root(const First& first)
106 return SquareRoot<First>(first);
110 template<typename Element>
111 class BasicVector3Literal
113 const BasicVector3<Element> m_value;
115 typedef Element value_type;
116 typedef IntegralConstant<3> dimension;
118 BasicVector3Literal(const BasicVector3<Element>& value)
122 const value_type& eval(unsigned int i) const
128 template<typename Element>
129 inline BasicVector3Literal<Element> vector3_literal(const BasicVector3<Element>& value)
131 return BasicVector3Literal<Element>(value);
134 typedef BasicVector3Literal<float> Vector3Literal;
136 template<typename Element>
137 class BasicVector3Identity
139 const BasicVector3<Element>& m_value;
141 typedef Element value_type;
142 typedef IntegralConstant<3> dimension;
144 BasicVector3Identity(const BasicVector3<Element>& value)
148 const value_type& eval(unsigned int i) const
154 template<typename Element>
155 inline BasicVector3Identity<Element> vector3_identity(const BasicVector3<Element>& value)
157 return BasicVector3Identity<Element>(value);
160 typedef BasicVector3Identity<float> Vector3Identity;
162 template<typename Expression>
163 inline BasicVector3<typename Expression::value_type> vector3_for_expression(const Expression& expression)
165 return Vector3(expression.eval(0), expression.eval(1), expression.eval(2));
169 template<typename Operation, typename First, typename Second>
173 Literal<typename Second::value_type> second;
175 typedef typename First::value_type value_type;
176 typedef typename First::dimension dimension;
178 VectorScalar(const First& first_, const Second& second_)
179 : first(first_), second(second_.eval())
182 value_type eval(unsigned int i) const
184 return Operation::apply( first.eval(i), second.eval() );
190 template<typename Operation, typename First, typename Second>
196 typedef typename First::value_type value_type;
197 typedef typename First::dimension dimension;
199 VectorVector(const First& first_, const Second& second_)
200 : first(first_), second(second_)
203 value_type eval(unsigned int i) const
205 return Operation::apply(first.eval(i), second.eval(i));
209 template<typename First, typename Second>
213 typedef First value_type;
215 static value_type apply(const First& first, const Second& second)
217 return static_cast<value_type>(first + second);
221 template<typename First, typename Second>
222 inline VectorVector<Added<typename First::value_type, typename Second::value_type>, First, Second>
223 vector_added(const First& first, const Second& second)
225 typedef typename First::value_type first_value_type;
226 typedef typename Second::value_type second_value_type;
227 return VectorVector<Added<first_value_type, second_value_type>, First, Second>(first, second);
230 template<typename First, typename Second>
234 typedef First value_type;
236 static value_type apply(const First& first, const Second& second)
238 return static_cast<value_type>(first * second);
242 template<typename First, typename Second>
243 inline VectorVector<Multiplied<typename First::value_type, typename Second::value_type>, First, Second>
244 vector_multiplied(const First& first, const Second& second)
246 typedef typename First::value_type first_value_type;
247 typedef typename Second::value_type second_value_type;
248 return VectorVector<Multiplied<first_value_type, second_value_type>, First, Second>(first, second);
251 template<typename First, typename Second>
252 inline VectorScalar<Multiplied<typename First::value_type, typename Second::value_type>, First, Second>
253 vector_scaled(const First& first, const Second& second)
255 typedef typename First::value_type first_value_type;
256 typedef typename Second::value_type second_value_type;
257 return VectorScalar<Multiplied<first_value_type, second_value_type>, First, Second>(first, second);
260 template<typename First>
264 typedef First value_type;
266 static value_type apply(const First& first)
272 template<typename First, typename Operation>
277 typedef typename First::value_type value_type;
278 typedef typename First::dimension dimension;
280 VectorUnary(const First& first_) : first(first_)
283 value_type eval(unsigned int i) const
285 return Operation::apply(first.eval(i));
289 template<typename First>
290 inline VectorUnary<First, Negated<typename First::value_type> >
291 vector_negated(const First& first)
293 typedef typename First::value_type first_value_type;
294 return VectorUnary<First, Negated<first_value_type> >(first);
297 template<typename First, typename Second>
303 typedef typename First::value_type value_type;
304 typedef typename First::dimension dimension;
306 VectorCross(const First& first_, const Second& second_)
307 : first(first_), second(second_)
310 value_type eval(unsigned int i) const
312 return first.eval((i+1)%3) * second.eval((i+2)%3) - first.eval((i+2)%3) * second.eval((i+1)%3);
316 template<typename First, typename Second>
317 inline VectorCross<First, Second>
318 vector_cross(const First& first, const Second& second)
320 return VectorCross<First, Second>(first, second);
324 template<typename First, typename Second>
330 typedef typename First::value_type value_type;
331 typedef typename First::dimension dimension;
333 VectorDot(const First& first_, const Second& second_)
334 : first(first_), second(second_)
338 template<typename Index>
341 static value_type apply(const First& first, const Second& second)
343 return static_cast<value_type>(
344 first.eval(Index::VALUE) * second.eval(Index::VALUE)
345 + eval_dot< IntegralConstant<Index::VALUE-1> >::apply(first, second)
351 struct eval_dot< IntegralConstant<0> >
353 static value_type apply(const First& first, const Second& second)
355 return first.eval(0) * second.eval(0);
359 value_type eval() const
361 return eval_dot< IntegralConstant<dimension::VALUE - 1> >::apply(first, second);
366 template<typename First, typename Second>
367 inline VectorDot<First, Second> vector_dot(const First& first, const Second& second)
369 return VectorDot<First, Second>(first, second);
372 template<typename First>
373 class VectorLengthSquared
377 typedef typename First::value_type value_type;
378 typedef typename First::dimension dimension;
380 VectorLengthSquared(const First& first_)
385 static value_type squared(const value_type& value)
387 return value * value;
390 template<typename Index>
393 static value_type apply(const First& first)
395 return static_cast<value_type>(
396 squared(first.eval(Index::VALUE))
397 + eval_squared< IntegralConstant<Index::VALUE - 1> >::apply(first)
403 struct eval_squared< IntegralConstant<0> >
405 static value_type apply(const First& first)
407 return squared(first.eval(0));
411 value_type eval() const
413 return eval_squared< IntegralConstant<dimension::VALUE - 1> >::apply(first);
417 template<typename First>
418 inline VectorLengthSquared<First> vector_length_squared(const First& first)
420 return VectorLengthSquared<First>(first);
423 template<typename First>
424 inline SquareRoot< VectorLengthSquared<First> > vector_length(const First& first)
426 return float_square_root(vector_length_squared(first));
430 template<typename First>
432 Multiplied<typename First::value_type, typename First::value_type>,
434 // multiple evaulations of subexpression
436 Literal<typename First::value_type>,
438 VectorLengthSquared<First>
441 > vector_normalised(const First& first)
443 typedef typename First::value_type first_value_type;
444 return vector_scaled(first, float_reciprocal(vector_length(first)));
447 template<typename First>
449 Multiplied<typename First::value_type, typename First::value_type>,
451 // single evaluation of subexpression
452 Literal<typename First::value_type>
454 vector_normalised(const First& first)
456 typedef typename First::value_type first_value_type;
457 return vector_scaled(first, float_literal(static_cast<first_value_type>(first_value_type(1.0) / vector_length(first).eval())));
464 const Matrix4 m_value;
466 typedef float value_type;
467 typedef IntegralConstant<4> dimension0;
468 typedef IntegralConstant<4> dimension1;
470 Matrix4Literal(const Matrix4& value)
474 const value_type& eval(unsigned int r, unsigned int c) const
476 return m_value[r*4+c];
480 inline Matrix4Literal matrix4_literal(const Matrix4& value)
482 return Matrix4Literal(value);
485 class Matrix4Identity
487 const Matrix4& m_value;
489 typedef float value_type;
490 typedef IntegralConstant<4> dimension0;
491 typedef IntegralConstant<4> dimension1;
493 Matrix4Identity(const Matrix4& value)
497 const value_type& eval(unsigned int r, unsigned int c) const
499 return m_value[r*4+c];
503 inline Matrix4Identity matrix4_identity(const Matrix4& value)
505 return Matrix4Identity(value);
508 template<typename Expression>
509 inline Matrix4 matrix4_for_expression(const Expression& expression)
512 expression.eval(0, 0), expression.eval(0, 1), expression.eval(0, 2), expression.eval(0, 3),
513 expression.eval(1, 0), expression.eval(1, 1), expression.eval(1, 2), expression.eval(1, 3),
514 expression.eval(2, 0), expression.eval(2, 1), expression.eval(2, 2), expression.eval(2, 3),
515 expression.eval(3, 0), expression.eval(3, 1), expression.eval(3, 2), expression.eval(3, 3)
519 template<typename Expression>
520 inline Matrix4 matrix4_affine_for_expression(const Expression& expression)
523 expression.eval(0, 0), expression.eval(0, 1), expression.eval(0, 2), 0,
524 expression.eval(1, 0), expression.eval(1, 1), expression.eval(1, 2), 0,
525 expression.eval(2, 0), expression.eval(2, 1), expression.eval(2, 2), 0,
526 expression.eval(3, 0), expression.eval(3, 1), expression.eval(3, 2), 1
531 template<typename First, typename Second>
532 class PointMultiplied
535 const Second& second;
537 typedef typename First::value_type value_type;
538 typedef typename First::dimension dimension;
540 PointMultiplied(const First& first_, const Second& second_)
541 : first(first_), second(second_)
544 value_type eval(unsigned int i) const
546 return static_cast<value_type>(second.eval(0, i) * first.eval(0)
547 + second.eval(1, i) * first.eval(1)
548 + second.eval(2, i) * first.eval(2)
549 + second.eval(3, i));
553 template<typename First, typename Second>
554 inline PointMultiplied<First, Second> point_multiplied(const First& point, const Second& matrix)
556 return PointMultiplied<First, Second>(point, matrix);
559 template<typename First, typename Second>
560 class Matrix4Multiplied
563 const Second& second;
565 typedef typename First::value_type value_type;
566 typedef typename First::dimension0 dimension0;
567 typedef typename First::dimension1 dimension1;
569 Matrix4Multiplied(const First& first_, const Second& second_)
570 : first(first_), second(second_)
574 value_type eval(unsigned int r, unsigned int c) const
576 return static_cast<value_type>(
577 second.eval(r, 0) * first.eval(0, c)
578 + second.eval(r, 1) * first.eval(1, c)
579 + second.eval(r, 2) * first.eval(2, c)
580 + second.eval(r, 3) * first.eval(3, c)
585 template<typename First, typename Second>
586 inline Matrix4Multiplied<First, Second> matrix4_multiplied(const First& first, const Second& second)
588 return Matrix4Multiplied<First, Second>(first, second);
591 template<typename First>
592 class MatrixTransposed
596 typedef typename First::value_type value_type;
597 typedef typename First::dimension0 dimension0;
598 typedef typename First::dimension1 dimension1;
600 MatrixTransposed(const First& first_)
605 value_type eval(unsigned int r, unsigned int c) const
607 return first.eval(c, r);
611 template<typename First>
612 inline MatrixTransposed<First> matrix_transposed(const First& first)
614 return MatrixTransposed<First>(first);