root/trunk/dep/include/g3dlite/G3D/Vector3.h

Revision 2, 13.5 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/**
2  @file Vector3.h
3 
4  3D vector class
5 
6  @maintainer Morgan McGuire, matrix@graphics3d.com
7
8  @created 2001-06-02
9  @edited  2005-08-23
10  Copyright 2000-2006, Morgan McGuire.
11  All rights reserved.
12 */
13
14#ifndef G3D_VECTOR3_H
15#define G3D_VECTOR3_H
16
17#include "G3D/platform.h"
18#include "G3D/g3dmath.h"
19#include "G3D/Vector2.h"
20#include <iostream>
21#include <string>
22
23namespace G3D {
24
25class Vector2;   
26class Vector3;
27class Vector4;
28
29/**
30  <B>Swizzles</B>
31 Vector classes have swizzle operators, e.g. <CODE>v.xy()</CODE>, that
32 allow selection of arbitrary sub-fields.  These cannot be used as write
33 masks.  Examples
34
35  <PRE>
36Vector3 v(1, 2, 3);
37Vector3 j;
38Vector2 b;
39
40b = v.xz();
41j = b.xx();
42</PRE>
43
44
45  <B>Warning</B>
46
47 Do not subclass-- this implementation makes assumptions about the
48 memory layout.
49 */
50class Vector3 {
51private:
52    /**
53     Reflect this vector about the (not necessarily unit) normal.
54     Note that if used for a collision or ray reflection you
55     must negate the resulting vector to get a direction pointing
56     <I>away</I> from the collision.
57
58     <PRE>
59       V'    N      V
60                 
61         r   ^   -,
62          \  |  /
63            \|/
64     </PRE>
65
66     See also Vector3::reflectionDirection
67     */
68    Vector3 reflectAbout(const Vector3& normal) const;
69
70    // Hidden operators
71    bool operator<(const Vector3&) const;
72    bool operator>(const Vector3&) const;
73    bool operator<=(const Vector3&) const;
74    bool operator>=(const Vector3&) const;
75
76public:
77    // construction
78    Vector3();
79    Vector3(float _x, float _y, float _z);
80    Vector3(const class Vector2& v, float _z);
81    Vector3(float coordinate[3]);
82    Vector3(double coordinate[3]);
83    Vector3(const Vector3& rkVector);
84    Vector3(const class Vector3int16& v);
85
86    // coordinates
87    float x, y, z;
88
89    // access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z
90    //
91    // WARNING.  These member functions rely on
92    // (1) Vector3 not having virtual functions
93    // (2) the data packed in a 3*sizeof(float) memory block
94    const float& operator[] (int i) const;
95    float& operator[] (int i);
96
97    inline operator float* () {
98        return (float*)this;
99    }
100
101    operator const float* () const {
102        return (float*)this;
103    }
104
105    enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1};
106
107    /**
108     Returns the largest dimension.  Particularly convenient for determining
109     which plane to project a triangle onto for point-in-polygon tests.
110     */
111    Axis primaryAxis() const;
112
113    // assignment and comparison
114    Vector3& operator= (const Vector3& rkVector);
115    bool operator== (const Vector3& rkVector) const;
116    bool operator!= (const Vector3& rkVector) const;
117    unsigned int hashCode() const;
118    bool fuzzyEq(const Vector3& other) const;
119    bool fuzzyNe(const Vector3& other) const;
120
121    /** Returns true if this vector has finite length. */
122    bool isFinite() const;
123
124    /** Returns true if this vector has length ~= 0 */
125    bool isZero() const;
126
127    /** Returns true if this vector has length ~= 1 */
128    bool isUnit() const;
129   
130    // arithmetic operations
131    Vector3 operator+ (const Vector3& v) const;
132    Vector3 operator- (const Vector3& v) const;
133    Vector3 operator* (float s) const;
134    Vector3 operator/ (float s) const;
135    Vector3 operator* (const Vector3& v) const;
136    Vector3 operator/ (const Vector3& v) const;
137    Vector3 operator- () const;
138
139    // arithmetic updates
140    Vector3& operator+= (const Vector3& v);
141    Vector3& operator-= (const Vector3& v);
142    Vector3& operator*= (float s);
143    Vector3& operator/= (float s);
144    Vector3& operator*= (const Vector3& v);
145    Vector3& operator/= (const Vector3& v);
146
147    /** @deprecated Use magnitude */
148        float G3D_DEPRECATED length() const;
149
150    float magnitude() const;
151   
152    /**
153     The result is a nan vector if the length is almost zero.
154     */
155    Vector3 direction() const;
156
157    /**
158     Potentially less accurate but faster than direction().
159     Only works if System::hasSSE is true.
160     */
161    Vector3 fastDirection() const;
162
163
164    /**
165      See also G3D::Ray::reflect.
166      The length is 1.
167     <PRE>
168       V'    N       V
169                 
170         r   ^    /
171          \  |  /
172            \|'-
173     </PRE>
174     */
175    Vector3 reflectionDirection(const Vector3& normal) const;
176   
177
178    /**
179     Returns Vector3::zero() if the length is nearly zero, otherwise
180     returns a unit vector.
181     */
182    inline Vector3 directionOrZero() const {
183        float mag = magnitude();
184        if (G3D::fuzzyEq(mag, 0.0f)) {
185            return Vector3::zero();
186        } else if (G3D::fuzzyEq(mag, 1.0f)) {
187            return *this;
188        } else {
189            return *this * (1.0f / mag);
190        }
191    }
192
193    /**
194     Returns the direction of a refracted ray,
195     where iExit is the index of refraction for the
196     previous material and iEnter is the index of refraction
197     for the new material.  Like Vector3::reflectionDirection,
198     the result has length 1 and is
199     pointed <I>away</I> from the intersection.
200
201     Returns Vector3::zero() in the case of total internal refraction.
202
203     @param iOutside The index of refraction (eta) outside
204     (on the <I>positive</I> normal side) of the surface.
205
206     @param iInside The index of refraction (eta) inside
207     (on the <I>negative</I> normal side) of the surface.
208
209     See also G3D::Ray::refract.
210     <PRE>
211              N      V
212                 
213              ^    /
214              |  /
215              |'-
216          __--
217     V'<--
218     </PRE>
219     */
220    Vector3 refractionDirection(
221        const Vector3&  normal,
222        float           iInside,
223        float           iOutside) const;
224
225    /** Synonym for direction */
226    inline Vector3 unit() const {
227        return direction();
228    }
229
230    /** Returns a normalized vector.  May be computed with lower precision than unit */
231    inline Vector3 fastUnit() const {
232        return fastDirection();
233    }
234
235    /** @deprecated Use squaredMagnitude */
236    float G3D_DEPRECATED squaredLength() const;
237
238    float squaredMagnitude () const;
239       
240    /** @deprecated Use squaredMagnitude */
241    inline float G3D_DEPRECATED norm() const {
242        return squaredMagnitude();
243    }
244
245    float dot(const Vector3& rkVector) const;
246   
247    float G3D_DEPRECATED unitize(float fTolerance = 1e-06);
248
249    /** Cross product.  Note that two cross products in a row
250        can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2  - (v1 dot v2) v3.
251      */
252    Vector3 cross(const Vector3& rkVector) const;
253    Vector3 unitCross (const Vector3& rkVector) const;
254
255    /**
256     Returns a matrix such that v.cross() * w = v.cross(w).
257     <PRE>
258     [ 0  -v.z  v.y ]
259     [ v.z  0  -v.x ]
260     [ -v.y v.x  0  ]
261     </PRE>
262     */
263    class Matrix3 cross() const;
264
265    Vector3 min(const Vector3 &v) const;
266    Vector3 max(const Vector3 &v) const;
267
268    std::string toString() const;
269
270    inline Vector3 clamp(const Vector3& low, const Vector3& high) const {
271        return Vector3(
272            G3D::clamp(x, low.x, high.x),
273            G3D::clamp(y, low.y, high.y),
274            G3D::clamp(z, low.z, high.z));
275    }
276
277    inline Vector3 clamp(float low, float high) const {
278        return Vector3(
279            G3D::clamp(x, low, high),
280            G3D::clamp(y, low, high),
281            G3D::clamp(z, low, high));
282    }
283
284    /**
285     Linear interpolation
286     */
287    inline Vector3 lerp(const Vector3& v, float alpha) const {
288        return (*this) + (v - *this) * alpha; 
289    }
290
291    /** Gram-Schmidt orthonormalization. */
292    static void orthonormalize (Vector3 akVector[3]);
293
294    /** Random unit vector, uniformly distributed */
295    static Vector3 random();
296
297    /** Random unit vector, distributed
298        so that the probability of V is proportional
299        to max(V dot Normal, 0).
300
301        @cite Henrik Wann Jensen, Realistic Image Synthesis using Photon Mapping eqn 2.24
302    */
303    static Vector3 cosRandom(const Vector3& normal);
304
305
306    /**
307     Random vector distributed over the hemisphere about normal.
308     */
309    static Vector3 hemiRandom(const Vector3& normal);
310
311    // Input W must be initialize to a nonzero vector, output is {U,V,W}
312    // an orthonormal basis.  A hint is provided about whether or not W
313    // is already unit length.
314    static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
315                                          Vector3& rkW, bool bUnitLengthW = true);
316
317    inline float sum() const {
318        return x + y + z;
319    }
320
321    inline float average() const {
322        return sum() / 3.0f;
323    }
324
325    // Special values.
326    inline static const Vector3& zero()     { static Vector3 v(0, 0, 0); return v; }
327    inline static const Vector3& one()      { static Vector3 v(1, 1, 1); return v; }
328    inline static const Vector3& unitX()    { static Vector3 v(1, 0, 0); return v; }
329    inline static const Vector3& unitY()    { static Vector3 v(0, 1, 0); return v; }
330    inline static const Vector3& unitZ()    { static Vector3 v(0, 0, 1); return v; }
331    inline static const Vector3& inf()      { static Vector3 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; }
332    inline static const Vector3& nan()      { static Vector3 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; }
333    /** Smallest (most negative) representable vector */
334    inline static const Vector3& minFinite(){ static Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; }
335    /** Largest representable vector */
336    inline static const Vector3& maxFinite(){ static Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; }
337
338    // Deprecated. See Matrix3::identity() for details.
339    /** @deprecated Use Vector3::zero() */
340    static const Vector3 ZERO;
341    /** @deprecated Use Vector3::zero() */
342    static const Vector3 ZERO3;
343    /** @deprecated Use Vector3::unitX() */
344    static const Vector3 UNIT_X;
345    /** @deprecated Use Vector3::unitY() */
346    static const Vector3 UNIT_Y;
347    /** @deprecated Use Vector3::unitZ() */
348    static const Vector3 UNIT_Z;
349    /** @deprecated Use Vector3::inf() */
350    static const Vector3 INF3;
351    /** @deprecated Use Vector3::nan() */
352    static const Vector3 NAN3;
353
354    // 2-char swizzles
355
356    Vector2 xx() const;
357    Vector2 yx() const;
358    Vector2 zx() const;
359    Vector2 xy() const;
360    Vector2 yy() const;
361    Vector2 zy() const;
362    Vector2 xz() const;
363    Vector2 yz() const;
364    Vector2 zz() const;
365
366    // 3-char swizzles
367
368    Vector3 xxx() const;
369    Vector3 yxx() const;
370    Vector3 zxx() const;
371    Vector3 xyx() const;
372    Vector3 yyx() const;
373    Vector3 zyx() const;
374    Vector3 xzx() const;
375    Vector3 yzx() const;
376    Vector3 zzx() const;
377    Vector3 xxy() const;
378    Vector3 yxy() const;
379    Vector3 zxy() const;
380    Vector3 xyy() const;
381    Vector3 yyy() const;
382    Vector3 zyy() const;
383    Vector3 xzy() const;
384    Vector3 yzy() const;
385    Vector3 zzy() const;
386    Vector3 xxz() const;
387    Vector3 yxz() const;
388    Vector3 zxz() const;
389    Vector3 xyz() const;
390    Vector3 yyz() const;
391    Vector3 zyz() const;
392    Vector3 xzz() const;
393    Vector3 yzz() const;
394    Vector3 zzz() const;
395
396    // 4-char swizzles
397
398    Vector4 xxxx() const;
399    Vector4 yxxx() const;
400    Vector4 zxxx() const;
401    Vector4 xyxx() const;
402    Vector4 yyxx() const;
403    Vector4 zyxx() const;
404    Vector4 xzxx() const;
405    Vector4 yzxx() const;
406    Vector4 zzxx() const;
407    Vector4 xxyx() const;
408    Vector4 yxyx() const;
409    Vector4 zxyx() const;
410    Vector4 xyyx() const;
411    Vector4 yyyx() const;
412    Vector4 zyyx() const;
413    Vector4 xzyx() const;
414    Vector4 yzyx() const;
415    Vector4 zzyx() const;
416    Vector4 xxzx() const;
417    Vector4 yxzx() const;
418    Vector4 zxzx() const;
419    Vector4 xyzx() const;
420    Vector4 yyzx() const;
421    Vector4 zyzx() const;
422    Vector4 xzzx() const;
423    Vector4 yzzx() const;
424    Vector4 zzzx() const;
425    Vector4 xxxy() const;
426    Vector4 yxxy() const;
427    Vector4 zxxy() const;
428    Vector4 xyxy() const;
429    Vector4 yyxy() const;
430    Vector4 zyxy() const;
431    Vector4 xzxy() const;
432    Vector4 yzxy() const;
433    Vector4 zzxy() const;
434    Vector4 xxyy() const;
435    Vector4 yxyy() const;
436    Vector4 zxyy() const;
437    Vector4 xyyy() const;
438    Vector4 yyyy() const;
439    Vector4 zyyy() const;
440    Vector4 xzyy() const;
441    Vector4 yzyy() const;
442    Vector4 zzyy() const;
443    Vector4 xxzy() const;
444    Vector4 yxzy() const;
445    Vector4 zxzy() const;
446    Vector4 xyzy() const;
447    Vector4 yyzy() const;
448    Vector4 zyzy() const;
449    Vector4 xzzy() const;
450    Vector4 yzzy() const;
451    Vector4 zzzy() const;
452    Vector4 xxxz() const;
453    Vector4 yxxz() const;
454    Vector4 zxxz() const;
455    Vector4 xyxz() const;
456    Vector4 yyxz() const;
457    Vector4 zyxz() const;
458    Vector4 xzxz() const;
459    Vector4 yzxz() const;
460    Vector4 zzxz() const;
461    Vector4 xxyz() const;
462    Vector4 yxyz() const;
463    Vector4 zxyz() const;
464    Vector4 xyyz() const;
465    Vector4 yyyz() const;
466    Vector4 zyyz() const;
467    Vector4 xzyz() const;
468    Vector4 yzyz() const;
469    Vector4 zzyz() const;
470    Vector4 xxzz() const;
471    Vector4 yxzz() const;
472    Vector4 zxzz() const;
473    Vector4 xyzz() const;
474    Vector4 yyzz() const;
475    Vector4 zyzz() const;
476    Vector4 xzzz() const;
477    Vector4 yzzz() const;
478    Vector4 zzzz() const;
479
480    /** A value that can be passed to ignore a parameter.  Never look at the result of dummy. */
481    static Vector3 dummy;
482};
483
484inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) {
485    return v * s;
486}
487
488inline G3D::Vector3 operator*(double s, const G3D::Vector3& v) {
489    return v * (float)s;
490}
491
492inline G3D::Vector3 operator*(int s, const G3D::Vector3& v) {
493    return v * (float)s;
494}
495
496std::ostream& operator<<(std::ostream& os, const Vector3&);
497
498}
499
500unsigned int hashCode(const G3D::Vector3& v);
501
502#include "Vector3.inl"
503
504#endif
Note: See TracBrowser for help on using the browser.