00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CS_MATH3D_D_H__
00022 #define __CS_MATH3D_D_H__
00023
00024 #include "csextern.h"
00025
00026 #include "cstypes.h"
00027
00035 #ifndef ABS
00036 #define ABS(x) ((x)<0?-(x):(x))
00037 #endif
00038
00039 class csDVector3;
00040 class csDMatrix3;
00041 class csVector3;
00042
00043 inline double dSqr (double d)
00044 {
00045 return d * d;
00046 }
00047
00051 class CS_CRYSTALSPACE_EXPORT csDVector3
00052 {
00053 public:
00055 double x;
00057 double y;
00059 double z;
00060
00066 csDVector3 () {}
00067
00073 csDVector3 (double m) : x(m), y(m), z(m) {}
00074
00076 csDVector3 (double ix, double iy, double iz = 0) { x = ix; y = iy; z = iz; }
00077
00079 csDVector3 (const csDVector3& v) { x = v.x; y = v.y; z = v.z; }
00080
00082 csDVector3 (const csVector3&);
00083
00085 inline friend
00086 csDVector3 operator+ (const csDVector3& v1, const csDVector3& v2)
00087 { return csDVector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }
00088
00090 inline friend
00091 csDVector3 operator- (const csDVector3& v1, const csDVector3& v2)
00092 { return csDVector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }
00093
00095 inline friend double operator* (const csDVector3& v1, const csDVector3& v2)
00096 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }
00097
00099 inline friend
00100 csDVector3 operator% (const csDVector3& v1, const csDVector3& v2)
00101 {
00102 return csDVector3 (v1.y*v2.z-v1.z*v2.y,
00103 v1.z*v2.x-v1.x*v2.z,
00104 v1.x*v2.y-v1.y*v2.x);
00105 }
00106
00108 void Cross (const csDVector3 & px, const csDVector3 & py)
00109 {
00110 x = px.y*py.z - px.z*py.y;
00111 y = px.z*py.x - px.x*py.z;
00112 z = px.x*py.y - px.y*py.x;
00113 }
00114
00116 inline friend csDVector3 operator* (const csDVector3& v, double f)
00117 { return csDVector3(v.x*f, v.y*f, v.z*f); }
00118
00120 inline friend csDVector3 operator* (double f, const csDVector3& v)
00121 { return csDVector3(v.x*f, v.y*f, v.z*f); }
00122
00124 inline friend csDVector3 operator/ (const csDVector3& v, double f)
00125 { f = 1.0f/f; return csDVector3(v.x*f, v.y*f, v.z*f); }
00126
00128 inline friend bool operator== (const csDVector3& v1, const csDVector3& v2)
00129 { return v1.x==v2.x && v1.y==v2.y && v1.z==v2.z; }
00130
00132 inline friend bool operator!= (const csDVector3& v1, const csDVector3& v2)
00133 { return v1.x!=v2.x || v1.y!=v2.y || v1.z!=v2.z; }
00134
00136 inline friend
00137 csDVector3 operator>> (const csDVector3& v1, const csDVector3& v2)
00138 { return v2*(v1*v2)/(v2*v2); }
00139
00141 inline friend
00142 csDVector3 operator<< (const csDVector3& v1, const csDVector3& v2)
00143 { return v1*(v1*v2)/(v1*v1); }
00144
00146 inline friend bool operator< (const csDVector3& v, double f)
00147 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; }
00148
00150 inline friend bool operator> (double f, const csDVector3& v)
00151 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; }
00152
00154 inline double operator[](int n) const {return !n?x:n&1?y:z;}
00155
00157 inline double & operator[](int n){return !n?x:n&1?y:z;}
00158
00160 inline csDVector3& operator+= (const csDVector3& v)
00161 {
00162 x += v.x;
00163 y += v.y;
00164 z += v.z;
00165
00166 return *this;
00167 }
00168
00170 inline csDVector3& operator-= (const csDVector3& v)
00171 {
00172 x -= v.x;
00173 y -= v.y;
00174 z -= v.z;
00175
00176 return *this;
00177 }
00178
00180 inline csDVector3& operator*= (double f)
00181 { x *= f; y *= f; z *= f; return *this; }
00182
00184 inline csDVector3& operator/= (double f)
00185 { x /= f; y /= f; z /= f; return *this; }
00186
00188 inline csDVector3 operator+ () const { return *this; }
00189
00191 inline csDVector3 operator- () const { return csDVector3(-x,-y,-z); }
00192
00194 inline void Set (double sx, double sy, double sz) { x = sx; y = sy; z = sz; }
00195
00197 double Norm () const;
00198
00200 double SquaredNorm () const;
00201
00207 csDVector3 Unit () const { return (*this)/(this->Norm()); }
00208
00210 inline static double Norm (const csDVector3& v) { return v.Norm(); }
00211
00213 inline static csDVector3 Unit (const csDVector3& v) { return v.Unit(); }
00214
00216 void Normalize();
00217 };
00218
00219
00223 class CS_CRYSTALSPACE_EXPORT csDMatrix3
00224 {
00225 public:
00226 double m11, m12, m13;
00227 double m21, m22, m23;
00228 double m31, m32, m33;
00229
00230 public:
00232 csDMatrix3 ();
00233
00235 csDMatrix3 (double m11, double m12, double m13,
00236 double m21, double m22, double m23,
00237 double m31, double m32, double m33);
00238
00240 inline csDVector3 Row1() const { return csDVector3 (m11,m12,m13); }
00241
00243 inline csDVector3 Row2() const { return csDVector3 (m21,m22,m23); }
00244
00246 inline csDVector3 Row3() const { return csDVector3 (m31,m32,m33); }
00247
00249 inline csDVector3 Col1() const { return csDVector3 (m11,m21,m31); }
00250
00252 inline csDVector3 Col2() const { return csDVector3 (m12,m22,m32); }
00253
00255 inline csDVector3 Col3() const { return csDVector3 (m13,m23,m33); }
00256
00258 inline void Set (double m11, double m12, double m13,
00259 double m21, double m22, double m23,
00260 double m31, double m32, double m33)
00261 {
00262 csDMatrix3::m11 = m11; csDMatrix3::m12 = m12; csDMatrix3::m13 = m13;
00263 csDMatrix3::m21 = m21; csDMatrix3::m22 = m22; csDMatrix3::m23 = m23;
00264 csDMatrix3::m31 = m31; csDMatrix3::m32 = m32; csDMatrix3::m33 = m33;
00265 }
00266
00268 csDMatrix3& operator+= (const csDMatrix3& m);
00269
00271 csDMatrix3& operator-= (const csDMatrix3& m);
00272
00274 csDMatrix3& operator*= (const csDMatrix3& m);
00275
00277 csDMatrix3& operator*= (double s);
00278
00280 csDMatrix3& operator/= (double s);
00281
00283 inline csDMatrix3 operator+ () const { return *this; }
00285 inline csDMatrix3 operator- () const
00286 {
00287 return csDMatrix3(-m11,-m12,-m13,
00288 -m21,-m22,-m23,
00289 -m31,-m32,-m33);
00290 }
00291
00293 void Transpose ();
00294
00296 csDMatrix3 GetTranspose () const;
00297
00299 inline csDMatrix3 GetInverse () const
00300 {
00301 csDMatrix3 C(
00302 (m22*m33 - m23*m32), -(m12*m33 - m13*m32), (m12*m23 - m13*m22),
00303 -(m21*m33 - m23*m31), (m11*m33 - m13*m31), -(m11*m23 - m13*m21),
00304 (m21*m32 - m22*m31), -(m11*m32 - m12*m31), (m11*m22 - m12*m21) );
00305 double s = (double)1./(m11*C.m11 + m12*C.m21 + m13*C.m31);
00306
00307 C *= s;
00308
00309 return C;
00310 }
00311
00313 void Invert() { *this = GetInverse (); }
00314
00316 double Determinant () const;
00317
00319 void Identity ();
00320
00322 friend csDMatrix3 operator+ (const csDMatrix3& m1, const csDMatrix3& m2);
00324 friend csDMatrix3 operator- (const csDMatrix3& m1, const csDMatrix3& m2);
00326 friend csDMatrix3 operator* (const csDMatrix3& m1, const csDMatrix3& m2);
00327
00329 inline friend csDVector3 operator* (const csDMatrix3& m, const csDVector3& v)
00330 {
00331 return csDVector3 (m.m11*v.x + m.m12*v.y + m.m13*v.z,
00332 m.m21*v.x + m.m22*v.y + m.m23*v.z,
00333 m.m31*v.x + m.m32*v.y + m.m33*v.z);
00334 }
00335
00337 friend csDMatrix3 operator* (const csDMatrix3& m, double f);
00339 friend csDMatrix3 operator* (double f, const csDMatrix3& m);
00341 friend csDMatrix3 operator/ (const csDMatrix3& m, double f);
00343 friend bool operator== (const csDMatrix3& m1, const csDMatrix3& m2);
00345 friend bool operator!= (const csDMatrix3& m1, const csDMatrix3& m2);
00347 friend bool operator< (const csDMatrix3& m, double f);
00349 friend bool operator> (double f, const csDMatrix3& m);
00350 };
00351
00352
00358 class CS_CRYSTALSPACE_EXPORT csDPlane
00359 {
00360 public:
00362 csDVector3 norm;
00363
00365 double DD;
00366
00368 csDPlane () : norm(0,0,1), DD(0) {}
00369
00371 csDPlane (const csDVector3& plane_norm, double d=0) :
00372 norm(plane_norm), DD(d) {}
00373
00375 csDPlane (double a, double b, double c, double d=0) : norm(a,b,c), DD(d) {}
00376
00378 inline csDVector3& Normal () { return norm; }
00380 inline const csDVector3& Normal () const { return norm; }
00381
00383 inline double A () const { return norm.x; }
00385 inline double B () const { return norm.y; }
00387 inline double C () const { return norm.z; }
00389 inline double D () const { return DD; }
00390
00392 inline double& A () { return norm.x; }
00394 inline double& B () { return norm.y; }
00396 inline double& C () { return norm.z; }
00398 inline double& D () { return DD; }
00399
00401 inline void Set (double a, double b, double c, double d)
00402 { norm.x = a; norm.y = b; norm.z = c; DD = d; }
00403
00405 inline double Classify (const csDVector3& pt) const { return norm*pt+DD; }
00406
00408 static double Classify (double A, double B, double C, double D,
00409 const csDVector3& pt)
00410 { return A*pt.x + B*pt.y + C*pt.z + D; }
00411
00417 inline double Distance (const csDVector3& pt) const
00418 { return ABS (Classify (pt)); }
00419
00421 void Invert () { norm = -norm; DD = -DD; }
00422
00424 void Normalize ()
00425 {
00426 double f = norm.Norm ();
00427 if (f) { norm /= f; DD /= f; }
00428 }
00429
00430 };
00431
00436 class CS_CRYSTALSPACE_EXPORT csDMath3
00437 {
00438 public:
00446 static int WhichSide3D (const csDVector3& p,
00447 const csDVector3& v1, const csDVector3& v2)
00448 {
00449
00450 double s = p.x*(v1.y*v2.z-v1.z*v2.y) + p.y*(v1.z*v2.x-v1.x*v2.z) +
00451 p.z*(v1.x*v2.y-v1.y*v2.x);
00452 if (s < 0) return 1;
00453 else if (s > 0) return -1;
00454 else return 0;
00455 }
00456
00462 static bool Visible (const csDVector3& p, const csDVector3& t1,
00463 const csDVector3& t2, const csDVector3& t3);
00464
00470 static bool Visible (const csDVector3& p, const csDPlane& pl)
00471 { return pl.Classify (p) <= 0; }
00472
00482 static void Between (const csDVector3& v1, const csDVector3& v2,
00483 csDVector3& v, double pct, double wid);
00484
00491 static void SetMinMax (const csDVector3& v,
00492 csDVector3& min, csDVector3& max)
00493 {
00494 if (v.x > max.x) max.x = v.x; else if (v.x < min.x ) min.x = v.x;
00495 if (v.y > max.y) max.y = v.y; else if (v.y < min.y ) min.y = v.y;
00496 if (v.z > max.z) max.z = v.z; else if (v.z < min.z ) min.z = v.z;
00497 }
00498
00504 inline static double DoubleArea3 (const csDVector3 &a, const csDVector3 &b,
00505 const csDVector3 &c)
00506 {
00507 csDVector3 v1 = b - a;
00508 csDVector3 v2 = c - a;
00509 return (v1 % v2).Norm ();
00510 }
00511
00517 inline static void CalcNormal (csDVector3& norm, const csDVector3& v1,
00518 const csDVector3& v2, const csDVector3& v3)
00519 {
00520 norm = (v1-v2)%(v1-v3);
00521 }
00522
00528 static void CalcNormal (csDVector3& norm,
00529 const csDVector3& v, const csDVector3& u)
00530 { norm = u%v; }
00531
00538 static void CalcPlane (const csDVector3& v1, const csDVector3& v2,
00539 const csDVector3& v3, csDVector3& normal, double& D)
00540 {
00541 normal = (v1-v2)%(v1-v3);
00542 D = - (normal * v1);
00543 }
00544
00551 static bool PlanesEqual (const csDPlane& p1, const csDPlane& p2)
00552 {
00553 return ( ( p1.norm - p2.norm) < (double).001 ) &&
00554 ( ABS (p1.DD-p2.DD) < (double).001 );
00555 }
00556
00562 static bool PlanesClose (const csDPlane& p1, const csDPlane& p2);
00563 };
00564
00569 class CS_CRYSTALSPACE_EXPORT csDSquaredDist
00570 {
00571 public:
00573 static double PointPoint (const csDVector3& p1, const csDVector3& p2)
00574 { return dSqr (p1.x - p2.x) + dSqr (p1.y - p2.y) + dSqr (p1.z - p2.z); }
00575
00577 static double PointLine (const csDVector3& p,
00578 const csDVector3& l1, const csDVector3& l2);
00579
00581 static double PointPlane (const csDVector3& p, const csDPlane& plane)
00582 { double r = plane.Classify (p); return r * r; }
00583
00590 static double PointPoly (const csDVector3& p, csDVector3 *V, int n,
00591 const csDPlane& plane, double sqdist = -1);
00592 };
00593
00599 class CS_CRYSTALSPACE_EXPORT csDIntersect3
00600 {
00601 public:
00606 static void Plane (
00607 const csDVector3& u, const csDVector3& v,
00608 const csDVector3& normal, const csDVector3& a,
00609 csDVector3& isect);
00610
00619 static bool Plane (
00620 const csDVector3& u, const csDVector3& v,
00621 double A, double B, double C, double D,
00622 csDVector3& isect,
00623 double& dist);
00624
00633 static bool Plane (
00634 const csDVector3& u, const csDVector3& v,
00635 const csDPlane& p,
00636 csDVector3& isect,
00637 double& dist);
00638
00644 static bool Planes(const csDPlane& p1, const csDPlane& p2,
00645 const csDPlane& p3, csDVector3& isect);
00646
00653 static double Z0Plane (
00654 const csDVector3& u, const csDVector3& v,
00655 csDVector3& isect);
00656
00663 static double ZPlane (double zval,
00664 const csDVector3& u, const csDVector3& v,
00665 csDVector3& isect);
00666
00671 static double XFrustum (
00672 double A, const csDVector3& u, const csDVector3& v, csDVector3& isect);
00673
00678 static double YFrustum (
00679 double B, const csDVector3& u, const csDVector3& v, csDVector3& isect);
00680 };
00681
00684 #endif // __CS_MATH3D_D_H__