Umasoft
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
MathTypes.h
Go to the documentation of this file.
1 //
2 // Basic data type definitions shared by all the VTP software.
3 //
4 // Copyright (c) 2001-2009 Virtual Terrain Project
5 // Free for all uses, see license.txt for details.
6 //
9 #ifndef VTMATHTYPESH
10 #define VTMATHTYPESH
11 
12 #include <math.h>
13 #include <locale.h>
14 #include <vector>
15 #include <string>
16 
17 #include "vtdata/config_vtdata.h"
18 #include "Array.h"
19 
20 // willemsn: this was taken from OSG's Math include file.
21 // 04/29/03
22 #ifdef __DARWIN_OSX__
23  #include <float.h>
24 
25  // PJA MAC OSX
26  // This appears to be the simplest way to get these defined under MACOSX
27  // where they arent in math.h
28  #ifndef acosf
29  #define acosf (float)acos
30  #endif
31 
32  #ifndef asinf
33  #define asinf (float)asin
34  #endif
35 
36  #ifndef atan2f
37  #define atan2f (float)atan2
38  #endif
39 
40  #ifndef cosf
41  #define cosf (float)cos
42  #endif
43 
44  #ifndef sinf
45  #define sinf (float)sin
46  #endif
47 
48  #ifndef tanf
49  #define tanf (float)tan
50  #endif
51 
52  #ifndef logf
53  #define logf (float)log
54  #endif
55 
56  #ifndef log10f
57  #define log10f (float)log10
58  #endif
59 
60  #ifndef powf
61  #define powf (float)pow
62  #endif
63 
64  #ifndef sqrtf
65  #define sqrtf (float)sqrt
66  #endif
67 
68  #ifndef fabsf
69  #define fabsf (float)fabs
70  #endif
71 #endif
72 
73 #ifndef PId
74  #define PId 3.14159265358979323846264338
75  #define PIf 3.14159265358979323846264338f
76  #define PI2d 6.28318530717958647692528676
77  #define PI2f 6.28318530717958647692528676f
78  #define PID2d 1.57079632679489661923132169
79  #define PID2f 1.57079632679489661923132169f
80  #define PID3d 1.04719755119659774615421446
81 #endif
82 
83 #ifndef NULL
84 #define NULL 0
85 #endif
86 
87 class DPoint3;
88 
92 class FPoint3
93 {
94 public:
95  FPoint3() { x = y = z = 0.0f; }
96  FPoint3(float fx, float fy, float fz) { x=fx; y=fy; z=fz; }
97  FPoint3(const DPoint3 &p);
98 
99  float Length() const { return sqrtf(x*x+y*y+z*z); }
100  float LengthSquared() const { return x*x+y*y+z*z; }
101  FPoint3 &Normalize() { float s = 1.0f/Length(); x*=s; y*=s; z*=s; return (*this); }
102  FPoint3 &SetLength(float len) { float s = len/Length(); x*=s; y*=s; z*=s; return (*this); }
103  void Set(float fx, float fy, float fz) { x=fx; y=fy; z=fz; }
104  float Dot(const FPoint3 &rhs) const
105  {
106  return x*rhs.x+y*rhs.y+z*rhs.z;
107  }
108  float Dot(const float *fp) const
109  {
110  return x*fp[0]+y*fp[1]+z*fp[2];
111  }
112  FPoint3 Cross(const FPoint3 &v) const
113  {
114  return FPoint3(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x);
115  }
120  void UnitNormal(const FPoint3 &p0, const FPoint3 &p1, const FPoint3 &p2)
121  {
122  FPoint3 edge0 = p1 - p0;
123  FPoint3 edge1 = p2 - p0;
124  *this = edge0.Cross(edge1);
125  this->Normalize();
126  }
127 
128  // assignment
129  FPoint3 &operator=(const FPoint3 &v) { x = v.x; y = v.y; z = v.z; return *this; }
130  FPoint3 &operator=(const DPoint3 &v);
131 
132  // operators
133  FPoint3 operator +(const FPoint3 &v) const { return FPoint3(x+v.x, y+v.y, z+v.z); }
134  FPoint3 operator -(const FPoint3 &v) const { return FPoint3(x-v.x, y-v.y, z-v.z); }
135  FPoint3 operator *(float s) const { return FPoint3(x*s, y*s, z*s); }
136  FPoint3 operator *(double s) const { return FPoint3((float)(x*s), (float)(y*s), (float)(z*s)); }
137  FPoint3 operator /(float s) const { return FPoint3(x/s, y/s, z/s); }
138  FPoint3 operator -() { return FPoint3(-x, -y, -z); }
139  bool operator==(const FPoint3 &v2) const
140  { return (x == v2.x && y == v2.y && z == v2.z); }
141  bool operator!=(const FPoint3 &v2) const
142  { return (x != v2.x || y != v2.y || z != v2.z); }
143 
144  void operator +=(const FPoint3 &v) { x+=v.x; y+=v.y; z+=v.z; }
145  void operator -=(const FPoint3 &v) { x-=v.x; y-=v.y; z-=v.z; }
146  void operator *=(float s) { x*=s; y*=s; z*=s; }
147  void operator /=(float s) { x/=s; y/=s; z/=s; }
148  FPoint3 operator -() const { return FPoint3 (-x, -y, -z); }
149 
150  // also allow array-like access, such that x,y,z components are 0,1,2
151  float &operator[](int nIndex) { return *(&x+nIndex); }
152  const float &operator[](int nIndex) const { return *(&x+nIndex); }
153 
154  float x, y, z;
155 };
156 
160 class DPoint3
161 {
162 public:
163  DPoint3() { x = y = z = 0.0f; }
164  DPoint3(double fx, double fy, double fz) { x=fx; y=fy; z=fz; }
165  DPoint3(const FPoint3 &p);
166 
167  double Length() const { return sqrt(x*x+y*y+z*z); }
168  double LengthSquared() const { return x*x+y*y+z*z; }
169  DPoint3 &Normalize()
170  {
171  double s = 1.0/Length();
172  x*=s; y*=s; z*=s;
173  return (*this);
174  }
175  DPoint3 &SetLength(double len) { double s = len/Length(); x*=s; y*=s; z*=s; return (*this); }
176  void Set(double fx, double fy, double fz) { x=fx; y=fy; z=fz; }
177  double Dot(const DPoint3 &rhs) const
178  {
179  return x*rhs.x+y*rhs.y+z*rhs.z;
180  }
181  DPoint3 Cross(const DPoint3 &v) const
182  {
183  return DPoint3(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x);
184  }
185  // assignment
186  DPoint3 &operator=(const DPoint3 &v) { x = v.x; y = v.y; z = v.z; return *this; }
187  DPoint3 &operator=(const FPoint3 &v);
188 
189  // operators
190  DPoint3 operator +(const DPoint3 &v) const { return DPoint3(x+v.x, y+v.y, z+v.z); }
191  DPoint3 operator -(const DPoint3 &v) const { return DPoint3(x-v.x, y-v.y, z-v.z); }
192  DPoint3 operator *(double s) const { return DPoint3(x*s, y*s, z*s); }
193  DPoint3 operator /(double s) const { return DPoint3(x/s, y/s, z/s); }
194  bool operator==(const DPoint3 &v2) const
195  { return (x == v2.x && y == v2.y && z == v2.z); }
196  bool operator!=(const DPoint3 &v2) const
197  { return (x != v2.x || y != v2.y || z != v2.z); }
198 
199  // dot product
200  double operator *(const DPoint3 &v) const { return x*v.x + y*v.y + z*v.z; }
201 
202  void operator +=(const DPoint3 &v) { x+=v.x; y+=v.y; z+=v.z; }
203  void operator -=(const DPoint3 &v) { x-=v.x; y-=v.y; z-=v.z; }
204  void operator *=(double s) { x*=s; y*=s; z*=s; }
205  void operator /=(double s) { x/=s; y/=s; z/=s; }
206 
207  double x, y, z;
208 };
209 
210 // Conversion
211 inline FPoint3::FPoint3(const DPoint3 &v) { x = (float) v.x; y = (float) v.y; z = (float) v.z; }
212 inline DPoint3::DPoint3(const FPoint3 &v) { x = v.x; y = v.y; z = v.z; }
213 inline FPoint3 &FPoint3::operator=(const DPoint3 &v) { x = (float) v.x; y = (float) v.y; z = (float) v.z; return *this; }
214 inline DPoint3 &DPoint3::operator=(const FPoint3 &v) { x = v.x; y = v.y; z = v.z; return *this; }
215 
217 
218 class FPoint2;
219 class DPoint2;
220 
224 class FPoint2
225 {
226 public:
227  FPoint2() { x = y = 0.0f; }
228  FPoint2(int ix, int iy) { x=(float)ix; y=(float)iy; }
229  FPoint2(float fx, float fy) { x=fx; y=fy; }
230  FPoint2(double dx, double dy) { x=(float)dx; y=(float)dy; }
231  FPoint2(const DPoint2 &d);
232 
233  float Length() const { return sqrtf(x*x+y*y); }
234  float LengthSquared() const { return x*x+y*y; }
235  FPoint2 &Normalize() { float s = 1.0f/Length(); x*=s; y*=s; return (*this); }
236  FPoint2 &SetLength(float len) { float s = len/Length(); x*=s; y*=s; return (*this); }
237  void Set(float fx, float fy) { x=fx; y=fy; }
238  float Dot(const FPoint2 &rhs) const
239  {
240  return x*rhs.x+y*rhs.y;
241  }
242  void Mult(const FPoint2 &factor) { x *= factor.x; y *= factor.y; }
243  void Mult(const float fx, const float fy) { x *= fx; y *= fy; }
244  void Div(const FPoint2 &factor) { x /= factor.x; y /= factor.y; }
245  void Div(const float fx, const float fy) { x /= fx; y /= fy; }
246  void Rotate(double radians)
247  {
248  float tempx = x;
249  x = x * (float) cos(radians) - y * (float) sin(radians);
250  y = tempx * (float) sin(radians) + y * (float) cos(radians);
251  }
254  float Cross(const FPoint2 &rhs)
255  {
256  return (x*rhs.y - y*rhs.x);
257  }
258 
259  // assignment
260  FPoint2 &operator=(const FPoint2 &v) { x = v.x; y = v.y; return *this; }
261  FPoint2 &operator=(const class DPoint2 &v);
262 
263  FPoint2 operator +(const FPoint2 &v) const { return FPoint2(x+v.x, y+v.y); }
264  FPoint2 operator -(const FPoint2 &v) const { return FPoint2(x-v.x, y-v.y); }
265  FPoint2 operator *(float s) const { return FPoint2(x*s, y*s); }
266  FPoint2 operator /(float s) const { return FPoint2(x/s, y/s); }
267 
268  void operator +=(const FPoint2 &v) { x+=v.x; y+=v.y; }
269  void operator -=(const FPoint2 &v) { x-=v.x; y-=v.y; }
270  void operator *=(float s) { x*=s; y*=s; }
271  void operator /=(float s) { x/=s; y/=s; }
272 
273  bool operator==(const FPoint2 &v) const { return (x == v.x && y == v.y); }
274  bool operator!=(const FPoint2 &v) const { return (x != v.x || y != v.y); }
275 
276  float x, y;
277 };
278 
282 class DPoint2
283 {
284 public:
285  DPoint2() { x = y = 0.0f; }
286  DPoint2(int ix, int iy) { x=(double)ix; y=(double)iy; }
287  DPoint2(float fx, float fy) { x=fx; y=fy; }
288  DPoint2(double fx, double fy) { x=fx; y=fy; }
289  DPoint2(const FPoint2 &f);
290 
291  double Length() const { return sqrt(x*x+y*y); }
292  double LengthSquared() const { return (x*x+y*y); }
293  DPoint2 &Normalize() { double s = 1.0f/Length(); x*=s; y*=s; return (*this); }
294  DPoint2 &SetLength(double len) { double s = len/Length(); x*=s; y*=s; return (*this); }
295  void Set(double fx, double fy) { x=fx; y=fy; }
296  double Dot(const DPoint2 &rhs) const
297  {
298  return x*rhs.x + y*rhs.y;
299  }
300  void Mult(const DPoint2 &factor) { x *= factor.x; y *= factor.y; }
301  void Mult(const double fx, const double fy) { x *= fx; y *= fy; }
302  void Div(const DPoint2 &factor) { x /= factor.x; y /= factor.y; }
303  void Div(const double fx, const double fy) { x /= fx; y /= fy; }
304  void Rotate(double radians)
305  {
306  double tempx = x;
307  x = x * cos(radians) - y * sin(radians);
308  y = tempx * sin(radians) + y * cos(radians);
309  }
312  double Cross(const DPoint2 &rhs)
313  {
314  return (x*rhs.y - y*rhs.x);
315  }
316 
317  // assignment
318  DPoint2 &operator=(const DPoint2 &v) { x = v.x; y = v.y; return *this; }
319  DPoint2 &operator=(const class FPoint2 &v);
320 
321  DPoint2 operator +(const DPoint2 &v) const { return DPoint2(x+v.x, y+v.y); }
322  DPoint2 operator -(const DPoint2 &v) const { return DPoint2(x-v.x, y-v.y); }
323  DPoint2 operator *(double s) const { return DPoint2(x*s, y*s); }
324  DPoint2 operator /(double s) const { return DPoint2(x/s, y/s); }
325 
326  void operator +=(const DPoint2 &v) { x+=v.x; y+=v.y; }
327  void operator -=(const DPoint2 &v) { x-=v.x; y-=v.y; }
328  void operator *=(double s) { x*=s; y*=s; }
329  void operator /=(double s) { x/=s; y/=s; }
330 
331  bool operator==(const DPoint2 &v) const { return (x == v.x && y == v.y); }
332  bool operator!=(const DPoint2 &v) const { return (x != v.x || y != v.y); }
333 
334  DPoint2 operator-(void) { return DPoint2(-x,-y); }
335 
336  double x, y;
337 };
338 
339 
340 // copy constructors FPoint2 <> DPoint2
341 inline FPoint2::FPoint2(const DPoint2 &d) { x=(float)d.x; y=(float)d.y; }
342 inline DPoint2::DPoint2(const FPoint2 &f) { x=f.x; y=f.y; }
343 
344 
349 class IPoint2 {
350 public:
351  IPoint2() {}
352  IPoint2(int ix, int iy) { x=ix; y=iy; }
353 
354  float Length() const { return sqrtf((float)x*x + (float)y*y); }
355  void Set(int ix, int iy) { x=ix; y=iy; }
356  IPoint2 &operator=(const IPoint2 &v) { x = v.x; y = v.y; return *this; }
357 
358  IPoint2 operator +(const IPoint2 &v) const { return IPoint2(x+v.x, y+v.y); }
359  IPoint2 operator -(const IPoint2 &v) const { return IPoint2(x-v.x, y-v.y); }
360  IPoint2 operator *(int s) const { return IPoint2(x*s, y*s); }
361  IPoint2 operator *(float f) const { return IPoint2((int)(x*f), (int)(y*f)); }
362 
363  void operator +=(const IPoint2 &v) { x+=v.x; y+=v.y; }
364  void operator -=(const IPoint2 &v) { x-=v.x; y-=v.y; }
365  void operator *=(int s) { x*=s; y*=s; }
366  void operator *=(float f) { x=(int)(x*f); y=(int)(y*f); }
367 
368  bool operator==(const IPoint2 &v) const { return (x == v.x && y == v.y); }
369  bool operator!=(const IPoint2 &v) const { return (x != v.x || y != v.y); }
370 
371  int x, y;
372 };
373 
374 inline FPoint2 &FPoint2::operator=(const class DPoint2 &v)
375 {
376  x = (float) v.x;
377  y = (float) v.y;
378  return *this;
379 }
380 
381 inline DPoint2 &DPoint2::operator=(const class FPoint2 &v)
382 {
383  x = v.x;
384  y = v.y;
385  return *this;
386 }
387 
388 // Forward declarations for the line classes
389 class DLine2;
390 class FLine2;
391 class DLine3;
392 class FLine3;
393 
398 class DLine2 : public vtArray<DPoint2>
399 {
400 public:
401  DLine2() {}
402  DLine2(int size) { SetSize(size); }
403  // copy constructor
404  DLine2(const DLine2 &ref) : vtArray<DPoint2>() { *this = ref; }
405 
406  // assignment
407  DLine2 &operator=(const DLine2 &v);
408  DLine2 &operator=(const FLine2 &v);
409 
411  void Add(const DPoint2 &p);
413  void Mult(double factor);
414 
415  // Modify
416  void InsertPointAfter(int iInsertAfter, const DPoint2 &Point);
417  void RemovePoint(int i);
418  void ReverseOrder();
419  int RemoveDegeneratePoints(double dEpsilon);
420  int RemoveColinearPoints(double dEpsilon);
421 
422  // Query
423  bool ContainsPoint(const DPoint2 &p) const;
424  double SegmentLength(uint i) const;
425  void NearestPoint(const DPoint2 &Point, int &iIndex, double &dist) const;
426  bool NearestSegment(const DPoint2 &Point, int &iIndex, double &dist, DPoint2 &Intersection) const;
427  bool IsConvex() const;
428  DPoint2 &GetSafePoint(int index) const;
429  void SetSafePoint(int index, const DPoint2 &p);
430  double Length() const;
431  DPoint2 Centroid() const;
432  DPoint2 Centroid2() const;
433  double Area() const
434  {
435  int n = (int) GetSize();
436  double A = 0.0;
437  for (int p=n-1,q=0; q<n; p=q++)
438  A += GetAt(p).x*GetAt(q).y - GetAt(q).x*GetAt(p).y;
439  return A*0.5;
440  }
441 };
442 
447 class FLine2 : public vtArray<FPoint2>
448 {
449 public:
450  FLine2() {}
451  FLine2(int size) { SetSize(size); }
452  // copy constructor
453  FLine2(const FLine2 &ref) : vtArray<FPoint2>() { *this = ref; }
454 
455  // assignment
456  FLine2 &operator=(const FLine2 &v);
457  FLine2 &operator=(const DLine2 &v);
458 
459  float Area() const;
460  float SegmentLength(uint i) const;
461  void NearestPoint(const FPoint2 &Point, int &iIndex, float &dist) const;
462  void NearestPoint(const FPoint2 &Point, int &iIndex) const;
463  bool NearestSegment(const FPoint2 &Point, int &iIndex, float &dist, FPoint2 &Intersection) const;
464  void InsertPointAfter(int iInsertAfter, const FPoint2 &Point);
465  void ReverseOrder();
466  bool IsConvex() const;
467 };
468 
469 inline DLine2 &DLine2::operator=(const DLine2 &v)
470 {
471  int size = v.GetSize();
472  SetSize(size);
473  for (int i = 0; i < size; i++)
474  SetAt(i, v.GetAt(i));
475 
476  return *this;
477 }
478 
479 inline DLine2 &DLine2::operator=(const FLine2 &v)
480 {
481  int size = v.GetSize();
482  SetSize(size);
483 
484  FPoint2 p1;
485  DPoint2 p2;
486  for (int i = 0; i < size; i++)
487  {
488  p1 = v.GetAt(i);
489  p2 = p1;
490  SetAt(i, p2);
491  }
492  return *this;
493 }
494 
495 inline FLine2 &FLine2::operator=(const FLine2 &v)
496 {
497  int size = v.GetSize();
498  SetSize(size);
499  for (int i = 0; i < size; i++)
500  SetAt(i, v.GetAt(i));
501 
502  return *this;
503 }
504 
505 inline FLine2 &FLine2::operator=(const DLine2 &v)
506 {
507  int size = v.GetSize();
508  SetSize(size);
509 
510  DPoint2 p1;
511  FPoint2 p2;
512  for (int i = 0; i < size; i++)
513  {
514  p1 = v.GetAt(i);
515  p2 = p1;
516  SetAt(i, p2);
517  }
518  return *this;
519 }
520 
522 
527 class DLine3 : public vtArray<DPoint3>
528 {
529 public:
530  DLine3() {}
531  // copy constructor
532  DLine3(const DLine3 &ref) : vtArray<DPoint3>() { *this = ref; }
533 
534  // assignment
535  DLine3 &operator=(const DLine3 &v);
536 // DLine3 &operator=(const FLine3 &v);
537 
538  void Add(const DPoint2 &p);
539  bool NearestSegment2D(const DPoint2 &Point, int &iIndex,
540  double &dist, DPoint3 &Intersection) const;
541  void NearestPoint2D(const DPoint2 &Point, int &iIndex, double &dist) const;
542  bool ContainsPoint2D(const DPoint2 &p) const;
543 };
544 
549 class FLine3 : public vtArray<FPoint3>
550 {
551 public:
552  FLine3() {}
553  FLine3(int size) { SetSize(size); }
554  // copy constructor
555  FLine3(const FLine3 &ref) : vtArray<FPoint3>() { *this = ref; }
556 
557  // assignment
558  FLine3 &operator=(const FLine3 &v);
559 // FLine3 &operator=(const DLine3 &v);
560 
561  void ReverseOrder();
562 };
563 
564 inline DLine3 &DLine3::operator=(const DLine3 &v)
565 {
566  int size = v.GetSize();
567  SetSize(size);
568  for (int i = 0; i < size; i++)
569  SetAt(i, v.GetAt(i));
570 
571  return *this;
572 }
573 
574 inline FLine3 &FLine3::operator=(const FLine3 &v)
575 {
576  int size = v.GetSize();
577  SetSize(size);
578  for (int i = 0; i < size; i++)
579  SetAt(i, v.GetAt(i));
580 
581  return *this;
582 }
583 
584 
586 
590 class FPlane : public FPoint3
591 {
592 public:
593  typedef enum { COLINEAR, COPLANAR, PARALLEL, FACING_AWAY, INTERSECTING } IntersectionType;
594 
595  // Default constructor
596  FPlane()
597  {
598  w = 0.0;
599  }
601  FPlane(float a, float b, float c, float d) { x = a; y = b; z = c; w = d; }
603  FPlane(const FPoint3& p, const FPoint3& q, const FPoint3& r);
605  FPlane(const FPoint3& Point, const FPoint3& Normal);
606 
607  const FPlane &operator=(const FPlane &rhs)
608  {
609  x = rhs.x;
610  y = rhs.y;
611  z = rhs.z;
612  w = rhs.w;
613  return *this;
614  }
615  void Set(const FPoint3 &p, const FPoint3 &n)
616  {
617  x = n.x;
618  y = n.y;
619  z = n.z;
620  w = -n.Dot(p);
621  }
622  void Set(float a, float b, float c, float d) { x = a; y = b; z = c; w = d; }
623  float Distance(const FPoint3 &v) const
624  {
625  return Dot(v) + w;
626  }
627 
629  const IntersectionType Intersection(const FPlane &Plane, FPoint3 &Origin, FPoint3 &Direction, float fEpsilon = 0.0) const;
631  const IntersectionType RayIntersection(const FPoint3 &Origin, const FPoint3 &Direction, float &fDistance, FPoint3 &Intersection, float fEpsilon = 0.0) const;
633  const IntersectionType LineIntersection(const FPoint3 &Origin, const FPoint3 &Direction, FPoint3 &Intersection, float fEpsilon = 0.0) const;
635  const IntersectionType ThreePlanesIntersection(const FPlane &Plane1, const FPlane &Plane2, FPoint3 &Intersection, float fEpsilon = 0.0) const;
636 
637  float w;
638 };
639 
640 
642 
647 class FBox3
648 {
649 public:
650  FBox3() {}
651  FBox3(float x1, float y1, float z1, float x2, float y2, float z2)
652  {
653  min.Set(x1, y1, z1);
654  max.Set(x2, y2, z2);
655  }
656  FBox3(const FPoint3 &min1, const FPoint3 &max1) { min = min1; max = max1; }
657 
658  void InsideOut()
659  {
660  min.Set(1E10f, 1E10f, 1E10f);
661  max.Set(-1E10f, -1E10f, -1E10f);
662  }
663  void Set(float x1, float y1, float z1, float x2, float y2, float z2)
664  {
665  min.Set(x1, y1, z1);
666  max.Set(x2, y2, z2);
667  }
668  FPoint3 Center() const { return ((min + max) * 0.5); }
669  void GrowToContainPoint(const FPoint3 &p)
670  {
671  if (p.x < min.x) min.x = p.x;
672  if (p.y < min.y) min.y = p.y;
673  if (p.z < min.z) min.z = p.z;
674  if (p.x > max.x) max.x = p.x;
675  if (p.y > max.y) max.y = p.y;
676  if (p.z > max.z) max.z = p.z;
677  }
678  void GrowToContainLine(const FLine3 &line)
679  {
680  for (uint i = 0; i < line.GetSize(); i++)
681  GrowToContainPoint(line[i]);
682  }
683  void GrowToContainBox(const FBox3 &box)
684  {
685  GrowToContainPoint(box.min);
686  GrowToContainPoint(box.max);
687  }
688 
689  FPoint3 min, max;
690 };
691 
693 
697 class FSphere
698 {
699 public:
700  FSphere() {}
701  FSphere(const FBox3 &src)
702  {
703  center = src.Center();
704  radius = (center - src.min).Length();
705  }
706  FSphere(const FPoint3 &p, float fRadius)
707  {
708  Set(p, fRadius);
709  }
710  const FSphere &operator=(const FSphere &rhs)
711  {
712  center = rhs.center;
713  radius = rhs.radius;
714  return *this;
715  }
716  void Set(const FPoint3 &p, float fRadius)
717  {
718  center = p;
719  radius = fRadius;
720  }
721  void Empty() { center.Set(0,0,0); radius = 0; }
722 
723  void GrowToContain(const FSphere &sh)
724  {
725  FPoint3 dv = sh.center - center;
726  float dv_len = dv.Length();
727 
728  if (dv_len == 0 && sh.radius > radius)
729  radius = sh.radius;
730  else if (dv_len+sh.radius > radius)
731  {
732  FPoint3 e1 = center - (dv*(radius/dv_len));
733  FPoint3 e2 = sh.center + (dv*(sh.radius/dv_len));
734  center = (e1 + e2) * 0.5f;
735  radius = (e2 - center).Length();
736  }
737  }
738  bool operator==(const FSphere &v) const { return (center == v.center && radius == v.radius); }
739  bool operator!=(const FSphere &v) const { return (center != v.center || radius != v.radius); }
740 
741  FPoint3 center;
742  float radius;
743 };
744 
746 
747 class DRECT;
748 
749 typedef std::vector<DLine2> DLine2Array;
750 typedef std::vector<FLine3> FLine3Array;
751 
761 class DPolygon2 : public DLine2Array
762 {
763 public:
764  // Query
765  uint NumTotalVertices() const;
766  bool ComputeExtents(DRECT &rect) const;
767  bool ContainsPoint(const DPoint2 &p) const;
768  void GetAsDLine2(DLine2 &dline) const;
769  int WhichRing(int &iVtxNum) const;
770  void NearestPoint(const DPoint2 &Point, int &iIndex, double &dist) const;
771  bool NearestSegment(const DPoint2 &Point, int &iIndex, double &dist, DPoint2 &Intersection) const;
772 
773  // Modify
774  void Add(const DPoint2 &p);
775  void Mult(double factor);
776  void ReverseOrder();
777  void InsertPointAfter(int iInsertAfter, const DPoint2 &Point);
778  void RemovePoint(int N);
779  int RemoveDegeneratePoints(double dEpsilon);
780  int RemoveColinearPoints(double dEpsilon);
781 };
782 
786 class DPolyArray : public std::vector<DPolygon2>
787 {
788 public:
789  DPolyArray() { s_previous_poly = -1; }
790 
791  int FindPoly(const DPoint2 &p) const;
792 
793  // for speed, remember the polygon that we found last time
794  static int s_previous_poly;
795 };
796 
806 class FPolygon3 : public FLine3Array
807 {
808 public:
809  void Add(const FPoint3 &p);
810  void Mult(float factor);
811  void ReverseOrder();
812  uint NumTotalVertices() const;
813  int WhichRing(int &iVtxNum) const;
814 };
815 
816 
827 class DRECT
828 {
829 public:
830  DRECT() { left = top = right = bottom = 0.0; }
831  DRECT(double l, double t, double r, double b) { left = l; top = t; right = r; bottom = b; }
832 
833  void SetRect(double l, double t, double r, double b) { left = l; top = t; right = r; bottom = b; }
834  // retrieves the width
835  double Width() const { return right - left; }
836  // returns the height, assumes upward increasing coordinate system
837  double Height() const { return top - bottom; };
838  // return true if null (all 0)
839  bool IsNull() const { return (left == 0.0 && top == 0.0 && right == 0.0 && bottom == 0.0); }
840  // return true if empty
841  bool IsEmpty() const { return (left == right && top == bottom); }
842  void Empty() { left = top = right = bottom = 0.0; }
843  void Sort()
844  {
845  if (left > right) { double tmp = left; left = right; right = tmp; }
846  if (bottom > top) { double tmp = bottom; bottom = top; top = tmp; }
847  }
848  void GetCenter(DPoint2 &p) const
849  {
850  p.x = (left + right) / 2.0;
851  p.y = (bottom + top) / 2.0;
852  }
853  DPoint2 GetCenter() const
854  {
855  return DPoint2((left + right) / 2.0, (bottom + top) / 2);
856  }
857  DPoint2 LowerLeft() const
858  {
859  return DPoint2(left, bottom);
860  }
861  bool ContainsPoint(const DPoint2 &p, bool bInclusive = false) const
862  {
863  if (bInclusive)
864  return (p.x >= left && p.x <= right && p.y >= bottom && p.y <= top);
865  else
866  return (p.x > left && p.x < right && p.y > bottom && p.y < top);
867  }
868  bool ContainsPoint(const DPoint3 &p) const
869  {
870  return (p.x > left && p.x < right && p.y > bottom && p.y < top);
871  }
872  bool ContainsLine(const DLine2 &line) const;
873  bool ContainsLine(const DLine3 &line) const;
874  bool ContainsRect(const DRECT &r2) const
875  {
876  return (r2.left >= left && r2.right <= right &&
877  r2.bottom >= bottom && r2.top <= top);
878  }
879  bool OverlapsRect(const DRECT &r2) const
880  {
881  if ( left > r2.right ||
882  r2.left > right ||
883  bottom > r2.top ||
884  r2.bottom > top)
885  return false;
886  else
887  return true;
888  }
889  void Grow(double x, double y)
890  {
891  left -= x;
892  right += x;
893  bottom -= y;
894  top += y;
895  }
896  void GrowToContainPoint(const DPoint2 &p)
897  {
898  if (p.x < left) left = p.x;
899  if (p.x > right) right = p.x;
900  if (p.y < bottom) bottom = p.y;
901  if (p.y > top) top = p.y;
902  }
903  void GrowToContainLine(const DLine2 &line)
904  {
905  DPoint2 p;
906  int size = line.GetSize();
907  for (int i = 0; i < size; i++)
908  {
909  p = line.GetAt(i);
910  if (p.x < left) left = p.x;
911  if (p.x > right) right = p.x;
912  if (p.y < bottom) bottom = p.y;
913  if (p.y > top) top = p.y;
914  }
915  }
916  void GrowToContainLine(const DLine3 &line)
917  {
918  DPoint3 p;
919  int size = line.GetSize();
920  for (int i = 0; i < size; i++)
921  {
922  p = line.GetAt(i);
923  if (p.x < left) left = p.x;
924  if (p.x > right) right = p.x;
925  if (p.y < bottom) bottom = p.y;
926  if (p.y > top) top = p.y;
927  }
928  }
929  // expand geographical rectangle r1 to include rectangle r2
930  void GrowToContainRect(const DRECT &r2)
931  {
932  if (r2.left < left) left = r2.left;
933  if (r2.right > right) right = r2.right;
934  if (r2.top > top) top = r2.top;
935  if (r2.bottom < bottom) bottom = r2.bottom;
936  }
937  bool operator==(const DRECT &v) const
938  {
939  return (left == v.left && top == v.top && right == v.right && bottom == v.bottom);
940  }
941  bool operator!=(const DRECT &v) const
942  {
943  return (left != v.left || top != v.top || right != v.right || bottom != v.bottom);
944  }
945 
946  double left;
947  double top;
948  double right;
949  double bottom;
950 };
951 
962 class FRECT
963 {
964 public:
965  FRECT() { left = top = right = bottom = 0.0; }
966  FRECT(float l, float t, float r, float b)
967  {
968  left = l; top = t; right = r; bottom = b;
969  }
970  void SetRect(float l, float t, float r, float b)
971  {
972  left = l; top = t; right = r; bottom = b;
973  }
974  // retrieves the width
975  float Width() const { return right - left; }
976  // returns the height
977  float Height() const { return top - bottom; };
978  // return true if empty
979  bool IsEmpty() const { return (left == right && top == bottom); }
980  void Empty() { left = top = right = bottom = 0.0; }
981  void Sort()
982  {
983  if (left > right) { float tmp = left; left = right; right = tmp; }
984  if (bottom > top) { float tmp = bottom; bottom = top; top = tmp; }
985  }
986  bool ContainsPoint(float x, float y) const
987  {
988  return (x > left && x < right && y > bottom && y < top);
989  }
990  void Center(FPoint2 &center) const
991  {
992  center.x = (left + right)/2;
993  center.y = (bottom + top)/2;
994  }
995  FPoint2 Center() const
996  {
997  return FPoint2((left + right)/2, (bottom + top)/2);
998  }
999  void operator+=(const FPoint2 &delta)
1000  {
1001  left += delta.x; top += delta.y;
1002  right += delta.x; bottom += delta.y;
1003  }
1004 
1005  float left;
1006  float top;
1007  float right;
1008  float bottom;
1009 };
1010 
1011 
1013 // Matrix classes
1014 
1015 class DMatrix3;
1016 class DMatrix4;
1017 
1022 {
1023 public:
1024  void Set(int i, int j, double v) { data[i][j] = v; }
1025  double Get(int i, int j) const { return data[i][j]; }
1026  double operator()(int i, int j) const { return data[i][j]; }
1027 
1028  void Identity();
1029  void AxisAngle(const DPoint3 &vec, double theta);
1030  void Transform(const DPoint3 &src, DPoint3 &dst) const;
1031  void SetByMatrix4(const DMatrix4 &m);
1032 
1033 protected:
1034  double data[3][3];
1035 };
1036 
1041 {
1042 public:
1043  void Set(int i, int j, double v) { data[i][j] = v; }
1044  double Get(int i, int j) const { return data[i][j]; }
1045  double operator()(int i, int j) const { return data[i][j]; }
1046 
1047  void Identity();
1048  void AxisAngle(const DPoint3 &vec, double theta);
1049  void Invert(const DMatrix4 &src);
1050 
1051 protected:
1052  double data[4][4];
1053 };
1054 
1056 
1057 class FMatrix4;
1058 
1063 {
1064 public:
1065  FMatrix3() {}
1066  FMatrix3(const FMatrix4 &mat) { SetFromMatrix4(mat); }
1067 
1068  void Set(int col, int row, float v) { data[col][row] = v; }
1069  float Get(int col, int row) const { return data[col][row]; }
1070  void SetRow(int row, float f0, float f1, float f2);
1071 
1072  void Identity();
1073  bool IsIdentity() const;
1074  void AxisAngle(const FPoint3 &vec, double theta);
1075  void SetFromVectors(const FPoint3 &forward, const FPoint3 &up);
1076 
1077  void Transform(const FPoint3 &src, FPoint3 &dst) const;
1078  void SetFromMatrix4(const FMatrix4 &mat);
1079 
1080  void MakeOrientation(const FPoint3 &vector, bool bPitch = true);
1081  void PreMult(const FMatrix3 &mat);
1082  void PostMult(const FMatrix3 &mat);
1083 
1084  // operators
1085  float operator()(int col, int row) const { return data[col][row]; }
1086  FMatrix3 &operator=(const FMatrix4 &mat);
1087 
1088 protected:
1089  float data[3][3];
1090 };
1091 
1092 typedef float FMatrix4Data[4][4];
1093 
1098 {
1099 public:
1100  FMatrix4() {}
1101  FMatrix4(const FMatrix3 &mat) { SetFromMatrix3(mat); }
1102 
1103  void Set(int col, int row, float v) { data[col][row] = v; }
1104  float Get(int col, int row) const { return data[col][row]; }
1105  void SetRow(int row, float f0, float f1, float f2, float f3);
1106 
1107  void SetData(FMatrix4Data data_in) { memcpy(data, data_in, 64); }
1108  const FMatrix4Data &GetData() const { return data; }
1109 
1110  // set/modify
1111  void Identity();
1112  bool IsIdentity() const;
1113  void AxisAngle(const FPoint3 &vec, double theta);
1114  void Translate(const FPoint3 &vec);
1115  void Invert(const FMatrix4 &src);
1116  FPoint3 GetTrans() const;
1117  void SetTrans(FPoint3 pos);
1118  void SetFromVectors(const FPoint3 &pos, const FPoint3 &forward,
1119  const FPoint3 &up);
1120  void SetFromMatrix3(const FMatrix3 &mat);
1121  void MakeScale(float x, float y, float z);
1122 
1123  void PreMult(const FMatrix4 &mat);
1124  void PostMult(const FMatrix4 &mat);
1125 
1126  // apply to vectors
1127  void Transform(const FPoint3 &src, FPoint3 &dst) const;
1128  void TransformVector(const FPoint3 &tmp, FPoint3 &dst) const;
1129 
1130  inline FPoint3 PreMult(const FPoint3 &v) const
1131  {
1132  double d = 1.0 / (data[3][0]*v.x + data[3][1]*v.y + data[3][2]*v.z + data[3][3]);
1133  return FPoint3( (float)((data[0][0]*v.x + data[0][1]*v.y + data[0][2]*v.z + data[0][3])*d),
1134  (float)((data[1][0]*v.x + data[1][1]*v.y + data[1][2]*v.z + data[1][3])*d),
1135  (float)((data[2][0]*v.x + data[2][1]*v.y + data[2][2]*v.z + data[2][3])*d));
1136  }
1137  inline FPoint3 PostMult(const FPoint3 &v) const
1138  {
1139  double d = 1.0 / (data[0][3]*v.x + data[1][3]*v.y + data[2][3]*v.z + data[3][3]);
1140  return FPoint3( (float)((data[0][0]*v.x + data[1][0]*v.y + data[2][0]*v.z + data[3][0])*d),
1141  (float)((data[0][1]*v.x + data[1][1]*v.y + data[2][1]*v.z + data[3][1])*d),
1142  (float)((data[0][2]*v.x + data[1][2]*v.y + data[2][2]*v.z + data[3][2])*d));
1143  }
1144 
1145  // operators
1146  float operator()(int col, int row) const { return data[col][row]; }
1147  FMatrix4 &operator=(const FMatrix3 &mat);
1148  bool operator==(const FMatrix4 &mat) const;
1149  bool operator!=(const FMatrix4 &mat) const;
1150 
1151 protected:
1152  float data[4][4];
1153 };
1154 
1155 inline FMatrix3 &FMatrix3::operator=(const FMatrix4 &mat)
1156 {
1157  SetFromMatrix4(mat);
1158  return (*this);
1159 }
1160 inline FMatrix4 &FMatrix4::operator=(const FMatrix3 &mat)
1161 {
1162  SetFromMatrix3(mat);
1163  return (*this);
1164 }
1165 
1166 inline bool FMatrix4::operator==(const FMatrix4 &mat) const
1167 {
1168  return memcmp(data, mat.data, sizeof(data)) == 0;
1169 }
1170 
1171 inline bool FMatrix4::operator!=(const FMatrix4 &mat) const
1172 {
1173  return memcmp(data, mat.data, sizeof(data)) != 0;
1174 }
1175 
1177 // Quaternion class
1178 
1184 class FQuat
1185 {
1186 public:
1187  FQuat() {}
1188  FQuat(float qx, float qy, float qz, float qw) { x = qx; y = qy; z = qz; w = qw; }
1189  FQuat(const FQuat &q) { x = q.x; y = q.y; z = q.z; w = q.w; }
1190  FQuat(const FPoint3 &axis, float angle) { AxisAngle(axis, angle); }
1191 
1192  void Init() { x = 0; y = 0; z = 0; w = 1; }
1193  void Set(float qx, float qy, float qz, float qw) { x = qx; y = qy; z = qz; w = qw; }
1194  void SetFromMatrix(const FMatrix3 &matrix);
1195  void SetFromVectors(const FPoint3 &forward, const FPoint3 &up);
1196  void SetFromVector(const FPoint3 &direction);
1197  void AxisAngle(const FPoint3 &axis, float angle);
1198  void GetMatrix(FMatrix3 &matrix) const;
1199 
1200  void Slerp(const FQuat &from, const FQuat &to, double f);
1201  float LengthSquared() const { return x*x + y*y + z*z + w*w; }
1202  const FQuat Inverse() const
1203  {
1204  float l2 = LengthSquared();
1205  return FQuat( -x / l2, -y / l2, -z / l2, w / l2);
1206  }
1207  void Invert();
1208 
1209  // operators
1210  const FQuat operator*(const FQuat &q) const;
1211  FQuat& operator*=(const FQuat &q);
1212  const FQuat operator/(const FQuat &q) const;
1213  FQuat& operator/=(const FQuat &q);
1214  FQuat &operator=(const FQuat &q) { x = q.x; y = q.y; z = q.z; w = q.w; return *this; }
1215 
1216  float x, y, z, w;
1217 };
1218 
1219 
1221 // PQ class (Position + Quaternion)
1222 
1228 class FPQ
1229 {
1230 public:
1231  FPQ() {}
1232  void FromMatrix(const FMatrix4 &matrix);
1233  void ToMatrix(FMatrix4 &matrix);
1234  void Interpolate(const FPQ &from, const FPQ &to, float f);
1235 
1236  // operators
1237  FPQ &operator=(const class FMatrix4 &matrix)
1238  {
1239  FromMatrix(matrix);
1240  return (*this);
1241  }
1242 
1243  FPoint3 p;
1244  FQuat q;
1245 };
1246 
1247 
1249 // Color classes
1250 
1256 class RGBi
1257 {
1258 public:
1259  RGBi() {}
1260  RGBi(short _r, short _g, short _b) { r = _r; g = _g; b = _b; }
1261  RGBi(const class RGBf &v) { *this = v; }
1262 
1263  void Set(short _r, short _g, short _b) { r = _r; g = _g; b = _b; }
1264  RGBi operator +(const RGBi &v) const { return RGBi(r+v.r, g+v.g, b+v.b); }
1265  RGBi operator +(const class RGBAi &v) const;
1266  RGBi operator -(const RGBi &v) const { return RGBi(r-v.r, g-v.g, b-v.b); }
1267  RGBi operator *(float s) const { return RGBi((short)(r*s), (short)(g*s), (short)(b*s)); }
1268  RGBi operator /(float s) const { return RGBi((short)(r/s), (short)(g/s), (short)(b/s)); }
1269  void operator *=(float s) { r=(short)(r*s); g=(short)(g*s); b=(short)(b*s); }
1270  void operator /=(float s) { r=(short)(r/s); g=(short)(g/s); b=(short)(b/s); }
1271 
1272  void operator +=(const RGBi &v) { r=r+v.r; g=g+v.g; b=b+v.b; }
1273  void operator +=(const class RGBAi &v);
1274 
1275  void Crop();
1276 
1277  // assignment
1278  RGBi &operator=(const RGBi &v) { r = v.r; g = v.g; b = v.b; return *this; }
1279  RGBi &operator=(const class RGBf &v);
1280 
1281  bool operator==(const RGBi &v) const { return (r == v.r && g == v.g && b == v.b); }
1282  bool operator!=(const RGBi &v) const { return (r != v.r || g != v.g || b != v.b); }
1283 
1284  short r, g, b;
1285 };
1286 
1292 class RGBAi
1293 {
1294 public:
1295  RGBAi() {}
1296  RGBAi(short _r, short _g, short _b, short _a = 255) { r = _r; g = _g; b = _b; a = _a; }
1297  RGBAi(const class RGBi &v) { *this = v; }
1298 
1299  void Set(short _r, short _g, short _b, short _a = 255) { r = _r; g = _g; b = _b; a = _a; }
1300  RGBAi operator +(const RGBAi &v) const { return RGBAi(r+v.r, g+v.g, b+v.b, a+v.a); }
1301  RGBAi operator -(const RGBAi &v) const { return RGBAi(r-v.r, g-v.g, b-v.b, a+v.a); }
1302  RGBAi operator *(float s) const { return RGBAi((short)(r*s), (short)(g*s), (short)(b*s), (short)(a*s)); }
1303  RGBAi operator /(float s) const { return RGBAi((short)(r/s), (short)(g/s), (short)(b/s), (short)(a/s)); }
1304  void operator *=(float s) { r=(short)(r*s); g=(short)(g*s); b=(short)(b*s); a=(short)(a*s); }
1305  void operator /=(float s) { r=(short)(r/s); g=(short)(g/s); b=(short)(b/s); a=(short)(a/s); }
1306 
1307  // generally it's useful to operate on the RGB alone and leave A unmodified
1308  void MultRGB(float s) { r=(short)(r*s); g=(short)(g*s); b=(short)(b*s); }
1309 
1310  void Crop();
1311 
1312  // assignment
1313  RGBAi &operator=(const RGBi &v) { r = v.r; g = v.g; b = v.b; a = 255; return *this; }
1314 
1315  short r, g, b, a;
1316 };
1317 
1318 inline void RGBi::operator +=(const class RGBAi &v) { r=r+v.r; g=g+v.g; b=b+v.b; }
1319 inline RGBi RGBi::operator +(const class RGBAi &v) const { return RGBi(r+v.r, g+v.g, b+v.b); }
1320 
1326 class RGBf
1327 {
1328 public:
1329  RGBf() {}
1330  RGBf(float _r, float _g, float _b) { r = _r; g = _g; b = _b; }
1331  RGBf(const class RGBi &v) { *this = v; }
1332  RGBf(const class RGBAf &v) { *this = v; }
1333 
1334  void Set(float _r, float _g, float _b) { r = _r; g = _g; b = _b; }
1335  RGBf operator +(const RGBf &v) const { return RGBf(r+v.r, g+v.g, b+v.b); }
1336  RGBf operator -(const RGBf &v) const { return RGBf(r-v.r, g-v.g, b-v.b); }
1337  RGBf operator *(float s) const { return RGBf(r*s, g*s, b*s); }
1338  RGBf operator /(float s) const { return RGBf(r/s, g/s, b/s); }
1339  void operator +=(const RGBf &v) { r+=v.r; g+=v.g; b+=v.b; }
1340  void operator *=(float s) { r*=s; g*=s; b*=s; }
1341  void operator /=(float s) { r/=s; g/=s; b/=s; }
1342 
1343  // assignment
1344  RGBf &operator=(const RGBf &v) { r = v.r; g = v.g; b = v.b; return *this; }
1345  RGBf &operator=(const class RGBi &v);
1346  RGBf &operator=(const class RGBAf &v);
1347 
1348  bool operator==(const RGBf &v2) const
1349  { return (r == v2.r && g == v2.g && b == v2.b); }
1350  bool operator!=(const RGBf &v2) const
1351  { return (r != v2.r || g != v2.g || b != v2.b); }
1352 
1353  float r, g, b;
1354 };
1355 
1356 inline RGBi &RGBi::operator=(const class RGBf &v)
1357 {
1358  r = (short) (v.r * 255.999f);
1359  g = (short) (v.g * 255.999f);
1360  b = (short) (v.b * 255.999f);
1361  return *this;
1362 }
1363 
1364 inline RGBf &RGBf::operator=(const class RGBi &v)
1365 {
1366  r = v.r / 255.0f;
1367  g = v.g / 255.0f;
1368  b = v.b / 255.0f;
1369  return *this;
1370 }
1371 
1372 
1378 class RGBAf
1379 {
1380 public:
1381  RGBAf() {}
1382  RGBAf(float _r, float _g, float _b) { r = _r; g = _g; b = _b; a = 1.0f; }
1383  RGBAf(float _r, float _g, float _b, float _a) { r = _r; g = _g; b = _b; a = _a; }
1384  RGBAf(const class RGBf &v) { *this = v; }
1385 
1386  void Set(float _r, float _g, float _b, float _a) { r = _r; g = _g; b = _b; a = _a; }
1387  RGBAf operator +(const RGBAf &v) const { return RGBAf(r+v.r, g+v.g, b+v.b, a+v.a); }
1388  RGBAf operator -(const RGBAf &v) const { return RGBAf(r-v.r, g-v.g, b-v.b, a+v.a); }
1389  RGBAf operator *(float s) const { return RGBAf(r*s, g*s, b*s); }
1390  RGBAf operator /(float s) const { return RGBAf(r/s, g/s, b/s); }
1391  void operator *=(float s) { r*=s; g*=s; b*=s; }
1392 
1393  // assignment
1394  RGBAf &operator=(const RGBf &v) { r = v.r; g = v.g; b = v.b; a = 1.0f; return *this; }
1395 
1396  // comparison
1397  bool operator==(const RGBAf &v2) const
1398  { return (r == v2.r && g == v2.g && b == v2.b && a == v2.a); }
1399  bool operator!=(const RGBAf &v2) const
1400  { return (r != v2.r || g != v2.g || b != v2.b || a != v2.a); }
1401 
1402  float r, g, b, a;
1403 };
1404 
1405 inline RGBf &RGBf::operator=(const class RGBAf &v)
1406 {
1407  r = v.r;
1408  g = v.g;
1409  b = v.b;
1410  return *this;
1411 }
1412 
1428 {
1429 public:
1431  LocaleWrap(int category, const char *locale_string);
1432  ~LocaleWrap();
1433 
1434 protected:
1435  std::string m_old_locale;
1436 };
1437 
1438 
1440 // handy helper functions
1441 //
1442 float random_offset(float x);
1443 float random(float x);
1444 int vt_log2(int n);
1445 float vt_log2f(float n);
1446 bool CrossingsTest(const DPoint2 *pgon, int numverts, const DPoint2 &point);
1447 bool CrossingsTest(const DPoint3 *pgon, int numverts, const DPoint2 &point);
1448 bool PointInTriangle(const FPoint2 &p, const FPoint2 &p1, const FPoint2 &p2,
1449  const FPoint2 &p3);
1450 bool PointInTriangle(const DPoint2 &p, const DPoint2 &p1, const DPoint2 &p2,
1451  const DPoint2 &p3);
1452 bool BarycentricCoords(const FPoint2 &p1, const FPoint2 &p2,
1453  const FPoint2 &p3, const FPoint2 &p, float fBary[3]);
1454 bool BarycentricCoords(const DPoint2 &p1, const DPoint2 &p2,
1455  const DPoint2 &p3, const DPoint2 &p, double fBary[3]);
1456 bool PlaneIntersection(const FPlane &plane1, const FPlane &plane2,
1457  const FPlane &plane3, FPoint3 &result);
1458 double DistancePointToLine(const DPoint2 &p1, const DPoint2 &p2, const DPoint2 &p3);
1459 float DistanceLineToLine(const FPoint3 &A1, const FPoint3 &A2,
1460  const FPoint3 &B1, const FPoint3 &B2,
1461  FPoint3 &result1, FPoint3 &result2);
1462 float DistanceSegmentToSegment(const FPoint3 &A1, const FPoint3 &A2,
1463  const FPoint3 &B1, const FPoint3 &B2,
1464  FPoint3 &result1, FPoint3 &result2);
1465 int LineSegmentsIntersect(const DPoint2 &p1, const DPoint2 &p2,
1466  const DPoint2 &p3, const DPoint2 &p4, DPoint2 *result = NULL);
1467 void vtLogMatrix(const FMatrix4 &mat);
1468 void vtLogMatrix(const FMatrix3 &mat);
1469 bool RaySphereIntersection(const FPoint3 &rkOrigin, const FPoint3 &rkDirection,
1470  const FSphere& rkSphere, int& riQuantity, FPoint3 akPoint[2]);
1471 void ProjectionXZ(const FLine3 &fline3, DLine2 &dline2);
1472 void ProjectionXZ(const FPolygon3 &fpoly3, DPolygon2 &dpoly2);
1473 void ProjectionXZ(const DLine2 &dline2, float fY, FLine3 &fline3);
1474 void ProjectionXZ(const DPolygon2 &dpoly2, float fY, FPolygon3 &fpoly3);
1475 
1476 #endif // VTMATHTYPESH