diff options
Diffstat (limited to 'externals/g3dlite/G3D/Vector3.h')
| -rw-r--r-- | externals/g3dlite/G3D/Vector3.h | 798 |
1 files changed, 0 insertions, 798 deletions
diff --git a/externals/g3dlite/G3D/Vector3.h b/externals/g3dlite/G3D/Vector3.h deleted file mode 100644 index 4825efb9985..00000000000 --- a/externals/g3dlite/G3D/Vector3.h +++ /dev/null @@ -1,798 +0,0 @@ -/** - @file Vector3.h - - 3D vector class - - @maintainer Morgan McGuire, http://graphics.cs.williams.edu - - @created 2001-06-02 - @edited 2009-11-01 - Copyright 2000-2009, Morgan McGuire. - All rights reserved. - */ - -#ifndef G3D_Vector3_h -#define G3D_Vector3_h - -#include "G3D/platform.h" -#include "G3D/g3dmath.h" -#include "G3D/Random.h" -#include "G3D/Vector2.h" -#include "G3D/Table.h" -#include "G3D/HashTrait.h" -#include "G3D/PositionTrait.h" -#include "G3D/Vector2.h" -#include <iostream> -#include <string> - -namespace G3D { - -class Vector2; -class Vector4; -class Vector4int8; -class Vector3int32; -class Any; - -/** - <B>Swizzles</B> - Vector classes have swizzle operators, e.g. <CODE>v.xy()</CODE>, that - allow selection of arbitrary sub-fields. These cannot be used as write - masks. Examples - - <PRE> -Vector3 v(1, 2, 3); -Vector3 j; -Vector2 b; - -b = v.xz(); -j = b.xx(); -</PRE> - - - <B>Warning</B> - - Do not subclass-- this implementation makes assumptions about the - memory layout. - */ -class Vector3 { -public: - - // coordinates - float x, y, z; - -private: - - // Hidden operators - bool operator<(const Vector3&) const; - bool operator>(const Vector3&) const; - bool operator<=(const Vector3&) const; - bool operator>=(const Vector3&) const; - -public: - /** Initializes to zero */ - Vector3(); - - /** \param any Must either Vector3(#, #, #) or Vector3 {x = #, y = #, z = #}*/ - Vector3(const Any& any); - - /** Converts the Vector3 to an Any. */ - operator Any() const; - - /** Divides by 127 */ - Vector3(const Vector4int8&); - Vector3(const class Vector3int32& v); - explicit Vector3(class BinaryInput& b); - Vector3(float _x, float _y, float _z); - explicit Vector3(const class Vector2& v, float _z); - explicit Vector3(float coordinate[3]); - explicit Vector3(double coordinate[3]); - Vector3(const class Vector3int16& v); - explicit Vector3(class TextInput& t); - explicit Vector3(const class Color3& c); - - /** Format is three float32's */ - void serialize(class BinaryOutput& b) const; - void deserialize(class BinaryInput& b); - - /** Format is "(%f, %f, %f)" */ - void serialize(class TextOutput& t) const; - void deserialize(class TextInput& t); - - // access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z - // - // WARNING. These member functions rely on - // (1) Vector3 not having virtual functions - // (2) the data packed in a 3*sizeof(float) memory block - const float& __fastcall operator[] (int i) const; - float& operator[] (int i); - - enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1}; - - /** - Returns the largest dimension. Particularly convenient for determining - which plane to project a triangle onto for point-in-polygon tests. - */ - Axis primaryAxis() const; - - // assignment and comparison - Vector3& __fastcall operator= (const Vector3& rkVector); - bool operator== (const Vector3& rkVector) const; - bool operator!= (const Vector3& rkVector) const; - size_t hashCode() const; - bool fuzzyEq(const Vector3& other) const; - bool fuzzyNe(const Vector3& other) const; - - /** Returns true if this vector has finite length. */ - bool isFinite() const; - - /** Returns true if this vector has length ~= 0 */ - bool isZero() const; - - /** Returns true if this vector has length ~= 1 */ - bool isUnit() const; - - // arithmetic operations - Vector3 __fastcall operator+ (const Vector3& v) const; - Vector3 __fastcall operator- (const Vector3& v) const; - Vector3 __fastcall operator* (float s) const; - inline Vector3 __fastcall operator/ (float s) const { - return *this * (1.0f / s); - } - Vector3 __fastcall operator* (const Vector3& v) const; - Vector3 __fastcall operator/ (const Vector3& v) const; - Vector3 __fastcall operator- () const; - - // arithmetic updates - Vector3& __fastcall operator+= (const Vector3& v); - Vector3& __fastcall operator-= (const Vector3& v); - Vector3& __fastcall operator*= (float s); - inline Vector3& __fastcall operator/= (float s) { - return (*this *= (1.0f / s)); - } - Vector3& __fastcall operator*= (const Vector3& v); - Vector3& __fastcall operator/= (const Vector3& v); - - /** Same as magnitude */ - float length() const; - - float magnitude() const; - - /** - The result is a nan vector if the length is almost zero. - */ - Vector3 direction() const; - - /** - Potentially less accurate but faster than direction(). - Only works if System::hasSSE is true. - */ - Vector3 fastDirection() const; - - /** - Reflect this vector about the (not necessarily unit) normal. - Assumes that both the before and after vectors point away from - the base of the normal. - - Note that if used for a collision or ray reflection you - must negate the resulting vector to get a direction pointing - <I>away</I> from the collision. - - <PRE> - V' N V - - r ^ -, - \ | / - \|/ - </PRE> - - See also Vector3::reflectionDirection - */ - Vector3 reflectAbout(const Vector3& normal) const; - - /** - See also G3D::Ray::reflect. - The length is 1. - <PRE> - V' N V - - r ^ / - \ | / - \|'- - </PRE> - */ - Vector3 reflectionDirection(const Vector3& normal) const; - - - /** - Returns Vector3::zero() if the length is nearly zero, otherwise - returns a unit vector. - */ - inline Vector3 directionOrZero() const { - float mag = magnitude(); - if (G3D::fuzzyEq(mag, 0.0f)) { - return Vector3::zero(); - } else if (G3D::fuzzyEq(mag, 1.0f)) { - return *this; - } else { - return *this * (1.0f / mag); - } - } - - /** - Returns the direction of a refracted ray, - where iExit is the index of refraction for the - previous material and iEnter is the index of refraction - for the new material. Like Vector3::reflectionDirection, - the result has length 1 and is - pointed <I>away</I> from the intersection. - - Returns Vector3::zero() in the case of total internal refraction. - - @param iOutside The index of refraction (eta) outside - (on the <I>positive</I> normal side) of the surface. - - @param iInside The index of refraction (eta) inside - (on the <I>negative</I> normal side) of the surface. - - See also G3D::Ray::refract. - <PRE> - N V - - ^ / - | / - |'- - __-- - V'<-- - </PRE> - */ - Vector3 refractionDirection( - const Vector3& normal, - float iInside, - float iOutside) const; - - /** Synonym for direction */ - inline Vector3 unit() const { - return direction(); - } - - /** Returns a normalized vector. May be computed with lower - precision than unit */ - inline Vector3 fastUnit() const { - return fastDirection(); - } - - /** Same as squaredMagnitude */ - float squaredLength() const; - - float squaredMagnitude () const; - - float __fastcall dot(const Vector3& rkVector) const; - - float unitize(float tolerance = 1e-06); - - /** Cross product. Note that two cross products in a row - can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2 - (v1 dot v2) v3. - */ - Vector3 __fastcall cross(const Vector3& rkVector) const; - Vector3 unitCross(const Vector3& rkVector) const; - - /** - Returns a matrix such that v.cross() * w = v.cross(w). - <PRE> - [ 0 -v.z v.y ] - [ v.z 0 -v.x ] - [ -v.y v.x 0 ] - </PRE> - */ - class Matrix3 cross() const; - - Vector3 __fastcall min(const Vector3 &v) const; - Vector3 __fastcall max(const Vector3 &v) const; - - /** Smallest element */ - inline float min() const { - return G3D::min(G3D::min(x, y), z); - } - - /** Largest element */ - inline float max() const { - return G3D::max(G3D::max(x, y), z); - } - - std::string toString() const; - - inline Vector3 clamp(const Vector3& low, const Vector3& high) const { - return Vector3( - G3D::clamp(x, low.x, high.x), - G3D::clamp(y, low.y, high.y), - G3D::clamp(z, low.z, high.z)); - } - - inline Vector3 clamp(float low, float high) const { - return Vector3( - G3D::clamp(x, low, high), - G3D::clamp(y, low, high), - G3D::clamp(z, low, high)); - } - - /** - Linear interpolation - */ - inline Vector3 lerp(const Vector3& v, float alpha) const { - return (*this) + (v - *this) * alpha; - } - - /** Gram-Schmidt orthonormalization. */ - static void orthonormalize (Vector3 akVector[3]); - - /** \brief Random unit vector, uniformly distributed on the sphere. - - Distribution rendered by G3D::DirectionHistogram: - \image html vector3-random.png - */ - static Vector3 random(Random& r = Random::common()); - - /** \brief Random unit vector, distributed according to \f$\max(\cos \theta,0)\f$. - - That is, so that the probability of \f$\vec{V}\f$ is proportional - to \f$\max(\vec{v} \cdot \vec{n}, 0)\f$. Useful in photon mapping for - Lambertian scattering. - - Distribution rendered by G3D::DirectionHistogram: - \image html vector3-coshemirandom.png - - \param n Unit vector at the center of the distribution. - - @cite Henrik Wann Jensen, Realistic Image Synthesis using Photon Mapping eqn 2.24 - */ - static Vector3 cosHemiRandom(const Vector3& n, Random& r = Random::common()); - - /** \brief Random unit vector, distributed according to \f$\max(\cos^k \theta,0)\f$. - - That is, so that the probability of \f$\vec{V}\f$ is - proportional to \f$\max((\vec{v} \cdot \vec{n})^k, 0)\f$. - Useful in photon mapping for glossy scattering. - - Distribution rendered by G3D::DirectionHistogram: - \image html vector3-cospowhemirandom.png - - \param n Unit vector at the center of the distribution. - - @cite Ashikhmin and Shirley, An anisotropic Phong BRDF model, Journal of Graphics Tools, 2002 - */ - static Vector3 cosPowHemiRandom(const Vector3& n, const float k, Random& r = Random::common()); - - /** - \brief Random vector distributed over the hemisphere about normal. - - Distribution rendered by G3D::DirectionHistogram: - \image html vector3-hemirandom.png - */ - static Vector3 hemiRandom(const Vector3& normal, Random& r = Random::common()); - - /** Input W must be initialize to a nonzero vector, output is {U,V,W} - an orthonormal basis. A hint is provided about whether or not W - is already unit length. - @deprecated Use getTangents - */ - static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV, - Vector3& rkW, bool bUnitLengthW = true); - - inline float sum() const { - return x + y + z; - } - - inline float average() const { - return sum() / 3.0f; - } - - // Special values. - static const Vector3& zero(); - static const Vector3& one(); - static const Vector3& unitX(); - static const Vector3& unitY(); - static const Vector3& unitZ(); - static const Vector3& inf(); - static const Vector3& nan(); - - /** Smallest (most negative) representable vector */ - static const Vector3& minFinite(); - - /** Largest representable vector */ - static const Vector3& maxFinite(); - - - /** Creates two orthonormal tangent vectors X and Y such that - if Z = this, X x Y = Z.*/ - inline void getTangents(Vector3& X, Vector3& Y) const { - debugAssertM(G3D::fuzzyEq(length(), 1.0f), - "makeAxes requires Z to have unit length"); - - // Choose another vector not perpendicular - X = (abs(x) < 0.9f) ? Vector3::unitX() : Vector3::unitY(); - - // Remove the part that is parallel to Z - X -= *this * this->dot(X); - X /= X.length(); - - Y = this->cross(X); - } - - - // 2-char swizzles - - Vector2 xx() const; - Vector2 yx() const; - Vector2 zx() const; - Vector2 xy() const; - Vector2 yy() const; - Vector2 zy() const; - Vector2 xz() const; - Vector2 yz() const; - Vector2 zz() const; - - // 3-char swizzles - - Vector3 xxx() const; - Vector3 yxx() const; - Vector3 zxx() const; - Vector3 xyx() const; - Vector3 yyx() const; - Vector3 zyx() const; - Vector3 xzx() const; - Vector3 yzx() const; - Vector3 zzx() const; - Vector3 xxy() const; - Vector3 yxy() const; - Vector3 zxy() const; - Vector3 xyy() const; - Vector3 yyy() const; - Vector3 zyy() const; - Vector3 xzy() const; - Vector3 yzy() const; - Vector3 zzy() const; - Vector3 xxz() const; - Vector3 yxz() const; - Vector3 zxz() const; - Vector3 xyz() const; - Vector3 yyz() const; - Vector3 zyz() const; - Vector3 xzz() const; - Vector3 yzz() const; - Vector3 zzz() const; - - // 4-char swizzles - - Vector4 xxxx() const; - Vector4 yxxx() const; - Vector4 zxxx() const; - Vector4 xyxx() const; - Vector4 yyxx() const; - Vector4 zyxx() const; - Vector4 xzxx() const; - Vector4 yzxx() const; - Vector4 zzxx() const; - Vector4 xxyx() const; - Vector4 yxyx() const; - Vector4 zxyx() const; - Vector4 xyyx() const; - Vector4 yyyx() const; - Vector4 zyyx() const; - Vector4 xzyx() const; - Vector4 yzyx() const; - Vector4 zzyx() const; - Vector4 xxzx() const; - Vector4 yxzx() const; - Vector4 zxzx() const; - Vector4 xyzx() const; - Vector4 yyzx() const; - Vector4 zyzx() const; - Vector4 xzzx() const; - Vector4 yzzx() const; - Vector4 zzzx() const; - Vector4 xxxy() const; - Vector4 yxxy() const; - Vector4 zxxy() const; - Vector4 xyxy() const; - Vector4 yyxy() const; - Vector4 zyxy() const; - Vector4 xzxy() const; - Vector4 yzxy() const; - Vector4 zzxy() const; - Vector4 xxyy() const; - Vector4 yxyy() const; - Vector4 zxyy() const; - Vector4 xyyy() const; - Vector4 yyyy() const; - Vector4 zyyy() const; - Vector4 xzyy() const; - Vector4 yzyy() const; - Vector4 zzyy() const; - Vector4 xxzy() const; - Vector4 yxzy() const; - Vector4 zxzy() const; - Vector4 xyzy() const; - Vector4 yyzy() const; - Vector4 zyzy() const; - Vector4 xzzy() const; - Vector4 yzzy() const; - Vector4 zzzy() const; - Vector4 xxxz() const; - Vector4 yxxz() const; - Vector4 zxxz() const; - Vector4 xyxz() const; - Vector4 yyxz() const; - Vector4 zyxz() const; - Vector4 xzxz() const; - Vector4 yzxz() const; - Vector4 zzxz() const; - Vector4 xxyz() const; - Vector4 yxyz() const; - Vector4 zxyz() const; - Vector4 xyyz() const; - Vector4 yyyz() const; - Vector4 zyyz() const; - Vector4 xzyz() const; - Vector4 yzyz() const; - Vector4 zzyz() const; - Vector4 xxzz() const; - Vector4 yxzz() const; - Vector4 zxzz() const; - Vector4 xyzz() const; - Vector4 yyzz() const; - Vector4 zyzz() const; - Vector4 xzzz() const; - Vector4 yzzz() const; - Vector4 zzzz() const; - - /** Can be passed to ignore a vector3 parameter */ - static Vector3& ignore(); -}; - -inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) { - return v * s; -} - -inline G3D::Vector3 operator*(double s, const G3D::Vector3& v) { - return v * (float)s; -} - -inline G3D::Vector3 operator*(int s, const G3D::Vector3& v) { - return v * (float)s; -} - -std::ostream& operator<<(std::ostream& os, const Vector3&); - - -void serialize(const Vector3::Axis& a, class BinaryOutput& bo); -void deserialize(Vector3::Axis& a, class BinaryInput& bo); - - -//---------------------------------------------------------------------------- -inline Vector3::Vector3() : x(0.0f), y(0.0f), z(0.0f) { -} - -//---------------------------------------------------------------------------- - -inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) { -} - -//---------------------------------------------------------------------------- -inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){ -} - -//---------------------------------------------------------------------------- -inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){ -} - -//---------------------------------------------------------------------------- -inline const float& Vector3::operator[] (int i) const { - return ((float*)this)[i]; -} - -inline float& Vector3::operator[] (int i) { - return ((float*)this)[i]; -} - - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator= (const Vector3& rkVector) { - x = rkVector.x; - y = rkVector.y; - z = rkVector.z; - return *this; -} - -//---------------------------------------------------------------------------- - -inline bool Vector3::fuzzyEq(const Vector3& other) const { - return G3D::fuzzyEq((*this - other).squaredMagnitude(), 0); -} - -//---------------------------------------------------------------------------- - -inline bool Vector3::fuzzyNe(const Vector3& other) const { - return G3D::fuzzyNe((*this - other).squaredMagnitude(), 0); -} - -//---------------------------------------------------------------------------- - -inline bool Vector3::isFinite() const { - return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z); -} - -//---------------------------------------------------------------------------- -inline bool Vector3::operator== (const Vector3& rkVector) const { - return ( x == rkVector.x && y == rkVector.y && z == rkVector.z ); -} - -//---------------------------------------------------------------------------- -inline bool Vector3::operator!= (const Vector3& rkVector) const { - return ( x != rkVector.x || y != rkVector.y || z != rkVector.z ); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::operator+ (const Vector3& rkVector) const { - return Vector3(x + rkVector.x, y + rkVector.y, z + rkVector.z); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::operator- (const Vector3& rkVector) const { - return Vector3(x - rkVector.x, y - rkVector.y, z - rkVector.z); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::operator* (const Vector3& rkVector) const { - return Vector3(x * rkVector.x, y * rkVector.y, z * rkVector.z); -} - -inline Vector3 Vector3::operator*(float f) const { - return Vector3(x * f, y * f, z * f); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::operator/ (const Vector3& rkVector) const { - return Vector3(x / rkVector.x, y / rkVector.y, z / rkVector.z); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::operator- () const { - return Vector3(-x, -y, -z); -} - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator+= (const Vector3& rkVector) { - x += rkVector.x; - y += rkVector.y; - z += rkVector.z; - return *this; -} - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator-= (const Vector3& rkVector) { - x -= rkVector.x; - y -= rkVector.y; - z -= rkVector.z; - return *this; -} - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator*= (float fScalar) { - x *= fScalar; - y *= fScalar; - z *= fScalar; - return *this; -} - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator*= (const Vector3& rkVector) { - x *= rkVector.x; - y *= rkVector.y; - z *= rkVector.z; - return *this; -} - -//---------------------------------------------------------------------------- -inline Vector3& Vector3::operator/= (const Vector3& rkVector) { - x /= rkVector.x; - y /= rkVector.y; - z /= rkVector.z; - return *this; -} - -//---------------------------------------------------------------------------- -inline float Vector3::squaredMagnitude () const { - return x*x + y*y + z*z; -} - -//---------------------------------------------------------------------------- -inline float Vector3::squaredLength () const { - return squaredMagnitude(); -} - -//---------------------------------------------------------------------------- -inline float Vector3::magnitude() const { - return ::sqrtf(x*x + y*y + z*z); -} - -//---------------------------------------------------------------------------- -inline float Vector3::length() const { - return magnitude(); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::direction () const { - const float lenSquared = squaredMagnitude(); - const float invSqrt = 1.0f / sqrtf(lenSquared); - return Vector3(x * invSqrt, y * invSqrt, z * invSqrt); -} - -//---------------------------------------------------------------------------- - -inline Vector3 Vector3::fastDirection () const { - float lenSquared = x * x + y * y + z * z; - float invSqrt = rsq(lenSquared); - return Vector3(x * invSqrt, y * invSqrt, z * invSqrt); -} - -//---------------------------------------------------------------------------- -inline float Vector3::dot (const Vector3& rkVector) const { - return x*rkVector.x + y*rkVector.y + z*rkVector.z; -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::cross (const Vector3& rkVector) const { - return Vector3(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z, - x*rkVector.y - y*rkVector.x); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::unitCross (const Vector3& rkVector) const { - Vector3 kCross(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z, - x*rkVector.y - y*rkVector.x); - kCross.unitize(); - return kCross; -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::min(const Vector3 &v) const { - return Vector3(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z)); -} - -//---------------------------------------------------------------------------- -inline Vector3 Vector3::max(const Vector3 &v) const { - return Vector3(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z)); -} - -//---------------------------------------------------------------------------- -inline bool Vector3::isZero() const { - return G3D::fuzzyEq(squaredMagnitude(), 0.0f); -} - -//---------------------------------------------------------------------------- - -inline bool Vector3::isUnit() const { - return G3D::fuzzyEq(squaredMagnitude(), 1.0f); -} - -} // namespace G3D - - -template <> -struct HashTrait<G3D::Vector3> { - static size_t hashCode(const G3D::Vector3& key) { - return key.hashCode(); - } -}; - - -template<> struct PositionTrait<class G3D::Vector2> { - static void getPosition(const G3D::Vector2& v, G3D::Vector3& p) { p = G3D::Vector3(v, 0); } -}; - -template<> struct PositionTrait<class G3D::Vector3> { - static void getPosition(const G3D::Vector3& v, G3D::Vector3& p) { p = v; } -}; - - -#endif |
