00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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