expression.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined (INCLUDED_EXPRESSION_H)
00023 #define INCLUDED_EXPRESSION_H
00024 
00025 #include <math/matrix.h>
00026 
00027 template<typename Value>
00028 class Literal
00029 {
00030         Value m_value;
00031     public:
00032         typedef Value value_type;
00033 
00034         Literal (const Value& value) :
00035             m_value(value)
00036         {
00037         }
00038         const value_type& eval () const
00039         {
00040             return m_value;
00041         }
00042 };
00043 
00044 template<typename Value>
00045 inline Literal<Value> float_literal (const Value& value)
00046 {
00047     return Literal<Value> (value);
00048 }
00049 
00050 template<typename Expression>
00051 inline float float_for_expression (const Expression& expression)
00052 {
00053     return expression.eval();
00054 }
00055 
00056 template<typename First, typename Second>
00057 class ScalarDivided
00058 {
00059         First first;
00060         Second second;
00061     public:
00062         typedef typename First::value_type value_type;
00063 
00064         ScalarDivided (const First& first_, const Second& second_) :
00065             first(first_), second(second_)
00066         {
00067         }
00068         value_type eval () const
00069         {
00070             return static_cast<value_type> (first.eval() / second.eval());
00071         }
00072 };
00073 
00074 template<typename First, typename Second>
00075 inline ScalarDivided<First, Second> float_divided (const First& first, const Second& second)
00076 {
00077     return ScalarDivided<First, Second> (first, second);
00078 }
00079 
00080 template<typename First>
00081 inline ScalarDivided<Literal<typename First::value_type> , First> float_reciprocal (const First& first)
00082 {
00083     typedef typename First::value_type first_value_type;
00084     return ScalarDivided<Literal<first_value_type> , First> (float_literal(first_value_type(1.0)), first);
00085 }
00086 
00087 template<typename First>
00088 class SquareRoot
00089 {
00090         First first;
00091     public:
00092         typedef typename First::value_type value_type;
00093 
00094         SquareRoot (const First& first_) :
00095             first(first_)
00096         {
00097         }
00098         value_type eval () const
00099         {
00100             return static_cast<value_type> (sqrt(first.eval()));
00101         }
00102 };
00103 
00104 template<typename First>
00105 inline SquareRoot<First> float_square_root (const First& first)
00106 {
00107     return SquareRoot<First> (first);
00108 }
00109 
00110 template<typename Element>
00111 class BasicVector3Literal
00112 {
00113         const BasicVector3<Element> m_value;
00114     public:
00115         typedef Element value_type;
00116         typedef IntegralConstant<3> dimension;
00117 
00118         BasicVector3Literal (const BasicVector3<Element>& value) :
00119             m_value(value)
00120         {
00121         }
00122         const value_type& eval (unsigned int i) const
00123         {
00124             return m_value[i];
00125         }
00126 };
00127 
00128 template<typename Element>
00129 inline BasicVector3Literal<Element> vector3_literal (const BasicVector3<Element>& value)
00130 {
00131     return BasicVector3Literal<Element> (value);
00132 }
00133 
00134 typedef BasicVector3Literal<float> Vector3Literal;
00135 
00136 template<typename Element>
00137 class BasicVector3Identity
00138 {
00139         const BasicVector3<Element>& m_value;
00140     public:
00141         typedef Element value_type;
00142         typedef IntegralConstant<3> dimension;
00143 
00144         BasicVector3Identity (const BasicVector3<Element>& value) :
00145             m_value(value)
00146         {
00147         }
00148         const value_type& eval (unsigned int i) const
00149         {
00150             return m_value[i];
00151         }
00152 };
00153 
00154 template<typename Element>
00155 inline BasicVector3Identity<Element> vector3_identity (const BasicVector3<Element>& value)
00156 {
00157     return BasicVector3Identity<Element> (value);
00158 }
00159 
00160 typedef BasicVector3Identity<float> Vector3Identity;
00161 
00162 template<typename Expression>
00163 inline BasicVector3<typename Expression::value_type> vector3_for_expression (const Expression& expression)
00164 {
00165     return Vector3(expression.eval(0), expression.eval(1), expression.eval(2));
00166 }
00167 
00168 template<typename Operation, typename First, typename Second>
00169 class VectorScalar
00170 {
00171         First first;
00172         Literal<typename Second::value_type> second;
00173     public:
00174         typedef typename First::value_type value_type;
00175         typedef typename First::dimension dimension;
00176 
00177         VectorScalar (const First& first_, const Second& second_) :
00178             first(first_), second(second_.eval())
00179         {
00180         }
00181         value_type eval (unsigned int i) const
00182         {
00183             return Operation::apply(first.eval(i), second.eval());
00184         }
00185 };
00186 
00187 template<typename Operation, typename First, typename Second>
00188 class VectorVector
00189 {
00190         First first;
00191         Second second;
00192     public:
00193         typedef typename First::value_type value_type;
00194         typedef typename First::dimension dimension;
00195 
00196         VectorVector (const First& first_, const Second& second_) :
00197             first(first_), second(second_)
00198         {
00199         }
00200         value_type eval (unsigned int i) const
00201         {
00202             return Operation::apply(first.eval(i), second.eval(i));
00203         }
00204 };
00205 
00206 template<typename First, typename Second>
00207 class Added
00208 {
00209     public:
00210         typedef First value_type;
00211 
00212         static value_type apply (const First& first, const Second& second)
00213         {
00214             return static_cast<value_type> (first + second);
00215         }
00216 };
00217 
00218 template<typename First, typename Second>
00219 inline VectorVector<Added<typename First::value_type, typename Second::value_type> , First, Second> vector_added (
00220         const First& first, const Second& second)
00221 {
00222     typedef typename First::value_type first_value_type;
00223     typedef typename Second::value_type second_value_type;
00224     return VectorVector<Added<first_value_type, second_value_type> , First, Second> (first, second);
00225 }
00226 
00227 template<typename First, typename Second>
00228 class Multiplied
00229 {
00230     public:
00231         typedef First value_type;
00232 
00233         static value_type apply (const First& first, const Second& second)
00234         {
00235             return static_cast<value_type> (first * second);
00236         }
00237 };
00238 
00239 template<typename First, typename Second>
00240 inline VectorVector<Multiplied<typename First::value_type, typename Second::value_type> , First, Second> vector_multiplied (
00241         const First& first, const Second& second)
00242 {
00243     typedef typename First::value_type first_value_type;
00244     typedef typename Second::value_type second_value_type;
00245     return VectorVector<Multiplied<first_value_type, second_value_type> , First, Second> (first, second);
00246 }
00247 
00248 template<typename First, typename Second>
00249 inline VectorScalar<Multiplied<typename First::value_type, typename Second::value_type> , First, Second> vector_scaled (
00250         const First& first, const Second& second)
00251 {
00252     typedef typename First::value_type first_value_type;
00253     typedef typename Second::value_type second_value_type;
00254     return VectorScalar<Multiplied<first_value_type, second_value_type> , First, Second> (first, second);
00255 }
00256 
00257 template<typename First>
00258 class Negated
00259 {
00260     public:
00261         typedef First value_type;
00262 
00263         static value_type apply (const First& first)
00264         {
00265             return -first;
00266         }
00267 };
00268 
00269 template<typename First, typename Operation>
00270 class VectorUnary
00271 {
00272         First first;
00273     public:
00274         typedef typename First::value_type value_type;
00275         typedef typename First::dimension dimension;
00276 
00277         VectorUnary (const First& first_) :
00278             first(first_)
00279         {
00280         }
00281         value_type eval (unsigned int i) const
00282         {
00283             return Operation::apply(first.eval(i));
00284         }
00285 };
00286 
00287 template<typename First>
00288 inline VectorUnary<First, Negated<typename First::value_type> > vector_negated (const First& first)
00289 {
00290     typedef typename First::value_type first_value_type;
00291     return VectorUnary<First, Negated<first_value_type> > (first);
00292 }
00293 
00294 template<typename First, typename Second>
00295 class VectorCross
00296 {
00297         First first;
00298         Second second;
00299     public:
00300         typedef typename First::value_type value_type;
00301         typedef typename First::dimension dimension;
00302 
00303         VectorCross (const First& first_, const Second& second_) :
00304             first(first_), second(second_)
00305         {
00306         }
00307         value_type eval (unsigned int i) const
00308         {
00309             return first.eval((i + 1) % 3) * second.eval((i + 2) % 3) - first.eval((i + 2) % 3) * second.eval((i + 1)
00310                     % 3);
00311         }
00312 };
00313 
00314 template<typename First, typename Second>
00315 inline VectorCross<First, Second> vector_cross (const First& first, const Second& second)
00316 {
00317     return VectorCross<First, Second> (first, second);
00318 }
00319 
00320 template<typename First, typename Second>
00321 class VectorDot
00322 {
00323         First first;
00324         Second second;
00325     public:
00326         typedef typename First::value_type value_type;
00327         typedef typename First::dimension dimension;
00328 
00329         VectorDot (const First& first_, const Second& second_) :
00330             first(first_), second(second_)
00331         {
00332         }
00333 
00334         template<typename Index>
00335         struct eval_dot
00336         {
00337                 static value_type apply (const First& first, const Second& second)
00338                 {
00339                     return static_cast<value_type> (first.eval(Index::VALUE) * second.eval(Index::VALUE) + eval_dot<
00340                             IntegralConstant<Index::VALUE - 1> >::apply(first, second));
00341                 }
00342         };
00343 
00344         template<>
00345         struct eval_dot<IntegralConstant<0> >
00346         {
00347                 static value_type apply (const First& first, const Second& second)
00348                 {
00349                     return first.eval(0) * second.eval(0);
00350                 }
00351         };
00352 
00353         value_type eval () const
00354         {
00355             return eval_dot<IntegralConstant<dimension::VALUE - 1> >::apply(first, second);
00356         }
00357 };
00358 
00359 template<typename First, typename Second>
00360 inline VectorDot<First, Second> vector_dot (const First& first, const Second& second)
00361 {
00362     return VectorDot<First, Second> (first, second);
00363 }
00364 
00365 template<typename First>
00366 class VectorLengthSquared
00367 {
00368         First first;
00369     public:
00370         typedef typename First::value_type value_type;
00371         typedef typename First::dimension dimension;
00372 
00373         VectorLengthSquared (const First& first_) :
00374             first(first_)
00375         {
00376         }
00377 
00378         static value_type squared (const value_type& value)
00379         {
00380             return value * value;
00381         }
00382 
00383         template<typename Index>
00384         struct eval_squared
00385         {
00386                 static value_type apply (const First& first)
00387                 {
00388                     return static_cast<value_type> (squared(first.eval(Index::VALUE)) + eval_squared<IntegralConstant<
00389                             Index::VALUE - 1> >::apply(first));
00390                 }
00391         };
00392 
00393         template<>
00394         struct eval_squared<IntegralConstant<0> >
00395         {
00396                 static value_type apply (const First& first)
00397                 {
00398                     return squared(first.eval(0));
00399                 }
00400         };
00401 
00402         value_type eval () const
00403         {
00404             return eval_squared<IntegralConstant<dimension::VALUE - 1> >::apply(first);
00405         }
00406 };
00407 
00408 template<typename First>
00409 inline VectorLengthSquared<First> vector_length_squared (const First& first)
00410 {
00411     return VectorLengthSquared<First> (first);
00412 }
00413 
00414 template<typename First>
00415 inline SquareRoot<VectorLengthSquared<First> > vector_length (const First& first)
00416 {
00417     return float_square_root(vector_length_squared(first));
00418 }
00419 
00420 template<typename First>
00421 inline VectorScalar <Multiplied<typename First::value_type, typename First::value_type>,First,
00422 // multiple evaulations of subexpression
00423 ScalarDivided <Literal<typename First::value_type>,SquareRoot <VectorLengthSquared<First>>>> vector_normalised(const First& first) {
00424     typedef typename First::value_type first_value_type;
00425     return vector_scaled(first, float_reciprocal(vector_length(first)));
00426 }
00427 
00428 class Matrix4Literal
00429 {
00430         const Matrix4 m_value;
00431     public:
00432         typedef float value_type;
00433         typedef IntegralConstant<4> dimension0;
00434         typedef IntegralConstant<4> dimension1;
00435 
00436         Matrix4Literal (const Matrix4& value) :
00437             m_value(value)
00438         {
00439         }
00440         const value_type& eval (unsigned int r, unsigned int c) const
00441         {
00442             return m_value[r * 4 + c];
00443         }
00444 };
00445 
00446 inline Matrix4Literal matrix4_literal (const Matrix4& value)
00447 {
00448     return Matrix4Literal(value);
00449 }
00450 
00451 class Matrix4Identity
00452 {
00453         const Matrix4& m_value;
00454     public:
00455         typedef float value_type;
00456         typedef IntegralConstant<4> dimension0;
00457         typedef IntegralConstant<4> dimension1;
00458 
00459         Matrix4Identity (const Matrix4& value) :
00460             m_value(value)
00461         {
00462         }
00463         const value_type& eval (unsigned int r, unsigned int c) const
00464         {
00465             return m_value[r * 4 + c];
00466         }
00467 };
00468 
00469 inline Matrix4Identity matrix4_identity (const Matrix4& value)
00470 {
00471     return Matrix4Identity(value);
00472 }
00473 
00474 template<typename Expression>
00475 inline Matrix4 matrix4_for_expression (const Expression& expression)
00476 {
00477     return Matrix4(expression.eval(0, 0), expression.eval(0, 1), expression.eval(0, 2), expression.eval(0, 3),
00478             expression.eval(1, 0), expression.eval(1, 1), expression.eval(1, 2), expression.eval(1, 3),
00479             expression.eval(2, 0), expression.eval(2, 1), expression.eval(2, 2), expression.eval(2, 3),
00480             expression.eval(3, 0), expression.eval(3, 1), expression.eval(3, 2), expression.eval(3, 3));
00481 }
00482 
00483 template<typename Expression>
00484 inline Matrix4 matrix4_affine_for_expression (const Expression& expression)
00485 {
00486     return Matrix4(expression.eval(0, 0), expression.eval(0, 1), expression.eval(0, 2), 0, expression.eval(1, 0),
00487             expression.eval(1, 1), expression.eval(1, 2), 0, expression.eval(2, 0), expression.eval(2, 1),
00488             expression.eval(2, 2), 0, expression.eval(3, 0), expression.eval(3, 1), expression.eval(3, 2), 1);
00489 }
00490 
00491 template<typename First, typename Second>
00492 class PointMultiplied
00493 {
00494         const First& first;
00495         const Second& second;
00496     public:
00497         typedef typename First::value_type value_type;
00498         typedef typename First::dimension dimension;
00499 
00500         PointMultiplied (const First& first_, const Second& second_) :
00501             first(first_), second(second_)
00502         {
00503         }
00504         value_type eval (unsigned int i) const
00505         {
00506             return static_cast<value_type> (second.eval(0, i) * first.eval(0) + second.eval(1, i) * first.eval(1)
00507                     + second.eval(2, i) * first.eval(2) + second.eval(3, i));
00508         }
00509 };
00510 
00511 template<typename First, typename Second>
00512 inline PointMultiplied<First, Second> point_multiplied (const First& point, const Second& matrix)
00513 {
00514     return PointMultiplied<First, Second> (point, matrix);
00515 }
00516 
00517 template<typename First, typename Second>
00518 class Matrix4Multiplied
00519 {
00520         const First& first;
00521         const Second& second;
00522     public:
00523         typedef typename First::value_type value_type;
00524         typedef typename First::dimension0 dimension0;
00525         typedef typename First::dimension1 dimension1;
00526 
00527         Matrix4Multiplied (const First& first_, const Second& second_) :
00528             first(first_), second(second_)
00529         {
00530         }
00531 
00532         value_type eval (unsigned int r, unsigned int c) const
00533         {
00534             return static_cast<value_type> (second.eval(r, 0) * first.eval(0, c) + second.eval(r, 1) * first.eval(1, c)
00535                     + second.eval(r, 2) * first.eval(2, c) + second.eval(r, 3) * first.eval(3, c));
00536         }
00537 };
00538 
00539 template<typename First, typename Second>
00540 inline Matrix4Multiplied<First, Second> matrix4_multiplied (const First& first, const Second& second)
00541 {
00542     return Matrix4Multiplied<First, Second> (first, second);
00543 }
00544 
00545 template<typename First>
00546 class MatrixTransposed
00547 {
00548         const First& first;
00549     public:
00550         typedef typename First::value_type value_type;
00551         typedef typename First::dimension0 dimension0;
00552         typedef typename First::dimension1 dimension1;
00553 
00554         MatrixTransposed (const First& first_) :
00555             first(first_)
00556         {
00557         }
00558 
00559         value_type eval (unsigned int r, unsigned int c) const
00560         {
00561             return first.eval(c, r);
00562         }
00563 };
00564 
00565 template<typename First>
00566 inline MatrixTransposed<First> matrix_transposed (const First& first)
00567 {
00568     return MatrixTransposed<First> (first);
00569 }
00570 
00571 #endif

Generated by  doxygen 1.6.2