00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(_XRB_VECTOR_HPP_)
00012 #define _XRB_VECTOR_HPP_
00013
00014 #include "xrb.hpp"
00015
00016 #include <stdio.h>
00017 #include <string.h>
00018
00019 #include "xrb_enums.hpp"
00020
00026 namespace Xrb
00027 {
00028
00029
00030 namespace Math
00031 {
00032 Float Sqrt (Float x);
00033 }
00034
00035
00036
00037
00038
00055 template <typename T, Uint32 dimension>
00056 class Vector
00057 {
00058 public:
00059
00066 static Vector<T, dimension> const ms_zero;
00067
00069 T m[dimension];
00070
00071
00072
00073
00074
00078 inline Vector ()
00079 {
00080 }
00085 inline explicit Vector (T const fill_with)
00086 {
00087 for (Uint32 i = 0; i < dimension; ++i)
00088 m[i] = fill_with;
00089 }
00097 inline Vector (T const component0, T const component1)
00098 {
00099 ASSERT1(dimension == 2);
00100 m[0] = component0;
00101 m[1] = component1;
00102 }
00111 inline Vector (T const component0, T const component1, T const component2)
00112 {
00113 ASSERT1(dimension == 3);
00114 m[0] = component0;
00115 m[1] = component1;
00116 m[2] = component2;
00117 }
00123 inline Vector (T const *const components)
00124 {
00125 ASSERT1(components != NULL);
00126 #if defined(XRB_VECTOR_USES_MEMCPY)
00127 memcpy(m, components, sizeof(T) * dimension);
00128 #else
00129 for (Uint32 i = 0; i < dimension; ++i)
00130 m[i] = components[i];
00131 #endif
00132 }
00136 inline Vector (Vector<T, dimension> const &source)
00137 {
00138 #if defined(XRB_VECTOR_USES_MEMCPY)
00139 memcpy(m, source.m, sizeof(T) * dimension);
00140 #else
00141 for (Uint32 i = 0; i < dimension; ++i)
00142 m[i] = source.m[i];
00143 #endif
00144 }
00148 inline ~Vector ()
00149 {
00150 }
00151
00152
00153
00154
00155
00159 inline void operator = (Vector<T, dimension> const &operand)
00160 {
00161 #if defined(XRB_VECTOR_USES_MEMCPY)
00162 memcpy(m, operand.m, sizeof(T) * dimension);
00163 #else
00164 for (Uint32 i = 0; i < dimension; ++i)
00165 m[i] = operand.m[i];
00166 #endif
00167 }
00173 inline bool operator == (Vector<T, dimension> const &operand) const
00174 {
00175 #if defined(XRB_VECTOR_USES_MEMCMP)
00176 return memcmp(m, operand.m, sizeof(T) * dimension) == 0;
00177 #else
00178 for (Uint32 i = 0; i < dimension; ++i)
00179 if (m[i] != operand.m[i])
00180 return false;
00181 return true;
00182 #endif
00183 }
00189 inline bool operator != (Vector<T, dimension> const &operand) const
00190 {
00191 #if defined(XRB_VECTOR_USES_MEMCMP)
00192 return memcmp(m, operand.m, sizeof(T) * dimension) != 0;
00193 #else
00194 for (Uint32 i = 0; i < dimension; ++i)
00195 if (m[i] != operand.m[i])
00196 return true;
00197 return false;
00198 #endif
00199 }
00206 inline T const &operator [] (Uint32 const index) const
00207 {
00208 ASSERT3(index < dimension);
00209 return m[index];
00210 }
00217 inline T &operator [] (Uint32 const index)
00218 {
00219 ASSERT3(index < dimension);
00220 return m[index];
00221 }
00227 inline void operator += (Vector<T, dimension> const &operand)
00228 {
00229 for (Uint32 i = 0; i < dimension; ++i)
00230 m[i] += operand.m[i];
00231 }
00237 inline void operator -= (Vector<T, dimension> const &operand)
00238 {
00239 for (Uint32 i = 0; i < dimension; ++i)
00240 m[i] -= operand.m[i];
00241 }
00249 inline void operator *= (Vector<T, dimension> const &operand)
00250 {
00251 for (Uint32 i = 0; i < dimension; ++i)
00252 m[i] *= operand.m[i];
00253 }
00259 template <typename U>
00260 inline void operator *= (U const operand)
00261 {
00262 for (Uint32 i = 0; i < dimension; ++i)
00263 m[i] *= static_cast<T>(operand);
00264 }
00273 inline void operator /= (Vector<T, dimension> const &operand)
00274 {
00275 for (Uint32 i = 0; i < dimension; ++i)
00276 m[i] /= operand.m[i];
00277 }
00284 template <typename U>
00285 inline void operator /= (U const operand)
00286 {
00287 for (Uint32 i = 0; i < dimension; ++i)
00288 m[i] /= static_cast<T>(operand);
00289 }
00293 inline Vector<T, dimension> operator - () const
00294 {
00295 Vector<T, dimension> retval;
00296 for (Uint32 i = 0; i < dimension; ++i)
00297 retval.m[i] = -m[i];
00298 return retval;
00299 }
00300
00301
00302
00303
00304
00311 inline T Length () const
00312 {
00313 return Math::Sqrt(*this | *this);
00314 }
00320 inline T LengthSquared () const
00321 {
00322 return *this | *this;
00323 }
00330 inline Vector<T, dimension> Normalization () const
00331 {
00332 Vector<T, dimension> retval(*this);
00333 retval.Normalize();
00334 return retval;
00335 }
00340 inline bool IsZero () const
00341 {
00342 #if defined(XRB_VECTOR_USES_MEMCMP)
00343 return memcmp(m, ms_zero.m, sizeof(T) * dimension) == 0;
00344 #else
00345 for (Uint32 i = 0; i < dimension; ++i)
00346 if (m[i] != ms_zero.m[i])
00347 return false;
00348 return true;
00349 #endif
00350 }
00351
00356 template <typename U>
00357 inline Vector<U, dimension> StaticCast () const
00358 {
00359 Vector<U, dimension> retval;
00360 for (Uint32 i = 0; i < dimension; ++i)
00361 retval.m[i] = static_cast<U>(m[i]);
00362 return retval;
00363 }
00364
00365
00366
00367
00368
00372 inline void FillWith (T const fill_with)
00373 {
00374 for (Uint32 i = 0; i < dimension; ++i)
00375 m[i] = fill_with;
00376 }
00381 inline void Negate ()
00382 {
00383 for (Uint32 i = 0; i < dimension; ++i)
00384 m[i] = -m[i];
00385 }
00391 inline void Normalize ()
00392 {
00393 operator/=(Math::Sqrt(*this | *this));
00394 }
00402 inline void SetComponents (T const component0, T const component1)
00403 {
00404 ASSERT1(dimension == 2);
00405 m[0] = component0;
00406 m[1] = component1;
00407 }
00416 inline void SetComponents (T const component0, T const component1, T const component2)
00417 {
00418 ASSERT1(dimension == 3);
00419 m[0] = component0;
00420 m[1] = component1;
00421 m[2] = component2;
00422 }
00429 inline void SetComponents (T const *const components)
00430 {
00431 ASSERT1(components != NULL);
00432 #if defined(XRB_VECTOR_USES_MEMCPY)
00433 memcpy(m, components, sizeof(T) * dimension);
00434 #else
00435 for (Uint32 i = 0; i < dimension; ++i)
00436 m[i] = components[i];
00437 #endif
00438 }
00444 template <typename U>
00445 inline void StaticCastAssign (Vector<U, dimension> const &source)
00446 {
00447 for (Uint32 i = 0; i < dimension; ++i)
00448 m[i] = static_cast<T>(source.m[i]);
00449 }
00450
00451
00452
00453
00454
00467 void Fprint (FILE *const fptr,
00468 char const *const component_printf_format,
00469 bool const add_newline = true) const
00470 {
00471 fprintf(fptr, "Vector (%uD) = (", dimension);
00472 Uint32 i;
00473 for (i = 0; i < dimension-1; ++i)
00474 {
00475 fprintf(fptr, component_printf_format, m[i]);
00476 fprintf(fptr, ", ");
00477 }
00478 ASSERT1(i == dimension-1);
00479 fprintf(fptr, component_printf_format, m[i]);
00480 fprintf(fptr, ")%c", add_newline ? '\n' : '\0');
00481 }
00482 };
00483
00488 template <typename T, Uint32 dimension>
00489 Vector<T, dimension> const Vector<T, dimension>::ms_zero(static_cast<T>(0));
00490
00491
00492
00493
00494
00501 template <typename T, Uint32 dimension>
00502 inline Vector<T, dimension> operator + (
00503 Vector<T, dimension> const &left_operand,
00504 Vector<T, dimension> const &right_operand)
00505 {
00506 Vector<T, dimension> retval;
00507 for (Uint32 i = 0; i < dimension; ++i)
00508 retval.m[i] = left_operand.m[i] + right_operand.m[i];
00509 return retval;
00510 }
00511
00518 template <typename T, Uint32 dimension>
00519 inline Vector<T, dimension> operator - (
00520 Vector<T, dimension> const &left_operand,
00521 Vector<T, dimension> const &right_operand)
00522 {
00523 Vector<T, dimension> retval;
00524 for (Uint32 i = 0; i < dimension; ++i)
00525 retval.m[i] = left_operand.m[i] - right_operand.m[i];
00526 return retval;
00527 }
00528
00537 template <typename T, Uint32 dimension>
00538 inline Vector<T, dimension> operator * (
00539 Vector<T, dimension> const &left_operand,
00540 Vector<T, dimension> const &right_operand)
00541 {
00542 Vector<T, dimension> retval;
00543 for (Uint32 i = 0; i < dimension; ++i)
00544 retval.m[i] = left_operand.m[i] * right_operand.m[i];
00545 return retval;
00546 }
00547
00555 template <typename T, Uint32 dimension, typename U>
00556 inline Vector<T, dimension> operator * (
00557 U const left_operand,
00558 Vector<T, dimension> const &right_operand)
00559 {
00560 Vector<T, dimension> retval;
00561 for (Uint32 i = 0; i < dimension; ++i)
00562 retval.m[i] = static_cast<T>(left_operand) * right_operand.m[i];
00563 return retval;
00564 }
00565
00573 template <typename T, Uint32 dimension, typename U>
00574 inline Vector<T, dimension> operator * (
00575 Vector<T, dimension> const &left_operand,
00576 U const right_operand)
00577 {
00578 Vector<T, dimension> retval;
00579 for (Uint32 i = 0; i < dimension; ++i)
00580 retval.m[i] = left_operand.m[i] * static_cast<T>(right_operand);
00581 return retval;
00582 }
00583
00593 template <typename T, Uint32 dimension>
00594 inline Vector<T, dimension> operator / (
00595 Vector<T, dimension> const &left_operand,
00596 Vector<T, dimension> const &right_operand)
00597 {
00598 Vector<T, dimension> retval;
00599 for (Uint32 i = 0; i < dimension; ++i)
00600 retval.m[i] = left_operand.m[i] / right_operand.m[i];
00601 return retval;
00602 }
00603
00613 template <typename T, Uint32 dimension, typename U>
00614 inline Vector<T, dimension> operator / (
00615 U const left_operand,
00616 Vector<T, dimension> const &right_operand)
00617 {
00618 Vector<T, dimension> retval;
00619 for (Uint32 i = 0; i < dimension; ++i)
00620 retval.m[i] = static_cast<T>(left_operand) / right_operand.m[i];
00621 return retval;
00622 }
00623
00632 template <typename T, Uint32 dimension, typename U>
00633 inline Vector<T, dimension> operator / (
00634 Vector<T, dimension> const &left_operand,
00635 U const right_operand)
00636 {
00637 Vector<T, dimension> retval;
00638 for (Uint32 i = 0; i < dimension; ++i)
00639 retval.m[i] = left_operand.m[i] / static_cast<T>(right_operand);
00640 return retval;
00641 }
00642
00652 template <typename T, Uint32 dimension>
00653 inline T operator | (
00654 Vector<T, dimension> const &left_operand,
00655 Vector<T, dimension> const &right_operand)
00656 {
00657 T retval = left_operand.m[0] * right_operand.m[0];
00658 for (Uint32 i = 1; i < dimension; ++i)
00659 retval += left_operand.m[i] * right_operand.m[i];
00660 return retval;
00661 }
00662
00673 template <typename T>
00674 inline T operator & (
00675 Vector<T, 2> const &left_operand,
00676 Vector<T, 2> const &right_operand)
00677 {
00678 return left_operand.m[0] * right_operand.m[1] -
00679 left_operand.m[1] * right_operand.m[0];
00680 }
00681
00691 template <typename T>
00692 inline Vector<T, 3> operator & (
00693 Vector<T, 3> const &left_operand,
00694 Vector<T, 3> const &right_operand)
00695 {
00696 return Vector<T, 3>(
00697 left_operand.m[1] * right_operand.m[2] -
00698 left_operand.m[2] * right_operand.m[1],
00699 left_operand.m[2] * right_operand.m[0] -
00700 left_operand.m[0] * right_operand.m[2],
00701 left_operand.m[0] * right_operand.m[1] -
00702 left_operand.m[1] * right_operand.m[0]);
00703 }
00704
00715 template <typename T>
00716 inline Vector<T, 2> PerpendicularVector2 (Vector<T, 2> const &source)
00717 {
00718 return Vector<T, 2>(-source[1], source[0]);
00719 }
00720
00721
00722
00723
00724
00725
00726
00730 typedef Vector<Float, 2> FloatVector2;
00734 typedef Vector<Uint32, 2> Uint32Vector2;
00738 typedef Vector<Sint32, 2> Sint32Vector2;
00739
00748 void Fprint (FILE *fptr, FloatVector2 const &vector, bool add_newline = true);
00757 void Fprint (FILE *fptr, Uint32Vector2 const &vector, bool add_newline = true);
00766 void Fprint (FILE *fptr, Sint32Vector2 const &vector, bool add_newline = true);
00767
00768 }
00769
00770 #endif // !defined(_XRB_VECTOR_HPP_)