diff options
Diffstat (limited to 'dep/g3dlite/source/Vector3.cpp')
-rw-r--r-- | dep/g3dlite/source/Vector3.cpp | 146 |
1 files changed, 93 insertions, 53 deletions
diff --git a/dep/g3dlite/source/Vector3.cpp b/dep/g3dlite/source/Vector3.cpp index 55343e96ece..e2d9643e5cc 100644 --- a/dep/g3dlite/source/Vector3.cpp +++ b/dep/g3dlite/source/Vector3.cpp @@ -1,14 +1,14 @@ /** - @file Vector3.cpp + \file G3D.lib/source/Vector3.cpp 3D vector class - @maintainer Morgan McGuire, http://graphics.cs.williams.edu + \maintainer Morgan McGuire, http://graphics.cs.williams.edu - @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + \cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com - @created 2001-06-02 - @edited 2009-11-27 + \created 2001-06-02 + \edited 2011-11-27 */ #include <limits> @@ -31,8 +31,39 @@ namespace G3D { + +Vector3 Vector3::movedTowards(const Vector3& goal, float maxTranslation) const { + Vector3 t = *this; + t.moveTowards(goal, maxTranslation); + return t; +} + + +void Vector3::moveTowards(const Vector3& goal, float maxTranslation) { + // Apply clamped translation + Vector3 dX = goal - *this; + float length = dX.length(); + if ((length < 0.00001f) || (length < maxTranslation)) { + *this = goal; + } else { + *this += G3D::min(1.0f, maxTranslation / length) * dX; + } +} + + Vector3::Vector3(const Any& any) { - any.verifyName("Vector3"); + if (any.name() == "Vector3::inf" || any.name() == "Point3::inf") { + *this = inf(); + return; + } else if (any.name() == "Vector3::zero" || any.name() == "Point3::zero") { + *this = zero(); + return; + } else if (any.name() == "Vector3::nan" || any.name() == "Point3::nan") { + *this = nan(); + return; + } + + any.verifyName("Vector3", "Point3"); any.verifyType(Any::TABLE, Any::ARRAY); any.verifySize(3); @@ -48,8 +79,25 @@ Vector3::Vector3(const Any& any) { } } -Vector3::operator Any() const { - Any any(Any::ARRAY, "Vector3"); + +bool Vector3::isNaN() const { + return G3D::isNaN(x) || G3D::isNaN(y) || G3D::isNaN(z); +} + + +Vector3& Vector3::operator=(const Any& a) { + *this = Vector3(a); + return *this; +} + + +Any Vector3::toAny() const { + return toAny("Vector3"); +} + + +Any Vector3::toAny(const std::string& name) const { + Any any(Any::ARRAY, name); any.append(x, y, z); return any; } @@ -105,7 +153,11 @@ Vector3::Axis Vector3::primaryAxis() const { size_t Vector3::hashCode() const { - return Vector4(*this, 0.0f).hashCode(); + const uint32* u = (const uint32*)this; + return + HashTrait<uint32>::hashCode(u[0]) ^ + HashTrait<uint32>::hashCode(~u[1]) ^ + HashTrait<uint32>::hashCode((u[2] << 16) | ~(u[2] >> 16)); } std::ostream& operator<<(std::ostream& os, const Vector3& v) { @@ -120,7 +172,7 @@ double frand() { } Vector3::Vector3(TextInput& t) { - deserialize(t); + deserialize(t); } Vector3::Vector3(BinaryInput& b) { @@ -178,22 +230,6 @@ Vector3 Vector3::random(Random& r) { } -float Vector3::unitize(float fTolerance) { - float fMagnitude = magnitude(); - - if (fMagnitude > fTolerance) { - float fInvMagnitude = 1.0f / fMagnitude; - x *= fInvMagnitude; - y *= fInvMagnitude; - z *= fInvMagnitude; - } else { - fMagnitude = 0.0f; - } - - return fMagnitude; -} - - Vector3 Vector3::reflectAbout(const Vector3& normal) const { Vector3 out; @@ -224,6 +260,26 @@ Vector3 Vector3::cosHemiRandom(const Vector3& normal, Random& r) { } +Vector3 Vector3::cosSphereRandom(const Vector3& normal, Random& r) { + debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f), + "cosSphereRandom requires its argument to have unit length"); + + float x, y, z; + r.cosSphere(x, y, z); + + // Make a coordinate system + const Vector3& Z = normal; + + Vector3 X, Y; + normal.getTangents(X, Y); + + return + x * X + + y * Y + + z * Z; +} + + Vector3 Vector3::cosPowHemiRandom(const Vector3& normal, const float k, Random& r) { debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f), "cosPowHemiRandom requires its argument to have unit length"); @@ -310,40 +366,20 @@ void Vector3::orthonormalize (Vector3 akVector[3]) { // product of vectors A and B. // compute u0 - akVector[0].unitize(); + akVector[0] = akVector[0].direction(); // compute u1 - float fDot0 = akVector[0].dot(akVector[1]); + float fDot0 = akVector[0].dot(akVector[1]); akVector[1] -= akVector[0] * fDot0; - akVector[1].unitize(); + akVector[1] = akVector[1].direction(); // compute u2 - float fDot1 = akVector[1].dot(akVector[2]); + float fDot1 = akVector[1].dot(akVector[2]); fDot0 = akVector[0].dot(akVector[2]); akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1; - akVector[2].unitize(); + akVector[2] = akVector[2].direction(); } -//---------------------------------------------------------------------------- -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; - rkU.y = + rkW.x; - rkU.z = 0.0; - } else { - rkU.x = 0.0; - rkU.y = + rkW.z; - rkU.z = -rkW.y; - } - - rkU.unitize(); - rkV = rkW.cross(rkU); -} //---------------------------------------------------------------------------- @@ -497,8 +533,12 @@ Vector4 Vector3::yzzz() const { return Vector4 (y, z, z, z); } Vector4 Vector3::zzzz() const { return Vector4 (z, z, z, z); } +void serialize(const Vector3& v, class BinaryOutput& b) { + v.serialize(b); +} - - +void deserialize(Vector3& v, class BinaryInput& b) { + v.deserialize(b); +} } // namespace |