00001
00011 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00012 #pragma once
00013 #endif
00014 #ifndef COMMON_MATH_H_
00015 #define COMMON_MATH_H_
00016
00017 #ifdef WIN32
00018 #include <windows.h>
00019 #endif
00020
00021 #ifdef USE_DIRECTX
00022 #include <d3dx9.h>
00023 #endif
00024
00025 namespace common
00026 {
00027
00032
00034
00035 template <typename DestT, typename SrcT>
00036 DestT & math_cast(const SrcT &x)
00037 {
00038 assert(0 && "Unsupported type in math_cast.");
00039 }
00040
00042 const float FLOAT_EPSILON = 1e-6f;
00043
00044
00045
00048
00050
00055 struct POINT_
00056 {
00057 union
00058 {
00059 struct
00060 {
00061 int x, y;
00062 };
00063 int v[2];
00064 };
00065
00066 static const POINT_ ZERO;
00067
00068 POINT_() { }
00069 POINT_(int x, int y) : x(x), y(y) { }
00070
00071 bool operator == (const POINT_ &v) const { return x == v.x && y == v.y; }
00072 bool operator != (const POINT_ &v) const { return x != v.x || y != v.y; }
00073
00074 POINT_ operator - () const { return POINT_(-x, -y); }
00075 POINT_ operator + (const POINT_ &v) const { return POINT_(x+v.x, y+v.y); }
00076 POINT_ operator - (const POINT_ &v) const { return POINT_(x-v.x, y-v.y); }
00077 POINT_ & operator += (const POINT_ &v) { x += v.x; y += v.y; return *this; }
00078 POINT_ & operator -= (const POINT_ &v) { x -= v.x; y -= v.y; return *this; }
00079 POINT_ & operator *= (int v) { x *= v; y *= v; return *this; }
00080 POINT_ & operator /= (int v) { x /= v; y /= v; return *this; }
00081
00082 int & operator [] (uint4 Index) { return v[Index]; }
00083 const int & operator [] (uint4 Index) const { return v[Index]; }
00084
00085 int * GetArray() { return &x; }
00086 const int * GetArray() const { return &x; }
00087 };
00088
00089 inline POINT_ operator * (const POINT_ pt, int v) { return POINT_(pt.x*v, pt.y*v); }
00090 inline POINT_ operator / (const POINT_ pt, int v) { return POINT_(pt.x/v, pt.y/v); }
00091 inline POINT_ operator * (int v, const POINT_ pt) { return POINT_(pt.x*v, pt.y*v); }
00092 inline POINT_ operator / (int v, const POINT_ pt) { return POINT_(pt.x/v, pt.y/v); }
00093
00094 #ifdef WIN32
00096 template <> inline ::POINT & math_cast<::POINT, POINT_>(const POINT_ &x) { return (::POINT&)(x); }
00098 template <> inline POINT_ & math_cast<POINT_, ::POINT>(const ::POINT &x) { return (POINT_&)(x); }
00099 #endif
00100
00101 extern const common::POINT_ POINT_ZERO;
00102 extern const common::POINT_ POINT_ONE;
00103 extern const common::POINT_ POINT_NEGATIVE_X;
00104 extern const common::POINT_ POINT_NEGATIVE_Y;
00105 extern const common::POINT_ POINT_POSITIVE_X;
00106 extern const common::POINT_ POINT_POSITIVE_Y;
00107
00108 inline void swap(POINT_ &v1, POINT_ &v2)
00109 {
00110 std::swap(v1.x, v2.x);
00111 std::swap(v1.y, v2.y);
00112 }
00113
00114 inline void Mul(POINT_ *out, const POINT_ &p1, const POINT_ &p2)
00115 {
00116 out->x = p1.x * p2.x;
00117 out->y = p1.y * p2.y;
00118 }
00119 inline void Div(POINT_ *out, const POINT_ &p1, const POINT_ &p2)
00120 {
00121 out->x = p1.x / p2.x;
00122 out->y = p1.y / p2.y;
00123 }
00124
00125 inline void Mul(POINT_ *inout, const POINT_ &v)
00126 {
00127 inout->x *= v.x;
00128 inout->y *= v.y;
00129 }
00130 inline void Div(POINT_ *inout, const POINT_ &v)
00131 {
00132 inout->x /= v.x;
00133 inout->y /= v.y;
00134 }
00135
00136 inline void Min(common::POINT_ *out, const common::POINT_ &a, const common::POINT_ &b)
00137 {
00138 out->x = std::min(a.x, b.x);
00139 out->y = std::min(a.y, b.y);
00140 }
00141
00142 inline void Max(common::POINT_ *out, const common::POINT_ &a, const common::POINT_ &b)
00143 {
00144 out->x = std::max(a.x, b.x);
00145 out->y = std::max(a.y, b.y);
00146 }
00147
00149
00150
00151
00154
00155 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
00156 typedef D3DXVECTOR2 VEC2;
00157 #else
00159 struct VEC2
00160 {
00161 float x, y;
00162
00163 VEC2() { }
00164 VEC2(float x, float y) : x(x), y(y) { }
00165 VEC2(const float *Array) : x(Array[0]), y(Array[1]) { }
00166
00167 operator float * () { return &x; }
00168 operator const float * () const { return &x; }
00169
00170 bool operator == (const VEC2 &v) const { return x == v.x && y == v.y; }
00171 bool operator != (const VEC2 &v) const { return x != v.x || y != v.y; }
00172
00173 VEC2 operator + () const { return *this; }
00174 VEC2 operator - () const { return VEC2(-x, -y); }
00175 VEC2 operator + (const VEC2 &v) const { return VEC2(x+v.x, y+v.y); }
00176 VEC2 operator - (const VEC2 &v) const { return VEC2(x-v.x, y-v.y); }
00177 VEC2 & operator += (const VEC2 &v) { x += v.x; y += v.y; return *this; }
00178 VEC2 & operator -= (const VEC2 &v) { x -= v.x; y -= v.y; return *this; }
00179 VEC2 & operator *= (float v) { x *= v; y *= v; return *this; }
00180 VEC2 & operator /= (float v) { float vInv = 1.0f/v; x *= vInv; y *= vInv; return *this; }
00181 };
00182 inline VEC2 operator * (const VEC2 pt, float v) { return VEC2(pt.x*v, pt.y*v); }
00183 inline VEC2 operator / (const VEC2 pt, float v) { float vInv = 1.0f/v; return VEC2(pt.x*vInv, pt.y*vInv); }
00184 inline VEC2 operator * (float v, const VEC2 pt) { return VEC2(pt.x*v, pt.y*v); }
00185 #endif
00186
00187 inline void swap(VEC2 &v1, VEC2 &v2)
00188 {
00189 std::swap(v1.x, v2.x);
00190 std::swap(v1.y, v2.y);
00191 }
00192
00193 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
00194 typedef D3DXVECTOR3 VEC3;
00195 #else
00197 struct VEC3
00198 {
00199 float x, y, z;
00200
00201 VEC3() { }
00202 VEC3(float x, float y, float z) : x(x), y(y), z(z) { }
00203 VEC3(const float *Array) : x(Array[0]), y(Array[1]), z(Array[2]) { }
00204
00205 operator float * () { return &x; }
00206 operator const float * () const { return &x; }
00207
00208 bool operator == (const VEC3 &v) const { return x == v.x && y == v.y && z == v.z; }
00209 bool operator != (const VEC3 &v) const { return x != v.x || y != v.y || z != v.z; }
00210
00211 VEC3 operator + () const { return *this; }
00212 VEC3 operator - () const { return VEC3(-x, -y, -z); }
00213 VEC3 operator + (const VEC3 &v) const { return VEC3(x+v.x, y+v.y, z+v.z); }
00214 VEC3 operator - (const VEC3 &v) const { return VEC3(x-v.x, y-v.y, z-v.z); }
00215 VEC3 & operator += (const VEC3 &v) { x += v.x; y += v.y; z += v.z; return *this; }
00216 VEC3 & operator -= (const VEC3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
00217 VEC3 & operator *= (float v) { x *= v; y *= v; z *= v; return *this; }
00218 VEC3 & operator /= (float v) { float vInv = 1.0f/v; x *= vInv; y *= vInv; z *= vInv; return *this; }
00219 };
00220 inline VEC3 operator * (const VEC3 pt, float v) { return VEC3(pt.x*v, pt.y*v, pt.z*v); }
00221 inline VEC3 operator / (const VEC3 pt, float v) { float vInv = 1.0f/v; return VEC3(pt.x*vInv, pt.y*vInv, pt.z*vInv); }
00222 inline VEC3 operator * (float v, const VEC3 pt) { return VEC3(pt.x*v, pt.y*v, pt.z*v); }
00223 #endif
00224
00225 inline void swap(VEC3 &v1, VEC3 &v2)
00226 {
00227 std::swap(v1.x, v2.x);
00228 std::swap(v1.y, v2.y);
00229 std::swap(v1.z, v2.z);
00230 }
00231
00232 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
00233 typedef D3DXVECTOR4 VEC4;
00234 #else
00236 struct VEC4
00237 {
00238 float x, y, z, w;
00239
00240 VEC4() { }
00241 VEC4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
00242 VEC4(const float *Array) : x(Array[0]), y(Array[1]), z(Array[2]), w(Array[3]) { }
00243
00244 operator float * () { return &x; }
00245 operator const float * () const { return &x; }
00246
00247 bool operator == (const VEC4 &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; }
00248 bool operator != (const VEC4 &v) const { return x != v.x || y != v.y || z != v.z || w != v.w; }
00249
00250 VEC4 operator + () const { return *this; }
00251 VEC4 operator - () const { return VEC4(-x, -y, -z, -w); }
00252 VEC4 operator + (const VEC4 &v) const { return VEC4(x+v.x, y+v.y, z+v.z, w+v.w); }
00253 VEC4 operator - (const VEC4 &v) const { return VEC4(x-v.x, y-v.y, z-v.z, w-v.w); }
00254 VEC4 & operator += (const VEC4 &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
00255 VEC4 & operator -= (const VEC4 &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
00256 VEC4 & operator *= (float v) { x *= v; y *= v; z *= v; w *= v; return *this; }
00257 VEC4 & operator /= (float v) { float vInv = 1.0f/v; x *= vInv; y *= vInv; z *= vInv; w *= vInv; return *this; }
00258 };
00259 inline VEC4 operator * (const VEC4 pt, float v) { return VEC4(pt.x*v, pt.y*v, pt.z*v, pt.w*v); }
00260 inline VEC4 operator / (const VEC4 pt, float v) { float vInv = 1.0f/v; return VEC4(pt.x*vInv, pt.y*vInv, pt.z*vInv, pt.w*vInv); }
00261 inline VEC4 operator * (float v, const VEC4 pt) { return VEC4(pt.x*v, pt.y*v, pt.z*v, pt.w*v); }
00262 #endif
00263
00264 inline void swap(VEC4 &v1, VEC4 &v2)
00265 {
00266 std::swap(v1.x, v2.x);
00267 std::swap(v1.y, v2.y);
00268 std::swap(v1.z, v2.z);
00269 std::swap(v1.w, v2.w);
00270 }
00271
00272 extern const VEC2 VEC2_ZERO;
00273 extern const VEC2 VEC2_ONE;
00274 extern const VEC2 VEC2_POSITIVE_X;
00275 extern const VEC2 VEC2_POSITIVE_Y;
00276 extern const VEC2 VEC2_NEGATIVE_X;
00277 extern const VEC2 VEC2_NEGATIVE_Y;
00278
00279 extern const VEC3 VEC3_ZERO;
00280 extern const VEC3 VEC3_ONE;
00281 extern const VEC3 VEC3_POSITIVE_X;
00282 extern const VEC3 VEC3_POSITIVE_Y;
00283 extern const VEC3 VEC3_POSITIVE_Z;
00284 extern const VEC3 VEC3_NEGATIVE_X;
00285 extern const VEC3 VEC3_NEGATIVE_Y;
00286 extern const VEC3 VEC3_NEGATIVE_Z;
00287
00288 extern const VEC4 VEC4_ZERO;
00289 extern const VEC4 VEC4_ONE;
00290 extern const VEC4 VEC4_POSITIVE_X;
00291 extern const VEC4 VEC4_POSITIVE_Y;
00292 extern const VEC4 VEC4_POSITIVE_Z;
00293 extern const VEC4 VEC4_POSITIVE_W;
00294 extern const VEC4 VEC4_NEGATIVE_X;
00295 extern const VEC4 VEC4_NEGATIVE_Y;
00296 extern const VEC4 VEC4_NEGATIVE_Z;
00297 extern const VEC4 VEC4_NEGATIVE_W;
00298
00300 inline float LengthSq(const VEC2 &v)
00301 {
00302 return v.x*v.x + v.y*v.y;
00303 }
00305 inline float LengthSq(const VEC3 &v)
00306 {
00307 return v.x*v.x + v.y*v.y + v.z*v.z;
00308 }
00310 inline float LengthSq(const VEC4 &v)
00311 {
00312 return v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w;
00313 }
00314
00316 inline float Length(const VEC2 &v)
00317 {
00318 return sqrtf(LengthSq(v));
00319 }
00321 inline float Length(const VEC3 &v)
00322 {
00323 return sqrtf(LengthSq(v));
00324 }
00326 inline float Length(const VEC4 &v)
00327 {
00328 return sqrtf(LengthSq(v));
00329 }
00330
00331 inline float ManhattanLength(const VEC2 &v)
00332 {
00333 return fabsf(v.x) + fabsf(v.y);
00334 }
00335 inline float ManhattanLength(const VEC3 &v)
00336 {
00337 return fabsf(v.x) + fabsf(v.y) + fabsf(v.z);
00338 }
00339 inline float ManhattanLength(const VEC4 &v)
00340 {
00341 return fabsf(v.x) + fabsf(v.y) + fabsf(v.z) + fabsf(v.z);
00342 }
00343
00344 inline float MaxLength(const VEC2 &v)
00345 {
00346 return std::max(fabsf(v.x), fabsf(v.y));
00347 }
00348 inline float MaxLength(const VEC3 &v)
00349 {
00350 return max3(fabsf(v.x), fabsf(v.y), fabsf(v.z));
00351 }
00352 inline float MaxLength(const VEC4 &v)
00353 {
00354 return std::max(
00355 std::max(fabsf(v.x), fabsf(v.y)),
00356 std::max(fabsf(v.z), fabsf(v.z)) );
00357 }
00358
00360 inline void Min(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00361 {
00362 Out->x = std::min(v1.x, v2.x);
00363 Out->y = std::min(v1.y, v2.y);
00364 }
00365 inline void Min(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00366 {
00367 Out->x = std::min(v1.x, v2.x);
00368 Out->y = std::min(v1.y, v2.y);
00369 Out->z = std::min(v1.z, v2.z);
00370 }
00371 inline void Min(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00372 {
00373 Out->x = std::min(v1.x, v2.x);
00374 Out->y = std::min(v1.y, v2.y);
00375 Out->z = std::min(v1.z, v2.z);
00376 Out->w = std::min(v1.w, v2.w);
00377 }
00378
00380 inline void Max(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00381 {
00382 Out->x = std::max(v1.x, v2.x);
00383 Out->y = std::max(v1.y, v2.y);
00384 }
00385 inline void Max(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00386 {
00387 Out->x = std::max(v1.x, v2.x);
00388 Out->y = std::max(v1.y, v2.y);
00389 Out->z = std::max(v1.z, v2.z);
00390 }
00391 inline void Max(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00392 {
00393 Out->x = std::max(v1.x, v2.x);
00394 Out->y = std::max(v1.y, v2.y);
00395 Out->z = std::max(v1.z, v2.z);
00396 Out->w = std::max(v1.w, v2.w);
00397 }
00398
00399 inline void saturate(VEC2 &v)
00400 {
00401 v.x = saturate(v.x); v.y = saturate(v.y);
00402 }
00403 inline void saturate(VEC3 &v)
00404 {
00405 v.x = saturate(v.x); v.y = saturate(v.y); v.z = saturate(v.z);
00406 }
00407 inline void saturate(VEC4 &v)
00408 {
00409 v.x = saturate(v.x); v.y = saturate(v.y); v.z = saturate(v.z); v.w = saturate(v.w);
00410 }
00411
00414
00415 inline void Mul(VEC2 *Out, const VEC2 &v, float f)
00416 {
00417 Out->x = v.x * f;
00418 Out->y = v.y * f;
00419 }
00420 inline void Mul(VEC3 *Out, const VEC3 &v, float f)
00421 {
00422 Out->x = v.x * f;
00423 Out->y = v.y * f;
00424 Out->z = v.z * f;
00425 }
00426 inline void Mul(VEC4 *Out, const VEC4 &v, float f)
00427 {
00428 Out->x = v.x * f;
00429 Out->y = v.y * f;
00430 Out->z = v.z * f;
00431 Out->w = v.w * f;
00432 }
00433
00434 inline void Add(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00435 {
00436 Out->x = v1.x + v2.x;
00437 Out->y = v1.y + v2.y;
00438 }
00439 inline void Add(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00440 {
00441 Out->x = v1.x + v2.x;
00442 Out->y = v1.y + v2.y;
00443 Out->z = v1.z + v2.z;
00444 }
00445 inline void Add(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00446 {
00447 Out->x = v1.x + v2.x;
00448 Out->y = v1.y + v2.y;
00449 Out->z = v1.z + v2.z;
00450 Out->w = v1.w + v2.w;
00451 }
00452
00453 inline void Sub(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00454 {
00455 Out->x = v1.x - v2.x;
00456 Out->y = v1.y - v2.y;
00457 }
00458 inline void Sub(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00459 {
00460 Out->x = v1.x - v2.x;
00461 Out->y = v1.y - v2.y;
00462 Out->z = v1.z - v2.z;
00463 }
00464 inline void Sub(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00465 {
00466 Out->x = v1.x - v2.x;
00467 Out->y = v1.y - v2.y;
00468 Out->z = v1.z - v2.z;
00469 Out->w = v1.w - v2.w;
00470 }
00471
00472 inline void Mul(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00473 {
00474 Out->x = v1.x * v2.x;
00475 Out->y = v1.y * v2.y;
00476 }
00477 inline void Mul(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00478 {
00479 Out->x = v1.x * v2.x;
00480 Out->y = v1.y * v2.y;
00481 Out->z = v1.z * v2.z;
00482 }
00483 inline void Mul(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00484 {
00485 Out->x = v1.x * v2.x;
00486 Out->y = v1.y * v2.y;
00487 Out->z = v1.z * v2.z;
00488 Out->w = v1.w * v2.w;
00489 }
00490
00491 inline void Div(VEC2 *Out, const VEC2 &v1, const VEC2 &v2)
00492 {
00493 Out->x = v1.x / v2.x;
00494 Out->y = v1.y / v2.y;
00495 }
00496 inline void Div(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00497 {
00498 Out->x = v1.x / v2.x;
00499 Out->y = v1.y / v2.y;
00500 Out->z = v1.z / v2.z;
00501 }
00502 inline void Div(VEC4 *Out, const VEC4 &v1, const VEC4 &v2)
00503 {
00504 Out->x = v1.x / v2.x;
00505 Out->y = v1.y / v2.y;
00506 Out->z = v1.z / v2.z;
00507 Out->w = v1.w / v2.w;
00508 }
00509
00510 inline void Mul(VEC2 *inout, const VEC2 &v)
00511 {
00512 inout->x *= v.x;
00513 inout->y *= v.y;
00514 }
00515 inline void Mul(VEC3 *inout, const VEC3 &v)
00516 {
00517 inout->x *= v.x;
00518 inout->y *= v.y;
00519 inout->z *= v.z;
00520 }
00521 inline void Mul(VEC4 *inout, const VEC4 &v)
00522 {
00523 inout->x *= v.x;
00524 inout->y *= v.y;
00525 inout->z *= v.z;
00526 inout->w *= v.w;
00527 }
00528
00529 inline void Div(VEC2 *inout, const VEC2 &v)
00530 {
00531 inout->x /= v.x;
00532 inout->y /= v.y;
00533 }
00534 inline void Div(VEC3 *inout, const VEC3 &v)
00535 {
00536 inout->x /= v.x;
00537 inout->y /= v.y;
00538 inout->z /= v.z;
00539 }
00540 inline void Div(VEC4 *inout, const VEC4 &v)
00541 {
00542 inout->x /= v.x;
00543 inout->y /= v.y;
00544 inout->z /= v.z;
00545 inout->w /= v.w;
00546 }
00547
00548 inline void Abs(VEC2 *v) { v->x = fabsf(v->x); v->y = fabsf(v->y); }
00549 inline void Abs(VEC3 *v) { v->x = fabsf(v->x); v->y = fabsf(v->y); v->z = fabsf(v->z); }
00550 inline void Abs(VEC4 *v) { v->x = fabsf(v->x); v->y = fabsf(v->y); v->z = fabsf(v->z); v->w = fabsf(v->w); }
00551
00553
00554
00556 inline float Dot(const VEC2 &v1, const VEC2 &v2)
00557 {
00558 return v1.x*v2.x + v1.y*v2.y;
00559 }
00560 inline float Dot(const VEC3 &v1, const VEC3 &v2)
00561 {
00562 return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
00563 }
00564 inline float Dot(const VEC4 &v1, const VEC4 &v2)
00565 {
00566 return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w;
00567 }
00568
00570 inline void Minus(VEC2 *Out, VEC2 &v) { Out->x = -v.x; Out->y = -v.y; }
00571 inline void Minus(VEC3 *Out, VEC3 &v) { Out->x = -v.x; Out->y = -v.y; Out->z = -v.z; }
00572 inline void Minus(VEC4 *Out, VEC4 &v) { Out->x = -v.x; Out->y = -v.y; Out->z = -v.z; Out->w = -v.w; }
00573 inline void Minus(VEC2 *InOut) { InOut->x = -InOut->x; InOut->y = -InOut->y; }
00574 inline void Minus(VEC3 *InOut) { InOut->x = -InOut->x; InOut->y = -InOut->y; InOut->z = -InOut->z; }
00575 inline void Minus(VEC4 *InOut) { InOut->x = -InOut->x; InOut->y = -InOut->y; InOut->z = -InOut->z; InOut->w = -InOut->w; }
00576
00578
00580 inline float Cross(const VEC2 &v1, const VEC2 &v2)
00581 {
00582 return v1.x*v2.y - v1.y*v2.x;
00583 }
00584
00586 inline void Cross(VEC3 *Out, const VEC3 &v1, const VEC3 &v2)
00587 {
00588 Out->x = v1.y * v2.z - v1.z * v2.y;
00589 Out->y = v1.z * v2.x - v1.x * v2.z;
00590 Out->z = v1.x * v2.y - v1.y * v2.x;
00591 }
00592
00594 inline float DistanceSq(const VEC2 &p1, const VEC2 &p2)
00595 {
00596 return LengthSq(p2-p1);
00597 }
00598 inline float DistanceSq(const VEC3 &p1, const VEC3 &p2)
00599 {
00600 return LengthSq(p2-p1);
00601 }
00602 inline float DistanceSq(const VEC4 &p1, const VEC4 &p2)
00603 {
00604 return LengthSq(p2-p1);
00605 }
00606
00608 inline float Distance(const VEC2 &p1, const VEC2 &p2)
00609 {
00610 return Length(p2-p1);
00611 }
00612 inline float Distance(const VEC3 &p1, const VEC3 &p2)
00613 {
00614 return Length(p2-p1);
00615 }
00616 inline float Distance(const VEC4 &p1, const VEC4 &p2)
00617 {
00618 return Length(p2-p1);
00619 }
00620
00621 inline float ManhattanDistance(const VEC2 &p1, const VEC2 &p2)
00622 {
00623 return fabsf(p2.x-p1.x) + fabsf(p2.y-p1.y);
00624 }
00625 inline float ManhattanDistance(const VEC3 &p1, const VEC3 &p2)
00626 {
00627 return fabsf(p2.x-p1.x) + fabsf(p2.y-p1.y) + fabsf(p2.z-p1.z);
00628 }
00629 inline float ManhattanDistance(const VEC4 &p1, const VEC4 &p2)
00630 {
00631 return fabsf(p2.x-p1.x) + fabsf(p2.y-p1.y) + fabsf(p2.z-p1.z) + fabsf(p2.w-p1.w);
00632 }
00633
00634 inline float MaxDistance(const VEC2 &p1, const VEC2 &p2)
00635 {
00636 return std::max( fabsf(p2.x-p1.x), fabsf(p2.y-p1.y) );
00637 }
00638 inline float MaxDistance(const VEC3 &p1, const VEC3 &p2)
00639 {
00640 return max3( fabsf(p2.x-p1.x), fabsf(p2.y-p1.y), fabsf(p2.z-p1.z) );
00641 }
00642 inline float MaxDistance(const VEC4 &p1, const VEC4 &p2)
00643 {
00644 return std::max(
00645 std::max( fabsf(p2.x-p1.x), fabsf(p2.y-p1.y) ),
00646 std::max( fabsf(p2.z-p1.z), fabsf(p2.w-p1.w) ) );
00647 }
00648
00650 inline void Lerp(VEC2 *Out, const VEC2 &v1, const VEC2 &v2, float t)
00651 {
00652 Out->x = v1.x + t*(v2.x-v1.x);
00653 Out->y = v1.y + t*(v2.y-v1.y);
00654 }
00655 inline void Lerp(VEC3 *Out, const VEC3 &v1, const VEC3 &v2, float t)
00656 {
00657 Out->x = v1.x + t*(v2.x-v1.x);
00658 Out->y = v1.y + t*(v2.y-v1.y);
00659 Out->z = v1.z + t*(v2.z-v1.z);
00660 }
00661 inline void Lerp(VEC4 *Out, const VEC4 &v1, const VEC4 &v2, float t)
00662 {
00663 Out->x = v1.x + t*(v2.x-v1.x);
00664 Out->y = v1.y + t*(v2.y-v1.y);
00665 Out->z = v1.z + t*(v2.z-v1.z);
00666 Out->w = v1.w + t*(v2.w-v1.w);
00667 }
00668
00670 inline void Normalize(VEC2 *Out, const VEC2 &v)
00671 {
00672 float l = 1.0f / Length(v);
00673 Out->x = v.x * l;
00674 Out->y = v.y * l;
00675 }
00676 inline void Normalize(VEC3 *Out, const VEC3 &v)
00677 {
00678 float l = 1.0f / Length(v);
00679 Out->x = v.x * l;
00680 Out->y = v.y * l;
00681 Out->z = v.z * l;
00682 }
00683 inline void Normalize(VEC4 *Out, const VEC4 &v)
00684 {
00685 float l = 1.0f / Length(v);
00686 Out->x = v.x * l;
00687 Out->y = v.y * l;
00688 Out->z = v.z * l;
00689 Out->w = v.w * l;
00690 }
00691
00693 inline void Normalize(VEC2 *v)
00694 {
00695 float rcl = 1.0f / Length(*v);
00696 v->x *= rcl;
00697 v->y *= rcl;
00698 }
00699 inline void Normalize(VEC3 *v)
00700 {
00701 float rcl = 1.0f / Length(*v);
00702 v->x *= rcl;
00703 v->y *= rcl;
00704 v->z *= rcl;
00705 }
00706 inline void Normalize(VEC4 *v)
00707 {
00708 float rcl = 1.0f / Length(*v);
00709 v->x *= rcl;
00710 v->y *= rcl;
00711 v->z *= rcl;
00712 v->w *= rcl;
00713 }
00714
00716 inline bool SafeNormalize(VEC2 *v)
00717 {
00718 float lenSq = LengthSq(*v);
00719 if (lenSq < FLOAT_EPSILON) return false;
00720 float f = 1.f / sqrtf(lenSq);
00721 v->x *= f; v->y *= f;
00722 return true;
00723 }
00724 inline bool SafeNormalize(VEC3 *v)
00725 {
00726 float lenSq = LengthSq(*v);
00727 if (lenSq < FLOAT_EPSILON) return false;
00728 float f = 1.f / sqrtf(lenSq);
00729 v->x *= f; v->y *= f; v->z *= f;
00730 return true;
00731 }
00732 inline bool SafeNormalize(VEC4 *v)
00733 {
00734 float lenSq = LengthSq(*v);
00735 if (lenSq < FLOAT_EPSILON) return false;
00736 float f = 1.f / sqrtf(lenSq);
00737 v->x *= f; v->y *= f; v->z *= f; v->w *= f;
00738 return true;
00739 }
00740
00742 inline void Vec3ToVec4(VEC4 *Out, const VEC3 &v)
00743 {
00744 Out->x = v.x;
00745 Out->y = v.y;
00746 Out->z = v.z;
00747 Out->w = 1.0f;
00748 }
00749
00751 inline void Vec4ToVec3_Ignore(VEC3 *Out, const VEC4 &v)
00752 {
00753 Out->x = v.x;
00754 Out->y = v.y;
00755 Out->z = v.z;
00756 }
00758 inline void Vec4ToVec3_Div(VEC3 *Out, const VEC4 &v)
00759 {
00760 float rcw = 1.0f / v.w;
00761 Out->x = v.x * rcw;
00762 Out->y = v.y * rcw;
00763 Out->z = v.z * rcw;
00764 }
00765
00767 inline void MidPoint(VEC2 *Out, const VEC2 &p1, const VEC2 &p2)
00768 {
00769 Out->x = (p1.x+p2.x) * 0.5f;
00770 Out->y = (p1.y+p2.y) * 0.5f;
00771 }
00772 inline void MidPoint(VEC3 *Out, const VEC3 &p1, const VEC3 &p2)
00773 {
00774 Out->x = (p1.x+p2.x) * 0.5f;
00775 Out->y = (p1.y+p2.y) * 0.5f;
00776 Out->z = (p1.z+p2.z) * 0.5f;
00777 }
00778 inline void MidPoint(VEC4 *Out, const VEC4 &p1, const VEC4 &p2)
00779 {
00780 Out->x = (p1.x+p2.x) * 0.5f;
00781 Out->y = (p1.y+p2.y) * 0.5f;
00782 Out->z = (p1.z+p2.z) * 0.5f;
00783 Out->w = (p1.w+p2.w) * 0.5f;
00784 }
00785
00787 inline bool VecEqual(const VEC2 &v1, const VEC2 &v2) {
00788 return float_equal(v1.x, v2.x) && float_equal(v1.y, v2.y);
00789 }
00790 inline bool VecEqual(const VEC3 &v1, const VEC3 &v2) {
00791 return float_equal(v1.x, v2.x) && float_equal(v1.y, v2.y) && float_equal(v1.z, v2.z);
00792 }
00793 inline bool VecEqual(const VEC4 &v1, const VEC4 &v2) {
00794 return float_equal(v1.x, v2.x) && float_equal(v1.y, v2.y) && float_equal(v1.z, v2.z) && float_equal(v1.w, v2.w);
00795 }
00796
00802
00803 inline bool Less(const VEC2 &v1, const VEC2 &v2)
00804 {
00805 return v1.x < v2.x && v1.y < v2.y;
00806 }
00807 inline bool Less(const VEC3 &v1, const VEC3 &v2)
00808 {
00809 return v1.x < v2.x && v1.y < v2.y && v1.z < v2.z;
00810 }
00811 inline bool Less(const VEC4 &v1, const VEC4 &v2)
00812 {
00813 return v1.x < v2.x && v1.y < v2.y && v1.z < v2.z && v1.w < v2.w;
00814 }
00815
00816 inline bool LessOrEqual(const VEC2 &v1, const VEC2 &v2)
00817 {
00818 return v1.x <= v2.x && v1.y <= v2.y;
00819 }
00820 inline bool LessOrEqual(const VEC3 &v1, const VEC3 &v2)
00821 {
00822 return v1.x <= v2.x && v1.y <= v2.y && v1.z <= v2.z;
00823 }
00824 inline bool LessOrEqual(const VEC4 &v1, const VEC4 &v2)
00825 {
00826 return v1.x <= v2.x && v1.y <= v2.y && v1.z <= v2.z && v1.w <= v2.w;
00827 }
00828
00829 inline bool Greater(const VEC2 &v1, const VEC2 &v2)
00830 {
00831 return v1.x > v2.x && v1.y > v2.y;
00832 }
00833 inline bool Greater(const VEC3 &v1, const VEC3 &v2)
00834 {
00835 return v1.x > v2.x && v1.y > v2.y && v1.z > v2.z;
00836 }
00837 inline bool Greater(const VEC4 &v1, const VEC4 &v2)
00838 {
00839 return v1.x > v2.x && v1.y > v2.y && v1.z > v2.z && v1.w > v2.w;
00840 }
00841
00842 inline bool GreaterOrEqual(const VEC2 &v1, const VEC2 &v2)
00843 {
00844 return v1.x >= v2.x && v1.y >= v2.y;
00845 }
00846 inline bool GreaterOrEqual(const VEC3 &v1, const VEC3 &v2)
00847 {
00848 return v1.x >= v2.x && v1.y >= v2.y && v1.z >= v2.z;
00849 }
00850 inline bool GreaterOrEqual(const VEC4 &v1, const VEC4 &v2)
00851 {
00852 return v1.x >= v2.x && v1.y >= v2.y && v1.z >= v2.z && v1.w >= v2.w;
00853 }
00854
00856
00857
00858 inline bool around(const VEC2 &v1, const VEC2 &v2, float Epsilon) {
00859 return around(v1.x, v2.x, Epsilon) && around(v1.y, v2.y, Epsilon);
00860 }
00861 inline bool around(const VEC3 &v1, const VEC3 &v2, float Epsilon) {
00862 return around(v1.x, v2.x, Epsilon) && around(v1.y, v2.y, Epsilon) && around(v1.z, v2.z, Epsilon);
00863 }
00864 inline bool around(const VEC4 &v1, const VEC4 &v2, float Epsilon) {
00865 return around(v1.x, v2.x, Epsilon) && around(v1.y, v2.y, Epsilon) && around(v1.z, v2.z, Epsilon) && around(v1.w, v2.w, Epsilon);
00866 }
00867
00869
00871 inline void Perpedicular(VEC2 *Out, const VEC2 &v)
00872 {
00873 Out->x = -v.y;
00874 Out->y = v.x;
00875 }
00876
00878
00882 inline void Reflect(VEC2 *Out, const VEC2 &v, const VEC2 &PlaneNormal)
00883 {
00884 *Out = v - (2.0f * Dot(v, PlaneNormal)) * PlaneNormal;
00885 }
00886 inline void Reflect(VEC3 *Out, const VEC3 &v, const VEC3 &PlaneNormal)
00887 {
00888 *Out = v - (2.0f * Dot(v, PlaneNormal)) * PlaneNormal;
00889 }
00890
00892
00895 inline void Refract(VEC2 *out, const VEC2 &I, const VEC2 &N, float eta)
00896 {
00897 float N_dot_I = Dot(N, I);
00898 float k = 1.f - eta * eta * (1.f - N_dot_I * N_dot_I);
00899 if (k < 0.f)
00900 *out = VEC2_ZERO;
00901 else
00902 *out = eta * I - (eta * N_dot_I + sqrtf(k)) * N;
00903 }
00905 inline void Refract(VEC3 *out, const VEC3 &I, const VEC3 &N, float eta)
00906 {
00907 float N_dot_I = Dot(N, I);
00908 float k = 1.f - eta * eta * (1.f - N_dot_I * N_dot_I);
00909 if (k < 0.f)
00910 *out = VEC3_ZERO;
00911 else
00912 *out = eta * I - (eta * N_dot_I + sqrtf(k)) * N;
00913 }
00914
00916
00919 inline void Project(VEC2 *Out, const VEC2 &V, const VEC2 &N)
00920 {
00921
00922
00923
00924 float T = (V.x*N.x + V.y*N.y) / (N.x*N.x + N.y*N.y);
00925 Out->x = N.x * T;
00926 Out->y = N.y * T;
00927 }
00928 inline void Project(VEC3 *Out, const VEC3 &V, const VEC3 &N)
00929 {
00930 float T = (V.x*N.x + V.y*N.y + V.z*N.z) / (N.x*N.x + N.y*N.y + N.z*N.z);
00931 Out->x = N.x * T;
00932 Out->y = N.y * T;
00933 Out->z = N.z * T;
00934 }
00936 inline void Project_N(VEC2 *Out, const VEC2 &V, const VEC2 &N)
00937 {
00938
00939
00940
00941 float T = V.x*N.x + V.y*N.y;
00942 Out->x = N.x * T;
00943 Out->y = N.y * T;
00944 }
00945 inline void Project_N(VEC3 *Out, const VEC3 &V, const VEC3 &N)
00946 {
00947 float T = V.x*N.x + V.y*N.y + V.z*N.z;
00948 Out->x = N.x * T;
00949 Out->y = N.y * T;
00950 Out->z = N.z * T;
00951 }
00952
00954 inline float ScalarTripleProduct(const VEC3 &u, const VEC3 &v, const VEC3 &w)
00955 {
00956 return u.x * (v.y * w.z - v.z * w.y) - u.y * (v.x * w.z - v.z * w.x) + u.z * (v.x * w.y - v.y * w.x);
00957 }
00958
00965
00966 void Orthogonalize_Fast(VEC3 *OutR1, VEC3 *OutR2, VEC3 *OutR3, const VEC3 &R1, const VEC3 &R2, const VEC3 &R3);
00968 void Orthogonalize(VEC3 *OutR1, VEC3 *OutR2, VEC3 *OutR3, const VEC3 &R1, const VEC3 &R2, const VEC3 &R3);
00970
00972
00974 void PerpedicularVectors(VEC3 *Out1, VEC3 *Out2, const VEC3 &v);
00975
00977
00978
00979
00980
00983
00985
00986 float TriangleArea(const VEC2 &p1, const VEC2 &p2, const VEC2 &p3);
00987 float TriangleArea(const VEC3 &p1, const VEC3 &p2, const VEC3 &p3);
00988
00990 bool TriangleIsCW(const VEC2 &p1, const VEC2 &p2, const VEC2 &p3);
00991
00993 float TrianglePerimeter(const VEC2 &p1, const VEC2 &p2, const VEC2 &p3);
00994 float TrianglePerimeter(const VEC3 &p1, const VEC3 &p2, const VEC3 &p3);
00995
00997
01000 inline void Barycentric(VEC2 *Out, const VEC2 &p1, const VEC2 &p2, const VEC2 &p3, float f, float g)
01001 {
01002 float e = 1.0f-f-g;
01003 Out->x = e*p1.x + f*p2.x + g*p3.x;
01004 Out->y = e*p1.y + f*p2.y + g*p3.y;
01005 }
01006 inline void Barycentric(VEC3 *Out, const VEC3 &p1, const VEC3 &p2, const VEC3 &p3, float f, float g)
01007 {
01008
01009
01010
01011
01012
01013
01014
01015 float e = 1.0f-f-g;
01016 Out->x = e*p1.x + f*p2.x + g*p3.x;
01017 Out->y = e*p1.y + f*p2.y + g*p3.y;
01018 Out->z = e*p1.z + f*p2.z + g*p3.z;
01019 }
01020 inline void Barycentric(VEC4 *Out, const VEC4 &p1, const VEC4 &p2, const VEC4 &p3, float f, float g)
01021 {
01022 float e = 1.0f-f-g;
01023 Out->x = e*p1.x + f*p2.x + g*p3.x;
01024 Out->y = e*p1.y + f*p2.y + g*p3.y;
01025 Out->z = e*p1.z + f*p2.z + g*p3.z;
01026 Out->w = e*p1.w + f*p2.w + g*p3.w;
01027 }
01028
01030
01032 void CalcBarycentric(const VEC2 &p, const VEC2 &p1, const VEC2 &p2, const VEC2 &p3, float *out_e, float *out_f, float *out_g);
01034
01037 void CalcBarycentric(const VEC3 &p, const VEC3 &p1, const VEC3 &p2, const VEC3 &p3, const VEC3 *Normal, float *out_e, float *out_f, float *out_g);
01038
01040 void TriangleInscribedCircle(VEC2 *OutCenter, float *OutRadius, const VEC2 &v1, const VEC2 &v2, const VEC2 &v3);
01041 void TriangleInscribedCircle(VEC3 *OutCenter, float *OutRadius, const VEC3 &v1, const VEC3 &v2, const VEC3 &v3);
01043 void TriangleCircumscribedCircle(VEC2 *OutCenter, float *OutRadius, const VEC2 &v1, const VEC2 &v2, const VEC2 &v3);
01044 void TriangleCircumscribedCircle(VEC3 *OutCenter, float *OutRadius, const VEC3 &v1, const VEC3 &v2, const VEC3 &v3);
01045
01047
01048
01049
01050
01053
01055 inline void PointOnRay(VEC2 *Out, const VEC2 &Origin, const VEC2 &Direction, float t)
01056 {
01057 Out->x = Origin.x + t * Direction.x;
01058 Out->y = Origin.y + t * Direction.y;
01059 }
01060 inline void PointOnRay(VEC3 *Out, const VEC3 &Origin, const VEC3 &Direction, float t)
01061 {
01062 Out->x = Origin.x + t * Direction.x;
01063 Out->y = Origin.y + t * Direction.y;
01064 Out->z = Origin.z + t * Direction.z;
01065 }
01066
01068
01069
01070
01071
01074
01076
01082 struct RECTI
01083 {
01084 POINT_ Min, Max;
01085
01086 RECTI() { }
01087 RECTI(const POINT_ &min_, const POINT_ &max_) : Min(min_), Max(max_) { }
01088 RECTI(int minX, int minY, int maxX, int maxY) : Min(minX, minY), Max(maxX, maxY) { }
01089 RECTI(const int *Arr) : Min(Arr[0], Arr[1]), Max(Arr[2], Arr[3]) { }
01090
01091 operator int * () { return &Min.x; }
01092 operator const int * () const { return &Min.x; }
01093
01094 bool operator == (const RECTI &r) const { return Min == r.Min && Max == r.Max; }
01095 bool operator != (const RECTI &r) const { return Min != r.Min || Max != r.Max; }
01096
01097 RECTI operator + () const { return *this; }
01098 RECTI operator - () const { return RECTI(-Max, -Min); }
01099 RECTI operator + (const POINT_ &p) const { return RECTI(Min+p, Max+p); }
01100 RECTI operator - (const POINT_ &p) const { return RECTI(Min-p, Max-p); }
01101 RECTI operator * (int s) const { return RECTI(Min*s, Max*s); }
01102 RECTI & operator += (const POINT_ &p) { Min += p; Max += p; return *this; }
01103 RECTI & operator -= (const POINT_ &p) { Min -= p; Max -= p; return *this; }
01104 RECTI & operator *= (int s) { Min *= s; Max *= s; return *this; }
01105
01106 int & left() { return Min.x; }
01107 int & top() { return Min.y; }
01108 int & right() { return Max.x; }
01109 int & bottom() { return Max.y; }
01110 int left() const { return Min.x; }
01111 int top() const { return Min.y; }
01112 int right() const { return Max.x; }
01113 int bottom() const { return Max.y; }
01114
01115 bool IsValid() const { return Min.x < Max.x && Min.y < Max.y; }
01116 void Repair()
01117 {
01118 if (Max.x < Min.x) std::swap(Min.x, Max.x);
01119 if (Max.y < Min.y) std::swap(Min.y, Max.y);
01120 }
01121
01123 void Extend(int d) { Min.x -= d; Min.y -= d; Max.x += d; Max.y += d; }
01125 float Diagonal() const { return sqrtf( (float)((Max.x-Min.x)*(Max.x-Min.x)) + (float)((Max.y-Min.y)*(Max.y-Min.y)) ); }
01127 int Field() const { return (Max.x-Min.x)*(Max.y-Min.y); }
01128
01129 void GetSize(POINT_ *out) const { *out = Max - Min; }
01130 int GetSizeDim(uint dim) const { return Max[dim] - Min[dim]; }
01131
01132 void GetHalfSize(POINT_ *out) { *out = (Max - Min) / 2; }
01133 int GetHalfSizeDim(uint dim) const { return (Max[dim] - Min[dim]) / 2; }
01134
01135 void SetSize(const POINT_ &newSize) { Max = Min + newSize; }
01136 void SetSizeDim(uint dim, int newSize) { Max[dim] = Min[dim] + newSize; }
01137
01138 void GetCenter(POINT_ *Out) const { *Out = (Min+Max)/2; }
01139 int GetCenterDim(uint dim) const { return (Min[dim]+Max[dim])/2; }
01140
01141 void GetCorner(POINT_ *out, uint i) const
01142 {
01143 out->x = (i & 1) ? Max.x : Min.x;
01144 out->y = (i & 2) ? Max.y : Min.y;
01145 }
01147 void GetEdge(POINT_ *outP1, POINT_ *outP2, uint index) const;
01148
01149 void AddInternalPoint(const POINT_ &p)
01150 {
01151 if (p.x < Min.x) Min.x = p.x;
01152 if (p.y < Min.y) Min.y = p.y;
01153 if (p.x > Max.x) Max.x = p.x;
01154 if (p.y > Max.y) Max.y = p.y;
01155 }
01156
01157 void AddInternalRect(const RECTI &rect)
01158 {
01159 if (rect.Min.x < Min.x) Min.x = rect.Min.x;
01160 if (rect.Min.y < Min.y) Min.y = rect.Min.y;
01161 if (rect.Max.x > Max.x) Max.x = rect.Max.x;
01162 if (rect.Max.y > Max.y) Max.y = rect.Max.y;
01163 }
01164 };
01165
01166 extern const RECTI RECTI_ZERO;
01167 extern const RECTI RECTI_ZERO_ONE;
01168 extern const RECTI RECTI_MINUS_ONE_ONE;
01169 extern const RECTI RECTI_MAX;
01170 extern const RECTI RECTI_INV_MAX;
01171
01173 struct RECTF
01174 {
01175 VEC2 Min, Max;
01176
01177 RECTF() { }
01178 RECTF(const VEC2 &min_, const VEC2 &max_) : Min(min_), Max(max_) { }
01179 RECTF(float minX, float minY, float maxX, float maxY) : Min(minX, minY), Max(maxX, maxY) { }
01180 RECTF(const float *Arr) : Min(Arr[0], Arr[1]), Max(Arr[2], Arr[3]) { }
01181
01182 operator float * () { return &Min.x; }
01183 operator const float * () const { return &Min.x; }
01184
01185 bool operator == (const RECTF &r) const { return Min == r.Min && Max == r.Max; }
01186 bool operator != (const RECTF &r) const { return Min != r.Min || Max != r.Max; }
01187
01188 RECTF operator + () const { return *this; }
01189 RECTF operator - () const { return RECTF(-Max, -Min); }
01190 RECTF operator + (const VEC2 &p) const { return RECTF(Min+p, Max+p); }
01191 RECTF operator - (const VEC2 &p) const { return RECTF(Min-p, Max-p); }
01192 RECTF operator * (float s) const { return RECTF(Min*s, Max*s); }
01193 RECTF operator / (float s) const { float sInv = 1.f/s; return RECTF(Min*sInv, Max*sInv); }
01194 RECTF & operator += (const VEC2 &p) { Min += p; Max += p; return *this; }
01195 RECTF & operator -= (const VEC2 &p) { Min -= p; Max -= p; return *this; }
01196 RECTF & operator *= (float s) { Min *= s; Max *= s; return *this; }
01197 RECTF & operator /= (float s) { float sInv = 1.f/s; Min *= sInv; Max *= sInv; return *this; }
01198
01199 float & left() { return Min.x; }
01200 float & top() { return Min.y; }
01201 float & right() { return Max.x; }
01202 float & bottom() { return Max.y; }
01203 float left() const { return Min.x; }
01204 float top() const { return Min.y; }
01205 float right() const { return Max.x; }
01206 float bottom() const { return Max.y; }
01207
01208 bool IsValid() const { return Min.x < Max.x && Min.y < Max.y; }
01209 void Repair()
01210 {
01211 if (Max.x < Min.x) std::swap(Min.x, Max.x);
01212 if (Max.y < Min.y) std::swap(Min.y, Max.y);
01213 }
01214
01216 void Extend(float d) { Min.x -= d; Min.y -= d; Max.x += d; Max.y += d; }
01218 float Diagonal() const { return sqrtf( sqr(Max.x-Min.x) + sqr(Max.y-Min.y) ); }
01220 float Field() const { return (Max.x-Min.x)*(Max.y-Min.y); }
01221
01222 void GetSize(VEC2 *out) const { *out = Max - Min; }
01223 float GetSizeDim(uint dim) const { return Max[dim] - Min[dim]; }
01224
01225 void GetHalfSize(VEC2 *out) { *out = (Max - Min) * 0.5f; }
01226 float GetHalfSizeDim(uint dim) const { return (Max[dim] - Min[dim]) * 0.5f; }
01227
01229 void SetSize(const VEC2 &newSize) { Max = Min + newSize; }
01230 void SetSizeDim(uint dim, float newSize) { Max[dim] = Min[dim] + newSize; }
01232 void GetCenter(VEC2 *Out) const { *Out = (Min+Max)*0.5f; }
01233 float GetCenterDim(uint dim) const { return (Min[dim]+Max[dim])*0.5f; }
01234
01235 void GetCorner(VEC2 *out, uint i) const
01236 {
01237 out->x = (i & 1) ? Max.x : Min.x;
01238 out->y = (i & 2) ? Max.y : Min.y;
01239 }
01241 void GetEdge(VEC2 *outP1, VEC2 *outP2, uint index) const;
01243 void GetQuad(RECTF *out, uint index) const;
01244
01245 void AddInternalPoint(const VEC2 &p)
01246 {
01247 if (p.x < Min.x) Min.x = p.x;
01248 if (p.y < Min.y) Min.y = p.y;
01249 if (p.x > Max.x) Max.x = p.x;
01250 if (p.y > Max.y) Max.y = p.y;
01251 }
01252
01253 void AddInternalRect(const RECTF &rect)
01254 {
01255 if (rect.Min.x < Min.x) Min.x = rect.Min.x;
01256 if (rect.Min.y < Min.y) Min.y = rect.Min.y;
01257 if (rect.Max.x > Max.x) Max.x = rect.Max.x;
01258 if (rect.Max.y > Max.y) Max.y = rect.Max.y;
01259 }
01260 };
01261
01262 extern const RECTF RECTF_ZERO;
01263 extern const RECTF RECTF_ZERO_ONE;
01264 extern const RECTF RECTF_MINUS_ONE_ONE;
01265 extern const RECTF RECTF_MAX;
01266 extern const RECTF RECTF_INV_MAX;
01267
01268 #ifdef WIN32
01270 template <> inline ::RECT & math_cast<::RECT, RECTI>(const RECTI &x) { return (::RECT&)(x); }
01272 template <> inline RECTI & math_cast<RECTI, ::RECT>(const ::RECT &x) { return (RECTI&)(x); }
01273 #endif
01274
01275 inline void swap(RECTI &r1, RECTI &r2)
01276 {
01277 std::swap(r1.Min.x, r2.Min.x); std::swap(r1.Min.y, r2.Min.y);
01278 std::swap(r1.Max.x, r2.Max.x); std::swap(r1.Max.y, r2.Max.y);
01279 }
01280
01281 inline void swap(RECTF &r1, RECTF &r2)
01282 {
01283 std::swap(r1.Min, r2.Min);
01284 std::swap(r1.Max, r2.Max);
01285 }
01286
01287 inline void Mul(RECTI *out, const RECTI &rect, const POINT_ &v)
01288 {
01289 Mul(&out->Min, rect.Min, v);
01290 Mul(&out->Max, rect.Max, v);
01291 }
01292 inline void Mul(RECTF *out, const RECTF &rect, const VEC2 &v)
01293 {
01294 Mul(&out->Min, rect.Min, v);
01295 Mul(&out->Max, rect.Max, v);
01296 }
01297 inline void Div(RECTI *out, const RECTI &rect, const POINT_ &v)
01298 {
01299 Div(&out->Min, rect.Min, v);
01300 Div(&out->Max, rect.Max, v);
01301 }
01302 inline void Div(RECTF *out, const RECTF &rect, const VEC2 &v)
01303 {
01304 Div(&out->Min, rect.Min, v);
01305 Div(&out->Max, rect.Max, v);
01306 }
01307
01308 inline void Mul(RECTI *inout, const POINT_ &v)
01309 {
01310 Mul(&inout->Min, v);
01311 Mul(&inout->Max, v);
01312 }
01313 inline void Mul(RECTF *inout, const VEC2 &v)
01314 {
01315 Mul(&inout->Min, v);
01316 Mul(&inout->Max, v);
01317 }
01318 inline void Div(RECTI *inout, const POINT_ &v)
01319 {
01320 Div(&inout->Min, v);
01321 Div(&inout->Max, v);
01322 }
01323 inline void Div(RECTF *inout, const VEC2 &v)
01324 {
01325 Div(&inout->Min, v);
01326 Div(&inout->Max, v);
01327 }
01328
01330 inline bool PointInRect(const POINT_ &p, const RECTI &r)
01331 {
01332 return
01333 (p.x >= r.Min.x) &&
01334 (p.x <= r.Max.x) &&
01335 (p.y >= r.Min.y) &&
01336 (p.y <= r.Max.y);
01337 }
01338 inline bool PointInRect(const VEC2 &p, const RECTF &r)
01339 {
01340 return
01341 (p.x >= r.Min.x) &&
01342 (p.x <= r.Max.x) &&
01343 (p.y >= r.Min.y) &&
01344 (p.y <= r.Max.y);
01345 }
01346
01348 inline bool RectInRect(const RECTI &sr, const RECTI &r)
01349 {
01350 return
01351 (sr.Min.x >= r.Min.x) &&
01352 (sr.Max.x <= r.Max.x) &&
01353 (sr.Min.y >= r.Min.y) &&
01354 (sr.Max.y <= r.Max.y);
01355 }
01356 inline bool RectInRect(const RECTF &sr, const RECTF &r)
01357 {
01358 return
01359 (sr.Min.x >= r.Min.x) &&
01360 (sr.Max.x <= r.Max.x) &&
01361 (sr.Min.y >= r.Min.y) &&
01362 (sr.Max.y <= r.Max.y);
01363 }
01364
01366 inline bool RectToRect(const RECTI &r1, const RECTI &r2)
01367 {
01368 return
01369 (r1.Min.x <= r2.Max.x) &&
01370 (r1.Max.x >= r2.Min.x) &&
01371 (r1.Min.y <= r2.Max.y) &&
01372 (r1.Max.y >= r2.Min.y);
01373 }
01374 inline bool RectToRect(const RECTF &r1, const RECTF &r2)
01375 {
01376 return
01377 (r1.Min.x <= r2.Max.x) &&
01378 (r1.Max.x >= r2.Min.x) &&
01379 (r1.Min.y <= r2.Max.y) &&
01380 (r1.Max.y >= r2.Min.y);
01381 }
01382
01384 inline bool Intersection(RECTI *Out, const RECTI &r1, const RECTI &r2)
01385 {
01386 *Out = RECTI(
01387 std::max(r1.Min.x, r2.Min.x),
01388 std::max(r1.Min.y, r2.Min.y),
01389 std::min(r1.Max.x, r2.Max.x),
01390 std::min(r1.Max.y, r2.Max.y));
01391 return Out->IsValid();
01392 }
01393 inline bool Intersection(RECTF *Out, const RECTF &r1, const RECTF &r2)
01394 {
01395 *Out = RECTF(
01396 std::max(r1.Min.x, r2.Min.x),
01397 std::max(r1.Min.y, r2.Min.y),
01398 std::min(r1.Max.x, r2.Max.x),
01399 std::min(r1.Max.y, r2.Max.y));
01400 return Out->IsValid();
01401 }
01402
01404 inline void Union(RECTI *Out, const RECTI &r1, const RECTI &r2)
01405 {
01406 Out->Min.x = std::min(r1.Min.x, r2.Min.x);
01407 Out->Min.y = std::min(r1.Min.y, r2.Min.y);
01408 Out->Max.x = std::max(r1.Max.x, r2.Max.x);
01409 Out->Max.y = std::max(r1.Max.y, r2.Max.y);
01410 }
01411 inline void Union(RECTF *Out, const RECTF &r1, const RECTF &r2)
01412 {
01413 Out->Min.x = std::min(r1.Min.x, r2.Min.x);
01414 Out->Min.y = std::min(r1.Min.y, r2.Min.y);
01415 Out->Max.x = std::max(r1.Max.x, r2.Max.x);
01416 Out->Max.y = std::max(r1.Max.y, r2.Max.y);
01417 }
01418
01419 inline void Lerp(RECTF *out, const RECTF &v1, const RECTF &v2, float t)
01420 {
01421 out->Min.x = Lerp(v1.Min.x, v2.Min.x, t);
01422 out->Min.y = Lerp(v1.Min.y, v2.Min.y, t);
01423 out->Max.x = Lerp(v1.Max.x, v2.Max.x, t);
01424 out->Max.y = Lerp(v1.Max.y, v2.Max.y, t);
01425 }
01426
01428
01429 void ClosestPointInRect(POINT_ *Out, const RECTI &Rect, const POINT_ &p);
01431
01432 void ClosestPointInRect(VEC2 *Out, const RECTF &Rect, const VEC2 &p);
01433
01435
01436
01437
01438
01442
01444
01448 struct BOX
01449 {
01450 VEC3 Min, Max;
01451
01452 BOX() { }
01453 BOX(const VEC3 &Min, const VEC3 &Max) : Min(Min), Max(Max) { }
01454 BOX(float p1x, float p1y, float p1z, float p2x, float p2y, float p2z) : Min(p1x, p1y, p1z), Max(p2x, p2y, p2z) { }
01455 BOX(const float *Arr) : Min(&Arr[0]), Max(&Arr[3]) { }
01456
01457 operator float * () { return &Min.x; }
01458 operator const float * () const { return &Min.x; }
01459
01460 bool operator == (const BOX &p) const { return Min == p.Min && Max == p.Max; }
01461 bool operator != (const BOX &p) const { return Min != p.Min || Max != p.Max; }
01462
01463 BOX operator + () const { return *this; }
01464 BOX operator - () const { return BOX(-Max, -Min); }
01465 BOX operator + (const VEC3 &v) const { return BOX(Min+v, Max+v); }
01466 BOX operator - (const VEC3 &v) const { return BOX(Min-v, Max-v); }
01467 BOX operator * (float f) const { return BOX(Min*f, Max*f); }
01468 BOX operator / (float f) const { float fInv = 1.f/f; return BOX(Min*fInv, Max*fInv); }
01469 BOX & operator += (const VEC3 &v) { Min += v; Max += v; return *this; }
01470 BOX & operator -= (const VEC3 &v) { Min -= v; Max -= v; return *this; }
01471 BOX & operator *= (float f) { Min *= f; Max *= f; return *this; }
01472 BOX & operator /= (float f) { float fInv = 1.f/f; Min *= fInv; Max *= fInv; return *this; }
01473
01474 bool IsValid() { return Less(Min, Max); }
01475 void Repair()
01476 {
01477 if (Max.x < Min.x) std::swap(Min.x, Max.x);
01478 if (Max.y < Min.y) std::swap(Min.y, Max.y);
01479 if (Max.z < Min.z) std::swap(Min.z, Max.z);
01480 }
01481
01483 void Extend(float d) { Min.x -= d; Min.y -= d; Min.z -= d; Max.x += d; Max.y += d; Max.z += d; }
01485 void GetSize(VEC3 *Out) const { Out->x = Max.x-Min.x; Out->y = Max.y-Min.y; Out->z = Max.z-Min.z; }
01486 float GetSizeDim(uint dim) const { return Max[dim]-Min[dim]; }
01488 void SetSize(const VEC3 &NewSize) { Max.x = Min.x + NewSize.x; Max.y = Min.y + NewSize.y; Max.z = Min.z + NewSize.z; }
01489 void SetSizeDim(uint dim, float newSize) { Max[dim] = Min[dim] + newSize; }
01491 float Diagonal() const { return sqrtf( (Max.x-Min.x)*(Max.x-Min.x) + (Max.y-Min.y)*(Max.y-Min.y) + (Max.z-Min.z)*(Max.z-Min.z) ); }
01493 float Volume() const { return (Max.x-Min.x)*(Max.y-Min.y)*(Max.z-Min.z); }
01495 void GetCenter(VEC3 *Out) const { Out->x = (Min.x+Max.x)*0.5f; Out->y = (Min.y+Max.y)*0.5f; Out->z = (Min.z+Max.z)*0.5f; }
01496 float GetCenterDim(uint dim) const { return (Min[dim]+Max[dim])*0.5f; }
01498 void GetHalfSize(VEC3 *OutHalfSize) const {
01499 OutHalfSize->x = (Max.x-Min.x)*0.5f;
01500 OutHalfSize->y = (Max.y-Min.y)*0.5f;
01501 OutHalfSize->z = (Max.z-Min.z)*0.5f;
01502 }
01503 float GetHalfSizeDim(uint dim) { return (Max[dim]-Min[dim])*0.5f; }
01505 void GetCorner(VEC3 *Out, uint i) const
01506 {
01507 Out->x = (i & 1) ? Max.x : Min.x;
01508 Out->y = (i & 2) ? Max.y : Min.y;
01509 Out->z = (i & 4) ? Max.z : Min.z;
01510 }
01512
01519 void GetAllCorners(VEC3 *Out) const
01520 {
01521 Out[0] = VEC3(Min.x, Min.y, Min.z); Out[1] = VEC3(Max.x, Min.y, Min.z); Out[2] = VEC3(Min.x, Max.y, Min.z); Out[3] = VEC3(Max.x, Max.y, Min.z);
01522 Out[4] = VEC3(Min.x, Min.y, Max.z); Out[5] = VEC3(Max.x, Min.y, Max.z); Out[6] = VEC3(Min.x, Max.y, Max.z); Out[7] = VEC3(Max.x, Max.y, Max.z);
01523 }
01525 void GetEdge(VEC3 *outP1, VEC3 *outP2, uint index) const;
01527 void GetOct(BOX *out, uint index) const;
01528
01530 void AddInternalPoint(const VEC3 &p)
01531 {
01532 Min.x = std::min(Min.x, p.x); Min.y = std::min(Min.y, p.y); Min.z = std::min(Min.z, p.z);
01533 Max.x = std::max(Max.x, p.x); Max.y = std::max(Max.y, p.y); Max.z = std::max(Max.z, p.z);
01534 }
01536
01537 void AddInternalBox(const BOX &b)
01538 {
01539 Min.x = std::min(Min.x, b.Min.x); Min.y = std::min(Min.y, b.Min.y); Min.z = std::min(Min.z, b.Min.z);
01540 Max.x = std::max(Max.x, b.Max.x); Max.y = std::max(Max.y, b.Max.y); Max.z = std::max(Max.z, b.Max.z);
01541 }
01542 };
01543
01544 extern const BOX BOX_ZERO;
01545 extern const BOX BOX_ZERO_ONE;
01546 extern const BOX BOX_MINUS_ONE_ONE;
01547 extern const BOX BOX_MAX;
01548 extern const BOX BOX_INV_MAX;
01549
01550
01551 inline void swap(BOX &b1, BOX &b2)
01552 {
01553 std::swap(b1.Min, b2.Min);
01554 std::swap(b1.Max, b2.Max);
01555 }
01556
01557 inline void Mul(BOX *Out, const BOX &b, const VEC3 &v)
01558 {
01559 Mul(&Out->Max, b.Max, v);
01560 Mul(&Out->Max, b.Max, v);
01561 }
01562 inline void Div(BOX *Out, const BOX &b, const VEC3 &v)
01563 {
01564 Div(&Out->Max, b.Max, v);
01565 Div(&Out->Max, b.Max, v);
01566 }
01567
01568 inline void Mul(BOX *inout, const VEC3 &v)
01569 {
01570 Mul(&inout->Max, v);
01571 Mul(&inout->Max, v);
01572 }
01573 inline void Div(BOX *inout, const VEC3 &v)
01574 {
01575 Div(&inout->Max, v);
01576 Div(&inout->Max, v);
01577 }
01578
01580 inline bool PointInBox(const VEC3 &p, const BOX &b)
01581 {
01582 return
01583 (p.x >= b.Min.x) && (p.x <= b.Max.x) &&
01584 (p.y >= b.Min.y) && (p.y <= b.Max.y) &&
01585 (p.z >= b.Min.z) && (p.z <= b.Max.z);
01586 }
01587
01589 inline bool BoxInBox(const BOX &sb, const BOX &b)
01590 {
01591 return
01592 (sb.Min.x >= b.Min.x) && (sb.Max.x <= b.Max.x) &&
01593 (sb.Min.y >= b.Min.y) && (sb.Max.y <= b.Max.y) &&
01594 (sb.Min.z >= b.Min.z) && (sb.Max.z <= b.Max.z);
01595 }
01596
01598 inline bool BoxToBox(const BOX &b1, const BOX &b2)
01599 {
01600 return
01601 (b1.Min.x <= b2.Max.x) && (b1.Max.x >= b2.Min.x) &&
01602 (b1.Min.y <= b2.Max.y) && (b1.Max.y >= b2.Min.y) &&
01603 (b1.Min.z <= b2.Max.z) && (b1.Max.z >= b2.Min.z);
01604 }
01605
01607 inline bool Intersection(BOX *Out, const BOX &b1, const BOX &b2)
01608 {
01609 *Out = BOX(
01610 VEC3(
01611 std::max(b1.Min.x, b2.Min.x),
01612 std::max(b1.Min.y, b2.Min.y),
01613 std::max(b1.Min.z, b2.Min.z)),
01614 VEC3(
01615 std::min(b1.Max.x, b2.Max.x),
01616 std::min(b1.Max.y, b2.Max.y),
01617 std::min(b1.Max.z, b2.Max.z)));
01618 return Out->IsValid();
01619 }
01620
01622 inline void Union(BOX *Out, const BOX &b1, const BOX &b2)
01623 {
01624 *Out = BOX(
01625 VEC3(
01626 std::min(b1.Min.x, b2.Min.x),
01627 std::min(b1.Min.y, b2.Min.y),
01628 std::min(b1.Min.z, b2.Min.z)),
01629 VEC3(
01630 std::max(b1.Max.x, b2.Max.x),
01631 std::max(b1.Max.y, b2.Max.y),
01632 std::max(b1.Max.z, b2.Max.z)));
01633 }
01634 inline void Lerp(BOX *out, const BOX &v1, const BOX &v2, float t)
01635 {
01636 Lerp(&out->Min, v1.Min, v2.Min, t);
01637 Lerp(&out->Max, v1.Max, v2.Max, t);
01638 }
01639
01641
01642
01643
01644
01648
01650 struct OBB
01651 {
01653 VEC3 Center;
01655 VEC3 HalfSize;
01657
01658 VEC3 Axes[3];
01659 };
01660
01662 bool ObbToObb(const OBB &a, const OBB &b);
01663
01665
01666
01667
01668
01672
01674 struct RECT3D
01675 {
01677 VEC3 Center;
01679 VEC2 HalfSize;
01681
01682 VEC3 Axes[2];
01683 };
01684
01686
01687
01688
01689
01694
01696
01701 struct COLOR
01702 {
01703 union
01704 {
01706 uint4 ARGB;
01708 PACKED struct
01709 {
01710 uint1 B, G, R, A;
01711 };
01712 };
01713
01714 COLOR() { }
01715 COLOR(uint4 c) : ARGB(c) { }
01716 COLOR(unsigned long c) : ARGB((uint4)c) { }
01717 COLOR(uint1 R, uint1 G, uint1 B) : B(B), G(G), R(R), A(0xFF) { }
01718 COLOR(uint1 A, uint1 R, uint1 G, uint1 B) : B(B), G(G), R(R), A(A) { }
01719
01720 bool operator == (COLOR c) const { return ARGB == c.ARGB; }
01721 bool operator != (COLOR c) const { return ARGB != c.ARGB; }
01722
01723
01724 COLOR operator + () const { return *this; }
01725 COLOR operator - () const { return COLOR(~ARGB); }
01726
01727 COLOR operator + (const COLOR &c) const { return COLOR(safe_add(A, c.A), safe_add(R, c.R), safe_add(G, c.G), safe_add(B, c.B)); }
01728 COLOR operator - (const COLOR &c) const { return COLOR(safe_sub(A, c.A), safe_sub(R, c.R), safe_sub(G, c.G), safe_sub(B, c.B)); }
01729 COLOR & operator += (const COLOR &c) { A = safe_add(A, c.A); R = safe_add(R, c.R); G = safe_add(G, c.G); B = safe_add(B, c.B); return *this; }
01730 COLOR & operator -= (const COLOR &c) { A = safe_sub(A, c.A); R = safe_sub(R, c.R); G = safe_sub(G, c.G); B = safe_sub(B, c.B); return *this; }
01731
01732
01733 COLOR operator * (float s) const { return COLOR( (uint1)(minmax(0, (int)(A*s), 255)), (uint1)(minmax(0, (int)(R*s), 255)), (uint1)(minmax(0, (int)(G*s), 255)), (uint1)(minmax(0, (int)(B*s), 255)) ); }
01734 COLOR operator / (float s) const { float sInv = 1.0f/s; return COLOR( (uint1)(minmax(0, (int)(A*sInv), 255)), (uint1)(minmax(0, (int)(R*sInv), 255)), (uint1)(minmax(0, (int)(G*sInv), 255)), (uint1)(minmax(0, (int)(B*sInv), 255)) ); }
01735 COLOR & operator *= (float s) { A = (uint1)(minmax(0, (int)(A*s), 255)); R = (uint1)(minmax(0, (int)(R*s), 255)); G = (uint1)(minmax(0, (int)(G*s), 255)); B = (uint1)(minmax(0, (int)(B*s), 255)); return *this; }
01736 COLOR & operator /= (float s) { float sInv = 1.0f/s; A = (uint1)(minmax(0, (int)(A*sInv), 255)); R = (uint1)(minmax(0, (int)(R*sInv), 255)); G = (uint1)(minmax(0, (int)(G*sInv), 255)); B = (uint1)(minmax(0, (int)(B*sInv), 255)); return *this; }
01737
01738 COLOR operator * (const COLOR &c) const { return COLOR( (uint1)(((int)A*(int)c.A)/255), (uint1)(((int)R*(int)c.R)/255), (uint1)(((int)G*(int)c.G)/255), (uint1)(((int)B*(int)c.B)/255) ); }
01739 COLOR & operator *= (const COLOR &c) { A = (uint1)(((int)A*(int)c.A)/255); R = (uint1)(((int)R*(int)c.R)/255); G = (uint1)(((int)G*(int)c.G)/255); B = (uint1)(((int)B*(int)c.B)/255); return *this; }
01740 };
01741
01742 extern const COLOR COLOR_TRANSPARENT_;
01743 extern const COLOR COLOR_BLACK;
01744 extern const COLOR COLOR_GRAY;
01745 extern const COLOR COLOR_SILVER;
01746 extern const COLOR COLOR_WHITE;
01747 extern const COLOR COLOR_FUCHSIA;
01748 extern const COLOR COLOR_RED;
01749 extern const COLOR COLOR_ORANGE;
01750 extern const COLOR COLOR_YELLOW;
01751 extern const COLOR COLOR_LIME;
01752 extern const COLOR COLOR_AQUA;
01753 extern const COLOR COLOR_BLUE;
01754 extern const COLOR COLOR_PURPLE;
01755 extern const COLOR COLOR_MAROON;
01756 extern const COLOR COLOR_OLIVE;
01757 extern const COLOR COLOR_GREEN;
01758 extern const COLOR COLOR_TEAL;
01759
01761
01766 struct COLORF
01767 {
01768 float R, G, B, A;
01769
01770 COLORF() { }
01771 COLORF(float R, float G, float B) : R(R), G(G), B(B), A(1.0f) { }
01772 COLORF(float A, float R, float G, float B) : R(R), G(G), B(B), A(A) { }
01773 COLORF(const float *Arr) : R(Arr[0]), G(Arr[1]), B(Arr[2]), A(Arr[3]) { }
01774
01775 operator float * () { return &R; }
01776 operator const float * () const { return &R; }
01777
01778 bool operator == (const COLORF &c) const { return A == c.A && R == c.R && G == c.G && B == c.B; }
01779 bool operator != (const COLORF &c) const { return A != c.A || R != c.R || G != c.G || B != c.B; }
01780
01781
01782 COLORF operator + () const { return *this; }
01783 COLORF operator - () const { return COLORF(1.0f-A, 1.0f-R, 1.0f-G, 1.0f-B); }
01784
01785 COLORF operator + (const COLORF &c) const { return COLORF(A+c.A, R+c.R, G+c.G, B+c.B); }
01786 COLORF operator - (const COLORF &c) const { return COLORF(A-c.A, R-c.R, G-c.G, B-c.B); }
01787 COLORF & operator += (const COLORF &c) { A += c.A; R += c.R; G += c.G; B += c.B; return *this; }
01788 COLORF & operator -= (const COLORF &c) { A -= c.A; R -= c.R; G -= c.G; B -= c.B; return *this; }
01789
01790 COLORF operator * (float s) const { return COLORF(A*s, R*s, G*s, B*s); }
01791 COLORF operator / (float s) const { float sInv = 1.0f/s; return COLORF(A*sInv, R*sInv, G*sInv, B*sInv); }
01792 COLORF & operator *= (float s) { A *= s; R *= s; G *= s; B *= s; return *this; }
01793 COLORF & operator /= (float s) { float sInv = 1.0f/s; A *= sInv; R *= sInv; G *= sInv; B *= sInv; return *this; }
01794
01795 COLORF operator * (const COLORF &c) const { return COLORF(A*c.A, R*c.R, G*c.G, B*c.B); }
01796 COLORF & operator *= (const COLORF &c) { A *= c.A; R *= c.R; G *= c.G; B *= c.B; return *this; }
01797
01799 bool IsValid() const { return (A >= 0.0f && A <= 1.0f) && (R >= 0.0f && R <= 1.0f) && (G >= 0.0f && G <= 1.0f) && (B >= 0.0f && B <= 1.0f); }
01801 void Repair()
01802 {
01803 A = minmax(0.0f, A, 1.0f); R = minmax(0.0f, R, 1.0f);
01804 G = minmax(0.0f, G, 1.0f); B = minmax(0.0f, B, 1.0f);
01805 }
01806 };
01807
01808 inline void swap(COLORF &c1, COLORF &c2)
01809 {
01810 std::swap(c1.A, c2.A); std::swap(c1.R, c2.R);
01811 std::swap(c1.G, c2.G); std::swap(c1.B, c2.B);
01812 }
01813
01814 extern const COLORF COLORF_TRANSPARENT_;
01815 extern const COLORF COLORF_BLACK;
01816 extern const COLORF COLORF_GRAY;
01817 extern const COLORF COLORF_SILVER;
01818 extern const COLORF COLORF_WHITE;
01819 extern const COLORF COLORF_FUCHSIA;
01820 extern const COLORF COLORF_RED;
01821 extern const COLORF COLORF_ORANGE;
01822 extern const COLORF COLORF_YELLOW;
01823 extern const COLORF COLORF_LIME;
01824 extern const COLORF COLORF_AQUA;
01825 extern const COLORF COLORF_BLUE;
01826 extern const COLORF COLORF_PURPLE;
01827 extern const COLORF COLORF_MAROON;
01828 extern const COLORF COLORF_OLIVE;
01829 extern const COLORF COLORF_GREEN;
01830 extern const COLORF COLORF_TEAL;
01831
01832 inline COLORF operator * (float s, const COLORF &c) { return COLORF(c.A*s, c.R*s, c.G*s, c.B*s); }
01833 inline COLORF operator / (float s, const COLORF &c) { float sInv = 1.0f/s; return COLORF(c.A*sInv, c.R*sInv, c.G*sInv, c.B*sInv); }
01834
01835 inline COLOR operator * (float s, const COLOR &c) { return COLOR( (uint1)(minmax(0, (int)(c.A*s), 255)), (uint1)(minmax(0, (int)(c.R*s), 255)), (uint1)(minmax(0, (int)(c.G*s), 255)), (uint1)(minmax(0, (int)(c.B*s), 255)) ); }
01836 inline COLOR operator / (float s, const COLOR &c) { float sInv = 1.0f/s; return COLOR( (uint1)(minmax(0, (int)(c.A*sInv), 255)), (uint1)(minmax(0, (int)(c.R*sInv), 255)), (uint1)(minmax(0, (int)(c.G*sInv), 255)), (uint1)(minmax(0, (int)(c.B*sInv), 255)) ); }
01837
01838 template <> inline uint4 & math_cast<uint4, COLOR>(const COLOR &x) { return (uint4&)(x); }
01839 template <> inline unsigned long & math_cast<unsigned long, COLOR>(const COLOR &x) { return (unsigned long&)(x); }
01840 template <> inline COLOR & math_cast<COLOR, uint4>(const uint4 &x) { return (COLOR&)(x); }
01841 template <> inline COLOR & math_cast<COLOR, unsigned long>(const unsigned long &x) { return (COLOR&)(x); }
01842
01843 #ifdef USE_DIRECTX
01844 template <> inline D3DXCOLOR & math_cast<D3DXCOLOR, COLORF>(const COLORF &x) { return (D3DXCOLOR&)(x); }
01845 template <> inline COLORF & math_cast<COLORF, D3DXCOLOR>(const D3DXCOLOR &x) { return (COLORF&)(x); }
01846 #endif
01847
01849 inline void ColorToColorf(COLORF *Out, COLOR c)
01850 {
01851 Out->R = c.R / 255.0f;
01852 Out->G = c.G / 255.0f;
01853 Out->B = c.B / 255.0f;
01854 Out->A = c.A / 255.0f;
01855 }
01857 inline COLOR ColorfToColor(const COLORF &c)
01858 {
01859 return COLOR(
01860 (uint1)(minmax(0.0f, c.A, 1.0f)*255.0f+0.5f),
01861 (uint1)(minmax(0.0f, c.R, 1.0f)*255.0f+0.5f),
01862 (uint1)(minmax(0.0f, c.G, 1.0f)*255.0f+0.5f),
01863 (uint1)(minmax(0.0f, c.B, 1.0f)*255.0f+0.5f));
01864 }
01865
01867
01873 void ColorToStr(tstring *Out, COLOR Color, char Format = 'X');
01874 void ColorToStr(tstring *Out, const COLORF &Color, char Format = 'F');
01876
01884 bool StrToColor(COLOR *Out, const tstring &Str);
01885 bool StrToColor(COLORF *Out, const tstring &Str);
01886
01887 inline void Add(COLORF *Out, const COLORF &c1, const COLORF &c2)
01888 {
01889 Out->A = c1.A + c2.A; Out->R = c1.R + c2.R;
01890 Out->G = c1.G + c2.G; Out->B = c1.B + c2.B;
01891 }
01892 inline void Sub(COLORF *Out, const COLORF &c1, const COLORF &c2)
01893 {
01894 Out->A = c1.A - c2.A; Out->R = c1.R - c2.R;
01895 Out->G = c1.G - c2.G; Out->B = c1.B - c2.B;
01896 }
01897 inline void Mul(COLORF *Out, const COLORF &c1, const COLORF &c2)
01898 {
01899 Out->A = c1.A * c2.A; Out->R = c1.R * c2.R;
01900 Out->G = c1.G * c2.G; Out->B = c1.B * c2.B;
01901 }
01902 inline void Mul(COLORF *inout, const COLORF &c)
01903 {
01904 inout->A *= c.A; inout->R *= c.R;
01905 inout->G *= c.G; inout->B *= c.B;
01906 }
01907 inline void Mul(COLORF *Out, const COLORF &c, float s)
01908 {
01909 Out->A = c.A * s; Out->R = c.R * s;
01910 Out->G = c.G * s; Out->B = c.B * s;
01911 }
01912 inline void Div(COLORF *Out, const COLORF &c, float s)
01913 {
01914 Out->A = c.A / s; Out->R = c.R / s;
01915 Out->G = c.G / s; Out->B = c.B / s;
01916 }
01917 inline void Negative(COLORF *Out, const COLORF &c)
01918 {
01919 Out->A = 1.0f - c.A; Out->R = 1.0f - c.R;
01920 Out->G = 1.0f - c.G; Out->B = 1.0f - c.B;
01921 }
01922
01924 inline COLOR ARGB_ABGR(COLOR color)
01925 {
01926 return COLOR(
01927 (color.ARGB & 0xFF00FF00) |
01928 ((color.ARGB >> 16) & 0x000000FF) |
01929 ((color.ARGB & 0x000000FF) << 16)
01930 );
01931 }
01932
01934 inline uint2 ColorToR5G6B5(COLOR color)
01935 {
01936 return
01937 ((unsigned short)(color.R >> 3) << 11) |
01938 ((unsigned short)(color.G >> 2) << 5) |
01939 ((unsigned short)(color.B >> 3));
01940 }
01941
01943 inline COLOR R5G6B5ToColor(uint2 color)
01944 {
01945 return COLOR(
01946 255,
01947 (uint1)(color >> 11 << 3),
01948 (uint1)(color >> 5 << 2),
01949 (uint1)(color << 3));
01950 }
01951
01952 inline void Lerp(COLORF *Out, const COLORF &c1, const COLORF &c2, float t)
01953 {
01954 Out->A = Lerp(c1.A, c2.A, t);
01955 Out->R = Lerp(c1.R, c2.R, t);
01956 Out->G = Lerp(c1.G, c2.G, t);
01957 Out->B = Lerp(c1.B, c2.B, t);
01958 }
01959 inline COLOR Lerp(COLOR c1, COLOR c2, float t)
01960 {
01961 return COLOR(
01962 (uint1)(minmax(0, (int)(c1.A + t*((float)c2.A-(float)c1.A)), 255)),
01963 (uint1)(minmax(0, (int)(c1.R + t*((float)c2.R-(float)c1.R)), 255)),
01964 (uint1)(minmax(0, (int)(c1.G + t*((float)c2.G-(float)c1.G)), 255)),
01965 (uint1)(minmax(0, (int)(c1.B + t*((float)c2.B-(float)c1.B)), 255)) );
01966 }
01967 inline void saturate(COLORF &v)
01968 {
01969 v.R = saturate(v.R); v.G = saturate(v.G); v.B = saturate(v.B); v.A = saturate(v.A);
01970 }
01971
01973
01977 void HsbToRgb(COLORF *Out, float hue, float saturation, float brightness);
01979 void RgbToHsb(float *OutHue, float *OutSaturation, float *OutBrightness, const COLORF &Color);
01980
01982
01983 inline void ColorRainbow(COLORF *Out, float t)
01984 {
01985 HsbToRgb(Out, t*0.75f, 1.0f, 1.0f);
01986 }
01987
01989 inline float ColorToGrayscale(const COLORF &c)
01990 {
01991 return 0.299f * c.R + 0.587f * c.G + 0.114f * c.B;
01992 }
01993 inline float ColorToGrayscale(COLOR &c)
01994 {
01995 return 0.299f * (c.R/255.0f) + 0.587f * (c.G/255.0f) + 0.114f * (c.B/255.0f);
01996 }
01997
01999 inline void GrayscaleToColor(COLORF *Out, float t)
02000 {
02001 Out->A = 1.0f;
02002 Out->R = Out->G = Out->B = t;
02003 }
02004 inline void GrayscaleToColor(COLOR *Out, float t)
02005 {
02006 Out->A = 255;
02007 Out->R = Out->G = Out->B = (uint1)(t*255.0f);
02008 }
02009
02011
02015 inline void AdjustContrast(COLORF *Color, float t)
02016 {
02017 Color->R = 0.5f + t * (Color->R - 0.5f);
02018 Color->G = 0.5f + t * (Color->G - 0.5f);
02019 Color->B = 0.5f + t * (Color->B - 0.5f);
02020 }
02021
02023
02027 inline void AdjustSaturation(COLORF *Color, float t)
02028 {
02029 float gray = ColorToGrayscale(*Color);
02030 Color->R = gray + t * (Color->R - gray);
02031 Color->G = gray + t * (Color->G - gray);
02032 Color->B = gray + t * (Color->B - gray);
02033 }
02034
02036 inline COLOR VectorToColor(const VEC3 &v)
02037 {
02038 int R = minmax(0, (int)(127.0f * v.x + 128.0f), 255);
02039 int G = minmax(0, (int)(127.0f * v.y + 128.0f), 255);
02040 int B = minmax(0, (int)(127.0f * v.z + 128.0f), 255);
02041 return COLOR((uint4)((R << 16) | (G << 8) | B));
02042 }
02043
02045 inline void ColorToVector(VEC3 *Out, COLOR color)
02046 {
02047 const float o = 1.0f / 127.0f;
02048 Out->x = (((color.ARGB >> 16) & 0xFF) - 128.0f) * o;
02049 Out->y = (((color.ARGB >> 8) & 0xFF) - 128.0f) * o;
02050 Out->z = (((color.ARGB ) & 0xFF) - 128.0f) * o;
02051 }
02052
02054 inline uint ColorDistance(COLOR Color1, COLOR Color2)
02055 {
02056 int rd = (int)Color1.R - (int)Color2.R;
02057 int gd = (int)Color1.G - (int)Color2.G;
02058 int bd = (int)Color1.B - (int)Color2.B;
02059 return (uint)(rd*rd + gd*gd + bd*bd);
02060 }
02061
02063 inline VEC4 ColorfToVec4(const COLORF &c) { return VEC4(c.R, c.G, c.B, c.A); }
02065 inline COLORF Vec4ToColorf(const VEC4 &v) { return COLORF(v.w, v.x, v.y, v.z); }
02066
02068
02069
02070
02071
02074
02075 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
02076 typedef D3DXPLANE PLANE;
02077 #else
02079
02088 struct PLANE
02089 {
02090 float a, b, c, d;
02091
02092 PLANE() { }
02093 PLANE(float a, float b, float c, float d) : a(a), b(b), c(c), d(d) { }
02094 PLANE(const float *Arr) : a(Arr[0]), b(Arr[1]), c(Arr[2]), d(Arr[3]) { }
02095
02096 operator float * () { return &a; }
02097 operator const float * () const { return &a; }
02098
02099 bool operator == (const PLANE &p) const { return a == p.a && b == p.b && c == p.c && d == p.d; }
02100 bool operator != (const PLANE &p) const { return a != p.a || b != p.b || c != p.c || d != p.d; }
02101
02102 PLANE operator + () const { return *this; }
02104 PLANE operator - () const { return PLANE(-a, -b, -c, -d); }
02105
02106 PLANE operator * (float s) const { return PLANE(a*s, b*s, c*s, d*s); }
02107 PLANE operator / (float s) const { float sInv = 1.0f/s; return PLANE(a*sInv, b*sInv, c*sInv, d*sInv); }
02108 PLANE & operator *= (float s) { a *= s; b *= s; c *= s; d *= s; return *this; }
02109 PLANE & operator /= (float s) { float sInv = 1.0f/s; a *= sInv; b *= sInv; c *= sInv; d *= sInv; return *this; }
02110 };
02111 inline PLANE operator * (float s, const PLANE &p) { return PLANE(p.a*s, p.b*s, p.c*s, p.d*s); }
02112 #endif
02113
02114 extern const PLANE PLANE_ZERO;
02115 extern const PLANE PLANE_POSITIVE_X;
02116 extern const PLANE PLANE_POSITIVE_Y;
02117 extern const PLANE PLANE_POSITIVE_Z;
02118 extern const PLANE PLANE_NEGATIVE_X;
02119 extern const PLANE PLANE_NEGATIVE_Y;
02120 extern const PLANE PLANE_NEGATIVE_Z;
02121
02122 inline void swap(PLANE &p1, PLANE &p2)
02123 {
02124 std::swap(p1.a, p2.a); std::swap(p1.b, p2.b);
02125 std::swap(p1.c, p2.c); std::swap(p1.d, p2.d);
02126 }
02127
02129 inline VEC3 & GetPlaneNormal(PLANE &Plane) { return (VEC3&)Plane.a; }
02131 inline const VEC3 & GetPlaneNormal(const PLANE &Plane) { return (const VEC3&)Plane.a; }
02132
02134
02135 inline void GetPlaneMemberPoint(VEC3 *Out, const PLANE &Plane)
02136 {
02137 *Out = GetPlaneNormal(Plane) * -Plane.d;
02138 }
02139
02141
02145 inline void RecalcPlaneD(PLANE *Plane, const VEC3 &p)
02146 {
02147 Plane->d = -Dot(GetPlaneNormal(*Plane), p);
02148 }
02149
02151 inline bool PlaneEqual(const PLANE &p1, const PLANE &p2) {
02152 return float_equal(p1.a, p2.a) && float_equal(p1.b, p2.b) && float_equal(p1.c, p2.c) && float_equal(p1.d, p2.d);
02153 }
02154
02156
02159 inline void PointsToPlane(PLANE *Out, const VEC3 &p1, const VEC3 &p2, const VEC3 &p3) {
02160 Cross(&GetPlaneNormal(*Out), p2-p1, p3-p1);
02161 Normalize(&GetPlaneNormal(*Out));
02162 Out->d = -Dot(p1, GetPlaneNormal(*Out));
02163 }
02165
02166 inline void PointNormalToPlane(PLANE *Out, const VEC3 &Point, const VEC3 &Normal) {
02167 Out->a = Normal.x; Out->b = Normal.y; Out->c = Normal.z;
02168 Out->d = -Dot(Normal, Point);
02169 }
02170
02172 inline void Mul(PLANE *Out, const PLANE &p, float s)
02173 {
02174 Out->a = p.a * s; Out->b = p.b * s;
02175 Out->c = p.c * s; Out->d = p.d * s;
02176 }
02177 inline void Div(PLANE *Out, const PLANE &p, float s)
02178 {
02179 Out->a = p.a / s; Out->b = p.b / s;
02180 Out->c = p.c / s; Out->d = p.d / s;
02181 }
02182
02184
02186 inline float Dot(const PLANE &p, const VEC4 &pt)
02187 {
02188 return p.a*pt.x + p.b*pt.y + p.c*pt.z + p.d*pt.w;
02189 }
02190
02192
02194 inline float DotCoord(const PLANE &p, const VEC3 &pt)
02195 {
02196 return p.a*pt.x + p.b*pt.y + p.c*pt.z + p.d;
02197 }
02198
02200
02201 inline float DotNormal(const PLANE &p, const VEC3 &v)
02202 {
02203 return p.a*v.x + p.b*v.y + p.c*v.z;
02204 }
02205
02207
02209 inline void Normalize(PLANE *Out, const PLANE &p)
02210 {
02211 float nlsq = 1.0f / Length(GetPlaneNormal(p));
02212 Out->a = p.a * nlsq; Out->b = p.b * nlsq;
02213 Out->c = p.c * nlsq; Out->d = p.d * nlsq;
02214 }
02216 inline void Normalize(PLANE *p)
02217 {
02218 float nlsq = 1.0f / Length(GetPlaneNormal(*p));
02219 p->a *= nlsq; p->b *= nlsq;
02220 p->c *= nlsq; p->d *= nlsq;
02221 }
02222
02224
02227 void GetBoxPlane(PLANE *out, const BOX &box, uint index);
02228
02230
02231
02232
02233
02236
02238
02247 struct LINE2D
02248 {
02249 float a, b, c;
02250
02251 LINE2D() { }
02252 LINE2D(float a, float b, float c) : a(a), b(b), c(c) { }
02253 LINE2D(const VEC2 &Normal, float c) : a(Normal.x), b(Normal.y), c(c) { }
02254 LINE2D(const float *Arr) : a(Arr[0]), b(Arr[1]), c(Arr[2]) { }
02255
02256 operator float * () { return &a; }
02257 operator const float * () const { return &a; }
02258
02259 VEC2 & GetNormal() { return (VEC2&)a; }
02260 const VEC2 & GetNormal() const { return (VEC2&)a; }
02261
02262 bool operator == (const LINE2D &L) const { return a == L.a && b == L.b && c == L.c; }
02263 bool operator != (const LINE2D &L) const { return a != L.a || b != L.b || c != L.c; }
02264
02265 LINE2D operator + () const { return *this; }
02267 LINE2D operator - () const { return LINE2D(-a, -b, -c); }
02268
02269
02270 LINE2D operator * (float s) const { return LINE2D(a*s, b*s, c*s); }
02271 LINE2D operator / (float s) const { float sInv = 1.0f/s; return LINE2D(a*sInv, b*sInv, c*sInv); }
02272 LINE2D & operator *= (float s) { a *= s; b *= s; c *= s; return *this; }
02273 LINE2D & operator /= (float s) { float sInv = 1.0f/s; a *= sInv; b *= sInv; c *= sInv; return *this; }
02274
02276 void GetTangent(VEC2 *Out) { Out->x = b; Out->y = -a; }
02277
02279
02280 void GetMemberPoint(VEC2 *Out)
02281 {
02282 *Out = GetNormal() * -c;
02283 }
02284
02286
02289 void RecalcD(const VEC2 &p)
02290 {
02291 c = -Dot(GetNormal(), p);
02292 }
02293 };
02294 inline LINE2D operator * (float s, const LINE2D &p) { return LINE2D(p.a*s, p.b*s, p.c*s); }
02295 inline LINE2D operator / (float s, const LINE2D &p) { float sInv = 1.0f/s; return LINE2D(p.a*sInv, p.b*sInv, p.c*sInv); }
02296
02297 extern const LINE2D LINE2D_ZERO;
02298 extern const LINE2D LINE2D_POSITIVE_X;
02299 extern const LINE2D LINE2D_NEGATIVE_X;
02300 extern const LINE2D LINE2D_POSITIVE_Y;
02301 extern const LINE2D LINE2D_NEGATIVE_Y;
02302
02304 inline VEC2 & GetLineNormal(LINE2D &line) { return (VEC2&)line.a; }
02306 inline const VEC2 & GetLineNormal(const LINE2D &line) { return (const VEC2&)line.a; }
02307
02309 inline bool LineEqual(const LINE2D &p1, const LINE2D &p2) {
02310 return float_equal(p1.a, p2.a) && float_equal(p1.b, p2.b) && float_equal(p1.c, p2.c);
02311 }
02312
02313 inline void swap(LINE2D &p1, LINE2D &p2)
02314 {
02315 std::swap(p1.a, p2.a); std::swap(p1.b, p2.b); std::swap(p1.c, p2.c);
02316 }
02317
02319
02320 inline void PointsToLine(LINE2D *Out, const VEC2 &p1, const VEC2 &p2) {
02321 Out->a = p1.y - p2.y;
02322 Out->b = p2.x - p1.x;
02323 Out->c = - Out->a * p1.x - Out->b * p1.y;
02324 }
02325
02327 inline void PointNormalToLine(LINE2D *Out, const VEC2 &Point, const VEC2 &Normal) {
02328 Out->a = Normal.x; Out->b = Normal.y;
02329 Out->c = -Dot(Normal, Point);
02330 }
02331
02333 inline bool LinesParallel(const LINE2D &L1, const LINE2D &L2) {
02334 return FLOAT_ALMOST_ZERO(L1.a*L2.b - L2.a*L1.b);
02335 }
02336
02338 inline bool LinesPerpedicular(const LINE2D &L1, const LINE2D &L2) {
02339 return FLOAT_ALMOST_ZERO(L1.a*L2.a + L1.b*L2.b);
02340 }
02341
02343
02344 inline float Dot(const LINE2D &L1, const LINE2D &L2) {
02345 return L1.a*L2.a + L1.b*L2.b;
02346 }
02347
02349
02350 inline float LineDistance(const LINE2D &L1, const LINE2D &L2) {
02351 return L1.c - L2.c;
02352 }
02353
02355
02356 bool LinesIntersection(VEC2 *Out, const LINE2D &L1, const LINE2D &L2);
02357
02359 bool PointsColinear(const VEC2 &p1, const VEC2 &p2, const VEC2 &p3);
02360
02362 inline void Mul(LINE2D *Out, const LINE2D &p, float s) {
02363 Out->a = p.a * s; Out->b = p.b * s; Out->c = p.c * s;
02364 }
02365 inline void Div(LINE2D *Out, const LINE2D &p, float s) {
02366 Out->a = p.a / s; Out->b = p.b / s; Out->c = p.c / s;
02367 }
02368
02370
02372 inline float Dot(const LINE2D &p, const VEC3 &pt) {
02373 return p.a*pt.x + p.b*pt.y + p.c*pt.z;
02374 }
02375
02377
02378 inline float DotCoord(const LINE2D &p, const VEC2 &pt) {
02379 return p.a*pt.x + p.b*pt.y + p.c;
02380 }
02381
02383
02384 inline float DotNormal(const LINE2D &p, const VEC2 &v) {
02385 return p.a*v.x + p.b*v.y;
02386 }
02387
02389
02391 inline void Normalize(LINE2D *Out, const LINE2D &p) {
02392 float nlsq = 1.f / Length(p.GetNormal());
02393 Out->a = p.a * nlsq; Out->b = p.b * nlsq; Out->c = p.c * nlsq;
02394 }
02396 inline void Normalize(LINE2D *p) {
02397 float nlsq = 1.f / Length(p->GetNormal());
02398 p->a *= nlsq; p->b *= nlsq; p->c *= nlsq;
02399 }
02400
02402
02405 void GetRectLine(LINE2D *out, const RECTF &rect, uint index);
02406
02408
02409
02410
02411
02414
02415 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
02416 typedef D3DXMATRIX MATRIX;
02417 #else
02419
02424 struct MATRIX
02425 {
02426 union
02427 {
02428 struct
02429 {
02430 float _11, _12, _13, _14;
02431 float _21, _22, _23, _24;
02432 float _31, _32, _33, _34;
02433 float _41, _42, _43, _44;
02434 };
02435 float m[4][4];
02436 };
02437
02438 MATRIX() { }
02439 MATRIX(float _11, float _12, float _13, float _14, float _21, float _22, float _23, float _24, float _31, float _32, float _33, float _34, float _41, float _42, float _43, float _44) : _11(_11), _12(_12), _13(_13), _14(_14), _21(_21), _22(_22), _23(_23), _24(_24), _31(_31), _32(_32), _33(_33), _34(_34), _41(_41), _42(_42), _43(_43), _44(_44) { }
02440 MATRIX(const float *Array) : _11(Array[0]), _12(Array[1]), _13(Array[2]), _14(Array[3]), _21(Array[4]), _22(Array[5]), _23(Array[6]), _24(Array[7]), _31(Array[8]), _32(Array[9]), _33(Array[10]), _34(Array[11]), _41(Array[12]), _42(Array[13]), _43(Array[14]), _44(Array[15]) { }
02441
02442 operator float * () { return &_11; }
02443 operator const float * () const { return &_11; }
02444
02445 bool operator == (const MATRIX &m) const { return _11 == m._11 && _12 == m._12 && _13 == m._13 && _14 == m._14 && _21 == m._21 && _22 == m._22 && _23 == m._23 && _24 == m._24 && _31 == m._31 && _32 == m._32 && _33 == m._33 && _34 == m._34 && _41 == m._41 && _42 == m._42 && _43 == m._43 && _44 == m._44; }
02446 bool operator != (const MATRIX &m) const { return _11 != m._11 || _12 != m._12 || _13 != m._13 || _14 != m._14 || _21 != m._21 || _22 != m._22 || _23 != m._23 || _24 != m._24 || _31 != m._31 || _32 != m._32 || _33 != m._33 || _34 != m._34 || _41 != m._41 || _42 != m._42 || _43 != m._43 || _44 != m._44; }
02447
02448 float & operator () (unsigned Row, unsigned Col) { return m[Row][Col]; }
02449 float operator () (unsigned Row, unsigned Col) const { return m[Row][Col]; }
02450
02451 MATRIX operator + () const { return *this; }
02452 MATRIX operator - () const;
02453 MATRIX operator + (const MATRIX &m) const;
02454 MATRIX operator - (const MATRIX &m) const;
02455 MATRIX operator * (const MATRIX &m) const
02456 {
02457 return MATRIX(
02458 _11 * m._11 + _12 * m._21 + _13 * m._31 + _14 * m._41,
02459 _11 * m._12 + _12 * m._22 + _13 * m._32 + _14 * m._42,
02460 _11 * m._13 + _12 * m._23 + _13 * m._33 + _14 * m._43,
02461 _11 * m._14 + _12 * m._24 + _13 * m._34 + _14 * m._44,
02462
02463 _21 * m._11 + _22 * m._21 + _23 * m._31 + _24 * m._41,
02464 _21 * m._12 + _22 * m._22 + _23 * m._32 + _24 * m._42,
02465 _21 * m._13 + _22 * m._23 + _23 * m._33 + _24 * m._43,
02466 _21 * m._14 + _22 * m._24 + _23 * m._34 + _24 * m._44,
02467
02468 _31 * m._11 + _32 * m._21 + _33 * m._31 + _34 * m._41,
02469 _31 * m._12 + _32 * m._22 + _33 * m._32 + _34 * m._42,
02470 _31 * m._13 + _32 * m._23 + _33 * m._33 + _34 * m._43,
02471 _31 * m._14 + _32 * m._24 + _33 * m._34 + _34 * m._44,
02472
02473 _41 * m._11 + _42 * m._21 + _43 * m._31 + _44 * m._41,
02474 _41 * m._12 + _42 * m._22 + _43 * m._32 + _44 * m._42,
02475 _41 * m._13 + _42 * m._23 + _43 * m._33 + _44 * m._43,
02476 _41 * m._14 + _42 * m._24 + _43 * m._34 + _44 * m._44);
02477 }
02478 MATRIX & operator += (const MATRIX &m);
02479 MATRIX & operator -= (const MATRIX &m);
02480 MATRIX & operator *= (const MATRIX &m);
02481
02482 MATRIX operator * (float s) const;
02483 MATRIX operator / (float s) const;
02484 MATRIX & operator *= (float s);
02485 MATRIX & operator /= (float s);
02486 };
02487 #endif
02488
02489 extern const MATRIX MATRIX_ZERO;
02490 extern const MATRIX MATRIX_IDENTITY;
02491
02492 void MatrixToStr(tstring *Out, const MATRIX &m);
02493 bool StrToMatrix(MATRIX *Out, const tstring &Str);
02494
02495 inline void swap(MATRIX &m1, MATRIX &m2)
02496 {
02497 std::swap(m1._11, m2._11); std::swap(m1._12, m2._12); std::swap(m1._13, m2._13); std::swap(m1._14, m2._14);
02498 std::swap(m1._21, m2._21); std::swap(m1._22, m2._22); std::swap(m1._23, m2._23); std::swap(m1._24, m2._24);
02499 std::swap(m1._31, m2._31); std::swap(m1._32, m2._32); std::swap(m1._33, m2._33); std::swap(m1._34, m2._34);
02500 std::swap(m1._41, m2._41); std::swap(m1._42, m2._42); std::swap(m1._43, m2._43); std::swap(m1._44, m2._44);
02501 }
02502
02504 bool MatrixEqual(const MATRIX &m1, const MATRIX &m2);
02506 void Minus(MATRIX *m);
02508 void Add(MATRIX *Out, const MATRIX &m1, const MATRIX &m2);
02510 void Sub(MATRIX *Out, const MATRIX &m1, const MATRIX &m2);
02512 void Mul(MATRIX *Out, const MATRIX &m1, const MATRIX &m2);
02514 void Mul(MATRIX *m, float s);
02516 void Div(MATRIX *m, float s);
02517
02519
02531 void Mul3x3(MATRIX &out, const MATRIX &m1, const MATRIX &m2);
02533
02545 void Mul4x3(MATRIX &out, const MATRIX &m1, const MATRIX &m2);
02546
02548 void Transform(VEC4 *Out, const VEC2 &v, const MATRIX &m);
02550 void Transform(VEC2 *Out, const VEC2 &v, const MATRIX &m);
02552 void TransformCoord(VEC2 *Out, const VEC2 &v, const MATRIX &m);
02554 void TransformNormal(VEC2 *Out, const VEC2 &v, const MATRIX &m);
02555
02557 void Transform(VEC4 *Out, const VEC3 &v, const MATRIX &m);
02559
02560 void Transform(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02562
02563 void TransformCoord(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02565
02566 void TransformNormal(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02567
02569 void TransformArray(VEC3 OutPoints[], const VEC3 InPoints[], size_t PointCount, const MATRIX &M);
02570 void TransformArray(VEC3 InOutPoints[], size_t PointCount, const MATRIX &M);
02571 void TransformNormalArray(VEC3 OutPoints[], const VEC3 InPoints[], size_t PointCount, const MATRIX &M);
02572 void TransformNormalArray(VEC3 InOutPoints[], size_t PointCount, const MATRIX &M);
02573 void TransformCoordArray(VEC3 OutPoints[], const VEC3 InPoints[], size_t PointCount, const MATRIX &M);
02574 void TransformCoordArray(VEC3 InOutPoints[], size_t PointCount, const MATRIX &M);
02575
02577
02578 void Transform(VEC4 *Out, const VEC4 &v, const MATRIX &m);
02579
02581 void TransformNormalByTranspose(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02583
02586 void Untransform(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02588
02590 void UntransformNormal(VEC3 *Out, const VEC3 &v, const MATRIX &m);
02591
02593
02595 void Transform(PLANE *Out, const PLANE &p, const MATRIX &m);
02597 void TransformRay(VEC3 *OutOrigin, VEC3 *OutDir, const VEC3 &RayOrigin, const VEC3 &RayDir, const MATRIX &m);
02598
02600 void TransformBox(BOX *Out, const BOX &In, const MATRIX &M);
02602
02603 void TransformBoxCoord(BOX *Out, const BOX &In, const MATRIX &M);
02604
02606 void MatrixSetTranslation(MATRIX *InOut, float TranslationX, float TranslationY, float TranslationZ);
02608 void MatrixSetTranslation(MATRIX *InOut, const VEC3 &Translation);
02610 void MatrixGetTranslation(float *OutTranslationX, float *OutTranslationY, float *OutTranslationZ, const MATRIX &m);
02612 void MatrixGetTranslation(VEC3 *OutTranslation, const MATRIX &m);
02613
02615
02616 void AxesToMatrix(MATRIX *Out, const VEC3 &AxisX, const VEC3 &AxisY, const VEC3 &AxisZ);
02618
02619 void AxesToMatrixTranslation(MATRIX *Out, const VEC3 &Origin, const VEC3 &AxisX, const VEC3 &AxisY, const VEC3 &AxisZ);
02620
02622
02623 void LookAtLH(MATRIX *Out, const VEC3 &Eye, const VEC3 &Forward, const VEC3 &Up);
02624 void LookAtRH(MATRIX *Out, const VEC3 &Eye, const VEC3 &Forward, const VEC3 &Up);
02625
02627 void Identity(MATRIX *Out);
02629 void Translation(MATRIX *Out, float x, float y, float z);
02630 void Translation(MATRIX *Out, const VEC3 &v);
02632 void Scaling(MATRIX *Out, float sx, float sy, float sz);
02633 void Scaling(MATRIX *Out, const VEC3 &sv);
02634 void Scaling(MATRIX *Out, float s);
02636
02638 void ScalingAxis(MATRIX *Out, const VEC3 &n, float k);
02639
02641 void Rotation2D(MATRIX *Out, float Angle);
02643 void RotationX(MATRIX *Out, float Angle);
02645 void RotationY(MATRIX *Out, float Angle);
02647 void RotationZ(MATRIX *Out, float Angle);
02649 void RotationAxisLH(MATRIX *Out, const VEC3 &Axis, float Angle);
02650 inline void RotationAxisRH(MATRIX *Out, const VEC3 &Axis, float Angle) { RotationAxisLH(Out, Axis, -Angle); }
02651
02653
02660 void RotationYawPitchRoll(MATRIX *Out, float Yaw, float Pitch, float Roll);
02661 void RotationYawPitchRoll(MATRIX *Out, const VEC3 &EulerAngles);
02663
02664 void RotationYawPitchRollInv(MATRIX *Out, float Yaw, float Pitch, float Roll);
02665 void RotationYawPitchRollInv(MATRIX *Out, const VEC3 &EulerAngles);
02666
02667
02668
02669
02671
02672 void OrthoLH(MATRIX *Out, float Width, float Height, float ZNear, float ZFar);
02673 void OrthoRH(MATRIX *Out, float Width, float Height, float ZNear, float ZFar);
02674 void OrthoOffCenterLH(MATRIX *Out, float Left, float Right, float Bottom, float Top, float ZNear, float ZFar);
02675 void OrthoOffCenterRH(MATRIX *Out, float Left, float Right, float Bottom, float Top, float ZNear, float ZFar);
02677
02681 void PerspectiveLH(MATRIX *Out, float Width, float Height, float ZNear, float ZFar);
02682 void PerspectiveRH(MATRIX *Out, float Width, float Height, float ZNear, float ZFar);
02683 void PerspectiveFovLH(MATRIX *Out, float FovY, float Aspect, float ZNear, float ZFar);
02684 void PerspectiveFovRH(MATRIX *Out, float FovY, float Aspect, float ZNear, float ZFar);
02685 void PerspectiveOffCenterLH(MATRIX *Out, float Left, float Right, float Bottom, float Top, float ZNear, float ZFar);
02686 void PerspectiveOffCenterRH(MATRIX *Out, float Left, float Right, float Bottom, float Top, float ZNear, float ZFar);
02688 void PerspectiveFovLH_Inf(MATRIX *Out, float FovY, float Aspect, float ZNear);
02690
02691 void MatrixShadow(MATRIX *Out, const VEC4 &Light, const PLANE &Plane);
02693
02694 void MatrixReflect(MATRIX *Out, const PLANE &p);
02695
02697 void Transpose(MATRIX *m);
02699 void Transpose(MATRIX *Out, const MATRIX &m);
02701 void Lerp(MATRIX *Out, const MATRIX &m1, const MATRIX &m2, float t);
02703 float Det(const MATRIX &m);
02705 bool Inverse(MATRIX *Out, const MATRIX &m);
02706
02707
02709
02714 struct MATRIX33
02715 {
02716 union
02717 {
02718 struct
02719 {
02720 float _11, _12, _13;
02721 float _21, _22, _23;
02722 float _31, _32, _33;
02723 };
02724 float m[3][3];
02725 };
02726
02727 MATRIX33() { }
02728 MATRIX33(float _11, float _12, float _13, float _21, float _22, float _23, float _31, float _32, float _33) : _11(_11), _12(_12), _13(_13), _21(_21), _22(_22), _23(_23), _31(_31), _32(_32), _33(_33) { }
02729 MATRIX33(const float *Array) : _11(Array[0]), _12(Array[1]), _13(Array[2]), _21(Array[4]), _22(Array[5]), _23(Array[6]), _31(Array[8]), _32(Array[9]), _33(Array[10]) { }
02730
02731 operator float * () { return &_11; }
02732 operator const float * () const { return &_11; }
02733
02734 bool operator == (const MATRIX33 &m) const { return _11 == m._11 && _12 == m._12 && _13 == m._13 && _21 == m._21 && _22 == m._22 && _23 == m._23 && _31 == m._31 && _32 == m._32 && _33 == m._33; }
02735 bool operator != (const MATRIX33 &m) const { return _11 != m._11 || _12 != m._12 || _13 != m._13 || _21 != m._21 || _22 != m._22 || _23 != m._23 || _31 != m._31 || _32 != m._32 || _33 != m._33; }
02736
02737 float & operator () (unsigned Row, unsigned Col) { return m[Row][Col]; }
02738 float operator () (unsigned Row, unsigned Col) const { return m[Row][Col]; }
02739
02740 MATRIX33 operator + () const { return *this; }
02741 MATRIX33 operator - () const;
02742 MATRIX33 operator + (const MATRIX33 &m) const;
02743 MATRIX33 operator - (const MATRIX33 &m) const;
02744 MATRIX33 operator * (const MATRIX33 &m) const
02745 {
02746 return MATRIX33(
02747 _11 * m._11 + _12 * m._21 + _13 * m._31,
02748 _11 * m._12 + _12 * m._22 + _13 * m._32,
02749 _11 * m._13 + _12 * m._23 + _13 * m._33,
02750
02751 _21 * m._11 + _22 * m._21 + _23 * m._31,
02752 _21 * m._12 + _22 * m._22 + _23 * m._32,
02753 _21 * m._13 + _22 * m._23 + _23 * m._33,
02754
02755 _31 * m._11 + _32 * m._21 + _33 * m._31,
02756 _31 * m._12 + _32 * m._22 + _33 * m._32,
02757 _31 * m._13 + _32 * m._23 + _33 * m._33);
02758 }
02759 MATRIX33 & operator += (const MATRIX33 &m);
02760 MATRIX33 & operator -= (const MATRIX33 &m);
02761 MATRIX33 & operator *= (const MATRIX33 &m);
02762
02763 MATRIX33 operator * (float s) const;
02764 MATRIX33 operator / (float s) const;
02765 MATRIX33 & operator *= (float s);
02766 MATRIX33 & operator /= (float s);
02767 };
02768
02769 extern const MATRIX33 MATRIX33_ZERO;
02770 extern const MATRIX33 MATRIX33_IDENTITY;
02771
02773 void Matrix33ToMatrix(MATRIX *Out, const MATRIX33 &m);
02775 void MatrixToMatrix33(MATRIX33 *Out, const MATRIX &m);
02776
02778 void Identity(MATRIX33 *Out);
02779
02781 void Transpose(MATRIX33 *m);
02783 void Transpose(MATRIX33 *Out, const MATRIX33 &m);
02784
02786
02787
02788
02789
02792
02793 #if defined(USE_DIRECTX) && !defined(DOXYGEN)
02794 typedef D3DXQUATERNION QUATERNION;
02795 #else
02797
02802 struct QUATERNION
02803 {
02804 float x, y, z, w;
02805
02806 QUATERNION() { }
02807 QUATERNION(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
02808 QUATERNION(const float *Array) : x(Array[0]), y(Array[1]), z(Array[2]), w(Array[3]) { }
02809
02810 operator float * () { return &x; }
02811 operator const float * () const { return &x; }
02812
02813 bool operator == (const QUATERNION &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; }
02814 bool operator != (const QUATERNION &v) const { return x != v.x || y != v.y || z != v.z || w != v.w; }
02815
02816 QUATERNION operator + () const { return *this; }
02817 QUATERNION operator - () const { return QUATERNION(-x, -y, -z, -w); }
02818 QUATERNION operator + (const QUATERNION &q) const { return QUATERNION(x+q.x, y+q.y, z+q.z, w+q.w); }
02819 QUATERNION operator - (const QUATERNION &q) const { return QUATERNION(x-q.x, y-q.y, z-q.z, w-q.w); }
02820 QUATERNION operator * (const QUATERNION &q) const { return QUATERNION(w*q.x + x*q.w + y*q.z - z*q.y, w*q.y + y*q.w + z*q.x - x*q.z, w*q.z + z*q.w + x*q.y - y*q.x, w*q.w - x*q.x - y*q.y - z*q.z); }
02821 QUATERNION & operator += (const QUATERNION &q) { x += q.x; y += q.y; z += q.z; w += q.w; return *this; }
02822 QUATERNION & operator -= (const QUATERNION &q) { x -= q.x; y -= q.y; z -= q.z; w -= q.w; return *this; }
02823 QUATERNION & operator *= (const QUATERNION &q) { QUATERNION R; R.x = w*q.x + x*q.w + y*q.z - z*q.y; R.y = w*q.y + y*q.w + z*q.x - x*q.z; R.z = w*q.z + z*q.w + x*q.y - y*q.x; R.w = w*q.w - x*q.x - y*q.y - z*q.z; *this = R; return *this; }
02824 QUATERNION & operator *= (float v) { x *= v; y *= v; z *= v; w *= v; return *this; }
02825 QUATERNION & operator /= (float v) { float vInv = 1.0f/v; x *= vInv; y *= vInv; z *= vInv; w *= vInv; return *this; }
02826 };
02827 inline QUATERNION operator * (const QUATERNION pt, float v) { return QUATERNION(pt.x*v, pt.y*v, pt.z*v, pt.w*v); }
02828 inline QUATERNION operator / (const QUATERNION pt, float v) { float vInv = 1.0f/v; return QUATERNION(pt.x*vInv, pt.y*vInv, pt.z*vInv, pt.w*vInv); }
02829 inline QUATERNION operator * (float v, const QUATERNION pt) { return QUATERNION(pt.x*v, pt.y*v, pt.z*v, pt.w*v); }
02830 inline QUATERNION operator / (float v, const QUATERNION pt) { float vInv = 1.0f/v; return QUATERNION(pt.x*vInv, pt.y*vInv, pt.z*vInv, pt.w*vInv); }
02831 #endif
02832
02833 extern const QUATERNION QUATERNION_ZERO;
02834 extern const QUATERNION QUATERNION_IDENTITY;
02835
02836 inline void swap(QUATERNION &v1, QUATERNION &v2)
02837 {
02838 std::swap(v1.x, v2.x);
02839 std::swap(v1.y, v2.y);
02840 std::swap(v1.z, v2.z);
02841 std::swap(v1.w, v2.w);
02842 }
02843
02845 inline float CalcQuaternionAngle(const QUATERNION &Q) { return safe_acos(Q.w) * 2.0f; }
02847 void CalcQuaternionAxis(VEC3 *Out, const QUATERNION &Q);
02848
02850 inline bool QuaternionEqual(const QUATERNION &q1, const QUATERNION &q2) {
02851 return float_equal(q1.x, q2.x) && float_equal(q1.y, q2.y) && float_equal(q1.z, q2.z) && float_equal(q1.w, q2.w);
02852 }
02853
02855 void Minus(QUATERNION *q);
02856 inline void Minus(QUATERNION *Out, const QUATERNION &q) { *Out = q; Minus(Out); }
02858 void Add(QUATERNION *Out, const QUATERNION &q1, const QUATERNION &q2);
02859 void Sub(QUATERNION *Out, const QUATERNION &q1, const QUATERNION &q2);
02860 void Mul(QUATERNION *Out, const QUATERNION &q1, const QUATERNION &q2);
02862 void Mul(QUATERNION *q, float v);
02863 void Div(QUATERNION *q, float v);
02864 inline void Mul(QUATERNION *Out, const QUATERNION &q, float v) { *Out = q; Mul(Out, v); }
02865 inline void Div(QUATERNION *Out, const QUATERNION &q, float v) { *Out = q; Div(Out, v); }
02866
02868 void RotationMatrixToQuaternion(QUATERNION *Out, const MATRIX &RotationMatrix);
02870 void QuaternionToRotationMatrix(MATRIX *Out, const QUATERNION &q);
02872
02877 void QuaternionTransform(VEC3 *Out, const VEC3 &p, const QUATERNION &q);
02879
02880 void EulerAnglesToQuaternionO2I(QUATERNION *Out, float Yaw, float Pitch, float Roll);
02882 void EulerAnglesToQuaternionI2O(QUATERNION *Out, float Yaw, float Pitch, float Roll);
02884 void QuaternionO2IToEulerAngles(float *Yaw, float *Pitch, float *Roll, const QUATERNION &q);
02886 void QuaternionI2OToEulerAngles(float *Yaw, float *Pitch, float *Roll, const QUATERNION &q);
02887
02889 void QuaternionRotationX(QUATERNION *Out, float a);
02891 void QuaternionRotationY(QUATERNION *Out, float a);
02893 void QuaternionRotationZ(QUATERNION *Out, float a);
02895 void AxisToQuaternion(QUATERNION *Out, const VEC3 &Axis, float Angle);
02896
02898
02899 void QuaternionDiff(QUATERNION *Out, const QUATERNION &a, const QUATERNION &b);
02901 void Conjugate(QUATERNION *q);
02902 inline void Conjugate(QUATERNION *Out, const QUATERNION &q) { *Out = q; Conjugate(Out); }
02904 void Inverse(QUATERNION *Out, const QUATERNION &q);
02906 void Normalize(QUATERNION *Out, const QUATERNION &q);
02907 void Normalize(QUATERNION *InOut);
02909 float Dot(const QUATERNION &q1, const QUATERNION &q2);
02911 float LengthSq(const QUATERNION &q);
02913 float Length(const QUATERNION &q);
02914 void Log(QUATERNION *Out, const QUATERNION &q);
02915 void Exp(QUATERNION *Out, const QUATERNION &q);
02917
02918 void Pow(QUATERNION *InOut, float t);
02919 inline void Pow(QUATERNION *Out, const QUATERNION &q, float t) { *Out = q; Pow(Out, t); }
02921 void Lerp(QUATERNION *Out, const QUATERNION &q1, const QUATERNION &q2, float t);
02923
02924 void Slerp(QUATERNION *Out, const QUATERNION &q0, const QUATERNION &q1, float t);
02926 void Squad(QUATERNION *Out, const QUATERNION &Q1, const QUATERNION &A, const QUATERNION &B, const QUATERNION &C, float t);
02928 void SquadSetup(QUATERNION *OutA, QUATERNION *OutB, QUATERNION *OutC, const QUATERNION &Q0, const QUATERNION &Q1, const QUATERNION &Q2, const QUATERNION &Q3);
02929
02931
02932
02933
02934
02937
02939
02952 struct AFFINE2D
02953 {
02954 union {
02955 struct {
02956 float a, b, c, d, e, f;
02957 };
02958 float m[2][3];
02959 };
02960
02961 AFFINE2D() { }
02962 AFFINE2D(float a, float b, float c, float d, float e, float f) : a(a), b(b), c(c), d(d), e(e), f(f) { }
02963 AFFINE2D(const float *arr) : a(arr[0]), b(arr[1]), c(arr[2]), d(arr[3]), e(arr[4]), f(arr[5]) { }
02964
02965 operator float * () { return &a; }
02966 operator const float * () const { return &a; }
02967
02968 float & operator [] (size_t index) { return (&a)[index]; }
02969 float operator [] (size_t index) const { return (&a)[index]; }
02970
02971 bool operator == (const AFFINE2D &rhs) const { return a == rhs.a && b == rhs.b && c == rhs.c && d == rhs.d && e == rhs.e && f == rhs.f; }
02972 bool operator != (const AFFINE2D &rhs) const { return a != rhs.a || b != rhs.b || c != rhs.c || d != rhs.d || e != rhs.e || f != rhs.f; }
02973
02974 float & operator () (uint row, uint col) { return m[row][col]; }
02975 float operator () (uint row, uint col) const { return m[row][col]; }
02976
02977 AFFINE2D operator + () const { return *this; }
02978 AFFINE2D operator - () const { return AFFINE2D(-a, -b, -c, -d, -e, -f); }
02979
02980 AFFINE2D operator + (const AFFINE2D &rhs) const { return AFFINE2D(a + rhs.a, b + rhs.b, c + rhs.c, d + rhs.d, e + rhs.e, f + rhs.f); }
02981 AFFINE2D operator - (const AFFINE2D &rhs) const { return AFFINE2D(a - rhs.a, b - rhs.b, c - rhs.c, d - rhs.d, e - rhs.e, f - rhs.f); }
02982 AFFINE2D operator * (const AFFINE2D &rhs) const
02983 {
02984 return AFFINE2D(
02985 a*rhs.a + b*rhs.d, a*rhs.b + b*rhs.e, a*rhs.c + b*rhs.f + c,
02986 d*rhs.a + e*rhs.d, d*rhs.b + e*rhs.e, d*rhs.c + e*rhs.f + f);
02987 }
02988
02989 AFFINE2D & operator += (const AFFINE2D &rhs) { a += rhs.a; b += rhs.b; c += rhs.c; d += rhs.d; e += rhs.e; f += rhs.f; return *this; }
02990 AFFINE2D & operator -= (const AFFINE2D &rhs) { a -= rhs.a; b -= rhs.b; c -= rhs.c; d -= rhs.d; e -= rhs.e; f -= rhs.f; return *this; }
02991 AFFINE2D & operator *= (const AFFINE2D &rhs) { return *this = *this * rhs; }
02992
02993 AFFINE2D operator * (float s) const { return AFFINE2D(a*s, b*s, c*s, d*s, e*s, f*s); }
02994 AFFINE2D operator / (float s) const { s = 1.f/s; return AFFINE2D(a*s, b*s, c*s, d*s, e*s, f*s); }
02995 AFFINE2D & operator *= (float s) { a*=s; b*=s; c*=s; d*=s; e*=s; f*=s; return *this; }
02996 AFFINE2D & operator /= (float s) { s = 1.f/s; a*=s; b*=s; c*=s; d*=s; e*=s; f*=s; return *this; }
02997 };
02998
02999 extern const AFFINE2D AFFINE2D_ZERO;
03000 extern const AFFINE2D AFFINE2D_IDENTITY;
03001
03002 void Affine2dToStr(tstring *Out, const AFFINE2D &aff);
03003 bool StrToAffine2d(AFFINE2D *Out, const tstring &Str);
03004
03005 inline void swap(AFFINE2D &aff1, AFFINE2D &aff2)
03006 {
03007 std::swap(aff1.a, aff2.a); std::swap(aff1.b, aff2.b); std::swap(aff1.c, aff2.c);
03008 std::swap(aff1.d, aff2.d); std::swap(aff1.e, aff2.e); std::swap(aff1.f, aff2.f);
03009 }
03010
03012 inline void Mul(AFFINE2D &out, const AFFINE2D &lhs, const AFFINE2D &rhs)
03013 {
03014 out.a = lhs.a*rhs.a; out.b = lhs.b*rhs.b; out.c = lhs.c*rhs.c;
03015 out.d = lhs.d*rhs.d; out.e = lhs.e*rhs.e; out.f = lhs.f*rhs.f;
03016 }
03018 inline void Div(AFFINE2D &out, const AFFINE2D &lhs, const AFFINE2D &rhs)
03019 {
03020 out.a = lhs.a/rhs.a; out.b = lhs.b/rhs.b; out.c = lhs.c/rhs.c;
03021 out.d = lhs.d/rhs.d; out.e = lhs.e/rhs.e; out.f = lhs.f/rhs.f;
03022 }
03023
03025 inline void Transform(VEC2 &out, const VEC2 &v, const AFFINE2D &aff)
03026 {
03027 out.x = aff.a*v.x + aff.b*v.y + aff.c;
03028 out.y = aff.d*v.x + aff.e*v.y + aff.f;
03029 }
03031 inline void TransformNormal(VEC2 &out, const VEC2 &v, const AFFINE2D &aff)
03032 {
03033 out.x = aff.a*v.x + aff.b*v.y;
03034 out.y = aff.d*v.x + aff.e*v.y;
03035 }
03036
03037 inline void Translation(AFFINE2D &out, const VEC2 &v)
03038 {
03039 out = AFFINE2D(
03040 1.f, 0.f, v.x,
03041 0.f, 1.f, v.y);
03042 }
03043 inline void Translation(AFFINE2D &out, float x, float y)
03044 {
03045 out = AFFINE2D(
03046 1.f, 0.f, x,
03047 0.f, 1.f, y);
03048 }
03049
03050 inline void Scaling(AFFINE2D &out, float s)
03051 {
03052 out = AFFINE2D(
03053 s, 0.f, 0.f,
03054 0.f, s, 0.f);
03055 }
03056 inline void Scaling(AFFINE2D &out, const VEC2 &v)
03057 {
03058 out = AFFINE2D(
03059 v.x, 0.f, 0.f,
03060 0.f, v.y, 0.f);
03061 }
03062 inline void Scaling(AFFINE2D &out, float x, float y)
03063 {
03064 out = AFFINE2D(
03065 x, 0.f, 0.f,
03066 0.f, y, 0.f);
03067 }
03068
03069 inline void Rotation(AFFINE2D &out, float angle)
03070 {
03071 float angleSin, angleCos;
03072 sincos(angle, &angleSin, &angleCos);
03073 out = AFFINE2D(
03074 angleCos, -angleSin, 0.f,
03075 angleSin, angleCos, 0.f);
03076 }
03077
03079 inline void Transpose(AFFINE2D &inout)
03080 {
03081 std::swap(inout.b, inout.d);
03082 }
03083
03084 void Lerp(AFFINE2D &out, const AFFINE2D &lhs, const AFFINE2D &rhs, float t);
03085 void Inverse(AFFINE2D &out, const AFFINE2D &aff);
03086
03095 void Affine2dToMatrix(MATRIX &out, const AFFINE2D &aff);
03097 void MatrixToAffine2d(AFFINE2D &out, const MATRIX &m);
03098
03100
03101
03102
03103
03106
03107 struct FRUSTUM_PLANES;
03108 struct FRUSTUM_POINTS;
03109
03111
03117 struct FRUSTUM_PLANES
03118 {
03123 static const size_t PLANE_LEFT = 0;
03124 static const size_t PLANE_RIGHT = 1;
03125 static const size_t PLANE_TOP = 2;
03126 static const size_t PLANE_BOTTOM = 3;
03127 static const size_t PLANE_NEAR = 4;
03128 static const size_t PLANE_FAR = 5;
03130
03131 PLANE Planes[6];
03132
03134 FRUSTUM_PLANES() { }
03136 FRUSTUM_PLANES(const MATRIX &WorldViewProj) { Set(WorldViewProj); }
03138 FRUSTUM_PLANES(const FRUSTUM_POINTS &FrustumPoints) { Set(FrustumPoints); }
03140 void Set(const MATRIX &WorldViewProj);
03141 void Set(const FRUSTUM_POINTS &FrustumPoints);
03143 void Normalize();
03144
03145 PLANE & operator [] (size_t Index) { return Planes[Index]; }
03146 const PLANE & operator [] (size_t Index) const { return Planes[Index]; }
03147 };
03148
03150
03155 struct FRUSTUM_POINTS
03156 {
03160 static const size_t NEAR_LEFT_BOTTOM = 0;
03161 static const size_t NEAR_RIGHT_BOTTOM = 1;
03162 static const size_t NEAR_LEFT_TOP = 2;
03163 static const size_t NEAR_RIGHT_TOP = 3;
03164 static const size_t FAR_LEFT_BOTTOM = 4;
03165 static const size_t FAR_RIGHT_BOTTOM = 5;
03166 static const size_t FAR_LEFT_TOP = 6;
03167 static const size_t FAR_RIGHT_TOP = 7;
03169
03170 VEC3 Points[8];
03171
03173 FRUSTUM_POINTS() { }
03175 FRUSTUM_POINTS(const FRUSTUM_PLANES &FrustumPlanes) { Set(FrustumPlanes); }
03177 FRUSTUM_POINTS(const MATRIX &WorldViewProjInv) { Set(WorldViewProjInv); }
03179 void Set(const FRUSTUM_PLANES &FrustumPlanes);
03180 void Set(const MATRIX &WorldViewProjInv);
03181
03182 VEC3 & operator [] (size_t Index) { return Points[Index]; }
03183 const VEC3 & operator [] (size_t Index) const { return Points[Index]; }
03184
03186 void CalcCenter(VEC3 *Out) const;
03188 void CalcBoundingBox(BOX *Box) const;
03190
03191 void CalcBoundingSphere(VEC3 *SphereCenter, float *SphereRadius) const;
03192 };
03193
03195
03202 class FRUSTUM_RADAR
03203 {
03204 private:
03205 VEC3 m_Eye;
03206 VEC3 m_Forward;
03207 VEC3 m_Up;
03208 VEC3 m_Right;
03209 float m_RFactor;
03210 float m_UFactor;
03211 float m_RSphereFactor;
03212 float m_USphereFactor;
03213 float m_ZNear;
03214 float m_ZFar;
03215
03216 public:
03218 FRUSTUM_RADAR() { }
03220 FRUSTUM_RADAR(const VEC3 &Eye, const VEC3 &Forward, const VEC3 &Up, const VEC3 &Right, float FovY, float Aspect, float ZNear, float ZFar) { Set(Eye, Forward, Up, Right, FovY, Aspect, ZNear, ZFar); }
03221
03226 const VEC3 & GetEye() const { return m_Eye; }
03227 const VEC3 & GetForward() const { return m_Forward; }
03228 const VEC3 & GetUp() const { return m_Up; }
03229 const VEC3 & GetRight() const { return m_Right; }
03230 float GetZNear() const { return m_ZNear; }
03231 float GetZFar() const { return m_ZFar; }
03233
03238 float GetRFactor() const { return m_RFactor; }
03239 float GetUFactor() const { return m_UFactor; }
03240 float GetRSphereFactor() const { return m_RSphereFactor; }
03241 float GetUSphereFactor() const { return m_USphereFactor; }
03243
03246 void SetEye (const VEC3 &Eye) { m_Eye = Eye; }
03247 void SetForward(const VEC3 &Forward) { m_Forward = Forward; }
03248 void SetUp (const VEC3 &Up) { m_Up = Up; }
03249 void SetRight (const VEC3 &Right) { m_Right = Right; }
03250 void SetZNear(float ZNear) { m_ZNear = ZNear; }
03251 void SetZFor (float ZFar) { m_ZFar = ZFar; }
03252 void SetFovAndAspect(float FovY, float Aspect);
03254
03256 void Set(const VEC3 &Eye, const VEC3 &Forward, const VEC3 &Up, const VEC3 &Right, float FovY, float Aspect, float ZNear, float ZFar) { SetProjection(FovY, Aspect, ZNear, ZFar); SetView(Eye, Forward, Up, Right); }
03258 void SetProjection(float FovY, float Aspect, float ZNear, float ZFar);
03260 void SetView(const VEC3 &Eye, const VEC3 &Forward, const VEC3 &Up, const VEC3 &Right);
03261 };
03262
03264
03265
03266
03267
03270
03272 float CapsuleVolume(const VEC3 &p1, const VEC3 &p2, float R);
03274 void RandomPointInCapsule(VEC3 *Out, const VEC3 &p1, const VEC3 &p2, float R, RandomGenerator &Rand);
03275 void RandomPointInCapsule(VEC3 *Out, const VEC3 &p1, const VEC3 &p2, float R);
03276
03278
03279
03280
03281
03282
03288
03289 template <typename T>
03290 inline void SmoothCD_T(T *InOutPos, const T &Dest, T *InOutVel, float SmoothTime, float TimeDelta)
03291 {
03292 assert(0 && "SmoothCD_T for invalid template type.");
03293 }
03294
03295 template <>
03296 inline void SmoothCD_T<float>(float *InOutPos, const float &Dest, float *InOutVel, float SmoothTime, float TimeDelta)
03297 {
03298 SmoothCD(InOutPos, Dest, InOutVel, SmoothTime, TimeDelta);
03299 }
03300
03301 template <>
03302 inline void SmoothCD_T<VEC2>(VEC2 *InOutPos, const VEC2 &Dest, VEC2 *InOutVel, float SmoothTime, float TimeDelta)
03303 {
03304 SmoothCD(&InOutPos->x, Dest.x, &InOutVel->x, SmoothTime, TimeDelta);
03305 SmoothCD(&InOutPos->y, Dest.y, &InOutVel->y, SmoothTime, TimeDelta);
03306 }
03307
03308 template <>
03309 inline void SmoothCD_T<VEC3>(VEC3 *InOutPos, const VEC3 &Dest, VEC3 *InOutVel, float SmoothTime, float TimeDelta)
03310 {
03311 SmoothCD(&InOutPos->x, Dest.x, &InOutVel->x, SmoothTime, TimeDelta);
03312 SmoothCD(&InOutPos->y, Dest.y, &InOutVel->y, SmoothTime, TimeDelta);
03313 SmoothCD(&InOutPos->z, Dest.z, &InOutVel->z, SmoothTime, TimeDelta);
03314 }
03315
03316 template <typename T>
03317 class SmoothCD_obj
03318 {
03319 public:
03320 T Pos;
03321 T Dest;
03322 T Vel;
03323 float SmoothTime;
03324
03326 SmoothCD_obj() { }
03328 SmoothCD_obj(const T &Pos, float SmoothTime, const T &Vel) : Pos(Pos), Dest(Pos), Vel(Vel), SmoothTime(SmoothTime) { }
03330 void Set(const T &Pos, const T &Vel) { this->Pos = Pos; this->Dest = Pos; this->Vel = Vel; }
03331
03333 void Update(const T &Dest, float TimeDelta) {
03334 this->Dest = Dest;
03335 SmoothCD_T<T>(&Pos, Dest, &Vel, SmoothTime, TimeDelta);
03336 }
03337 };
03338
03340
03341
03342
03348
03350 void SphericalToCartesian(VEC3 *Out, float Yaw, float Pitch, float R);
03351
03365 void CartesianToSpherical(float *OutYaw, float *OutPitch, float *OutR, const VEC3 &Pos);
03366
03368
03369
03371
03377 void ConvexHull2D(std::vector<VEC2> *OutPoints, const VEC2 InPoints[], size_t InPointCount);
03378
03389 extern const MATRIX HL2_TO_TANGENT_MATRIX;
03390 extern const MATRIX TANGENT_TO_HL2_MATRIX;
03392 extern const VEC3 HL2_BASIS_VECTORS[3];
03393
03394
03395
03398
03400
03402 template <typename T>
03403 inline void EvalCatmullRomCurve(T *out, const T &a, const T &b, const T &c, const T &d, float t)
03404 {
03405 float t2 = t * t;
03406 float t3 = t2 * t;
03407 *out = 0.5f * ( (2.f *b) + (c-a)*t + (2*a - 5*b + 4*c - d)*t2 + (3*b - 3*c + d - a)*t3 );
03408 }
03409
03411
03413 template <typename T>
03414 inline void EvalCatmullRomCurveDiff(T *out, const T &a, const T &b, const T &c, const T &d, float t)
03415 {
03416 float t2 = t * t;
03417 *out = 0.5f * ( (c - a) + 2.f*(a*2.f - b*5.f + c* 4.f - d)*t + 3.f*(a*-1.f + b*3.f -c*3.f + d)*t2 );
03418 }
03419
03421
03423 template <typename T>
03424 inline void EvalQuadraticBezierCurve(T *out, const T &a, const T &b, const T &c, float t)
03425 {
03426 float t_inv = 1.f - t;
03427 out = t_inv*t_inv*a + 2.f*t*t_inv*b + t*t*c;
03428 }
03429
03431
03433 template <typename T>
03434 inline void EvalCubicBezierCurve(T *out, const T &a, const T &b, const T &c, const T &d, float t)
03435 {
03436 float t2=t*t;
03437 float t3=t2*t;
03438 float v=1-t;
03439 float v2=v*v;
03440 float v3=v2*v;
03441 *out = a*v3 + b*3.f*v2*t + c*3.f*v*t2 + d*t3;
03442 }
03443
03445
03447 template <typename T>
03448 inline void EvalCubicBezierCurveDiff(T *out, const T &a, const T &b, const T &c, const T &d, float t)
03449 {
03450 float tinv = 1.f - t;
03451 float tinvpow2 = tinv * tinv;
03452 float upow2 = t * t;
03453 float ta = 3.f * tinvpow2;
03454 float tb = 6.f * tinv * t;
03455 float tc = 3.f * upow2;
03456 float c0 = -ta;
03457 float c1 = ta - tb;
03458 float c2 = tb - tc;
03459 float c3 = tc;
03460 *out = b*(ta-tb) + c*(tb-tc) + d*tc - a*ta;
03461 }
03462
03464
03468 template <typename T>
03469 inline void SplitCubicBezierCurve(T out1[4], T out2[4], const T &a, const T &b, const T &c, const T &d)
03470 {
03471 out1[0] = a;
03472 out1[1] = a*0.5f + b*0.5f;
03473 out1[2] = a*0.25f + b*0.5f + c*0.25f;
03474 out1[3] = a*0.125f + b*0.375f + c*0.375f + d*0.125f;
03475 out2[3] = d;
03476 out2[2] = d*0.5f + c*0.5f;
03477 out2[1] = d*0.25f + c*0.5f + b*0.25f;
03478 out2[0] = d*0.125f + c*0.375f + b*0.375f + a*0.125f;
03479 }
03480
03482
03486 template <typename T>
03487 inline void SplitCubicBezierCurve(T out1[4], T out2[4], const T &a, const T &b, const T &c, const T &d, float t)
03488 {
03489 T p01 = a + (b - a) * t;
03490 T p12 = b + (c - b) * t;
03491 T p23 = c + (d - c) * t;
03492 T pa = p01 + (p12 - p01) * t;
03493 T pb = p12 + (p23 - p12) * t;
03494 T pc = pa + (pb - pa) * t;
03495 out1[0] = a; out1[1] = p01; out1[2] = pa; out1[3] = pc;
03496 out2[0] = pc; out2[1] = pb; out2[2] = p23; out2[3] = d;
03497 }
03498
03499 template <typename T>
03500 class CubicBezierCurveIntegral
03501 {
03502 public:
03503 void Setup(const T &a, const T &b, const T &c, const T &d, const T &zero)
03504 {
03505 m_Data[0] = zero;
03506 m_Data[1] = a * 0.25f;
03507 m_Data[2] = (a + b) * 0.25f;
03508 m_Data[3] = (a + b + c) * 0.25f;
03509 m_Data[4] = (a + b + c + d) * 0.25f;
03510 }
03511
03512 void Calc(T *out, float t)
03513 {
03514 float t2 = t * t;
03515 float t3 = t2 * t;
03516 float t4 = t3 * t;
03517
03518 float inv_t = 1.0f - t;
03519 float inv_t2 = inv_t * inv_t;
03520 float inv_t3 = inv_t2 * inv_t;
03521 float inv_t4 = inv_t3 * inv_t;
03522
03523 *out = m_Data[0]*inv_t4 + m_Data[1]*4*inv_t3*t + m_Data[2]*6*inv_t2*t2 + m_Data[3]*4*inv_t*t3 + m_Data[4]*t4;
03524 }
03525
03526 private:
03527 T m_Data[5];
03528 };
03529
03530 float CalcCubicBezierCurveLength(const VEC3 &a, const VEC3 &b, const VEC3 &c, const VEC3 &d, float t1, float t2);
03531 float GetCubicBezierCurveArcLengthParam(const VEC3 &a, const VEC3 &b, const VEC3 &c, const VEC3 &d, float len, float epsilon);
03533 bool IntersectCubicBezierCurve2DWithX(const VEC2 curve[4], float x, float eps, float *outY, float *outT, float t0 = 0.f, float t1 = 1.f);
03534
03536
03537
03538
03539
03542
03544
03552 float Orient2D(const VEC2 &a, const VEC2 &b, const VEC2 &c);
03554
03564 float Orient3D(const VEC3 &a, const VEC3 &b, const VEC3 &c, const VEC3 &d);
03565
03566 inline bool PointInCircle(const VEC2 &pt, const VEC2 &circleCenter, float circleRadius)
03567 {
03568 return DistanceSq(pt, circleCenter) <= sqr(circleRadius);
03569 }
03571 bool PointInTriangle(const VEC2 &p, const VEC2 &a, const VEC2 &b, const VEC2 &c);
03573
03574 bool IsQuadConvex(const VEC2 &a, const VEC2 &b, const VEC2 &c, const VEC2 &d);
03576
03577 bool IsQuadConvex(const VEC3 &a, const VEC3 &b, const VEC3 &c, const VEC3 &d);
03579
03583 float ClosestPointOnLine(const VEC3 &p, const VEC3 &RayOrig, const VEC3 &RayDir);
03585
03591 float ClosestPointSegmentSegment(
03592 const VEC3 &Seg1_Beg, const VEC3 &Seg1_End, const VEC3 &Seg2_Beg, const VEC3 &Seg2_End,
03593 float &OutSeg1_t, float &OutSeg2_t, VEC3 &OutSeg1_pt, VEC3 &OutSeg2_pt);
03595
03596 float PointToLineDistanceSq(const VEC2 &P, const VEC2 &LineOrig, const VEC2 &LineDir);
03597 float PointToLineDistanceSq(const VEC3 &P, const VEC3 &LineOrig, const VEC3 &LineDir);
03599 float PointToSegmentDistanceSq(const VEC2 &p, const VEC2 &segment_p1, const VEC2 &segment_p2);
03601 float PointToSegmentDistanceSq(const VEC3 &p, const VEC3 &segment_p1, const VEC3 &segment_p2);
03603
03604 bool PointOnLine(const VEC3 &P, const VEC3 &LineOrig, const VEC3 &LineDir);
03606
03607 float PointToLine(const VEC3 &P, const VEC3 &LineOrig, const VEC3 &LineDir);
03609
03610 bool PointInLineSegment(const VEC3 &P, const VEC3 &SegmentBeg, const VEC3 &SegmentEnd);
03612
03614 float ClosestPointOnSegment(VEC2 *Out, const VEC2 &p, const VEC2 &p1, const VEC2 &p2);
03615 float ClosestPointOnSegment(VEC3 *Out, const VEC3 &p, const VEC3 &p1, const VEC3 &p2);
03617
03619 float ClosestPointOnRay(VEC2 *Out, const VEC2 &p, const VEC2 &RayOrig, const VEC2 &RayDir);
03620 float ClosestPointOnRay(VEC3 *Out, const VEC3 &p, const VEC3 &RayOrig, const VEC3 &RayDir);
03622
03623 void ClosestPointInBox(VEC3 *Out, const BOX &Box, const VEC3 &p);
03625 void ClosestPointInObb(VEC3 *OutPoint, const VEC3 &Point, const OBB &Obb);
03627 void ClosestPointInRect3d(VEC3 *OutPoint, const VEC3 &Point, const RECT3D &Rect3d);
03629 void ClosestPointInRect3d(VEC3 *OutPoint, const VEC3 &p, const VEC3 &a, const VEC3 &b, const VEC3 &c);
03631 void ClosestPointInTriangle(VEC3 *OutPoint, const VEC3 &p, const VEC3 &a, const VEC3 &b, const VEC3 &c);
03633 void ClosestPointInTriangle(VEC2 *out, const VEC2 &pt, const VEC2 &triA, const VEC2 &triB, const VEC2 &triC);
03635 void ClosestPointInTetrahedron(VEC3 *OutPoint, const VEC3 &p, const VEC3 &a, const VEC3 &b, const VEC3 &c, const VEC3 &d);
03637 float PointToRectDistanceSq(const VEC2 &p, const RECTF &rect);
03638 float PointToRectManhattanDistance(const VEC2 &p, const RECTF &rect);
03639 float PointToRectMaxDistance(const VEC2 &p, const RECTF &rect);
03641
03642 float PointToBoxDistanceSq(const VEC3 &p, const BOX &box);
03643 float PointToBoxManhattanDistance(const VEC3 &p, const BOX &box);
03644 float PointToBoxMaxDistance(const VEC3 &p, const BOX &box);
03646 float RectToRectDistanceSq(const RECTF &rect1, const RECTF &rect2);
03647 float RectToRectManhattanDistance(const RECTF &rect1, const RECTF &rect2);
03648 float RectToRectMaxDistance(const RECTF &rect1, const RECTF &rect2);
03650 float BoxToBoxDistanceSq(const BOX &box1, const BOX &box2);
03651 float BoxToBoxManhattanDistance(const BOX &box1, const BOX &box2);
03652 float BoxToBoxMaxDistance(const BOX &box1, const BOX &box2);
03654 float PointToObbDistanceSq(const VEC3 &Point, const OBB &Obb);
03655 bool CircleToRect(const VEC2 &circleCenter, float circleRadius, const RECTF &rect);
03657 bool PointInSphere(const VEC3 &p, const VEC3 &SphereCenter, float SphereRadius);
03659
03660 float PointToSphereDistance(const VEC3 &p, const VEC3 &SphereCenter, float SphereRadius);
03662
03664 void ClosestPointOnSphere(VEC3 *Out, const VEC3 &SphereCenter, float SphereRadius, const VEC3 &p);
03666
03667 bool PointOnPlane(const VEC3 &p, const PLANE &plane);
03669
03670 void ClosestPointOnPlane(VEC3 *Out, const PLANE &Plane, const VEC3 &p);
03672 bool PointInTriangle(const VEC3 &point, const VEC3 &pa, const VEC3 &pb, const VEC3 &pc);
03674 bool PointInFrustum(const VEC3 &p, const FRUSTUM_PLANES &Frustum);
03675 bool PointInFrustum(const VEC3 &p, const FRUSTUM_RADAR &Frustum);
03677
03682 bool ClosestPointsOnLines(float *OutT1, float *OutT2, const VEC3 &RayOrig1, const VEC3 &RayDir1, const VEC3 &RayOrig2, const VEC3 &RayDir2);
03684
03688 bool RayToBox(float *OutT, const VEC3 &RayOrig, const VEC3 &RayDir, const BOX &Box);
03690
03694 bool RayToSphere(const VEC3 &RayOrig, const VEC3 &RayDir, const VEC3 &SphereCenter, float SphereRadius, float *OutT);
03696
03700 bool RayToPlane(const VEC3 &RayOrig, const VEC3 &RayDir, const PLANE &Plane, float *OutT, float *OutVD);
03702
03705 bool RayToTriangle(
03706 const VEC3 &RayOrig, const VEC3 &RayDir,
03707 const VEC3 &p0, const VEC3 &p1, const VEC3 &p2,
03708 bool BackfaceCulling,
03709 float *OutT);
03711
03715 bool RayToQuad(const VEC3 &RayOrig, const VEC3 &RayDir, const VEC3 QuadPoints[4], VEC3 *OutPoint = NULL);
03717 bool RayToFrustum(const VEC3 &RayOrig, const VEC3 &RayDir, const FRUSTUM_PLANES &Frustum, float *t_near, float *t_far);
03719
03721 bool RayToCylinder(
03722 const VEC3 &RayOrig, const VEC3 &RayDir,
03723 const VEC3 &CylinderBeg, const VEC3 &CylinderEnd, float CylinderRadius,
03724 float *OutT);
03726
03727 bool PointInConvexPolyhedron(const VEC3 &Point, const PLANE PolyhedronPlanes[], size_t PolyhedronPlaneCount);
03728 bool PointInConvexPolyhedron(const VEC3 &Point, const void *PolyhedronPlanes, size_t PolyhedronPlaneCount, int PolyhedronPlaneStride);
03730
03734 bool RayToConvexPolyhedron(
03735 const VEC3 &RayOrig, const VEC3 &RayDir,
03736 const PLANE PolyhedronPlanes[], size_t PolyhedronPlaneCount,
03737 float *OutBegT, float *OutEndT);
03738 bool RayToConvexPolyhedron(
03739 const VEC3 &RayOrig, const VEC3 &RayDir,
03740 const void *PolyhedronPlanes, size_t PolyhedronPlaneCount, int PolyhedronPlaneStride,
03741 float *OutBegT, float *OutEndT);
03743 bool SphereToBox(const VEC3 &SphereCenter, float SphereRadius, const BOX &Box);
03745 bool SphereToObb(const VEC3 &SphereCenter, float SphereRadius, const OBB &Obb);
03747 bool SphereToTriangle(const VEC3 &SphereCenter, float SphereRadius, const VEC3 &TriA, const VEC3 &TriB, const VEC3 &TriC);
03749 bool SphereInBox(const VEC3 &SphereCenter, float SphereRadius, const BOX &Box);
03751 bool BoxInSphere(const BOX &Box, const VEC3 &SphereCenter, float SphereRadius);
03753
03758 int ClassifyBoxToPlane(const PLANE &plane, const BOX &box);
03760 int ClassifyObbToPlane(const PLANE &Plane, const OBB &Obb);
03762
03763 inline bool PlaneToBox(const PLANE &plane, const BOX &box) { return ClassifyBoxToPlane(plane, box) == 0; }
03765 bool TriangleInBox(const VEC3 &p1, const VEC3 &p2, const VEC3 &p3, const BOX &Box);
03767
03769 bool TriangleToBox(const VEC3 &TriA, const VEC3 &TriB, const VEC3 &TriC, const BOX &Box);
03771
03772 bool BoxToFrustum_Fast(const BOX &Box, const FRUSTUM_PLANES &Frustum);
03774
03777 bool BoxToFrustum(const BOX &Box, const FRUSTUM_PLANES &FrustumPlanes, const FRUSTUM_POINTS *OptFrustumPoints = NULL);
03778 bool BoxToFrustum(const BOX &Box, const FRUSTUM_RADAR &Frustum);
03780 bool BoxInFrustum(const BOX &Box, const FRUSTUM_PLANES &Frustum);
03782 bool SphereToSphere(const VEC3 &Center1, float Radius1, const VEC3 &Center2, float Radius2);
03784
03785 bool SphereToPlane(const VEC3 &SphereCenter, float SphereRadius, const PLANE &Plane);
03787
03792 int ClassifySphereToPlane(const VEC3 &SphereCenter, float SphereRadius, const PLANE &Plane);
03794
03795 bool CapsuleToPlane(const VEC3 &CapsuleBeg, const VEC3 &CapsuleEnd, float CapsuleRadius, const PLANE &Plane);
03797
03798 bool SphereToFrustum_Fast(const VEC3 &SphereCenter, float SphereRadius, const FRUSTUM_PLANES &Frustum);
03800
03802 bool SphereToFrustum(
03803 const VEC3 &SphereCenter, float SphereRadius,
03804 const FRUSTUM_PLANES &FrustumPlanes, const FRUSTUM_POINTS *OptFrustumPoints = NULL);
03806
03810 bool SphereToFrustum(const VEC3 &SphereCenter, float SphereRadius, const FRUSTUM_RADAR &Frustum);
03812 bool SphereInFrustum(const VEC3 &SphereCenter, float SphereRadius, const FRUSTUM_PLANES &Frustum);
03814
03817 bool Intersect2Planes(const PLANE &Plane1, const PLANE &Plane2, VEC3 *OutLineOrig, VEC3 *OutLineDir);
03819
03820 bool Intersect3Planes(const PLANE &P1, const PLANE &P2, const PLANE &P3, VEC3 *OutP);
03822 bool PlaneToTriangle(const PLANE &Plane, const VEC3 &p0, const VEC3 &p1, const VEC3 &p2);
03824
03829 int ClassifyPlaneToTriangle(const PLANE &Plane, const VEC3 &p0, const VEC3 &p1, const VEC3 &p2);
03831 int ClassifyFrustumToPlane(const FRUSTUM_POINTS &Frustum, const PLANE &Plane);
03833
03834 bool SegmentToSegment(const VEC2 &Seg1_Beg, const VEC2 &Seg1_End, const VEC2 &Seg2_Beg, const VEC2 &Seg2_End, float *OutSeg1_t = NULL);
03836
03837 bool TriangleToTriangle(
03838 const VEC3 &V0,const VEC3 &V1,const VEC3 &V2,
03839 const VEC3 &U0,const VEC3 &U1,const VEC3 &U2);
03841 bool TriangleInFrustum(const VEC3 &t1, const VEC3 &t2, const VEC3 &t3, const FRUSTUM_PLANES &Frustum);
03843
03845 bool TriangleToFrustum(
03846 const VEC3 &t1, const VEC3 &t2, const VEC3 &t3, const PLANE *OptTrianglePlane,
03847 const FRUSTUM_PLANES &FrustumPlanes, const FRUSTUM_POINTS *OptFrustumPoints);
03849 bool FrustumToFrustum(
03850 const FRUSTUM_PLANES &Frustum1_Planes, const FRUSTUM_POINTS &Frustum1_Points,
03851 const FRUSTUM_PLANES &Frustum2_Planes, const FRUSTUM_POINTS &Frustum2_Points);
03853 bool SphereToCapsule(
03854 const VEC3 &SphereCenter, float SphereRadius,
03855 const VEC3 &Capsule_Beg, const VEC3 &Capsule_End, float Capsule_Radius);
03857 bool CapsuleToCapsule(
03858 const VEC3 &Capsule1_Beg, const VEC3 &Capsule1_End, float Capsule1_Radius,
03859 const VEC3 &Capsule2_Beg, const VEC3 &Capsule2_End, float Capsule2_Radius);
03861
03862 bool PointInConvexPolygon(const VEC2 &Point, const VEC2 PolygonPoints[], size_t PolygonPointCount);
03863 bool PointInConvexPolygon(const VEC2 &Point, const void *PolygonPoints, size_t PolygonPointCount, int PolygonPointStride);
03865
03867 bool PointInPolygon(const VEC2 &Point, const VEC2 PolygonPoints[], size_t PolygonPointCount);
03868 bool PointInPolygon(const VEC2 &Point, const void *PolygonPoints, size_t PolygonPointCount, int PolygonPointStride);
03870
03876 bool RayToConvexPolygon(
03877 const VEC3 &RayOrig, const VEC3 &RayDir,
03878 const VEC3 PolygonPoints[], size_t PolygonPointCount,
03879 bool BackfaceCulling, float *OutT, VEC3 *OutPoint, const PLANE *PolygonPlane = NULL);
03880 bool RayToConvexPolygon(
03881 const VEC3 &RayOrig, const VEC3 &RayDir,
03882 const void *PolygonPoints, size_t PolygonPointCount, int PolygonPointStride,
03883 bool BackfaceCulling, float *OutT, VEC3 *OutPoint, const PLANE *PolygonPlane = NULL);
03885
03891 bool RayToPolygon(
03892 const VEC3 &RayOrig, const VEC3 &RayDir,
03893 const VEC3 PolygonPoints[], size_t PolygonPointCount,
03894 bool BackfaceCulling, float *OutT, VEC3 *OutPoint, const PLANE *PolygonPlane = NULL);
03895 bool RayToPolygon(
03896 const VEC3 &RayOrig, const VEC3 &RayDir,
03897 const void *PolygonPoints, size_t PolygonPointCount, int PolygonPointStride,
03898 bool BackfaceCulling, float *OutT, VEC3 *OutPoint, const PLANE *PolygonPlane = NULL);
03899
03901
03907 bool SweptSphereToPlane(const VEC3 &SphereCenter, float SphereRadius, const VEC3 &SphereSweepDir, const PLANE &Plane, float *OutT0, float *OutT1);
03909
03913 bool SweptSphereToFrustum(const VEC3 &SphereCenter, float SphereRadius, const VEC3 &SphereSweepDir, const FRUSTUM_PLANES &Frustum);
03915
03922 bool SweptSphereToSphere(
03923 const VEC3 &SphereCenter1, float SphereRadius1,
03924 const VEC3 &SphereCenter2, float SphereRadius2,
03925 const VEC3 &SphereSweepDir1,
03926 float *OutT1, float *OutT2);
03928
03936 bool SweptBoxToBox(const BOX &Box1, const BOX &Box2, const VEC3 &SweepDirBox1, float *OutT1, float *OutT2);
03937
03942 int RayToCone(const VEC3 &rayOrig, const VEC3 & rayDir, const VEC3 &coneVertex, const VEC3 &coneDirVec, float coneHalfAngle, VEC3 intersections[2]);
03943 bool PointInCone(const VEC3 &pt, const VEC3 &coneVertex, const VEC3 &coneDirVec, float coneHalfAngle);
03944 bool SegmentIntersectsOrIsContainedInCone(const VEC3 & segmentPoint1, const VEC3 & segmentPoint2, const VEC3 & coneVertex, const VEC3 & coneDirVec, const float coneHalfAngle, VEC3 intersections[2], int &numIntersectionsFound);
03945 bool SegmentIntersectsOrIsContainedInCone(const VEC3 & segmentPoint1, const VEC3 & segmentPoint2, const VEC3 & coneVertex, const VEC3 & coneDirVec, const float coneHalfAngle);
03946
03948
03949
03951
03952 size_t ClosestPoint(const VEC2 &p, const VEC2 Points[], size_t PointCount, float *OutDistance = NULL);
03953 size_t ClosestPoint(const VEC2 &p, const void *Data, size_t PointCount, int Stride, float *OutDistance = NULL);
03955
03956 size_t ClosestPoint(const VEC3 &p, const VEC3 Points[], size_t PointCount, float *OutDistance = NULL);
03957 size_t ClosestPoint(const VEC3 &p, const void *Data, size_t PointCount, int Stride, float *OutDistance = NULL);
03959
03960 size_t FurthestPoint(const VEC2 &p, const VEC2 Points[], size_t PointCount, float *OutDistance = NULL);
03961 size_t FurthestPoint(const VEC2 &p, const void *Data, size_t PointCount, int Stride, float *OutDistance = NULL);
03963
03964 size_t FurthestPoint(const VEC3 &p, const VEC3 Points[], size_t PointCount, float *OutDistance = NULL);
03965 size_t FurthestPoint(const VEC3 &p, const void *Data, size_t PointCount, int Stride, float *OutDistance = NULL);
03967 size_t FurthestPointForDir(const VEC2 &Dir, const VEC2 Points[], size_t PointCount);
03968 size_t FurthestPointForDir(const VEC2 &Dir, const void *Data, size_t PointCount, int Stride);
03970 size_t FurthestPointForDir(const VEC3 &Dir, const VEC3 Points[], size_t PointCount);
03971 size_t FurthestPointForDir(const VEC3 &Dir, const void *Data, size_t PointCount, int Stride);
03972
03974 void RectBoundingPoints(RECTF *OutRect, const VEC2 Points[], size_t PointCount);
03975 void RectBoundingPoints(RECTF *OutRect, const void *Data, size_t PointCount, int Stride);
03977 void BoxBoundingPoints(BOX *box, const VEC3 points[], size_t PointCount);
03978 void BoxBoundingPoints(BOX *box, const void *Data, size_t PointCount, int Stride);
03980 void SphereBoundingSpheres(VEC3 *OutCenter, float *OutRadius, const VEC3 &Center1, float Radius1, const VEC3 &Center2, float Radius2);
03981
03983
03984 void CircleBoundingPoints(VEC2 *OutSphereCenter, float *OutSphereRadius, const VEC2 Points[], size_t PointCount);
03985 void CircleBoundingPoints(VEC2 *OutSphereCenter, float *OutSphereRadius, const void *PointData, size_t PointCount, int PointStride);
03987
03988 void SphereBoundingPoints(VEC3 *OutSphereCenter, float *OutSphereRadius, const VEC3 Points[], size_t PointCount);
03989 void SphereBoundingPoints(VEC3 *OutSphereCenter, float *OutSphereRadius, const void *PointData, size_t PointCount, int PointStride);
03990
03992 void OriginCircleBoundingPoints(float *OutRadius, const VEC2 Points[], size_t PointCount);
03993 void OriginCircleBoundingPoints(float *OutRadius, const void *PointData, size_t PointCount, int PointStride);
03995 void OriginSphereBoundingPoints(float *OutRadius, const VEC3 Points[], size_t PointCount);
03996 void OriginSphereBoundingPoints(float *OutRadius, const void *PointData, size_t PointCount, int PointStride);
03997
03999 void CalcCentroid(VEC2 *OutCentroid, const VEC2 Points[], size_t PointCount);
04000 void CalcCentroid(VEC2 *OutCentroid, const void *PointData, size_t PointCount, int PointStride);
04002 void CalcCentroid(VEC3 *OutCentroid, const VEC3 Points[], size_t PointCount);
04003 void CalcCentroid(VEC3 *OutCentroid, const void *PointData, size_t PointCount, int PointStride);
04004
04006 void CalcCovarianceMatrix(MATRIX33 *OutCov, const VEC3 Points[], size_t PointCount);
04007 void CalcCovarianceMatrix(MATRIX33 *OutCov, const void *PointData, size_t PointCount, int PointStride);
04009
04012 void CalcEigenvaluesAndEigenvectors(MATRIX33 *InCovOutEigenvalues, MATRIX33 *OutEigenvectors);
04013
04015 void BoxBoundingSphere(VEC3 *SphereCenter, float *SphereRadius, const BOX &Box);
04017 void SphereBoundingBox(BOX *Out, const VEC3 &SphereCenter, float SphereRadius);
04019
04020 void BoxBoundingSpheres(BOX *OutBox, const VEC3 SpheresCenter[], const float SpheresRadius[], size_t SphereCount);
04021
04023 void RandomPointInUnitSphere(VEC3 *Out, RandomGenerator &Rand);
04024 void RandomPointInUnitSphere(VEC3 *Out);
04026 void RandomPointInUnitCircle(VEC2 *Out, RandomGenerator &Rand);
04027 void RandomPointInUnitCircle(VEC2 *Out);
04028
04030
04039 void CalcBillboardOrientation(
04040 VEC3 *OutRight, VEC3 *OutUp,
04041 unsigned DegreesOfFreedom, bool UseRealDir,
04042 const VEC3 &DefinedRight, const VEC3 &DefinedUp,
04043 const VEC3 &CamRightDir, const VEC3 &CamRealUpDir, const VEC3 &CameraToObjectDir);
04044
04046
04047 class RayToTriangleCalc
04048 {
04049 public:
04051 RayToTriangleCalc() { }
04053 RayToTriangleCalc(const VEC3 &TriA, const VEC3 &TriB, const VEC3 &TriC) { Init(TriA, TriB, TriC); }
04055 void Init(const VEC3 &TriA, const VEC3 &TriB, const VEC3 &TriC);
04056
04058
04065 bool RayToTriangle(
04066 const VEC3 &RayOrig, const VEC3 &RayDir, bool BackfaceCulling,
04067 float *OutT, float *OutU, float *OutV, float *OutW, VEC3 *OutPoint) const;
04068
04069 private:
04070 PLANE m_Plane;
04071 PLANE m_EdgePlaneBC;
04072 PLANE m_EdgePlaneCA;
04073 };
04074
04075
04076
04079
04080 extern const float POISSON_DISC_1D[];
04081 const uint4 POISSON_DISC_1D_COUNT = 100;
04082
04083 extern const VEC2 POISSON_DISC_2D[];
04084 const uint4 POISSON_DISC_2D_COUNT = 100;
04085
04086 extern const VEC3 POISSON_DISC_3D[];
04087 const uint4 POISSON_DISC_3D_COUNT = 100;
04088
04090
04091
04093
04094
04095 }
04096
04097
04143
04144 #define VEC2_SWIZZLE(v, c0, c1) (common::VEC2((v).c0, (v).c1))
04145 #define VEC3_SWIZZLE(v, c0, c1, c2) (common::VEC3((v).c0, (v).c1, (v).c2))
04146 #define VEC4_SWIZZLE(v, c0, c1, c2, c3) (common::VEC4((v).c0, (v).c1, (v).c2, (v).c3))
04147
04149
04151
04152
04153
04154
04155
04156
04159
04160 template <>
04161 struct SthToStr_obj<common::POINT_>
04162 {
04163 void operator () (tstring *Str, const common::POINT_ &Sth)
04164 {
04165 *Str = common::Format(_T("#,#")) % Sth.x % Sth.y;
04166 }
04167 static inline bool IsSupported() { return true; }
04168 };
04169
04170 template <>
04171 struct StrToSth_obj<common::POINT_>
04172 {
04173 bool operator () (common::POINT_ *Sth, const tstring &Str)
04174 {
04175 size_t CommaPos = Str.find(_T(','));
04176 if (CommaPos == tstring::npos) return false;
04177 if (!StrToSth<int>(&Sth->x, Str.substr(0, CommaPos))) return false;
04178 if (!StrToSth<int>(&Sth->y, Str.substr(CommaPos+1))) return false;
04179 return true;
04180 }
04181 static inline bool IsSupported() { return true; }
04182 };
04183
04184 template <>
04185 struct SthToStr_obj<common::VEC2>
04186 {
04187 void operator () (tstring *Str, const common::VEC2 &Sth)
04188 {
04189 *Str = common::Format(_T("#,#")) % Sth.x % Sth.y;
04190 }
04191 static inline bool IsSupported() { return true; }
04192 };
04193
04194 template <>
04195 struct StrToSth_obj<common::VEC2>
04196 {
04197 bool operator () (common::VEC2 *Sth, const tstring &Str)
04198 {
04199 size_t CommaPos = Str.find(_T(','));
04200 if (CommaPos == tstring::npos) return false;
04201 if (!StrToSth<float>(&Sth->x, Str.substr(0, CommaPos))) return false;
04202 if (!StrToSth<float>(&Sth->y, Str.substr(CommaPos+1))) return false;
04203 return true;
04204 }
04205 static inline bool IsSupported() { return true; }
04206 };
04207
04208 template <>
04209 struct SthToStr_obj<common::VEC3>
04210 {
04211 void operator () (tstring *Str, const common::VEC3 &Sth)
04212 {
04213 *Str = common::Format(_T("#,#,#")) % Sth.x % Sth.y % Sth.z;
04214 }
04215 static inline bool IsSupported() { return true; }
04216 };
04217
04218 template <>
04219 struct StrToSth_obj<common::VEC3>
04220 {
04221 bool operator () (common::VEC3 *Sth, const tstring &Str)
04222 {
04223 size_t CommaPos1 = Str.find(_T(','));
04224 if (CommaPos1 == tstring::npos) return false;
04225 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04226 if (CommaPos2 == tstring::npos) return false;
04227 if (!StrToSth<float>(&Sth->x, Str.substr(0, CommaPos1))) return false;
04228 if (!StrToSth<float>(&Sth->y, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04229 if (!StrToSth<float>(&Sth->z, Str.substr(CommaPos2+1))) return false;
04230 return true;
04231 }
04232 static inline bool IsSupported() { return true; }
04233 };
04234
04235 template <>
04236 struct SthToStr_obj<common::VEC4>
04237 {
04238 void operator () (tstring *Str, const common::VEC4 &Sth)
04239 {
04240 *Str = common::Format(_T("#,#,#,#")) % Sth.x % Sth.y % Sth.z % Sth.w;
04241 }
04242 static inline bool IsSupported() { return true; }
04243 };
04244
04245 template <>
04246 struct StrToSth_obj<common::VEC4>
04247 {
04248 bool operator () (common::VEC4 *Sth, const tstring &Str)
04249 {
04250 size_t CommaPos1 = Str.find(_T(','));
04251 if (CommaPos1 == tstring::npos) return false;
04252 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04253 if (CommaPos2 == tstring::npos) return false;
04254 size_t CommaPos3 = Str.find(_T(','), CommaPos2+1);
04255 if (CommaPos3 == tstring::npos) return false;
04256 if (!StrToSth<float>(&Sth->x, Str.substr(0, CommaPos1))) return false;
04257 if (!StrToSth<float>(&Sth->y, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04258 if (!StrToSth<float>(&Sth->z, Str.substr(CommaPos2+1, CommaPos3-(CommaPos2+1)))) return false;
04259 if (!StrToSth<float>(&Sth->w, Str.substr(CommaPos3+1))) return false;
04260 return true;
04261 }
04262 static inline bool IsSupported() { return true; }
04263 };
04264
04265 template <>
04266 struct SthToStr_obj<common::RECTI>
04267 {
04268 void operator () (tstring *Str, const common::RECTI &Sth)
04269 {
04270 *Str = common::Format(_T("#,#,#,#")) % Sth.Min.x % Sth.Min.y % Sth.Max.x % Sth.Max.y;
04271 }
04272 static inline bool IsSupported() { return true; }
04273 };
04274
04275 template <>
04276 struct StrToSth_obj<common::RECTI>
04277 {
04278 bool operator () (common::RECTI *Sth, const tstring &Str)
04279 {
04280 size_t CommaPos1 = Str.find(_T(','));
04281 if (CommaPos1 == tstring::npos) return false;
04282 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04283 if (CommaPos2 == tstring::npos) return false;
04284 size_t CommaPos3 = Str.find(_T(','), CommaPos2+1);
04285 if (CommaPos3 == tstring::npos) return false;
04286 if (!StrToSth<int>(&Sth->Min.x, Str.substr(0, CommaPos1))) return false;
04287 if (!StrToSth<int>(&Sth->Min.y, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04288 if (!StrToSth<int>(&Sth->Max.x, Str.substr(CommaPos2+1, CommaPos3-(CommaPos2+1)))) return false;
04289 if (!StrToSth<int>(&Sth->Max.y, Str.substr(CommaPos3+1))) return false;
04290 return true;
04291 }
04292 static inline bool IsSupported() { return true; }
04293 };
04294
04295 template <>
04296 struct SthToStr_obj<common::RECTF>
04297 {
04298 void operator () (tstring *Str, const common::RECTF &Sth)
04299 {
04300 *Str = common::Format(_T("#,#,#,#")) % Sth.Min.x % Sth.Min.y % Sth.Max.x % Sth.Max.y;
04301 }
04302 static inline bool IsSupported() { return true; }
04303 };
04304
04305 template <>
04306 struct StrToSth_obj<common::RECTF>
04307 {
04308 bool operator () (common::RECTF *Sth, const tstring &Str)
04309 {
04310 size_t CommaPos1 = Str.find(_T(','));
04311 if (CommaPos1 == tstring::npos) return false;
04312 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04313 if (CommaPos2 == tstring::npos) return false;
04314 size_t CommaPos3 = Str.find(_T(','), CommaPos2+1);
04315 if (CommaPos3 == tstring::npos) return false;
04316 if (!StrToSth<float>(&Sth->Min.x, Str.substr(0, CommaPos1))) return false;
04317 if (!StrToSth<float>(&Sth->Min.y, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04318 if (!StrToSth<float>(&Sth->Max.x, Str.substr(CommaPos2+1, CommaPos3-(CommaPos2+1)))) return false;
04319 if (!StrToSth<float>(&Sth->Max.y, Str.substr(CommaPos3+1))) return false;
04320 return true;
04321 }
04322 static inline bool IsSupported() { return true; }
04323 };
04324
04325 template <>
04326 struct SthToStr_obj<common::BOX>
04327 {
04328 void operator () (tstring *Str, const common::BOX &Sth)
04329 {
04330 *Str = common::Format(_T("#;#")) % Sth.Min % Sth.Max;
04331 }
04332 static inline bool IsSupported() { return true; }
04333 };
04334
04335 template <>
04336 struct StrToSth_obj<common::BOX>
04337 {
04338 bool operator () (common::BOX *Sth, const tstring &Str)
04339 {
04340 size_t SemicolonPos = Str.find(_T(';'));
04341 if (SemicolonPos == tstring::npos) return false;
04342 if (!StrToSth<common::VEC3>(&Sth->Min, Str.substr(0, SemicolonPos))) return false;
04343 if (!StrToSth<common::VEC3>(&Sth->Max, Str.substr(SemicolonPos+1))) return false;
04344 return true;
04345 }
04346 static inline bool IsSupported() { return true; }
04347 };
04348
04349 template <> struct SthToStr_obj<common::COLOR> {
04350 void operator () (tstring *Str, const common::COLOR &Sth) { common::ColorToStr(Str, Sth); }
04351 static inline bool IsSupported() { return true; }
04352 };
04353 template <> struct StrToSth_obj<common::COLOR> {
04354 bool operator () (common::COLOR *Sth, const tstring &Str) { return common::StrToColor(Sth, Str); }
04355 static inline bool IsSupported() { return true; }
04356 };
04357
04358 template <> struct SthToStr_obj<common::COLORF> {
04359 void operator () (tstring *Str, const common::COLORF &Sth) { common::ColorToStr(Str, Sth); }
04360 static inline bool IsSupported() { return true; }
04361 };
04362 template <> struct StrToSth_obj<common::COLORF> {
04363 bool operator () (common::COLORF *Sth, const tstring &Str) { return common::StrToColor(Sth, Str); }
04364 static inline bool IsSupported() { return true; }
04365 };
04366
04367 template <>
04368 struct SthToStr_obj<common::PLANE>
04369 {
04370 void operator () (tstring *Str, const common::PLANE &Sth)
04371 {
04372 *Str = common::Format(_T("#,#,#,#")) % Sth.a % Sth.b % Sth.c % Sth.d;
04373 }
04374 static inline bool IsSupported() { return true; }
04375 };
04376
04377 template <>
04378 struct StrToSth_obj<common::PLANE>
04379 {
04380 bool operator () (common::PLANE *Sth, const tstring &Str)
04381 {
04382 size_t CommaPos1 = Str.find(_T(','));
04383 if (CommaPos1 == tstring::npos) return false;
04384 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04385 if (CommaPos2 == tstring::npos) return false;
04386 size_t CommaPos3 = Str.find(_T(','), CommaPos2+1);
04387 if (CommaPos3 == tstring::npos) return false;
04388 if (!StrToSth<float>(&Sth->a, Str.substr(0, CommaPos1))) return false;
04389 if (!StrToSth<float>(&Sth->b, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04390 if (!StrToSth<float>(&Sth->c, Str.substr(CommaPos2+1, CommaPos3-(CommaPos2+1)))) return false;
04391 if (!StrToSth<float>(&Sth->d, Str.substr(CommaPos3+1))) return false;
04392 return true;
04393 }
04394 static inline bool IsSupported() { return true; }
04395 };
04396
04397 template <>
04398 struct SthToStr_obj<common::LINE2D>
04399 {
04400 void operator () (tstring *Str, const common::LINE2D &Sth)
04401 {
04402 *Str = common::Format(_T("#,#,#")) % Sth.a % Sth.b % Sth.c;
04403 }
04404 static inline bool IsSupported() { return true; }
04405 };
04406
04407 template <>
04408 struct StrToSth_obj<common::LINE2D>
04409 {
04410 bool operator () (common::LINE2D *Sth, const tstring &Str)
04411 {
04412 size_t CommaPos1 = Str.find(_T(','));
04413 if (CommaPos1 == tstring::npos) return false;
04414 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04415 if (CommaPos2 == tstring::npos) return false;
04416 if (!StrToSth<float>(&Sth->a, Str.substr(0, CommaPos1))) return false;
04417 if (!StrToSth<float>(&Sth->b, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04418 if (!StrToSth<float>(&Sth->c, Str.substr(CommaPos2+1))) return false;
04419 return true;
04420 }
04421 static inline bool IsSupported() { return true; }
04422 };
04423
04424 template <> struct SthToStr_obj<common::MATRIX> {
04425 void operator () (tstring *Str, const common::MATRIX &Sth) { common::MatrixToStr(Str, Sth); }
04426 static inline bool IsSupported() { return true; }
04427 };
04428 template <> struct StrToSth_obj<common::MATRIX> {
04429 bool operator () (common::MATRIX *Sth, const tstring &Str) { return common::StrToMatrix(Sth, Str); }
04430 static inline bool IsSupported() { return true; }
04431 };
04432
04433 template <>
04434 struct SthToStr_obj<common::QUATERNION>
04435 {
04436 void operator () (tstring *Str, const common::QUATERNION &Sth)
04437 {
04438 *Str = common::Format(_T("#,#,#,#")) % Sth.x % Sth.y % Sth.z % Sth.w;
04439 }
04440 static inline bool IsSupported() { return true; }
04441 };
04442
04443 template <>
04444 struct StrToSth_obj<common::QUATERNION>
04445 {
04446 bool operator () (common::QUATERNION *Sth, const tstring &Str)
04447 {
04448 size_t CommaPos1 = Str.find(_T(','));
04449 if (CommaPos1 == tstring::npos) return false;
04450 size_t CommaPos2 = Str.find(_T(','), CommaPos1+1);
04451 if (CommaPos2 == tstring::npos) return false;
04452 size_t CommaPos3 = Str.find(_T(','), CommaPos2+1);
04453 if (CommaPos3 == tstring::npos) return false;
04454 if (!StrToSth<float>(&Sth->x, Str.substr(0, CommaPos1))) return false;
04455 if (!StrToSth<float>(&Sth->y, Str.substr(CommaPos1+1, CommaPos2-(CommaPos1+1)))) return false;
04456 if (!StrToSth<float>(&Sth->z, Str.substr(CommaPos2+1, CommaPos3-(CommaPos2+1)))) return false;
04457 if (!StrToSth<float>(&Sth->w, Str.substr(CommaPos3+1))) return false;
04458 return true;
04459 }
04460 static inline bool IsSupported() { return true; }
04461 };
04462
04463 template <>
04464 struct SthToStr_obj<common::AFFINE2D>
04465 {
04466 void operator () (tstring *Str, const common::AFFINE2D &Sth)
04467 {
04468 common::Affine2dToStr(Str, Sth);
04469 }
04470 static inline bool IsSupported() { return true; }
04471 };
04472
04473 template <>
04474 struct StrToSth_obj<common::AFFINE2D>
04475 {
04476 bool operator () (common::AFFINE2D *Sth, const tstring &Str)
04477 {
04478 return common::StrToAffine2d(Sth, Str);
04479 }
04480 static inline bool IsSupported() { return true; }
04481 };
04482
04484
04485 #endif