diff options
author | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
commit | e585187b248f48b3c6e9247b49fa07c6565d65e5 (patch) | |
tree | 637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /dep/src/g3dlite/Vector3.cpp | |
parent | 26b5e033ffde3d161382fc9addbfa99738379641 (diff) |
*Backed out changeset 3be01fb200a5
--HG--
branch : trunk
Diffstat (limited to 'dep/src/g3dlite/Vector3.cpp')
-rw-r--r-- | dep/src/g3dlite/Vector3.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/dep/src/g3dlite/Vector3.cpp b/dep/src/g3dlite/Vector3.cpp index 3346037e868..09c3003888b 100644 --- a/dep/src/g3dlite/Vector3.cpp +++ b/dep/src/g3dlite/Vector3.cpp @@ -1,11 +1,16 @@ /** @file Vector3.cpp + 3D vector class + @maintainer Morgan McGuire, matrix@graphics3d.com + @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + @created 2001-06-02 @edited 2006-01-30 */ + #include <limits> #include <stdlib.h> #include "G3D/Vector3.h" @@ -15,8 +20,11 @@ #include "G3D/Vector3int16.h" #include "G3D/Matrix3.h" #include "G3D/Vector2.h" + namespace G3D { + Vector3 Vector3::dummy; + // Deprecated. const Vector3 Vector3::ZERO(0, 0, 0); const Vector3 Vector3::ZERO3(0, 0, 0); @@ -25,13 +33,18 @@ const Vector3 Vector3::UNIT_Y(0, 1, 0); const Vector3 Vector3::UNIT_Z(0, 0, 1); const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); + Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) { } + Vector3::Axis Vector3::primaryAxis() const { + Axis a = X_AXIS; + double nx = abs(x); double ny = abs(y); double nz = abs(z); + if (nx > ny) { if (nx > nz) { a = X_AXIS; @@ -45,43 +58,56 @@ Vector3::Axis Vector3::primaryAxis() const { a = Z_AXIS; } } + return a; } + unsigned int Vector3::hashCode() const { unsigned int xhash = (*(int*)(void*)(&x)); unsigned int yhash = (*(int*)(void*)(&y)); unsigned int zhash = (*(int*)(void*)(&z)); + return xhash + (yhash * 37) + (zhash * 101); } + std::ostream& operator<<(std::ostream& os, const Vector3& v) { return os << v.toString(); } + //---------------------------------------------------------------------------- + double frand() { return rand() / (double) RAND_MAX; } + Vector3::Vector3(const class Vector3int16& v) { x = v.x; y = v.y; z = v.z; } + Vector3 Vector3::random() { Vector3 result; + do { result = Vector3(uniformRandom(-1.0, 1.0), uniformRandom(-1.0, 1.0), uniformRandom(-1.0, 1.0)); } while (result.squaredMagnitude() >= 1.0f); + result.unitize(); + return result; } + //---------------------------------------------------------------------------- Vector3 Vector3::operator/ (float fScalar) const { Vector3 kQuot; + if ( fScalar != 0.0 ) { float fInvScalar = 1.0f / fScalar; kQuot.x = fInvScalar * x; @@ -92,6 +118,7 @@ Vector3 Vector3::operator/ (float fScalar) const { return Vector3::inf(); } } + //---------------------------------------------------------------------------- Vector3& Vector3::operator/= (float fScalar) { if (fScalar != 0.0) { @@ -104,11 +131,14 @@ Vector3& Vector3::operator/= (float fScalar) { y = (float)G3D::inf(); z = (float)G3D::inf(); } + return *this; } + //---------------------------------------------------------------------------- float Vector3::unitize (float fTolerance) { float fMagnitude = magnitude(); + if (fMagnitude > fTolerance) { float fInvMagnitude = 1.0f / fMagnitude; x *= fInvMagnitude; @@ -117,38 +147,53 @@ float Vector3::unitize (float fTolerance) { } else { fMagnitude = 0.0f; } + return fMagnitude; } + //---------------------------------------------------------------------------- + Vector3 Vector3::reflectAbout(const Vector3& normal) const { + Vector3 out; + Vector3 N = normal.direction(); + // 2 * normal.dot(this) * normal - this return N * 2 * this->dot(N) - *this; } + //---------------------------------------------------------------------------- #if 0 Vector3 Vector3::cosRandom(const Vector3& normal) { double e1 = G3D::random(0, 1); double e2 = G3D::random(0, 1); + // Angle from normal double theta = acos(sqrt(e1)); + // Angle about normal double phi = 2 * G3D_PI * e2; + // Make a coordinate system Vector3 U = normal.direction(); Vector3 V = Vector3::unitX(); + if (abs(U.dot(V)) > .9) { V = Vector3::unitY(); } + Vector3 W = U.cross(V).direction(); V = W.cross(U); + // Convert to rectangular form return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W); } //---------------------------------------------------------------------------- + Vector3 Vector3::hemiRandom(const Vector3& normal) { Vector3 V = Vector3::random(); + if (V.dot(normal) < 0) { return -V; } else { @@ -157,30 +202,40 @@ Vector3 Vector3::hemiRandom(const Vector3& normal) { } #endif //---------------------------------------------------------------------------- + Vector3 Vector3::reflectionDirection(const Vector3& normal) const { return -reflectAbout(normal).direction(); } + //---------------------------------------------------------------------------- + Vector3 Vector3::refractionDirection( const Vector3& normal, float iInside, float iOutside) const { + // From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis // Using Photon Mapping. AK Peters. ISBN: 1568811470. July 2001. + // Invert the directions from Wann Jensen's formulation // and normalize the vectors. const Vector3 W = -direction(); Vector3 N = normal.direction(); + float h1 = iOutside; float h2 = iInside; + if (normal.dot(*this) > 0.0f) { h1 = iInside; h2 = iOutside; N = -N; } + const float hRatio = h1 / h2; const float WdotN = W.dot(N); + float det = 1.0f - (float)square(hRatio) * (1.0f - (float)square(WdotN)); + if (det < 0) { // Total internal reflection return Vector3::zero(); @@ -188,6 +243,7 @@ Vector3 Vector3::refractionDirection( return -hRatio * (W - WdotN * N) - N * sqrt(det); } } + //---------------------------------------------------------------------------- void Vector3::orthonormalize (Vector3 akVector[3]) { // If the input vectors are v0, v1, and v2, then the Gram-Schmidt @@ -199,23 +255,28 @@ void Vector3::orthonormalize (Vector3 akVector[3]) { // // where |A| indicates length of vector A and A*B indicates dot // product of vectors A and B. + // compute u0 akVector[0].unitize(); + // compute u1 float fDot0 = akVector[0].dot(akVector[1]); akVector[1] -= akVector[0] * fDot0; akVector[1].unitize(); + // compute u2 float fDot1 = akVector[1].dot(akVector[2]); fDot0 = akVector[0].dot(akVector[2]); akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1; akVector[2].unitize(); } + //---------------------------------------------------------------------------- void Vector3::generateOrthonormalBasis (Vector3& rkU, Vector3& rkV, Vector3& rkW, bool bUnitLengthW) { if ( !bUnitLengthW ) rkW.unitize(); + if ( G3D::abs(rkW.x) >= G3D::abs(rkW.y) && G3D::abs(rkW.x) >= G3D::abs(rkW.z) ) { rkU.x = -rkW.y; @@ -226,23 +287,30 @@ void Vector3::generateOrthonormalBasis (Vector3& rkU, Vector3& rkV, rkU.y = + rkW.z; rkU.z = -rkW.y; } + rkU.unitize(); rkV = rkW.cross(rkU); } + //---------------------------------------------------------------------------- + std::string Vector3::toString() const { return G3D::format("(%g, %g, %g)", x, y, z); } + //---------------------------------------------------------------------------- + Matrix3 Vector3::cross() const { return Matrix3( 0, -z, y, z, 0, -x, -y, x, 0); } + //---------------------------------------------------------------------------- // 2-char swizzles + Vector2 Vector3::xx() const { return Vector2 (x, x); } Vector2 Vector3::yx() const { return Vector2 (y, x); } Vector2 Vector3::zx() const { return Vector2 (z, x); } @@ -252,7 +320,9 @@ Vector2 Vector3::zy() const { return Vector2 (z, y); } Vector2 Vector3::xz() const { return Vector2 (x, z); } Vector2 Vector3::yz() const { return Vector2 (y, z); } Vector2 Vector3::zz() const { return Vector2 (z, z); } + // 3-char swizzles + Vector3 Vector3::xxx() const { return Vector3 (x, x, x); } Vector3 Vector3::yxx() const { return Vector3 (y, x, x); } Vector3 Vector3::zxx() const { return Vector3 (z, x, x); } @@ -280,7 +350,9 @@ Vector3 Vector3::zyz() const { return Vector3 (z, y, z); } Vector3 Vector3::xzz() const { return Vector3 (x, z, z); } Vector3 Vector3::yzz() const { return Vector3 (y, z, z); } Vector3 Vector3::zzz() const { return Vector3 (z, z, z); } + // 4-char swizzles + Vector4 Vector3::xxxx() const { return Vector4 (x, x, x, x); } Vector4 Vector3::yxxx() const { return Vector4 (y, x, x, x); } Vector4 Vector3::zxxx() const { return Vector4 (z, x, x, x); } @@ -365,5 +437,8 @@ Vector4 Vector3::zzzz() const { return Vector4 (z, z, z, z); } + + + } // namespace |