aboutsummaryrefslogtreecommitdiff
path: root/dep/g3dlite/source/Vector3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/g3dlite/source/Vector3.cpp')
-rw-r--r--dep/g3dlite/source/Vector3.cpp146
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