diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/Vec/Quat.h | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/Vec/Quat.h')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Quat.h | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/Vec/Quat.h b/KaplaDemo/samples/sampleViewer3/Vec/Quat.h new file mode 100644 index 00000000..d6b63633 --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Vec/Quat.h @@ -0,0 +1,301 @@ +#ifndef QUAT_H +#define QUAT_H + +// Singe / VecReal Precision Vec 3 +// Matthias Mueller +// derived from Quat.h + +#include "Vec3.h" + +namespace M +{ + +class Quat +{ +public: + Quat() { } + + VecReal x,y,z,w; + + Quat(VecReal nx, VecReal ny, VecReal nz, VecReal nw) : x(nx),y(ny),z(nz),w(nw) {} + + Quat(VecReal angleRadians, const Vec3& unitAxis) + { + const VecReal a = angleRadians * 0.5f; + const VecReal s = vecSin(a); + w = cos(a); + x = unitAxis.x * s; + y = unitAxis.y * s; + z = unitAxis.z * s; + } + + Quat(const Quat& v): x(v.x), y(v.y), z(v.z), w(v.w) {} + + void toRadiansAndUnitAxis(VecReal& angle, Vec3& axis) const + { + const VecReal quatEpsilon = VecReal(1.0e-8f); + const VecReal s2 = x*x+y*y+z*z; + if(s2<quatEpsilon*quatEpsilon) // can't extract a sensible axis + { + angle = 0; + axis = Vec3(1,0,0); + } + else + { + const VecReal s = 1.0f / vecSqrt(s2); + axis = Vec3(x,y,z) * s; + angle = vecAbs(w)<quatEpsilon ? VEC_PI : vecAtan2(s2*s, w) * 2; + } + + } + + /** + \brief Gets the angle between this quat and the identity quaternion. + + <b>Unit:</b> Radians + */ + VecReal getAngle() const + { + return vecACos(w) * VecReal(2); + } + + + /** + \brief Gets the angle between this quat and the argument + + <b>Unit:</b> Radians + */ + VecReal getAngle(const Quat& q) const + { + return vecACos(dot(q)) * VecReal(2); + } + + + /** + \brief This is the squared 4D vector length, should be 1 for unit quaternions. + */ + VecReal magnitudeSquared() const + { + return x*x + y*y + z*z + w*w; + } + + /** + \brief returns the scalar product of this and other. + */ + VecReal dot(const Quat& v) const + { + return x * v.x + y * v.y + z * v.z + w * v.w; + } + + Quat getNormalized() const + { + const VecReal s = (VecReal)1.0/magnitude(); + return Quat(x*s, y*s, z*s, w*s); + } + + + VecReal magnitude() const + { + return vecSqrt(magnitudeSquared()); + } + + //modifiers: + /** + \brief maps to the closest unit quaternion. + */ + VecReal normalize() // convert this Quat to a unit quaternion + { + const VecReal mag = magnitude(); + if (mag) + { + const VecReal imag = VecReal(1) / mag; + + x *= imag; + y *= imag; + z *= imag; + w *= imag; + } + return mag; + } + + /* + \brief returns the conjugate. + + \note for unit quaternions, this is the inverse. + */ + Quat getConjugate() const + { + return Quat(-x,-y,-z,w); + } + + /* + \brief returns imaginary part. + */ + Vec3 getImaginaryPart() const + { + return Vec3(x,y,z); + } + + /** brief computes rotation of x-axis */ + Vec3 getBasisVector0() const + { + // return rotate(Vec3(1,0,0)); + const VecReal x2 = x*(VecReal)2.0; + const VecReal w2 = w*(VecReal)2.0; + return Vec3( (w * w2) - 1.0f + x*x2, + (z * w2) + y*x2, + (-y * w2) + z*x2); + } + + /** brief computes rotation of y-axis */ + Vec3 getBasisVector1() const + { + // return rotate(Vec3(0,1,0)); + const VecReal y2 = y*(VecReal)2.0; + const VecReal w2 = w*(VecReal)2.0; + return Vec3( (-z * w2) + x*y2, + (w * w2) - 1.0f + y*y2, + (x * w2) + z*y2); + } + + + /** brief computes rotation of z-axis */ + Vec3 getBasisVector2() const + { + // return rotate(Vec3(0,0,1)); + const VecReal z2 = z*(VecReal)2.0; + const VecReal w2 = w*(VecReal)2.0; + return Vec3( (y * w2) + x*z2, + (-x * w2) + y*z2, + (w * w2) - 1.0f + z*z2); + } + + /** + rotates passed vec by this (assumed unitary) + */ + const Vec3 rotate(const Vec3& v) const + // const Vec3 rotate(const Vec3& v) const + { + const VecReal vx = (VecReal)2.0*v.x; + const VecReal vy = (VecReal)2.0*v.y; + const VecReal vz = (VecReal)2.0*v.z; + const VecReal w2 = w*w-(VecReal)0.5; + const VecReal dot2 = (x*vx + y*vy +z*vz); + return Vec3 + ( + (vx*w2 + (y * vz - z * vy)*w + x*dot2), + (vy*w2 + (z * vx - x * vz)*w + y*dot2), + (vz*w2 + (x * vy - y * vx)*w + z*dot2) + ); + /* + const Vec3 qv(x,y,z); + return (v*(w*w-0.5f) + (qv.cross(v))*w + qv*(qv.dot(v)))*2; + */ + } + + /** + inverse rotates passed vec by this (assumed unitary) + */ + const Vec3 rotateInv(const Vec3& v) const + // const Vec3 rotateInv(const Vec3& v) const + { + const VecReal vx = (VecReal)2.0*v.x; + const VecReal vy = (VecReal)2.0*v.y; + const VecReal vz = (VecReal)2.0*v.z; + const VecReal w2 = w*w-(VecReal)0.5; + const VecReal dot2 = (x*vx + y*vy +z*vz); + return Vec3 + ( + (vx*w2 - (y * vz - z * vy)*w + x*dot2), + (vy*w2 - (z * vx - x * vz)*w + y*dot2), + (vz*w2 - (x * vy - y * vx)*w + z*dot2) + ); + // const Vec3 qv(x,y,z); + // return (v*(w*w-0.5f) - (qv.cross(v))*w + qv*(qv.dot(v)))*2; + } + + /** + \brief Assignment operator + */ + Quat& operator=(const Quat& p) { x = p.x; y = p.y; z = p.z; w = p.w; return *this; } + + Quat& operator*= (const Quat& q) + { + const VecReal tx = w*q.x + q.w*x + y*q.z - q.y*z; + const VecReal ty = w*q.y + q.w*y + z*q.x - q.z*x; + const VecReal tz = w*q.z + q.w*z + x*q.y - q.x*y; + + w = w*q.w - q.x*x - y*q.y - q.z*z; + x = tx; + y = ty; + z = tz; + + return *this; + } + + Quat& operator+= (const Quat& q) + { + x+=q.x; + y+=q.y; + z+=q.z; + w+=q.w; + return *this; + } + + Quat& operator-= (const Quat& q) + { + x-=q.x; + y-=q.y; + z-=q.z; + w-=q.w; + return *this; + } + + Quat& operator*= (const VecReal s) + { + x*=s; + y*=s; + z*=s; + w*=s; + return *this; + } + + /** quaternion multiplication */ + Quat operator*(const Quat& q) const + { + return Quat(w*q.x + q.w*x + y*q.z - q.y*z, + w*q.y + q.w*y + z*q.x - q.z*x, + w*q.z + q.w*z + x*q.y - q.x*y, + w*q.w - x*q.x - y*q.y - z*q.z); + } + + /** quaternion addition */ + Quat operator+(const Quat& q) const + { + return Quat(x+q.x,y+q.y,z+q.z,w+q.w); + } + + /** quaternion subtraction */ + Quat operator-() const + { + return Quat(-x,-y,-z,-w); + } + + + Quat operator-(const Quat& q) const + { + return Quat(x-q.x,y-q.y,z-q.z,w-q.w); + } + + + Quat operator*(VecReal r) const + { + return Quat(x*r,y*r,z*r,w*r); + } + + static Quat createIdentity() { return Quat(0,0,0,1); } +}; + +} + +#endif |