root/trunk/dep/src/g3dlite/Vector3.cpp @ 2

Revision 2, 15.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.cpp
3 
4 3D vector class
5 
6 @maintainer Morgan McGuire, matrix@graphics3d.com
7 
8 @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
9 
10 @created 2001-06-02
11 @edited  2006-01-30
12 */
13
14#include <limits>
15#include <stdlib.h>
16#include "G3D/Vector3.h"
17#include "G3D/g3dmath.h"
18#include "G3D/format.h"
19#include "G3D/stringutils.h"
20#include "G3D/Vector3int16.h"
21#include "G3D/Matrix3.h"
22#include "G3D/Vector2.h"
23 
24namespace G3D {
25
26Vector3 Vector3::dummy;
27
28// Deprecated.
29const Vector3 Vector3::ZERO(0, 0, 0);
30const Vector3 Vector3::ZERO3(0, 0, 0);
31const Vector3 Vector3::UNIT_X(1, 0, 0);
32const Vector3 Vector3::UNIT_Y(0, 1, 0);
33const Vector3 Vector3::UNIT_Z(0, 0, 1);
34const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
35const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan());
36
37Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) {
38}
39
40Vector3::Axis Vector3::primaryAxis() const {
41   
42    Axis a = X_AXIS;
43
44    double nx = abs(x);
45    double ny = abs(y);
46    double nz = abs(z);
47
48    if (nx > ny) {
49        if (nx > nz) {
50            a = X_AXIS;
51        } else {
52            a = Z_AXIS;
53        }
54    } else {
55        if (ny > nz) {
56            a = Y_AXIS;
57        } else {
58            a = Z_AXIS;
59        }
60    }
61
62    return a;
63}
64
65
66unsigned int Vector3::hashCode() const {
67    unsigned int xhash = (*(int*)(void*)(&x));
68    unsigned int yhash = (*(int*)(void*)(&y));
69    unsigned int zhash = (*(int*)(void*)(&z));
70
71    return xhash + (yhash * 37) + (zhash * 101);
72}
73
74std::ostream& operator<<(std::ostream& os, const Vector3& v) {
75    return os << v.toString();
76}
77
78
79//----------------------------------------------------------------------------
80
81double frand() {
82    return rand() / (double) RAND_MAX;
83}
84
85
86Vector3::Vector3(const class Vector3int16& v) {
87    x = v.x;
88    y = v.y;
89    z = v.z;
90}
91
92
93Vector3 Vector3::random() {
94    Vector3 result;
95
96    do {
97        result = Vector3(uniformRandom(-1.0, 1.0), 
98                         uniformRandom(-1.0, 1.0),
99                         uniformRandom(-1.0, 1.0));
100    } while (result.squaredMagnitude() >= 1.0f);
101
102    result.unitize();
103
104    return result;
105}
106
107//----------------------------------------------------------------------------
108Vector3 Vector3::operator/ (float fScalar) const {
109    Vector3 kQuot;
110
111    if ( fScalar != 0.0 ) {
112                float fInvScalar = 1.0f / fScalar;
113        kQuot.x = fInvScalar * x;
114        kQuot.y = fInvScalar * y;
115        kQuot.z = fInvScalar * z;
116        return kQuot;
117    } else {
118        return Vector3::inf();
119    }
120}
121
122//----------------------------------------------------------------------------
123Vector3& Vector3::operator/= (float fScalar) {
124    if (fScalar != 0.0) {
125                float fInvScalar = 1.0f / fScalar;
126        x *= fInvScalar;
127        y *= fInvScalar;
128        z *= fInvScalar;
129    } else {
130        x = (float)G3D::inf();
131        y = (float)G3D::inf();
132        z = (float)G3D::inf();
133    }
134
135    return *this;
136}
137
138//----------------------------------------------------------------------------
139float Vector3::unitize (float fTolerance) {
140        float fMagnitude = magnitude();
141
142    if (fMagnitude > fTolerance) {
143                float fInvMagnitude = 1.0f / fMagnitude;
144        x *= fInvMagnitude;
145        y *= fInvMagnitude;
146        z *= fInvMagnitude;
147    } else {
148        fMagnitude = 0.0f;
149    }
150
151    return fMagnitude;
152}
153
154//----------------------------------------------------------------------------
155
156Vector3 Vector3::reflectAbout(const Vector3& normal) const {
157
158    Vector3 out;
159
160    Vector3 N = normal.direction();
161
162    // 2 * normal.dot(this) * normal - this
163    return N * 2 * this->dot(N) - *this;
164}
165
166//----------------------------------------------------------------------------
167#if 0
168Vector3 Vector3::cosRandom(const Vector3& normal) {
169    double e1 = G3D::random(0, 1);
170    double e2 = G3D::random(0, 1);
171
172    // Angle from normal
173    double theta = acos(sqrt(e1));
174
175    // Angle about normal
176    double phi   = 2 * G3D_PI * e2;
177
178    // Make a coordinate system
179    Vector3 U = normal.direction();
180    Vector3 V = Vector3::unitX();
181
182    if (abs(U.dot(V)) > .9) {
183        V = Vector3::unitY();
184    }
185
186    Vector3 W = U.cross(V).direction();
187    V = W.cross(U);
188
189    // Convert to rectangular form
190    return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W);
191}
192//----------------------------------------------------------------------------
193
194Vector3 Vector3::hemiRandom(const Vector3& normal) {
195    Vector3 V = Vector3::random();
196
197    if (V.dot(normal) < 0) {
198        return -V;
199    } else {
200        return V;
201    }
202}
203#endif
204//----------------------------------------------------------------------------
205
206Vector3 Vector3::reflectionDirection(const Vector3& normal) const {
207    return -reflectAbout(normal).direction();
208}
209
210//----------------------------------------------------------------------------
211
212Vector3 Vector3::refractionDirection(
213    const Vector3&  normal,
214    float           iInside,
215    float           iOutside) const {
216
217    // From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis
218    // Using Photon Mapping.  AK Peters. ISBN: 1568811470. July 2001.
219
220    // Invert the directions from Wann Jensen's formulation
221    // and normalize the vectors.
222    const Vector3 W = -direction();
223    Vector3 N = normal.direction();
224
225    float h1 = iOutside;
226    float h2 = iInside;
227
228    if (normal.dot(*this) > 0.0f) {
229        h1 = iInside;
230        h2 = iOutside;
231        N  = -N;
232    }
233
234    const float hRatio = h1 / h2;
235    const float WdotN = W.dot(N);
236
237    float det = 1.0f - (float)square(hRatio) * (1.0f - (float)square(WdotN));
238
239    if (det < 0) {
240        // Total internal reflection
241        return Vector3::zero();
242    } else {
243        return -hRatio * (W - WdotN * N) - N * sqrt(det);
244    }
245}
246
247//----------------------------------------------------------------------------
248void Vector3::orthonormalize (Vector3 akVector[3]) {
249    // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
250    // orthonormalization produces vectors u0, u1, and u2 as follows,
251    //
252    //   u0 = v0/|v0|
253    //   u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
254    //   u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
255    //
256    // where |A| indicates length of vector A and A*B indicates dot
257    // product of vectors A and B.
258
259    // compute u0
260    akVector[0].unitize();
261
262    // compute u1
263        float fDot0 = akVector[0].dot(akVector[1]);
264    akVector[1] -= akVector[0] * fDot0;
265    akVector[1].unitize();
266
267    // compute u2
268        float fDot1 = akVector[1].dot(akVector[2]);
269    fDot0 = akVector[0].dot(akVector[2]);
270    akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1;
271    akVector[2].unitize();
272}
273
274//----------------------------------------------------------------------------
275void Vector3::generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
276                                        Vector3& rkW, bool bUnitLengthW) {
277    if ( !bUnitLengthW )
278        rkW.unitize();
279
280    if ( G3D::abs(rkW.x) >= G3D::abs(rkW.y)
281            && G3D::abs(rkW.x) >= G3D::abs(rkW.z) ) {
282        rkU.x = -rkW.y;
283        rkU.y = + rkW.x;
284        rkU.z = 0.0;
285    } else {
286        rkU.x = 0.0;
287        rkU.y = + rkW.z;
288        rkU.z = -rkW.y;
289    }
290
291    rkU.unitize();
292    rkV = rkW.cross(rkU);
293}
294
295//----------------------------------------------------------------------------
296
297std::string Vector3::toString() const {
298    return G3D::format("(%g, %g, %g)", x, y, z);
299}
300
301
302//----------------------------------------------------------------------------
303
304Matrix3 Vector3::cross() const {
305    return Matrix3( 0, -z,  y,
306                    z,  0, -x,
307                   -y,  x,  0);
308}
309
310
311//----------------------------------------------------------------------------
312// 2-char swizzles
313
314Vector2 Vector3::xx() const  { return Vector2       (x, x); }
315Vector2 Vector3::yx() const  { return Vector2       (y, x); }
316Vector2 Vector3::zx() const  { return Vector2       (z, x); }
317Vector2 Vector3::xy() const  { return Vector2       (x, y); }
318Vector2 Vector3::yy() const  { return Vector2       (y, y); }
319Vector2 Vector3::zy() const  { return Vector2       (z, y); }
320Vector2 Vector3::xz() const  { return Vector2       (x, z); }
321Vector2 Vector3::yz() const  { return Vector2       (y, z); }
322Vector2 Vector3::zz() const  { return Vector2       (z, z); }
323
324// 3-char swizzles
325
326Vector3 Vector3::xxx() const  { return Vector3       (x, x, x); }
327Vector3 Vector3::yxx() const  { return Vector3       (y, x, x); }
328Vector3 Vector3::zxx() const  { return Vector3       (z, x, x); }
329Vector3 Vector3::xyx() const  { return Vector3       (x, y, x); }
330Vector3 Vector3::yyx() const  { return Vector3       (y, y, x); }
331Vector3 Vector3::zyx() const  { return Vector3       (z, y, x); }
332Vector3 Vector3::xzx() const  { return Vector3       (x, z, x); }
333Vector3 Vector3::yzx() const  { return Vector3       (y, z, x); }
334Vector3 Vector3::zzx() const  { return Vector3       (z, z, x); }
335Vector3 Vector3::xxy() const  { return Vector3       (x, x, y); }
336Vector3 Vector3::yxy() const  { return Vector3       (y, x, y); }
337Vector3 Vector3::zxy() const  { return Vector3       (z, x, y); }
338Vector3 Vector3::xyy() const  { return Vector3       (x, y, y); }
339Vector3 Vector3::yyy() const  { return Vector3       (y, y, y); }
340Vector3 Vector3::zyy() const  { return Vector3       (z, y, y); }
341Vector3 Vector3::xzy() const  { return Vector3       (x, z, y); }
342Vector3 Vector3::yzy() const  { return Vector3       (y, z, y); }
343Vector3 Vector3::zzy() const  { return Vector3       (z, z, y); }
344Vector3 Vector3::xxz() const  { return Vector3       (x, x, z); }
345Vector3 Vector3::yxz() const  { return Vector3       (y, x, z); }
346Vector3 Vector3::zxz() const  { return Vector3       (z, x, z); }
347Vector3 Vector3::xyz() const  { return Vector3       (x, y, z); }
348Vector3 Vector3::yyz() const  { return Vector3       (y, y, z); }
349Vector3 Vector3::zyz() const  { return Vector3       (z, y, z); }
350Vector3 Vector3::xzz() const  { return Vector3       (x, z, z); }
351Vector3 Vector3::yzz() const  { return Vector3       (y, z, z); }
352Vector3 Vector3::zzz() const  { return Vector3       (z, z, z); }
353
354// 4-char swizzles
355
356Vector4 Vector3::xxxx() const  { return Vector4       (x, x, x, x); }
357Vector4 Vector3::yxxx() const  { return Vector4       (y, x, x, x); }
358Vector4 Vector3::zxxx() const  { return Vector4       (z, x, x, x); }
359Vector4 Vector3::xyxx() const  { return Vector4       (x, y, x, x); }
360Vector4 Vector3::yyxx() const  { return Vector4       (y, y, x, x); }
361Vector4 Vector3::zyxx() const  { return Vector4       (z, y, x, x); }
362Vector4 Vector3::xzxx() const  { return Vector4       (x, z, x, x); }
363Vector4 Vector3::yzxx() const  { return Vector4       (y, z, x, x); }
364Vector4 Vector3::zzxx() const  { return Vector4       (z, z, x, x); }
365Vector4 Vector3::xxyx() const  { return Vector4       (x, x, y, x); }
366Vector4 Vector3::yxyx() const  { return Vector4       (y, x, y, x); }
367Vector4 Vector3::zxyx() const  { return Vector4       (z, x, y, x); }
368Vector4 Vector3::xyyx() const  { return Vector4       (x, y, y, x); }
369Vector4 Vector3::yyyx() const  { return Vector4       (y, y, y, x); }
370Vector4 Vector3::zyyx() const  { return Vector4       (z, y, y, x); }
371Vector4 Vector3::xzyx() const  { return Vector4       (x, z, y, x); }
372Vector4 Vector3::yzyx() const  { return Vector4       (y, z, y, x); }
373Vector4 Vector3::zzyx() const  { return Vector4       (z, z, y, x); }
374Vector4 Vector3::xxzx() const  { return Vector4       (x, x, z, x); }
375Vector4 Vector3::yxzx() const  { return Vector4       (y, x, z, x); }
376Vector4 Vector3::zxzx() const  { return Vector4       (z, x, z, x); }
377Vector4 Vector3::xyzx() const  { return Vector4       (x, y, z, x); }
378Vector4 Vector3::yyzx() const  { return Vector4       (y, y, z, x); }
379Vector4 Vector3::zyzx() const  { return Vector4       (z, y, z, x); }
380Vector4 Vector3::xzzx() const  { return Vector4       (x, z, z, x); }
381Vector4 Vector3::yzzx() const  { return Vector4       (y, z, z, x); }
382Vector4 Vector3::zzzx() const  { return Vector4       (z, z, z, x); }
383Vector4 Vector3::xxxy() const  { return Vector4       (x, x, x, y); }
384Vector4 Vector3::yxxy() const  { return Vector4       (y, x, x, y); }
385Vector4 Vector3::zxxy() const  { return Vector4       (z, x, x, y); }
386Vector4 Vector3::xyxy() const  { return Vector4       (x, y, x, y); }
387Vector4 Vector3::yyxy() const  { return Vector4       (y, y, x, y); }
388Vector4 Vector3::zyxy() const  { return Vector4       (z, y, x, y); }
389Vector4 Vector3::xzxy() const  { return Vector4       (x, z, x, y); }
390Vector4 Vector3::yzxy() const  { return Vector4       (y, z, x, y); }
391Vector4 Vector3::zzxy() const  { return Vector4       (z, z, x, y); }
392Vector4 Vector3::xxyy() const  { return Vector4       (x, x, y, y); }
393Vector4 Vector3::yxyy() const  { return Vector4       (y, x, y, y); }
394Vector4 Vector3::zxyy() const  { return Vector4       (z, x, y, y); }
395Vector4 Vector3::xyyy() const  { return Vector4       (x, y, y, y); }
396Vector4 Vector3::yyyy() const  { return Vector4       (y, y, y, y); }
397Vector4 Vector3::zyyy() const  { return Vector4       (z, y, y, y); }
398Vector4 Vector3::xzyy() const  { return Vector4       (x, z, y, y); }
399Vector4 Vector3::yzyy() const  { return Vector4       (y, z, y, y); }
400Vector4 Vector3::zzyy() const  { return Vector4       (z, z, y, y); }
401Vector4 Vector3::xxzy() const  { return Vector4       (x, x, z, y); }
402Vector4 Vector3::yxzy() const  { return Vector4       (y, x, z, y); }
403Vector4 Vector3::zxzy() const  { return Vector4       (z, x, z, y); }
404Vector4 Vector3::xyzy() const  { return Vector4       (x, y, z, y); }
405Vector4 Vector3::yyzy() const  { return Vector4       (y, y, z, y); }
406Vector4 Vector3::zyzy() const  { return Vector4       (z, y, z, y); }
407Vector4 Vector3::xzzy() const  { return Vector4       (x, z, z, y); }
408Vector4 Vector3::yzzy() const  { return Vector4       (y, z, z, y); }
409Vector4 Vector3::zzzy() const  { return Vector4       (z, z, z, y); }
410Vector4 Vector3::xxxz() const  { return Vector4       (x, x, x, z); }
411Vector4 Vector3::yxxz() const  { return Vector4       (y, x, x, z); }
412Vector4 Vector3::zxxz() const  { return Vector4       (z, x, x, z); }
413Vector4 Vector3::xyxz() const  { return Vector4       (x, y, x, z); }
414Vector4 Vector3::yyxz() const  { return Vector4       (y, y, x, z); }
415Vector4 Vector3::zyxz() const  { return Vector4       (z, y, x, z); }
416Vector4 Vector3::xzxz() const  { return Vector4       (x, z, x, z); }
417Vector4 Vector3::yzxz() const  { return Vector4       (y, z, x, z); }
418Vector4 Vector3::zzxz() const  { return Vector4       (z, z, x, z); }
419Vector4 Vector3::xxyz() const  { return Vector4       (x, x, y, z); }
420Vector4 Vector3::yxyz() const  { return Vector4       (y, x, y, z); }
421Vector4 Vector3::zxyz() const  { return Vector4       (z, x, y, z); }
422Vector4 Vector3::xyyz() const  { return Vector4       (x, y, y, z); }
423Vector4 Vector3::yyyz() const  { return Vector4       (y, y, y, z); }
424Vector4 Vector3::zyyz() const  { return Vector4       (z, y, y, z); }
425Vector4 Vector3::xzyz() const  { return Vector4       (x, z, y, z); }
426Vector4 Vector3::yzyz() const  { return Vector4       (y, z, y, z); }
427Vector4 Vector3::zzyz() const  { return Vector4       (z, z, y, z); }
428Vector4 Vector3::xxzz() const  { return Vector4       (x, x, z, z); }
429Vector4 Vector3::yxzz() const  { return Vector4       (y, x, z, z); }
430Vector4 Vector3::zxzz() const  { return Vector4       (z, x, z, z); }
431Vector4 Vector3::xyzz() const  { return Vector4       (x, y, z, z); }
432Vector4 Vector3::yyzz() const  { return Vector4       (y, y, z, z); }
433Vector4 Vector3::zyzz() const  { return Vector4       (z, y, z, z); }
434Vector4 Vector3::xzzz() const  { return Vector4       (x, z, z, z); }
435Vector4 Vector3::yzzz() const  { return Vector4       (y, z, z, z); }
436Vector4 Vector3::zzzz() const  { return Vector4       (z, z, z, z); }
437
438
439
440
441
442
443} // namespace
Note: See TracBrowser for help on using the browser.