glfxvec.h

00001 /*-------------------------------------------------------------------------
00002 This source code is part of GLfx library (OpenGL effect library)
00003 For more information and updates see http://glfx.sourceforge.net/
00004 Copyright (C) 2005-6 Tomek Rozen <trozen at users sourceforge net>
00005 
00006 This library is free software; you can redistribute it and/or modify it
00007 under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation; either version 2.1 of the License,
00009 or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful, but WITHOUT
00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00014 for more details.
00015 -------------------------------------------------------------------------*/
00016 
00017 // Version: 8 (increment this number with every significant change)
00018 // Note that this file may be used without the rest of GLFX library
00019 // as it does not depend on other headers and source files
00020 // (all declarations and implementation is inlined into this file).
00021 
00022 #ifndef __GLFXVEC_H__
00023 #define __GLFXVEC_H__
00024 
00025 #include <math.h>
00026 #include <assert.h>
00027 
00028 #pragma pack(4)
00029 
00030 namespace GLFX {
00031 
00032 // ========================================================================
00033 // Types and constants
00034 
00036 const float PI = 3.14159265358979323846f;
00038 const float TWOPI = PI * 2;
00040 const float EPSILON = 1e-4f;
00041 
00042 // ========================================================================
00043 // Helper functions
00044 
00046 inline float ToRadians(float degrees) {
00047     return degrees * PI / 180.0f;
00048 }
00049 
00051 inline float ToDegrees(float radians) {
00052     return radians * 180.0f / PI;
00053 }
00054 
00055 // ========================================================================
00056 // Types
00057 
00058 struct Vec2;
00059 struct Vec3;
00060 struct Vec4;
00061 struct Quat;
00062 struct Matrix3;
00063 struct Matrix4;
00064 struct Color;
00065 
00066 // ========================================================================
00067 // Vectors
00068 
00070 struct Vec2
00071 {
00073     float x;
00075     float y;
00076 
00077     inline Vec2();
00079     inline Vec2(const float* v);
00081     inline Vec2(const Vec2& v);
00083     inline Vec2(float x, float y);
00085     inline Vec2(float f);
00086 
00088     inline operator float*();
00090     inline operator const float*() const;
00092     inline operator Vec3() const;
00094     inline operator Vec4() const;
00096     inline float& operator[](int n);
00098     inline Vec2& operator=(const Vec2& v);
00100     inline Vec2& operator*=(const Vec2& v);
00102     inline Vec2& operator/=(const Vec2& v);
00104     inline Vec2& operator+=(const Vec2& v);
00106     inline Vec2& operator-=(const Vec2& v);
00107 
00109     inline Vec2& Normalize();
00111     inline float Length() const;
00113     inline bool Equal(const Vec2& v) const;
00115     inline bool NotEqual(const Vec2& v)const ;
00116     
00117     friend Vec2 operator*(const Vec2& a, const Vec2& b);
00118     friend Vec2 operator/(const Vec2& a, const Vec2& b);
00119     friend Vec2 operator+(const Vec2& a, const Vec2& b);
00120     friend Vec2 operator+(const Vec2& v);
00121     friend Vec2 operator-(const Vec2& a, const Vec2& b);
00122     friend Vec2 operator-(const Vec2& v);
00123     friend bool operator==(const Vec2& a, const Vec2& b);
00124     friend bool operator!=(const Vec2& a, const Vec2& b);
00125 
00126     friend Vec2 Perpendicular(const Vec2& v);
00127     friend float Dot(const Vec2& a, const Vec2& b);
00128     friend Vec2 Normalize(const Vec2& v);
00129     friend Vec2 Lerp(const Vec2& a, const Vec2& b, float f);
00130     friend float Length(const Vec2& a);
00131 };
00132 
00134 struct Vec3
00135 {
00136 
00138     float x;
00140     float y;
00142     float z;
00143 
00144     inline Vec3();
00146     inline Vec3(const float* v);
00148     inline Vec3(const Vec3& v);
00150     inline Vec3(float x, float y, float z);
00152     inline Vec3(float f);
00153 
00155     inline operator float*();
00157     inline operator const float*() const;
00159     inline operator Vec2() const;
00161     inline operator Vec4() const;
00163     inline float& operator[](int n);
00165     inline Vec3& operator=(const Vec3& v);
00167     inline Vec3& Normalize();
00169     inline float Length() const;
00171     inline bool Equal(const Vec3& v) const;
00173     inline bool NotEqual(const Vec3& v) const;
00175     inline Vec3 MakePlanar(const Vec3& v) const;
00176 
00178     inline Vec3& operator*=(const Vec3& v);
00180     inline Vec3& operator/=(const Vec3& v);
00182     inline Vec3& operator+=(const Vec3& v);
00184     inline Vec3& operator-=(const Vec3& v);
00185     
00186     friend Vec3 operator*(const Vec3& a, const Vec3& b);
00187     friend Vec3 operator/(const Vec3& a, const Vec3& b);
00188     friend Vec3 operator+(const Vec3& a, const Vec3& b);
00189     friend Vec3 operator+(const Vec3& v);
00190     friend Vec3 operator-(const Vec3& a, const Vec3& b);
00191     friend Vec3 operator-(const Vec3& v);
00192     friend bool operator==(const Vec3& a, const Vec3& b);
00193     friend bool operator!=(const Vec3& a, const Vec3& b);
00194     friend bool operator<(const Vec3& a, const Vec3& b);
00195 
00196     friend Vec3 Cross(const Vec3& a, const Vec3& b);
00197     friend float Dot(const Vec3& a, const Vec3& b);
00198     friend Vec3 Normalize(const Vec3& v);
00199     friend Vec3 Lerp(const Vec3& a, const Vec3& b, float f);
00200     friend Vec3 RotateVectorX(const Vec3& v, float angle);
00201     friend Vec3 RotateVectorY(const Vec3& v, float angle);
00202     friend Vec3 RotateVectorZ(const Vec3& v, float angle);
00203     friend float Length(const Vec3& a);
00204 
00205 };
00206 
00208 struct Vec4
00209 {
00210 
00212     float x;
00214     float y;
00216     float z;
00218     float w;
00219 
00220     inline Vec4();
00222     inline Vec4(const float* v);
00224     inline Vec4(const Vec4& v);
00226     inline Vec4(const Vec3& v, float w);
00228     inline Vec4(float x, float y, float z, float w);
00230     inline Vec4(float f);
00231 
00233     inline operator float*();
00235     inline operator const float*() const;
00237     inline operator Vec3() const;
00239     inline operator const Vec3&() const;
00241     inline float& operator[](int n);
00243     inline Vec4& operator=(const Vec4& v);
00245     inline Vec4& operator*=(const Vec4& v);
00247     inline Vec4& operator/=(const Vec4& v);
00249     inline Vec4& operator+=(const Vec4& v);
00251     inline Vec4& operator-=(const Vec4& v);
00253     inline Vec3& N();
00255     inline const Vec3& N() const;
00257     inline bool Equal(const Vec4& v) const;
00259     inline bool NotEqual(const Vec4& v) const;
00260     
00262     inline float Eval(const Vec3& point) const;
00264     inline bool Coplanar(const Vec4& v) const;
00266     inline bool RayIntersect(Vec3& out, const Vec3& org, const Vec3& dir) const;
00268     inline bool LineIntersect(Vec3& out, const Vec3& beg, const Vec3& end) const;
00270     inline Vec3 MirrorPoint(const Vec3& point) const;
00272     inline Vec3 MirrorVector(const Vec3& point) const;
00274     inline Vec4 MirrorPlane(const Vec4& plane) const;
00276     inline Vec3 ProjectPoint(const Vec3& point) const;
00278     inline bool PointOnPlane(const Vec3& point) const;
00279 
00280     friend Vec4 operator*(const Vec4& a, const Vec4& b);
00281     friend Vec4 operator/(const Vec4& a, const Vec4& b);
00282     friend Vec4 operator+(const Vec4& a, const Vec4& b);
00283     friend Vec4 operator+(const Vec4& v);
00284     friend Vec4 operator-(const Vec4& a, const Vec4& b);
00285     friend Vec4 operator-(const Vec4& v);
00286     friend bool operator==(const Vec4& a, const Vec4& b);
00287     friend bool operator!=(const Vec4& a, const Vec4& b);
00288     friend bool PlanesIntersect(Vec3& out, const Vec4& a, const Vec4& b, const Vec4& c);
00289     friend Vec4 PlaneFromPoint(const Vec3& point, const Vec3& normal);
00290     friend Vec4 PlaneFromPoints(const Vec3& a, const Vec3& b, const Vec3& c);
00291     friend Vec4 PlaneFromEdge(const Vec3& begin, const Vec3& end, const Vec3& normal);
00292     friend Vec4 Lerp(const Vec4& a, const Vec4& b, float f);
00293 
00294 };
00295 
00296 // ========================================================================
00297 // Quaternion
00298 
00304 struct Quat
00305 {
00307     float x;
00309     float y;
00311     float z;
00313     float w;
00314 
00315     inline Quat();
00317     inline Quat(const float* q);
00319     inline Quat(const Quat& q);
00321     inline Quat(const Vec3& v, float w);
00323     inline Quat(float x, float y, float z, float w);
00325     inline Quat(float f);
00326 
00328     inline operator float*();
00330     inline operator const float*() const;
00332     inline operator Vec4() const;
00334     inline float& operator[](int n);
00336     inline Quat& operator=(const Quat& q);
00337 
00339     inline Quat& operator*=(const Quat& q);
00341     inline Quat& operator*=(const float f);
00343     inline Quat& operator+=(const Quat& q);
00345     inline Quat& operator-=(const Quat& q);
00346 
00348     inline Vec3& N();
00350     inline const Vec3& N() const;
00351 
00353     inline Vec3 TransformVector(const Vec3& v) const;
00354 
00355     friend Quat operator*(const Quat& a, const Quat& b);
00356     friend Quat operator*(const Quat& q, float f);
00357     friend Quat operator*(float f, const Quat& q);
00358     friend Quat operator+(const Quat& a, const Quat& b);
00359     friend Quat operator+(const Quat& q);
00360     friend Quat operator-(const Quat& a, const Quat& b);
00361     friend Quat operator-(const Quat& q);
00362     friend bool operator==(const Quat& a, const Quat& b);
00363     friend bool operator!=(const Quat& a, const Quat& b);
00364 
00365     friend Quat Normalize(const Quat& q);
00366     friend float Dot(const Quat& a, const Quat& b);
00367     friend Quat Slerp(const Quat& a, const Quat& b, float f, bool shortestPath);
00368     friend Quat Inverse(const Quat& q);
00369     friend Quat UnitInverse(const Quat& q);
00370     friend Quat QuaternionFromAngleAxis(const Vec3& axis, float angle);
00371     friend Quat QuaternionRotationYawPitchRoll(float yaw, float pitch, float roll);
00372     friend Quat QuaternionRotationYawPitchRoll(const Vec3& angles);
00373 
00374 };
00375 
00376 // ========================================================================
00377 // Matrices
00378 
00380 struct Matrix3
00381 {
00383     float _11;
00385     float _12;
00387     float _13;
00389     float _21;
00391     float _22;
00393     float _23;
00395     float _31;
00397     float _32;
00399     float _33;
00400 
00401     inline Matrix3();
00403     inline Matrix3(const float* m);
00405     inline Matrix3(const Matrix3& m);
00407     inline Matrix3(float _11, float _12, float _13, float _21, float _22, float _23, float _31, float _32, float _33);
00409     inline Matrix3(float f);
00411     inline operator float*();
00413     inline operator const float*() const;
00415     inline operator Matrix4() const;
00417     inline Vec3& operator[](int n);
00419     inline float& operator()(int n, int m);
00421     inline Matrix3& operator=(const Matrix3& m);
00422 
00424     inline Matrix3& operator*=(const Matrix3& m);
00425 
00427     inline float Det() const;
00429     inline Vec2 TransformPoint(const Vec2& tc) const;
00430 
00431     friend Matrix3 operator*(const Matrix3& a, const Matrix3& b);
00432     friend float Det(const Matrix3& m);
00433     friend Matrix3 MatrixTextureRotation(float angle);
00434     friend Matrix3 MatrixTextureTranslation(float u, float v);
00435     friend Matrix3 MatrixTextureTranslation(const Vec2& v);
00436     friend Matrix3 MatrixTextureScaling(float u, float v);
00437     friend Matrix3 MatrixTextureScaling(const Vec2& v);
00438 
00439 };
00440 
00442 struct Matrix4
00443 {
00444 
00446     float _11;
00448     float _12;
00450     float _13;
00452     float _14;
00454     float _21;
00456     float _22;
00458     float _23;
00460     float _24;
00462     float _31;
00464     float _32;
00466     float _33;
00468     float _34;
00470     float _41;
00472     float _42;
00474     float _43;
00476     float _44;
00477 
00478     inline Matrix4();
00480     inline Matrix4(const float* m);
00482     inline Matrix4(const Matrix4& m);
00484     inline Matrix4(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);
00486     inline Matrix4(float f);
00488     inline operator float*();
00490     inline operator const float*() const;
00492     inline operator Matrix3() const;
00494     inline Vec4& operator[](int n);
00496     inline float& operator()(int n, int m);
00498     inline Matrix4& operator=(const Matrix4& m);
00499 
00501     inline Matrix4& operator*=(const Matrix4& a);
00502 
00504     inline float Det() const;
00506     inline Matrix4& Inverse();
00508     inline Matrix4& Transpose();
00509 
00511     inline Vec3 TransformPoint(const Vec3& point) const;
00513     inline Vec3 TransformVector(const Vec3& vector) const;
00514 
00515     friend Matrix4 operator*(const Matrix4& a, const Matrix4& b);
00516     friend Matrix4 MatrixTranslation(float x, float y, float z);
00517     friend Matrix4 MatrixTranslation(const Vec3& v);
00518     friend Matrix4 MatrixRotationX(float angle);
00519     friend Matrix4 MatrixRotationY(float angle);
00520     friend Matrix4 MatrixRotationZ(float angle);
00521     friend Matrix4 MatrixRotationQuaternion(const Quat& quat);
00522     friend Matrix4 MatrixRotationYawPitchRoll(float yaw, float pitch, float roll);
00523     friend Matrix4 MatrixRotationYawPitchRoll(const Vec3& angles);
00524     friend Matrix4 MatrixScaling(float x, float y, float z);
00525     friend Matrix4 MatrixScaling(const Vec3& v);
00526     friend Matrix4 MatrixPerspectiveFovXRH(float fovx, float aspect, float znear, float zfar);
00527     friend Matrix4 MatrixPerspectiveFovYRH(float fovy, float aspect, float znear, float zfar);
00528     friend Matrix4 MatrixOrthoRH(float w, float h, float zn, float zf);
00529     friend Matrix4 MatrixOrthoLH(float w, float h, float zn, float zf);
00530     friend Matrix4 MatrixLookAtRH(const Vec3& eye, const Vec3& at, const Vec3& up);
00531     friend float Det(const Matrix4& m);
00532     friend Matrix4 Inverse(const Matrix4& m);
00533     friend Matrix4 Transpose(const Matrix4& m);
00534 
00535 };
00536 
00537 // ========================================================================
00538 
00540 struct Color
00541 {
00543     unsigned char blue;
00545     unsigned char green;
00547     unsigned char red;
00549     unsigned char alpha;
00550 
00551     inline Color();
00553     inline Color(const Vec3& v);
00555     inline Color(const Vec4& v);
00557     inline Color(float r, float g, float b, float a = 1.0f);
00559     inline Color(int r, int g, int b, int a = 255);
00561     inline Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255);
00563     inline Color(const Color& c);
00565     inline Color(unsigned long c);
00567     inline Color(long c);
00569     inline Color(unsigned int c);
00571     inline Color(int c);
00573     inline Color(float c);
00574 
00576     inline operator Vec3() const;
00578     inline operator Vec4() const;
00580     inline operator unsigned char*() const;
00581 
00583     inline Color& operator*=(Color c);
00584 
00586     inline unsigned long ARGB() const;
00587 
00589     inline unsigned long& ARGB();
00590 
00592     inline float Redf() const;
00594     inline float Greenf() const;
00596     inline float Bluef() const;
00598     inline float Alphaf() const;
00599 
00600     friend Color operator*(Color a, Color b);
00601 
00602 };
00603 
00604 // ========================================================================
00605 // Various geometric functions
00606 
00608 inline bool PointInTriangle(const Vec3& point, const Vec3& a, const Vec3& b, const Vec3& c);
00610 inline void LinesNearestPoints(Vec3 out1, Vec3 out2, const Vec3& org1, const Vec3& dir1, const Vec3& org2, const Vec3& dir2);
00612 inline bool TriangleSameWinding(const Vec3& a1, const Vec3& a2, const Vec3& a3, const Vec3& b1, const Vec3& b2, const Vec3& b3);
00614 inline bool TriangleWindingCheck(const Vec3& a1, const Vec3& a2, const Vec3& a3, const Vec3& normal);
00616 inline float PointRayDist(const Vec3& point, const Vec3& org, const Vec3& dir);
00618 inline float PointSegmentDist(const Vec3& point, const Vec3& a, const Vec3& b);
00620 inline float RaySegmentDist(const Vec3& org, const Vec3& dir, const Vec3& a, const Vec3& b);
00622 inline bool LineShapeIntersect(Vec3& intersect, const Vec3& beg, const Vec3& end, const Vec4& shapePlane, const Vec3* shape, int shapeCount);
00624 inline bool PointInPoly(const Vec3& pnt, const Vec3* shape, int length, const Vec3& normal);
00626 inline float PointShapeDist(const Vec3& point, const Vec3* shape, int length, const Vec4& plane);
00628 inline bool PointsAreCollinear(const Vec3& a, const Vec3& b, const Vec3& c);
00629 
00630 // ========================================================================
00631 // Implementations starts here
00632 // ========================================================================
00633 // Vec2 methods
00634 
00635 inline Vec2::Vec2() {
00636 }
00637 
00638 inline Vec2::Vec2(const float* v) {
00639     x = v[0]; y = v[1];
00640 }
00641 
00642 inline Vec2::Vec2(const Vec2& v) {
00643     x = v.x; y = v.y;
00644 }
00645 
00646 inline Vec2::Vec2(float x, float y) {
00647     this->x = x; this->y = y;
00648 }
00649 
00650 inline Vec2::Vec2(float f) {
00651     x = y = f;
00652 }
00653 
00654 inline Vec2::operator float*() {
00655     return (float*)this;
00656 }
00657 
00658 inline Vec2::operator const float*() const {
00659     return (const float*)this;
00660 }
00661 
00662 inline Vec2::operator Vec3() const {
00663     return Vec3(x, y, 0);
00664 }
00665 
00666 inline Vec2::operator Vec4() const {
00667     return Vec4(x, y, 0, 0);
00668 }
00669 
00670 inline float& Vec2::operator[](int n) {
00671     assert(n >= 0 && n < 2);
00672     return *((float*)this + n);
00673 }
00674 
00675 inline Vec2& Vec2::operator=(const Vec2& v) {
00676     x = v.x; y = v.y;
00677     return *this;
00678 }
00679 
00680 inline Vec2& Vec2::operator*=(const Vec2& v) {
00681     x *= v.x; y *= v.y;
00682     return *this;
00683 }
00684 
00685 inline Vec2& Vec2::operator/=(const Vec2& v) {
00686     x /= v.x; y /= v.y;
00687     return *this;
00688 }
00689 
00690 inline Vec2& Vec2::operator+=(const Vec2& v) {
00691     x += v.x; y += v.y;
00692     return *this;
00693 }
00694 
00695 inline Vec2& Vec2::operator-=(const Vec2& v) {
00696     x -= v.x; y -= v.y;
00697     return *this;
00698 }
00699 
00700 inline Vec2& Vec2::Normalize() {
00701     *this /= Length();
00702     return *this;
00703 }
00704 
00705 inline float Vec2::Length() const {
00706     return (float)sqrt(x * x + y * y);
00707 }
00708 
00709 inline bool Vec2::Equal(const Vec2& v) const {
00710     return fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON;
00711 }
00712 
00713 inline bool Vec2::NotEqual(const Vec2& v) const {
00714     return fabs(x - v.x) >= EPSILON && fabs(y - v.y) >= EPSILON;
00715 }
00716 
00718 inline Vec2 operator*(const Vec2& a, const Vec2& b) {
00719     return Vec2(a.x * b.x, a.y * b.y);
00720 }
00721 
00723 inline Vec2 operator/(const Vec2& a, const Vec2& b) {
00724     return Vec2(a.x / b.x, a.y / b.y);
00725 }
00726 
00728 inline Vec2 operator+(const Vec2& a, const Vec2& b) {
00729     return Vec2(a.x + b.x, a.y + b.y);
00730 }
00731 
00733 inline Vec2 operator+(const Vec2& v) {
00734     return v;
00735 }
00736 
00738 inline Vec2 operator-(const Vec2& a, const Vec2& b) {
00739     return Vec2(a.x - b.x, a.y - b.y);
00740 }
00741 
00743 inline Vec2 operator-(const Vec2& v) {
00744     return Vec2(-v.x, -v.y);
00745 }
00746 
00748 inline bool operator==(const Vec2& a, const Vec2& b) {
00749     return a.x == b.x && a.y == b.y;
00750 }
00751 
00753 inline bool operator!=(const Vec2& a, const Vec2& b) {
00754     return a.x != b.x || a.y != b.y;
00755 }
00756 
00758 inline Vec2 Perpendicular(const Vec2& v) {
00759     return Vec2(-v.y, v.x);
00760 }
00761 
00763 inline float Dot(const Vec2& a, const Vec2& b) {
00764     return a.x * b.x + a.y * b.y;
00765 }
00766 
00768 inline Vec2 Normalize(const Vec2& v) {
00769     return v / v.Length();
00770 }
00771 
00773 inline Vec2 Lerp(const Vec2& a, const Vec2& b, float f) {
00774     return Vec2(a.x * (1.0f - f) + b.x * f, a.y * (1.0f - f) + b.y * f);
00775 }
00776 
00778 inline float Length(const Vec2& a) {
00779     return a.Length();
00780 }
00781 
00782 // ========================================================================
00783 // Vec3 methods
00784 
00785 inline Vec3::Vec3() {
00786 }
00787 
00788 inline Vec3::Vec3(const float* v) {
00789     x = v[0]; y = v[1]; z = v[2];
00790 }
00791 
00792 inline Vec3::Vec3(const Vec3& v) {
00793     x = v.x; y = v.y; z = v.z;
00794 }
00795 
00796 inline Vec3::Vec3(float x, float y, float z) {
00797     this->x = x; this->y = y; this->z = z;
00798 }
00799 
00800 inline Vec3::Vec3(float f) {
00801     x = y = z = f;
00802 }
00803 
00804 inline Vec3::operator float*() {
00805     return (float*)this;
00806 }
00807 
00808 inline Vec3::operator const float*() const {
00809     return (const float*)this;
00810 }
00811 
00812 inline Vec3::operator Vec2() const {
00813     return Vec2(x, y);
00814 }
00815 
00816 inline Vec3::operator Vec4() const {
00817     return Vec4(x, y, z, 0);
00818 }
00819 
00820 inline float& Vec3::operator[](int n) {
00821     assert(n >= 0 && n < 3);
00822     return ((float*)this)[n];
00823 }
00824 
00825 inline Vec3& Vec3::operator=(const Vec3& v) {
00826     x = v.x; y = v.y; z = v.z;
00827     return *this;
00828 }
00829 
00830 inline Vec3& Vec3::Normalize() {
00831     *this /= Length();
00832     return *this;
00833 }
00834 
00835 inline float Vec3::Length() const {
00836     return (float)sqrt(x * x + y * y + z * z);
00837 }
00838 
00839 inline bool Vec3::Equal(const Vec3& v) const {
00840     return (float)fabs(x - v.x) < EPSILON && (float)fabs(y - v.y) < EPSILON && (float)fabs(z - v.z) < EPSILON;
00841 }
00842 
00843 inline bool Vec3::NotEqual(const Vec3& v) const {
00844     return (float)fabs(x - v.x) >= EPSILON || (float)fabs(y - v.y) >= EPSILON || (float)fabs(z - v.z) >= EPSILON;
00845 }
00846 
00847 inline Vec3 Vec3::MakePlanar(const Vec3& v) const {
00848     return v - *this * Dot(*this, v);
00849 }
00850 
00851 inline Vec3& Vec3::operator*=(const Vec3& v) {
00852     x *= v.x; y *= v.y; z *= v.z;
00853     return *this;
00854 }
00855 
00856 inline Vec3& Vec3::operator/=(const Vec3& v) {
00857     x /= v.x; y /= v.y; z /= v.z;
00858     return *this;
00859 }
00860 
00861 inline Vec3& Vec3::operator+=(const Vec3& v) {
00862     x += v.x; y += v.y; z += v.z;
00863     return *this;
00864 }
00865 
00866 inline Vec3& Vec3::operator-=(const Vec3& v) {
00867     x -= v.x; y -= v.y; z -= v.z;
00868     return *this;
00869 }
00870 
00872 inline Vec3 operator*(const Vec3& a, const Vec3& b) {
00873     return Vec3(a.x * b.x, a.y * b.y, a.z * b.z);
00874 }
00875 
00877 inline Vec3 operator/(const Vec3& a, const Vec3& b) {
00878     return Vec3(a.x / b.x, a.y / b.y, a.z / b.z);
00879 }
00880 
00882 inline Vec3 operator/(float f, const Vec3& v) {
00883     return Vec3(f / v.x, f / v.y, f / v.z);
00884 }
00885 
00887 inline Vec3 operator+(const Vec3& a, const Vec3& b) {
00888     return Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
00889 }
00890 
00892 inline Vec3 operator+(const Vec3& v) {
00893     return v;
00894 }
00895 
00897 inline Vec3 operator-(const Vec3& a, const Vec3& b) {
00898     return Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
00899 }
00900 
00902 inline Vec3 operator-(const Vec3& v) {
00903     return Vec3(-v.x, -v.y, -v.z);
00904 }
00905 
00907 inline bool operator==(const Vec3& a, const Vec3& b) {
00908     return a.x == b.x && a.y == b.y && a.z == b.z;
00909 }
00910 
00912 inline bool operator!=(const Vec3& a, const Vec3& b) {
00913     return a.x != b.x || a.y != b.y || a.z != b.z;
00914 }
00915 
00917 inline bool operator<(const Vec3& a, const Vec3& b) {
00918     return a.x < b.x || a.y < b.y || a.z < b.z;
00919 }
00920 
00922 inline Vec3 Cross(const Vec3& a, const Vec3& b) {
00923     return Vec3(a.y * b.z - a.z * b.y,
00924                 a.z * b.x - a.x * b.z,
00925                 a.x * b.y - a.y * b.x);
00926 }
00927 
00929 inline float Dot(const Vec3& a, const Vec3& b) {
00930     return a.x * b.x + a.y * b.y + a.z * b.z;
00931 }
00932 
00934 inline Vec3 Normalize(const Vec3& v) {
00935     return v / v.Length();
00936 }
00937 
00939 inline Vec3 Lerp(const Vec3& a, const Vec3& b, float f) {
00940     return Vec3(a.x * (1.0f - f) + b.x * f, a.y * (1.0f - f) + b.y * f, a.z * (1.0f - f) + b.z * f);
00941 }
00942 
00944 inline float Length(const Vec3& a) {
00945     return a.Length();
00946 }
00947 
00949 inline Vec3 RotateVectorX(const Vec3& v, float angle) {
00950     return Vec3(v.x,
00951                 v.y * (float)cos(angle) - v.z * (float)sin(angle),
00952                 v.y * (float)sin(angle) + v.z * (float)cos(angle));
00953 }
00954 
00956 inline Vec3 RotateVectorY(const Vec3& v, float angle) {
00957     return Vec3(v.x * (float)cos(angle) + v.z * (float)sin(angle),
00958                 v.y,
00959                 -v.x * (float)sin(angle) + v.z * (float)cos(angle));
00960 
00961 }
00962 
00964 inline Vec3 RotateVectorZ(const Vec3& v, float angle) {
00965     return Vec3(v.x * (float)cos(angle) - v.y * (float)sin(angle),
00966                 v.x * (float)sin(angle) + v.y * (float)cos(angle),
00967                 v.z);
00968 }
00969 
00970 // ========================================================================
00971 // Vec4 methods
00972 
00973 inline Vec4::Vec4() {
00974 }
00975 
00976 inline Vec4::Vec4(const float* v) {
00977     x = v[0]; y = v[1]; z = v[2]; w = v[3];
00978 }
00979 
00980 inline Vec4::Vec4(const Vec4& v) {
00981     x = v.x; y = v.y; z = v.z; w = v.w;
00982 }
00983 
00984 inline Vec4::Vec4(const Vec3& v, float w) {
00985     x = v.x; y = v.y; z = v.z; this->w = w;
00986 }
00987 
00988 inline Vec4::Vec4(float x, float y, float z, float w) {
00989     this->x = x; this->y = y; this->z = z; this->w = w;
00990 }
00991 
00992 inline Vec4::Vec4(float f) {
00993     x = y = z = w = f;
00994 }
00995 
00996 inline Vec4::operator float*() {
00997     return (float*)this;
00998 }
00999 
01000 inline Vec4::operator const float*() const {
01001     return (const float*)this;
01002 }
01003 
01004 inline Vec4::operator Vec3() const {
01005     return Vec3(x, y, z);
01006 }
01007 
01008 inline Vec4::operator const Vec3&() const {
01009     return *(Vec3*)this;
01010 }
01011 
01012 inline float& Vec4::operator[](int n) {
01013     assert(n >= 0 && n < 4);
01014     return *((float*)this + n);
01015 }
01016 
01017 inline Vec4& Vec4::operator=(const Vec4& v) {
01018     x = v.x; y = v.y; z = v.z; w = v.w;
01019     return *this;
01020 }
01021 
01022 inline Vec4& Vec4::operator*=(const Vec4& v) {
01023     x *= v.x; y *= v.y; z *= v.z; w *= v.w;
01024     return *this;
01025 }
01026 
01027 inline Vec4& Vec4::operator/=(const Vec4& v) {
01028     x /= v.x; y /= v.y; z /= v.z; w /= v.w;
01029     return *this;
01030 }
01031 
01032 inline Vec4& Vec4::operator+=(const Vec4& v) {
01033     x += v.x; y += v.y; z += v.z; w += v.w;
01034     return *this;
01035 }
01036 
01037 inline Vec4& Vec4::operator-=(const Vec4& v) {
01038     x -= v.x; y -= v.y; z -= v.z; w -= v.w;
01039     return *this;
01040 }
01041 
01042 inline Vec3& Vec4::N() {
01043     return *(Vec3*)this;
01044 }
01045 
01046 inline const Vec3& Vec4::N() const {
01047     return *(const Vec3*)this;
01048 }
01049 
01050 inline bool Vec4::Equal(const Vec4& v) const {
01051     return (float)fabs(x - v.x) < EPSILON && (float)fabs(y - v.y) < EPSILON && (float)fabs(z - v.z) < EPSILON && (float)fabs(w - v.w) < EPSILON;
01052 }
01053 
01054 inline bool Vec4::NotEqual(const Vec4& v) const {
01055     return (float)fabs(x - v.x) >= EPSILON || (float)fabs(y - v.y) >= EPSILON || (float)fabs(z - v.z) >= EPSILON || (float)fabs(w - v.w) >= EPSILON;
01056 }
01057 
01058 inline float Vec4::Eval(const Vec3& point) const {
01059     return Dot((Vec3&)*this, point) + w;
01060 }
01061 
01062 inline bool Vec4::Coplanar(const Vec4& v) const {
01063     return Equal(v) || Equal(-v);
01064 }
01065 
01066 inline bool Vec4::RayIntersect(Vec3& out, const Vec3& org, const Vec3& dir) const {
01067     float   b, e;
01068     Vec3    end;
01069 
01070     if(fabs(Dot(dir, (Vec3&)*this)) < EPSILON)
01071         return false;
01072 
01073     end = org + dir;
01074 
01075     b = Eval(org);
01076     e = Eval(end);
01077     out = (org * e - end * b) / (e - b);
01078     return true;
01079 }
01080 
01081 inline bool Vec4::LineIntersect(Vec3& out, const Vec3& beg, const Vec3& end) const {
01082     float       e, b;
01083 
01084     b = Eval(beg);
01085     e = Eval(end);
01086 
01087     if(fabs(e - b) < EPSILON)
01088         return false;
01089 
01090     out = (beg * e - end * b) / (e - b);
01091     return true;
01092 }
01093 
01094 inline Vec3 Vec4::MirrorPoint(const Vec3& point) const {
01095     return point + N() * -2.0f * Eval(point);
01096 }
01097 
01098 inline Vec3 Vec4::MirrorVector(const Vec3& point) const {
01099     return point + N() * -2.0f * Dot(N(), point);
01100 }
01101 
01102 inline Vec4 Vec4::MirrorPlane(const Vec4& plane) const {
01103     return PlaneFromPoint(MirrorPoint(plane.N() * plane.w), MirrorVector(plane.N()));
01104 }
01105 
01106 inline Vec3 Vec4::ProjectPoint(const Vec3& point) const {
01107     return point - Eval(point) * N();
01108 }
01109 
01110 inline bool Vec4::PointOnPlane(const Vec3& point) const {
01111     return fabs(Eval(point)) < EPSILON;
01112 }
01113 
01115 inline Vec4 operator*(const Vec4& a, const Vec4& b) {
01116     return Vec4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
01117 }
01118 
01120 inline Vec4 operator/(const Vec4& a, const Vec4& b) {
01121     return Vec4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
01122 }
01123 
01125 inline Vec4 operator+(const Vec4& a, const Vec4& b) {
01126     return Vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
01127 }
01128 
01130 inline Vec4 operator+(const Vec4& v) {
01131     return v;
01132 }
01133 
01135 inline Vec4 operator-(const Vec4& a, const Vec4& b) {
01136     return Vec4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
01137 }
01138 
01140 inline Vec4 operator-(const Vec4& v) {
01141     return Vec4(-v.x, -v.y, -v.z, -v.w);
01142 }
01143 
01145 inline bool operator==(const Vec4& a, const Vec4& b) {
01146     return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
01147 }
01148 
01150 inline bool operator!=(const Vec4& a, const Vec4& b) {
01151     return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
01152 }
01153 
01155 inline bool PlanesIntersect(Vec3& out, const Vec4& a, const Vec4& b, const Vec4& c) {
01156     float   det, det_k;
01157     det = a[0] * b[1] * c[2] + a[1] * b[2] * c[0] + a[2] * b[0] * c[1] -
01158         (c[0] * b[1] * a[2] + c[1] * b[2] * a[0] + c[2] * b[0] * a[1]);
01159     if( (float)fabs(det) < EPSILON )
01160         return false;
01161     det_k = (-a[3]) * b[1] * c[2] + a[1] * b[2] * (-c[3]) + a[2] * (-b[3]) * c[1] -
01162         ((-c[3]) * b[1] * a[2] + c[1] * b[2] * (-a[3]) + c[2] * (-b[3]) * a[1]);
01163     out[0] = det_k / det;
01164     det_k = a[0] * (-b[3]) * c[2] + (-a[3]) * b[2] * c[0] + a[2] * b[0] * (-c[3]) -
01165         (c[0] * (-b[3]) * a[2] + (-c[3]) * b[2] * a[0] + c[2] * b[0] * (-a[3]));
01166     out[1] = det_k / det;
01167     det_k = a[0] * b[1] * (-c[3]) + a[1] * (-b[3]) * c[0] + (-a[3]) * b[0] * c[1] -
01168         (c[0] * b[1] * (-a[3]) + c[1] * (-b[3]) * a[0] + (-c[3]) * b[0] * a[1]);
01169     out[2] = det_k / det;
01170     return true;
01171 }
01172 
01174 inline Vec4 PlaneFromPoint(const Vec3& point, const Vec3& normal) {
01175     return Vec4(normal, -Dot(point, normal));
01176 }
01177 
01179 inline Vec4 PlaneFromPoints(const Vec3& a, const Vec3& b, const Vec3& c) {
01180     return PlaneFromPoint(b, Normalize(Cross(c - b, a - b)));
01181 }
01182 
01184 inline Vec4 PlaneFromEdge(const Vec3& begin, const Vec3& end, const Vec3& normal) {
01185     return PlaneFromPoints(begin, end, end + normal);
01186 }
01187 
01189 inline Vec4 Lerp(const Vec4& a, const Vec4& b, float f) {
01190     return Vec4(a.x * (1.0f - f) + b.x * f, a.y * (1.0f - f) + b.y * f, a.z * (1.0f - f) + b.z * f, a.w * (1.0f - f) + b.w * f);
01191 }
01192 
01193 // ========================================================================
01194 // Quat
01195 
01196 inline Quat::Quat() {
01197 }
01198 
01199 inline Quat::Quat(const float* q) {
01200     x = q[0]; y = q[1]; z = q[2]; w = q[3];
01201 }
01202 
01203 inline Quat::Quat(const Quat& q) {
01204     x = q.x; y = q.y; z = q.z; w = q.w;
01205 }
01206 
01207 inline Quat::Quat(const Vec3& v, float w) {
01208     x = v.x; y = v.y; z = v.z; this->w = w;
01209 }
01210 
01211 inline Quat::Quat(float x, float y, float z, float w) {
01212     this->x = x; this->y = y; this->z = z; this->w = w;
01213 }
01214 
01215 inline Quat::Quat(float f) {
01216     x = y = z = 0.0f; w = f;
01217 }
01218 
01219 inline Quat::operator float*() {
01220     return (float*)this;
01221 }
01222 
01223 inline Quat::operator const float*() const {
01224     return (const float*)this;
01225 }
01226 
01227 inline Quat::operator Vec4() const {
01228     return Vec4(x, y, z, w);
01229 }
01230 
01231 inline float& Quat::operator[](int n) {
01232     assert(n >= 0 && n < 4);
01233     return *((float*)this + n);
01234 }
01235 
01236 inline Quat& Quat::operator=(const Quat& q) {
01237     x = q.x; y = q.y; z = q.z; w = q.w;
01238     return *this;
01239 }
01240 
01241 inline Quat& Quat::operator*=(const Quat& q) {
01242     *this = *this * q;
01243     return *this;
01244 }
01245 
01246 inline Quat& Quat::operator*=(float f) {
01247     x *= f; y *= f; z *= f; w *= f;
01248     return *this;
01249 }
01250 
01251 inline Quat& Quat::operator+=(const Quat& q) {
01252     x += q.x; y += q.y; z += q.z; w += q.w;
01253     return *this;
01254 }
01255 
01256 inline Quat& Quat::operator-=(const Quat& q) {
01257     x -= q.x; y -= q.y; z -= q.z; w -= q.w;
01258     return *this;
01259 }
01260 
01261 inline Vec3& Quat::N() {
01262     return *(Vec3*)this;
01263 }
01264 
01265 inline const Vec3& Quat::N() const {
01266     return *(const Vec3*)this;
01267 }
01268 
01269 inline Vec3 Quat::TransformVector(const Vec3& v) const {
01270     float x2 = 2.0f * x, y2 = 2.0f * y, z2 = 2.0f * z;
01271     float wx = x2 * w, wy = y2 * w, wz = z2 * w;
01272     float xx = x2 * x, xy = y2 * x, xz = z2 * x;
01273     float yy = y2 * y, yz = z2 * y, zz = z2 * z;
01274 
01275     return Vec3(
01276         (1.0f - (yy + zz)) * v.x + (xy - wz) * v.y + (xz + wy) * v.z,
01277         (xy + wz) * v.x + (1.0f - (xx + zz)) * v.y + (yz - wx) * v.z,
01278         (xz - wy) * v.x + (yz + wx) * v.y + (1.0f - (xx + yy)) * v.z
01279     );
01280 }
01281 
01283 inline Quat operator*(const Quat& a, const Quat& b) {
01284     return Quat(
01285         a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
01286         a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
01287         a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x,
01288         a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z
01289     );
01290 }
01291 
01293 inline Quat operator*(float f, const Quat& q) {
01294     return Quat(q.x * f, q.y * f, q.z * f, q.w * f);
01295 }
01296 
01298 inline Quat operator*(const Quat& q, float f) {
01299     return Quat(q.x * f, q.y * f, q.z * f, q.w * f);
01300 }
01301 
01303 inline Quat operator+(const Quat& a, const Quat& b) {
01304     return Quat(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
01305 }
01306 
01308 inline Quat operator+(const Quat& q) {
01309     return q;
01310 }
01311 
01313 inline Quat operator-(const Quat& a, const Quat& b) {
01314     return Quat(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
01315 }
01316 
01318 inline Quat operator-(const Quat& q) {
01319     return Quat(q.x, q.y, q.z, -q.w);
01320 }
01321 
01323 inline bool operator==(const Quat& a, const Quat& b) {
01324     return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
01325 }
01326 
01328 inline bool operator!=(const Quat& a, const Quat& b) {
01329     return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
01330 }
01331 
01333 inline Quat Normalize(const Quat& q) {
01334     float len = Dot(q, q);
01335     float factor = 1.0f / sqrt(len);
01336     return q * factor;
01337 }
01338 
01340 inline float Dot(const Quat& a, const Quat& b) {
01341     return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
01342 }
01343 
01345 inline Quat Slerp(const Quat& a, const Quat& b, float f, bool shortestPath) {
01346     float c = Dot(a, b);
01347     float angle;
01348     if(c > 1.0f) {
01349         angle = 0.0f;
01350     } else if(c < -1.0f) {
01351         angle = PI;
01352     } else {
01353         angle = acos(c);
01354     }
01355     if(fabs(angle) < EPSILON) {
01356         return a;
01357     }
01358     float s = sin(angle);
01359     float invs = 1.0f / s;
01360     float coeff0 = sinf((1.0f - f) * angle) * invs;
01361     float coeff1 = sinf(f * angle) * invs;
01362     // Do we need to invert rotation?
01363     if(c < 0.0f && shortestPath) {
01364         coeff0 = -coeff0;
01365         // taking the complement requires renormalisation
01366         Quat t(coeff0 * a + coeff1 * b);
01367         return Normalize(t);
01368     } else {
01369         return coeff0 * a + coeff1 * b;
01370     }
01371 }
01372 
01374 inline Quat Inverse(const Quat& q) {
01375     float norm = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
01376     if(norm > 0.0f) {
01377         return Quat(-q.x / norm, -q.y / norm, -q.z / norm, q.w / norm);
01378     } else {
01379         return Quat(0.0f);
01380     }
01381 }
01382 
01384 inline Quat UnitInverse(const Quat& q) {
01385     return Quat(-q.x, -q.y, -q.z, q.w);
01386 }
01387 
01389 inline Quat QuaternionFromAngleAxis(const Vec3& axis, float angle) {
01390     // assert: axis.Length() == 1.0f
01391     float s = (float)sin(0.5f * angle);
01392     return Quat(axis.x * s, axis.y * s, axis.z * s, (float)cos(0.5f * angle));
01393 }
01394 
01396 inline Quat QuaternionRotationYawPitchRoll(float yaw, float pitch, float roll) {
01397     float sinY, cosY, sinP, cosP, sinR, cosR;
01398 
01399     sinY = (float)sin(0.5f * yaw);
01400     cosY = (float)cos(0.5f * yaw);
01401 
01402     sinP = (float)sin(0.5f * pitch);
01403     cosP = (float)cos(0.5f * pitch);
01404 
01405     sinR = (float)sin(0.5f * roll);
01406     cosR = (float)cos(0.5f * roll);
01407 
01408     return Quat(cosR * sinP * cosY + sinR * cosP * sinY,
01409                 cosR * cosP * sinY - sinR * sinP * cosY,
01410                 sinR * cosP * cosY - cosR * sinP * sinY,
01411                 cosR * cosP * cosY + sinR * sinP * sinY);
01412 }
01413 
01415 inline Quat QuaternionRotationYawPitchRoll(const Vec3& angles) {
01416     return QuaternionRotationYawPitchRoll(angles.y, angles.x, angles.z);
01417 }
01418 
01419 // ========================================================================
01420 // Matrix3
01421 
01422 inline Matrix3::Matrix3() {
01423 }
01424 
01425 inline Matrix3::Matrix3(const float* m) {
01426     memcpy(this, m, sizeof(Matrix3));
01427 }
01428 
01429 inline Matrix3::Matrix3(const Matrix3& m) {
01430     memcpy(this, &m, sizeof(Matrix3));
01431 }
01432 
01433 inline Matrix3::Matrix3(float _11, float _12, float _13, float _21, float _22, float _23, float _31, float _32, float _33) {
01434     this->_11 = _11; this->_12 = _12; this->_13 = _13;
01435     this->_21 = _21; this->_22 = _22; this->_23 = _23;
01436     this->_31 = _31; this->_32 = _32; this->_33 = _33;
01437 }
01438 
01439 inline Matrix3::Matrix3(float f) {
01440     _11 = f; _12 = 0; _13 = 0;
01441     _21 = 0; _22 = f; _23 = 0;
01442     _31 = 0; _32 = 0; _33 = f;
01443 }
01444 
01445 inline Matrix3::operator float*() {
01446     return (float*)this;
01447 }
01448 
01449 inline Matrix3::operator const float*() const {
01450     return (const float*)this;
01451 }
01452 
01453 inline Matrix3::operator Matrix4() const {
01454     return Matrix4(_11, _12, _13, 0, _21, _22, _23, 0, _31, _32, _33, 0, 0, 0, 0, 1);
01455 }
01456 
01457 inline Vec3& Matrix3::operator[](int n) {
01458     assert(n >= 0 && n < 3);
01459     return *(Vec3*)this;
01460 }
01461 
01462 inline float& Matrix3::operator()(int n, int m) {
01463     assert(n >= 0 && n < 3);
01464     assert(m >= 0 && m < 3);
01465     return ((float*)this)[n * 3 + m];
01466 }
01467 
01468 inline Matrix3& Matrix3::operator=(const Matrix3& m) {
01469     memcpy(this, &m, sizeof(Matrix3));
01470     return *this;
01471 }
01472 
01473 inline Matrix3& Matrix3::operator*=(const Matrix3& m) {
01474     Matrix3 t = *this;
01475     _11 = t._11 * m._11 + t._12 * m._21 + t._13 * m._31;
01476     _12 = t._11 * m._12 + t._12 * m._22 + t._13 * m._32;
01477     _13 = t._11 * m._13 + t._12 * m._23 + t._13 * m._33;
01478 
01479     _21 = t._21 * m._11 + t._22 * m._21 + t._23 * m._31;
01480     _22 = t._21 * m._12 + t._22 * m._22 + t._23 * m._32;
01481     _23 = t._21 * m._13 + t._22 * m._23 + t._23 * m._33;
01482 
01483     _31 = t._31 * m._11 + t._32 * m._21 + t._33 * m._31;
01484     _32 = t._31 * m._12 + t._32 * m._22 + t._33 * m._32;
01485     _33 = t._31 * m._13 + t._32 * m._23 + t._33 * m._33;
01486 
01487     return *this;
01488 }
01489 
01490 inline float Matrix3::Det() const {
01491     return _11 * (_22 * _33 - _23 * _32) - 
01492             _21 * (_12 * _33 - _13 * _32) +
01493             _31 * (_12 * _23 - _13 * _22);
01494 }
01495 
01496 inline Vec2 Matrix3::TransformPoint(const Vec2& tc) const {
01497     return Vec2(tc.x * _11 + tc.y * _21 + _31, tc.x * _12 + tc.y * _22 + _32);
01498 }
01499 
01501 inline Matrix3 operator*(const Matrix3& a, const Matrix3& b) {
01502     Matrix3 r = a;
01503     r *= b;
01504     return r;
01505 }
01506 
01508 inline float Det(const Matrix3& m) {
01509     return m.Det();
01510 }
01511 
01513 inline Matrix3 MatrixTextureRotation(float angle) {
01514     float c = (float)cos(angle), s = (float)sin(angle);
01515     return Matrix3(c, s, 0,
01516                     -s, c, 0,
01517                     0, 0, 1);
01518 }
01519 
01521 inline Matrix3 MatrixTextureTranslation(float u, float v) {
01522     return Matrix3(1, 0, 0,
01523                     0, 1, 0,
01524                     u, v, 1);
01525 }
01526 
01528 inline Matrix3 MatrixTextureTranslation(const Vec2& v) {
01529     return Matrix3(1, 0, 0,
01530                     0, 1, 0,
01531                     v.x, v.y, 1);
01532 }
01533 
01535 inline Matrix3 MatrixTextureScaling(float u, float v) {
01536     return Matrix3(u, 0, 0,
01537                     0, v, 0,
01538                     0, 0, 1);
01539 }
01540 
01542 inline Matrix3 MatrixTextureScaling(const Vec2& v) {
01543     return Matrix3(v.x, 0, 0,
01544                     0, v.y, 0,
01545                     0, 0, 1);
01546 }
01547 
01548 // ========================================================================
01549 
01550 inline Matrix4::Matrix4() {
01551 }
01552 
01553 inline Matrix4::Matrix4(const float* m) {
01554     memcpy(this, m, sizeof(Matrix4));
01555 }
01556 
01557 inline Matrix4::Matrix4(const Matrix4& m) {
01558     memcpy(this, &m, sizeof(Matrix4));
01559 }
01560 
01561 inline Matrix4::Matrix4(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) {
01562     this->_11 = _11; this->_12 = _12; this->_13 = _13; this->_14 = _14;
01563     this->_21 = _21; this->_22 = _22; this->_23 = _23; this->_24 = _24;
01564     this->_31 = _31; this->_32 = _32; this->_33 = _33; this->_34 = _34;
01565     this->_41 = _41; this->_42 = _42; this->_43 = _43; this->_44 = _44;
01566 }
01567 
01568 inline Matrix4::Matrix4(float f) {
01569     _11 = f; _12 = 0; _13 = 0; _14 = 0;
01570     _21 = 0; _22 = f; _23 = 0; _24 = 0;
01571     _31 = 0; _32 = 0; _33 = f; _34 = 0;
01572     _41 = 0; _42 = 0; _43 = 0; _44 = f;
01573 }
01574 
01575 inline Matrix4::operator float*() {
01576     return (float*)this;
01577 }
01578 
01579 inline Matrix4::operator const float*() const {
01580     return (const float*)this;
01581 }
01582 
01583 inline Matrix4::operator Matrix3() const {
01584     return Matrix3(_11, _12, _13, _21, _22, _23, _31, _32, _33);
01585 }
01586 
01587 inline Vec4& Matrix4::operator[](int n) {
01588     assert(n >= 0 && n < 4);
01589     return *((Vec4*)this + n);
01590 }
01591 
01592 inline float& Matrix4::operator()(int n, int m) {
01593     assert(n >= 0 && n < 4);
01594     assert(m >= 0 && m < 4);
01595     return ((float*)this)[n * 4 + m];
01596 }
01597 
01598 inline Matrix4& Matrix4::operator=(const Matrix4& m) {
01599     memcpy(this, &m, sizeof(Matrix4));
01600     return *this;
01601 }
01602 
01603 inline Matrix4& Matrix4::operator*=(const Matrix4& a) {
01604     Matrix4 t = *this;
01605     _11 = t._11 * a._11 + t._12 * a._21 + t._13 * a._31 + t._14 * a._41;
01606     _12 = t._11 * a._12 + t._12 * a._22 + t._13 * a._32 + t._14 * a._42;
01607     _13 = t._11 * a._13 + t._12 * a._23 + t._13 * a._33 + t._14 * a._43;
01608     _14 = t._11 * a._14 + t._12 * a._24 + t._13 * a._34 + t._14 * a._44;
01609 
01610     _21 = t._21 * a._11 + t._22 * a._21 + t._23 * a._31 + t._24 * a._41;
01611     _22 = t._21 * a._12 + t._22 * a._22 + t._23 * a._32 + t._24 * a._42;
01612     _23 = t._21 * a._13 + t._22 * a._23 + t._23 * a._33 + t._24 * a._43;
01613     _24 = t._21 * a._14 + t._22 * a._24 + t._23 * a._34 + t._24 * a._44;
01614 
01615     _31 = t._31 * a._11 + t._32 * a._21 + t._33 * a._31 + t._34 * a._41;
01616     _32 = t._31 * a._12 + t._32 * a._22 + t._33 * a._32 + t._34 * a._42;
01617     _33 = t._31 * a._13 + t._32 * a._23 + t._33 * a._33 + t._34 * a._43;
01618     _34 = t._31 * a._14 + t._32 * a._24 + t._33 * a._34 + t._34 * a._44;
01619 
01620     _41 = t._41 * a._11 + t._42 * a._21 + t._43 * a._31 + t._44 * a._41;
01621     _42 = t._41 * a._12 + t._42 * a._22 + t._43 * a._32 + t._44 * a._42;
01622     _43 = t._41 * a._13 + t._42 * a._23 + t._43 * a._33 + t._44 * a._43;
01623     _44 = t._41 * a._14 + t._42 * a._24 + t._43 * a._34 + t._44 * a._44;
01624 
01625     return *this;
01626 }
01627 
01628 inline float Matrix4::Det() const {
01629     return _11 * GLFX::Det(Matrix3(_22, _23, _24, _32, _33, _34, _42, _43, _44)) -
01630             _21 * GLFX::Det(Matrix3(_12, _13, _14, _32, _33, _34, _42, _43, _44)) +
01631             _31 * GLFX::Det(Matrix3(_12, _13, _14, _22, _23, _24, _42, _43, _44)) -
01632             _41 * GLFX::Det(Matrix3(_12, _13, _14, _22, _23, _24, _32, _33, _34));
01633 }
01634 
01635 inline Matrix4& Matrix4::Inverse() {
01636     Matrix4 t = *this;
01637     float det = Det();
01638 
01639     _11 = GLFX::Det(Matrix3(t._22, t._23, t._24, t._32, t._33, t._34, t._42, t._43, t._44));
01640     _12 = -GLFX::Det(Matrix3(t._12, t._13, t._14, t._32, t._33, t._34, t._42, t._43, t._44));
01641     _13 = GLFX::Det(Matrix3(t._12, t._13, t._14, t._22, t._23, t._24, t._42, t._43, t._44));
01642     _14 = -GLFX::Det(Matrix3(t._12, t._13, t._14, t._22, t._23, t._24, t._32, t._33, t._34));
01643 
01644     _21 = -GLFX::Det(Matrix3(t._21, t._23, t._24, t._31, t._33, t._34, t._41, t._43, t._44));
01645     _22 = GLFX::Det(Matrix3(t._11, t._13, t._14, t._31, t._33, t._34, t._41, t._43, t._44));
01646     _23 = -GLFX::Det(Matrix3(t._11, t._13, t._14, t._21, t._23, t._24, t._41, t._43, t._44));
01647     _24 = GLFX::Det(Matrix3(t._11, t._13, t._14, t._21, t._23, t._24, t._31, t._33, t._34));
01648 
01649     _31 = GLFX::Det(Matrix3(t._21, t._22, t._24, t._31, t._32, t._34, t._41, t._42, t._44));
01650     _32 = -GLFX::Det(Matrix3(t._11, t._12, t._14, t._31, t._32, t._34, t._41, t._42, t._44));
01651     _33 = GLFX::Det(Matrix3(t._11, t._12, t._14, t._21, t._22, t._24, t._41, t._42, t._44));
01652     _34 = -GLFX::Det(Matrix3(t._11, t._12, t._14, t._21, t._22, t._24, t._31, t._32, t._34));
01653 
01654     _41 = -GLFX::Det(Matrix3(t._21, t._22, t._23, t._31, t._32, t._33, t._41, t._42, t._43));
01655     _42 = GLFX::Det(Matrix3(t._11, t._12, t._13, t._31, t._32, t._33, t._41, t._42, t._43));
01656     _43 = -GLFX::Det(Matrix3(t._11, t._12, t._13, t._21, t._22, t._23, t._41, t._42, t._43));
01657     _44 = GLFX::Det(Matrix3(t._11, t._12, t._13, t._21, t._22, t._23, t._31, t._32, t._33));
01658 
01659     if(!det)
01660         return *this;       // singular matrix, no inverse
01661 
01662     for(int i = 0; i < 16; i++)
01663         ((float*)this)[i] /= det;
01664 
01665     return *this;
01666 }
01667 
01668 inline Matrix4& Matrix4::Transpose() {
01669     float t;
01670     t = _12; _12 = _21; _21 = t;
01671     t = _13; _13 = _31; _31 = t;
01672     t = _14; _14 = _41; _41 = t;
01673     t = _23; _23 = _32; _32 = t;
01674     t = _24; _24 = _42; _42 = t;
01675     t = _34; _34 = _43; _43 = t;
01676     return *this;
01677 }
01678 
01679 inline Vec3 Matrix4::TransformPoint(const Vec3& point) const {
01680     float d = point.x * _14 + point.y * _24 + point.z * _34 + _44;
01681     return Vec3((point.x * _11 + point.y * _21 + point.z * _31 + _41) / d,
01682                 (point.x * _12 + point.y * _22 + point.z * _32 + _42) / d,
01683                 (point.x * _13 + point.y * _23 + point.z * _33 + _43) / d);
01684 }
01685 
01686 inline Vec3 Matrix4::TransformVector(const Vec3& vector) const {
01687     // TODO: this is not working right
01688     float d = vector.x * _14 + vector.y * _24 + vector.z * _34 + _44;
01689     return Vec3((vector.x * _11 + vector.y * _21 + vector.z * _31) / d,
01690                 (vector.x * _12 + vector.y * _22 + vector.z * _32) / d,
01691                 (vector.x * _13 + vector.y * _23 + vector.z * _33) / d);
01692 }
01693 
01695 inline Matrix4 operator*(const Matrix4& a, const Matrix4& b) {
01696     Matrix4 t = a;
01697     t *= b;
01698     return t;
01699 }
01700 
01702 inline Matrix4 MatrixTranslation(float x, float y, float z) {
01703     return Matrix4(1, 0, 0, 0,
01704                     0, 1, 0, 0,
01705                     0, 0, 1, 0,
01706                     x, y, z, 1);
01707 }
01708 
01710 inline Matrix4 MatrixTranslation(const Vec3& v) {
01711     return Matrix4(1, 0, 0, 0,
01712                     0, 1, 0, 0,
01713                     0, 0, 1, 0,
01714                     v.x, v.y, v.z, 1);
01715 }
01716 
01718 inline Matrix4 MatrixRotationX(float angle) {
01719     float   c = (float)cos(angle);
01720     float   s = (float)sin(angle);
01721     float   n = -s;
01722 
01723     return Matrix4(1, 0, 0, 0,
01724                     0, c, s, 0,
01725                     0, n, c, 0,
01726                     0, 0, 0, 1);
01727 }
01728 
01730 inline Matrix4 MatrixRotationY(float angle) {
01731     float   c = (float)cos(angle);
01732     float   s = (float)sin(angle);
01733     float   n = -s;
01734 
01735     return Matrix4(c, 0, n, 0,
01736                     0, 1, 0, 0,
01737                     s, 0, c, 0,
01738                     0, 0, 0, 1);
01739 }
01740 
01742 inline Matrix4 MatrixRotationZ(float angle) {
01743     float   c = (float)cos(angle);
01744     float   s = (float)sin(angle);
01745     float   n = -s;
01746 
01747     return Matrix4(c, s, 0, 0,
01748                     n, c, 0, 0,
01749                     0, 0, 1, 0,
01750                     0, 0, 0, 1);
01751 }
01752 
01754 inline Matrix4 MatrixRotationQuaternion(const Quat& quat) {
01755     float x = 2.0f * quat.x, y = 2.0f * quat.y, z = 2.0f * quat.z;
01756     float wx = x * quat.w, wy = y * quat.w, wz = z * quat.w;
01757     float xx = x * quat.x, xy = y * quat.x, xz = z * quat.x;
01758     float yy = y * quat.y, yz = z * quat.y, zz = z * quat.z;
01759 
01760     return Matrix4(1.0f - (yy + zz), xy - wz, xz + wy, 0,
01761                     xy + wz, 1.0f - (xx + zz), yz - wx, 0,
01762                     xz - wy, yz + wx, 1.0f - (xx + yy), 0,
01763                     0, 0, 0, 1);
01764                     
01765 }
01766 
01769 inline Matrix4 MatrixRotationYawPitchRoll(float yaw, float pitch, float roll) {
01770     return MatrixRotationY(yaw) * MatrixRotationX(pitch) * MatrixRotationZ(roll);
01771 }
01772 
01775 inline Matrix4 MatrixRotationYawPitchRoll(const Vec3& angles) {
01776     return MatrixRotationYawPitchRoll(angles.y, angles.x, angles.z);
01777 }
01778 
01780 inline Matrix4 MatrixScaling(float x, float y, float z) {
01781     return Matrix4(x, 0, 0, 0,
01782                     0, y, 0, 0,
01783                     0, 0, z, 0,
01784                     0, 0, 0, 1);
01785 }
01786 
01788 inline Matrix4 MatrixScaling(const Vec3& v) {
01789     return MatrixScaling(v.x, v.y, v.z);
01790 }
01791 
01793 inline Matrix4 MatrixPerspectiveFovXRH(float fovx, float aspect, float znear, float zfar) {
01794     float   w, h, x, y, c, d;
01795 
01796     w = 2 * znear * (float)tan(fovx * PI / 360);
01797     h = w / aspect;
01798     x = 2 * znear / w;
01799     y = 2 * znear / h;
01800     c = -(zfar + znear) / (zfar - znear);
01801     d = -(2 * zfar * znear) / (zfar - znear);
01802 
01803     return Matrix4(x, 0, 0, 0,
01804                     0, y, 0, 0,
01805                     0, 0, c, -1,
01806                     0, 0, d, 0);
01807 }
01808 
01810 inline Matrix4 MatrixPerspectiveFovYRH(float fovy, float aspect, float znear, float zfar) {
01811     float   w, h, x, y, c, d;
01812 
01813     h = 2 * znear * (float)tan(fovy * PI / 360);
01814     w = h * aspect;
01815     x = 2 * znear / w;
01816     y = 2 * znear / h;
01817     c = -(zfar + znear) / (zfar - znear);
01818     d = -(2 * zfar * znear) / (zfar - znear);
01819 
01820     return Matrix4(x, 0, 0, 0,
01821                     0, y, 0, 0,
01822                     0, 0, c, -1,
01823                     0, 0, d, 0);
01824 }
01825 
01827 inline Matrix4 MatrixOrthoRH(float w, float h, float zn, float zf) {
01828     float   x, y, z, t;
01829     x = 2.0f / w;
01830     y = 2.0f / h;
01831     z = -1.0f / (zf - zn);
01832     t = -zn / (zf - zn);
01833 
01834     return Matrix4(x, 0, 0, 0,
01835                     0, y, 0, 0,
01836                     0, 0, z, 0,
01837                     0, 0, t, 1);
01838 }
01839 
01841 inline Matrix4 MatrixOrthoLH(float w, float h, float zn, float zf) {
01842     float   x, y, z, t;
01843     x = 2 / w;
01844     y = 2 / h;
01845     // FIXME: Is this ok?
01846     z = 1.0f / (zf - zn);
01847     t = zn / (zf - zn);
01848 
01849     return Matrix4(x, 0, 0, 0,
01850                     0, y, 0, 0,
01851                     0, 0, z, 0,
01852                     0, 0, t, 1);
01853 }
01854 
01856 inline Matrix4 MatrixLookAtRH(const Vec3& eye, const Vec3& at, const Vec3& up) {
01857     Vec3    x, y, z;
01858     Matrix4 r;
01859 
01860     z = eye - at;
01861     z = Normalize(z);
01862 
01863     x = Cross(up, z);
01864     y = Cross(z, x);
01865 
01866     x = Normalize(x);
01867     y = Normalize(y);
01868 
01869     r(0, 0) = x[0];     r(0, 1) = y[0];     r(0, 2) = z[0];      r(0, 3) = 0;
01870     r(1, 0) = x[1];     r(1, 1) = y[1];     r(1, 2) = z[1];      r(1, 3) = 0;
01871     r(2, 0) = x[2];     r(2, 1) = y[2];     r(2, 2) = z[2];      r(2, 3) = 0;
01872     r(3, 0) = 0;        r(3, 1) = 0;        r(3, 2) = 0;         r(3, 3) = 1;
01873 
01874     return MatrixTranslation(-eye) * r;
01875 }
01876 
01878 inline float Det(const Matrix4& m) {
01879     return m.Det();
01880 }
01881 
01883 inline Matrix4 Inverse(const Matrix4& m) {
01884     Matrix4 t = m;
01885     return t.Inverse();
01886 }
01887 
01889 inline Matrix4 Transpose(const Matrix4& m) {
01890     Matrix4 t = m;
01891     return t.Transpose();
01892 }
01893 
01894 // ========================================================================
01895 
01896 inline Color::Color() {
01897 }
01898 
01899 inline Color::Color(const Vec3& v) {
01900     red = (unsigned char)(v.x * 255.0f);
01901     green = (unsigned char)(v.y * 255.0f);
01902     blue = (unsigned char)(v.z * 255.0f);
01903     alpha = 0xff;
01904 }
01905 
01906 inline Color::Color(const Vec4& v) {
01907     red = (unsigned char)(v.x * 255.0f);
01908     green = (unsigned char)(v.y * 255.0f);
01909     blue = (unsigned char)(v.z * 255.0f);
01910     alpha = (unsigned char)(v.w * 255.0f);
01911 }
01912 
01913 inline Color::Color(float r, float g, float b, float a) {
01914     red = (unsigned char)(r * 255.0f);
01915     green = (unsigned char)(g * 255.0f);
01916     blue = (unsigned char)(b * 255.0f);
01917     alpha = (unsigned char)(a * 255.0f);
01918 }
01919 
01920 inline Color::Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
01921     red = r;
01922     green = g;
01923     blue = b;
01924     alpha = a;
01925 }
01926 
01927 inline Color::Color(int r, int g, int b, int a) {
01928     red = r & 0xff;
01929     green = g & 0xff;
01930     blue = b & 0xff;
01931     alpha = a & 0xff;
01932 }
01933 
01934 inline Color::Color(const Color& c) {
01935     *(unsigned long*)this = *(unsigned long*)&c;
01936 }
01937 
01938 inline Color::Color(unsigned long c) {
01939     *(unsigned long*)this = c;
01940 }
01941 
01942 inline Color::Color(long c) {
01943     *(long*)this = c;
01944 }
01945 
01946 inline Color::Color(unsigned int c) {
01947     *(unsigned int*)this = c;
01948 }
01949 
01950 inline Color::Color(int c) {
01951     *(int*)this = c;
01952 }
01953 
01954 inline Color::Color(float c) {
01955     red = green = blue = alpha = (unsigned char)(c * 255.0f);
01956 }
01957 
01958 inline Color::operator Vec3() const {
01959     return Vec3(Redf(), Greenf(), Bluef());
01960 }
01961 
01962 inline Color::operator Vec4() const {
01963     return Vec4(Redf(), Greenf(), Bluef(), Alphaf());
01964 }
01965 
01966 inline Color::operator unsigned char*() const {
01967     return (unsigned char*)this;
01968 }
01969 
01970 inline Color& Color::operator*=(Color c) {
01971     red = ((unsigned int)red * (unsigned int)c.red) >> 8;
01972     green = ((unsigned int)green * (unsigned int)c.green) >> 8;
01973     blue = ((unsigned int)blue * (unsigned int)c.blue) >> 8;
01974     alpha = ((unsigned int)alpha * (unsigned int)c.alpha) >> 8;
01975     return *this;
01976 }
01977 
01978 inline unsigned long Color::ARGB() const {
01979     return *(unsigned long*)this;
01980 }
01981 
01982 inline unsigned long& Color::ARGB() {
01983     return *(unsigned long*)this;
01984 }
01985 
01986 inline float Color::Redf() const {
01987     return red / 255.0f;
01988 }
01989 
01990 inline float Color::Greenf() const {
01991     return green / 255.0f;
01992 }
01993 
01994 inline float Color::Bluef() const {
01995     return blue / 255.0f;
01996 }
01997 
01998 inline float Color::Alphaf() const {
01999     return alpha / 255.0f;
02000 }
02001 
02003 inline Color operator*(Color a, Color b) {
02004     Color r = a;
02005     r *= b;
02006     return r;
02007 }
02008 
02009 // ========================================================================
02010 
02011 inline bool PointInTriangle(const Vec3& point, const Vec3& a, const Vec3& b, const Vec3& c) {
02012     Vec3 normal = Cross(c - b, a - b);
02013     return PlaneFromEdge(a, b, normal).Eval(point) < EPSILON &&
02014         PlaneFromEdge(b, c, normal).Eval(point) < EPSILON &&
02015         PlaneFromEdge(c, a, normal).Eval(point) < EPSILON;
02016 }
02017 
02018 inline void LinesNearestPoints(Vec3 out1, Vec3 out2, const Vec3& org1, const Vec3& dir1, const Vec3& org2, const Vec3& dir2) {
02019     if(dir1.Equal(dir2)) {
02020         out1 = org1;
02021         out2 = org2;
02022         return;
02023     }
02024     float   a, b;
02025     float   t, s;
02026     a = Dot(dir1, dir2);
02027     b = Dot(dir1, org2) - Dot(dir1, org1);
02028     s = (2 * a * Dot(org1, dir1) - 2 * Dot(org1, dir2) + 2 * a * b -
02029         2 * a * Dot(dir1, org2) - 2 * b * Dot(dir1, dir2) + 2 * Dot(org2, dir2) ) /
02030         (-2 * (a * a + 1 - 2 * a * Dot(dir1, dir2)));
02031     t = a * s + b;
02032 
02033     out1 = dir1 * t + org1;
02034     out2 = dir2 * t + org2;
02035 }
02036 
02037 inline bool TriangleSameWinding(const Vec3& a1, const Vec3& a2, const Vec3& a3, const Vec3& b1, const Vec3& b2, const Vec3& b3) {
02038     return Dot(Cross(a3 - a2, a1 - a2), Cross(b3 - b2, b1 - b2)) > 0;
02039 }
02040 
02041 inline bool TriangleWindingCheck(const Vec3& a1, const Vec3& a2, const Vec3& a3, const Vec3& normal) {
02042     return Dot(Cross(a3 - a2, a1 - a2), normal) > 0;
02043 }
02044 
02045 inline float PointRayDist(const Vec3& point, const Vec3& org, const Vec3& dir) {
02046     return Length(org + dir * (Dot(dir, point) - Dot(dir, org)) - point);
02047 }
02048 
02049 inline float PointSegmentDist(const Vec3& point, const Vec3& a, const Vec3& b) {
02050     Vec4 plane = PlaneFromPoint(a, Normalize(a - b));
02051     if(plane.Eval(point) > 0.0f)
02052         return Length(point - a);
02053     plane = PlaneFromPoint(b, Normalize(b - a));
02054     if(plane.Eval(point) > 0.0f)
02055         return Length(point - b);
02056     return PointRayDist(point, a, plane.N());
02057 }
02058 
02059 inline float RaySegmentDist(const Vec3& org, const Vec3& dir, const Vec3& a, const Vec3& b) {
02060     Vec3 out1, out2;
02061     Vec4 plane;
02062     LinesNearestPoints(out1, out2, org, dir, a, Normalize(b - a));
02063     plane = PlaneFromPoint(a, Normalize(a - b));
02064     if(plane.Eval(out2) > 0)
02065         return PointRayDist(a, org, dir);
02066     plane = PlaneFromPoint(b, Normalize(b - a));
02067     if(plane.Eval(out2) > 0)
02068         return PointRayDist(b, org, dir);
02069     return Length(out1 - out2);
02070 }
02071 
02072 inline bool LineShapeIntersect(Vec3& intersect, const Vec3& beg, const Vec3& end, const Vec4& shapePlane, const Vec3* shape, int shapeCount) {
02073     float   eval = 0;
02074     if(!shapePlane.LineIntersect(intersect, beg, end))
02075         return false;
02076     for(int i = 0; i < shapeCount; i++) {
02077         Vec4 sidePlane = PlaneFromEdge(shape[i], shape[(i + 1) % shapeCount], (Vec3&)shapePlane);
02078         if(fabs(eval) < EPSILON) {
02079             eval = sidePlane.Eval(intersect);
02080         } else {
02081             if(eval * sidePlane.Eval(intersect) < -EPSILON)
02082                 return false;
02083         }
02084     }
02085     return true;
02086 }
02087 
02088 inline bool PointInPoly(const Vec3& pnt, const Vec3* shape, int length, const Vec3& normal) {
02089     float eval = 0;
02090     for(int i = 0; i < length; i++) {
02091         Vec4 plane = PlaneFromEdge(shape[i], shape[(i + 1) % length], normal);
02092         if(fabs(eval) < EPSILON) {
02093             eval = plane.Eval(pnt);
02094         } else {
02095             if(eval * plane.Eval(pnt) < EPSILON)
02096                 return false;
02097         }
02098     }
02099     return true;
02100 }
02101 
02102 inline float PointShapeDist(const Vec3& point, const Vec3* shape, int length, const Vec4& plane) {
02103     Vec3 proj = plane.ProjectPoint(point);
02104     if(PointInPoly(proj, shape, length, (Vec3&)plane)) {
02105         return Length(proj - point);
02106     }
02107     float minDist;
02108     minDist = PointSegmentDist(point, shape[0], shape[1]);
02109     for(int i = 1; i < length; i++) {
02110         float dist = PointSegmentDist(point, shape[i], shape[(i + 1) % length]);
02111         if(dist < minDist)
02112             minDist = dist;
02113     }
02114     return minDist;
02115 }
02116 
02117 inline bool PointsAreCollinear(const Vec3& a, const Vec3& b, const Vec3& c) {
02118     if(a.Equal(b) || a.Equal(c) || b.Equal(c))
02119         return true;
02120     Vec3 u, v;
02121     u = Normalize(a - b);
02122     v = Normalize(b - c);
02123     if(Dot(u, v) < 0)
02124         return u.Equal(-v);
02125     return u.Equal(v);
02126 }
02127 
02128 // ========================================================================
02129 
02130 }
02131 
02132 #pragma pack()
02133 
02134 #endif // __GLFXVEC_H__

SourceForge.net Logo