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 | |
| 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')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Bounds3.h | 182 | ||||
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Plane.h | 73 | ||||
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Quat.h | 301 | ||||
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Transform.h | 94 | ||||
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Vec/Vec3.h | 490 |
5 files changed, 1140 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/Vec/Bounds3.h b/KaplaDemo/samples/sampleViewer3/Vec/Bounds3.h new file mode 100644 index 00000000..24b68fbf --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Vec/Bounds3.h @@ -0,0 +1,182 @@ +#ifndef BOUNDS3_H +#define BOUNDS3_H + +#include "Vec3.h" + +// Singe / VecVecReal Precision Vec 3 +// Matthias Mueller +// derived from Vec3.h + +namespace M +{ + +class Bounds3 +{ +public: + + Vec3 minimum, maximum; + + Bounds3() + { + // Default to empty boxes for compatibility TODO: PT: remove this if useless + setEmpty(); + } + + + ~Bounds3() + { + //nothing + } + + + void setEmpty() + { + // We know use this particular pattern for empty boxes + set(MAX_VEC_REAL, MAX_VEC_REAL, MAX_VEC_REAL, + MIN_VEC_REAL, MIN_VEC_REAL, MIN_VEC_REAL); + } + + void setInfinite() + { + set(MIN_VEC_REAL, MIN_VEC_REAL, MIN_VEC_REAL, + MAX_VEC_REAL, MAX_VEC_REAL, MAX_VEC_REAL); + } + + void set(VecReal mi, VecReal miny, VecReal minz, VecReal maxx, VecReal maxy,VecReal maxz) + { + minimum.set(mi, miny, minz); + maximum.set(maxx, maxy, maxz); + } + + void set(const Vec3& _min, const Vec3& _max) + { + minimum = _min; + maximum = _max; + } + + void include(const Vec3& v) + { + maximum.max(v); + minimum.min(v); + } + + void combine(const Bounds3& b2) + { + // - if we're empty, min = MAX,MAX,MAX => min will be b2 in all cases => it will copy b2, ok + // - if b2 is empty, the opposite happens => keep us unchanged => ok + // => same behavior as before, automatically + minimum.min(b2.minimum); + maximum.max(b2.maximum); + } + + //void boundsOfOBB(const Mat33& orientation, const Vec3& translation, const Vec3& halfDims) + //{ + //VecReal dimx = halfDims[0]; + //VecReal dimy = halfDims[1]; + //VecReal dimz = halfDims[2]; + + //VecReal x = Math::abs(orientation(0,0) * dimx) + Math::abs(orientation(0,1) * dimy) + Math::abs(orientation(0,2) * dimz); + //VecReal y = Math::abs(orientation(1,0) * dimx) + Math::abs(orientation(1,1) * dimy) + Math::abs(orientation(1,2) * dimz); + //VecReal z = Math::abs(orientation(2,0) * dimx) + Math::abs(orientation(2,1) * dimy) + Math::abs(orientation(2,2) * dimz); + + //set(-x + translation[0], -y + translation[1], -z + translation[2], x + translation[0], y + translation[1], z + translation[2]); + //} + + //void transform(const Mat33& orientation, const Vec3& translation) + //{ + //// convert to center and extents form + //Vec3 center, extents; + //getCenter(center); + //getExtents(extents); + + //center = orientation * center + translation; + //boundsOfOBB(orientation, center, extents); + //} + + bool isEmpty() const + { + // Consistency condition for (Min, Max) boxes: min < max + // TODO: PT: should we test against the explicit pattern ? + if(minimum.x < maximum.x) return false; + if(minimum.y < maximum.y) return false; + if(minimum.z < maximum.z) return false; + return true; + } + + bool intersects(const Bounds3& b) const + { + if ((b.minimum.x > maximum.x) || (minimum.x > b.maximum.x)) return false; + if ((b.minimum.y > maximum.y) || (minimum.y > b.maximum.y)) return false; + if ((b.minimum.z > maximum.z) || (minimum.z > b.maximum.z)) return false; + return true; + } + + bool intersects2D(const Bounds3& b, unsigned axis) const + { + // TODO: PT: could be static and like this: + // static unsigned i[3] = { 1,2,0,1 }; + // const unsigned ii = i[axis]; + // const unsigned jj = i[axis+1]; + const unsigned i[3] = { 1,0,0 }; + const unsigned j[3] = { 2,2,1 }; + const unsigned ii = i[axis]; + const unsigned jj = j[axis]; + if ((b.minimum[ii] > maximum[ii]) || (minimum[ii] > b.maximum[ii])) return false; + if ((b.minimum[jj] > maximum[jj]) || (minimum[jj] > b.maximum[jj])) return false; + return true; + } + + bool contain(const Vec3& v) const + { + if ((v.x < minimum.x) || (v.x > maximum.x)) return false; + if ((v.y < minimum.y) || (v.y > maximum.y)) return false; + if ((v.z < minimum.z) || (v.z > maximum.z)) return false; + return true; + } + + void getCenter(Vec3& center) const + { + center.add(minimum,maximum); + center *= VecReal(0.5); + } + + void getDimensions(Vec3& dims) const + { + dims.subtract(maximum,minimum); + } + + void getExtents(Vec3& extents) const + { + extents.subtract(maximum,minimum); + extents *= VecReal(0.5); + } + + void setCenterExtents(const Vec3& c, const Vec3& e) + { + minimum = c - e; + maximum = c + e; + } + + void scale(VecReal _scale) + { + Vec3 center, extents; + getCenter(center); + getExtents(extents); + setCenterExtents(center, extents * _scale); + } + + void fatten(VecReal distance) + { + minimum.x -= distance; + minimum.y -= distance; + minimum.z -= distance; + + maximum.x += distance; + maximum.y += distance; + maximum.z += distance; + } +}; + +} + +#endif diff --git a/KaplaDemo/samples/sampleViewer3/Vec/Plane.h b/KaplaDemo/samples/sampleViewer3/Vec/Plane.h new file mode 100644 index 00000000..db735926 --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Vec/Plane.h @@ -0,0 +1,73 @@ +#ifndef PLANE_H +#define PLANE_H + +#include "Vec3.H" + +// Singe / VecReal Precision Vec 3 +// Matthias Mueller +// derived from Plane + +namespace M +{ + +class Plane +{ +public: + Plane() {} + Plane(VecReal nx, VecReal ny, VecReal nz, VecReal distance) + : n(nx, ny, nz) + , d(distance) + {} + + Plane(const Vec3& normal, VecReal distance) + : n(normal) + , d(distance) + {} + + Plane(const Vec3& point, const Vec3& normal) + : n(normal) + , d(-point.dot(n)) // p satisfies normal.dot(p) + d = 0 + { + } + + Plane(const Vec3& p0, const Vec3& p1, const Vec3& p2) + { + n = (p1 - p0).cross(p2 - p0).getNormalized(); + d = -p0.dot(n); + } + + VecReal distance(const Vec3& p) const + { + return p.dot(n) + d; + } + + bool contains(const Vec3& p) const + { + return vecAbs(distance(p)) < (1.0e-7f); + } + + Vec3 project(const Vec3 & p) const + { + return p - n * distance(p); + } + + Vec3 pointInPlane() const + { + return -n*d; + } + + void normalize() + { + VecReal denom = 1.0f / n.magnitude(); + n *= denom; + d *= denom; + } + + Vec3 n; //!< The normal to the plane + VecReal d; //!< The distance from the origin +}; + +} + +#endif + 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 diff --git a/KaplaDemo/samples/sampleViewer3/Vec/Transform.h b/KaplaDemo/samples/sampleViewer3/Vec/Transform.h new file mode 100644 index 00000000..e08801de --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Vec/Transform.h @@ -0,0 +1,94 @@ +#ifndef TRANSFORM_H +#define TRANSFORM_H + +#include "Vec3.h" +#include "Quat.h" +#include "Plane.h" + +// Singe / VecVecReal Precision Vec 3 +// Matthias Mueller +// derived from NxVec3.h + +namespace M +{ + +class Transform +{ +public: + Quat q; + Vec3 p; + + Transform() {}; + Transform(const Vec3& position): q(0, 0, 0, 1), p(position) {} + Transform(const Quat& orientation): q(orientation), p(0, 0, 0) {} + Transform(const Vec3& p0, const Quat& q0): q(q0), p(p0) {} + + Transform operator*(const Transform& x) const + { + return transform(x); + } + + Transform getInverse() const + { + return Transform(q.rotateInv(-p),q.getConjugate()); + } + + + Vec3 transform(const Vec3& input) const + { + return q.rotate(input) + p; + } + + Vec3 transformInv(const Vec3& input) const + { + return q.rotateInv(input-p); + } + + Vec3 rotate(const Vec3& input) const + { + return q.rotate(input); + } + + Vec3 rotateInv(const Vec3& input) const + { + return q.rotateInv(input); + } + + Transform transform(const Transform& src) const + { + return Transform(q.rotate(src.p) + p, q*src.q); + } + + Transform transformInv(const Transform& src) const + { + Quat qinv = q.getConjugate(); + return Transform(qinv.rotate(src.p - p), qinv*src.q); + } + + static Transform createIdentity() + { + return Transform(Vec3(0)); + } + + Plane transform(const Plane& plane) const + { + Vec3 transformedNormal = rotate(plane.n); + return Plane(transformedNormal, plane.d - p.dot(transformedNormal)); + } + + Plane inverseTransform(const Plane& plane) const + { + Vec3 transformedNormal = rotateInv(plane.n); + return Plane(transformedNormal, plane.d + p.dot(plane.n)); + } + + Transform getNormalized() const + { + return Transform(p, q.getNormalized()); + } + +}; + +} + +#endif diff --git a/KaplaDemo/samples/sampleViewer3/Vec/Vec3.h b/KaplaDemo/samples/sampleViewer3/Vec/Vec3.h new file mode 100644 index 00000000..13b877dd --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Vec/Vec3.h @@ -0,0 +1,490 @@ +#ifndef VEC3_H +#define VEC3_H + +#include <math.h> + +// Singe / VecReal Precision Vec 3 +// Matthias Mueller +// derived from NxVec3.h + +namespace M +{ + +#define VEC3_DOUBLE 0 + +#if VEC3_DOUBLE + +typedef double VecReal; +#define MAX_VEC_REAL DBL_MAX +#define MIN_VEC_REAL -DBL_MAX +#define VEC_PI 3.14159265358979323846 + +inline int vecFloor(VecReal f ) { return (int)::floor(f); } +inline VecReal vecSqrt(VecReal f) { return ::sqrt(f); } +inline VecReal vecSin(VecReal f) { return ::sin(f); } +inline VecReal vecCos(VecReal f) { return ::cos(f); } +inline VecReal vecAbs(VecReal f) { return ::abs(f); } +inline VecReal vecAtan2(VecReal y, VecReal x) { return ::atan2(y, x); } +inline VecReal vecASin(VecReal f) { return ::asin(f); } +inline VecReal vecACos(VecReal f) { return ::acos(f); } +inline VecReal vecATan(VecReal f) { return ::atan(f); } + +#else + +typedef float VecReal; +#define MAX_VEC_REAL FLT_MAX +#define MIN_VEC_REAL -FLT_MAX +#define VEC_PI 3.14159265358979323846f + +inline int vecFloor(VecReal f ) { return (int)::floorf(f); } +inline VecReal vecSqrt(VecReal f) { return ::sqrtf(f); } +inline VecReal vecSin(VecReal f) { return ::sinf(f); } +inline VecReal vecCos(VecReal f) { return ::cosf(f); } +inline VecReal vecAbs(VecReal f) { return ::fabs(f); } +inline VecReal vecAtan2(VecReal y, VecReal x) { return ::atan2f(y, x); } +inline VecReal vecASin(VecReal f) { return ::asinf(f); } +inline VecReal vecACos(VecReal f) { return ::acosf(f); } +inline VecReal vecATan(VecReal f) { return ::atanf(f); } + +#endif + + +/** +\brief Enum to classify an axis. +*/ + enum DAxisType + { + D_AXIS_PLUS_X, + D_AXIS_MINUS_X, + D_AXIS_PLUS_Y, + D_AXIS_MINUS_Y, + D_AXIS_PLUS_Z, + D_AXIS_MINUS_Z, + D_AXIS_ARBITRARY + }; + +// ------------------------------------------------------------------------------------- +class Vec3 +{ +public: + VecReal x,y,z; + + Vec3() {}; + Vec3(VecReal _x, VecReal _y, VecReal _z) : x(_x), y(_y), z(_z) {} + Vec3(const VecReal v[]) : x(v[0]), y(v[1]), z(v[2]) {} + + const VecReal* Vec3::get() const { return &x;} + VecReal* get() { return &x; } + void get(VecReal * v) const + { + v[0] = x; + v[1] = y; + v[2] = z; + } + + VecReal& operator[](int index) + { + return (&x)[index]; + } + + const VecReal operator[](int index) const + { + return (&x)[index]; + } + + void setx(const VecReal & d) + { + x = d; + } + + + void sety(const VecReal & d) + { + y = d; + } + + + void setz(const VecReal & d) + { + z = d; + } + + Vec3 getNormalized() const + { + const VecReal m = magnitudeSquared(); + return m>0 ? *this * 1.0 / vecSqrt(m) : Vec3(0,0,0); + } + + //Operators + + bool operator< (const Vec3&v) const + { + return ((x < v.x)&&(y < v.y)&&(z < v.z)); + } + + + bool operator==(const Vec3& v) const + { + return ((x == v.x)&&(y == v.y)&&(z == v.z)); + } + + + bool operator!=(const Vec3& v) const + { + return ((x != v.x)||(y != v.y)||(z != v.z)); + } + + //Methods + + void set(const Vec3 & v) + { + x = v.x; + y = v.y; + z = v.z; + } + + + void setNegative(const Vec3 & v) + { + x = -v.x; + y = -v.y; + z = -v.z; + } + + + void setNegative() + { + x = -x; + y = -y; + z = -z; + } + + + + void set(const VecReal * v) + { + x = v[0]; + y = v[1]; + z = v[2]; + } + + + void set(VecReal _x, VecReal _y, VecReal _z) + { + this->x = _x; + this->y = _y; + this->z = _z; + } + + + void set(VecReal v) + { + x = v; + y = v; + z = v; + } + + + void zero() + { + x = y = z = 0.0; + } + + + void setPlusInfinity() + { + x = y = z = MAX_VEC_REAL; + } + + + void setMinusInfinity() + { + x = y = z = MIN_VEC_REAL; + } + + + void max(const Vec3 & v) + { + x = x > v.x ? x : v.x; + y = y > v.y ? y : v.y; + z = z > v.z ? z : v.z; + } + + void min(const Vec3 & v) + { + x = x < v.x ? x : v.x; + y = y < v.y ? y : v.y; + z = z < v.z ? z : v.z; + } + + + + + void add(const Vec3 & a, const Vec3 & b) + { + x = a.x + b.x; + y = a.y + b.y; + z = a.z + b.z; + } + + + void subtract(const Vec3 &a, const Vec3 &b) + { + x = a.x - b.x; + y = a.y - b.y; + z = a.z - b.z; + } + + + void arrayMultiply(const Vec3 &a, const Vec3 &b) + { + x = a.x * b.x; + y = a.y * b.y; + z = a.z * b.z; + } + + + void multiply(VecReal s, const Vec3 & a) + { + x = a.x * s; + y = a.y * s; + z = a.z * s; + } + + + void multiplyAdd(VecReal s, const Vec3 & a, const Vec3 & b) + { + x = s * a.x + b.x; + y = s * a.y + b.y; + z = s * a.z + b.z; + } + + + VecReal normalize() + { + VecReal m = magnitude(); + if (m) + { + const VecReal il = VecReal(1.0) / m; + x *= il; + y *= il; + z *= il; + } + return m; + } + + + void setMagnitude(VecReal length) + { + VecReal m = magnitude(); + if(m) + { + VecReal newLength = length / m; + x *= newLength; + y *= newLength; + z *= newLength; + } + } + + + DAxisType snapToClosestAxis() + { + const VecReal almostOne = 0.999999f; + if(x >= almostOne) { set( 1.0f, 0.0f, 0.0f); return D_AXIS_PLUS_X ; } + else if(x <= -almostOne) { set(-1.0f, 0.0f, 0.0f); return D_AXIS_MINUS_X; } + else if(y >= almostOne) { set( 0.0f, 1.0f, 0.0f); return D_AXIS_PLUS_Y ; } + else if(y <= -almostOne) { set( 0.0f, -1.0f, 0.0f); return D_AXIS_MINUS_Y; } + else if(z >= almostOne) { set( 0.0f, 0.0f, 1.0f); return D_AXIS_PLUS_Z ; } + else if(z <= -almostOne) { set( 0.0f, 0.0f, -1.0f); return D_AXIS_MINUS_Z; } + else return D_AXIS_ARBITRARY; + } + + + unsigned int closestAxis() const + { + const VecReal* vals = &x; + unsigned int m = 0; + if(abs(vals[1]) > abs(vals[m])) m = 1; + if(abs(vals[2]) > abs(vals[m])) m = 2; + return m; + } + + + //const methods + + //bool isFinite() const + //{ + // return NxMath::isFinite(x) && NxMath::isFinite(y) && NxMath::isFinite(z); + //} + + + VecReal dot(const Vec3 &v) const + { + return x * v.x + y * v.y + z * v.z; + } + + + bool sameDirection(const Vec3 &v) const + { + return x*v.x + y*v.y + z*v.z >= 0.0f; + } + + + VecReal magnitude() const + { + return sqrt(x * x + y * y + z * z); + } + + + VecReal magnitudeSquared() const + { + return x * x + y * y + z * z; + } + + + VecReal distance(const Vec3 & v) const + { + VecReal dx = x - v.x; + VecReal dy = y - v.y; + VecReal dz = z - v.z; + return sqrt(dx * dx + dy * dy + dz * dz); + } + + + VecReal distanceSquared(const Vec3 &v) const + { + VecReal dx = x - v.x; + VecReal dy = y - v.y; + VecReal dz = z - v.z; + return dx * dx + dy * dy + dz * dz; + } + + + void cross(const Vec3 &left, const Vec3 & right) //prefered version, w/o temp object. + { + // temps needed in case left or right is this. + VecReal a = (left.y * right.z) - (left.z * right.y); + VecReal b = (left.z * right.x) - (left.x * right.z); + VecReal c = (left.x * right.y) - (left.y * right.x); + + x = a; + y = b; + z = c; + } + + + bool equals(const Vec3 & v, VecReal epsilon) const + { + return + abs(x - v.x) < epsilon && + abs(y - v.y) < epsilon && + abs(z - v.z) < epsilon; + } + + + + Vec3 operator -() const + { + return Vec3(-x, -y, -z); + } + + + Vec3 operator +(const Vec3 & v) const + { + return Vec3(x + v.x, y + v.y, z + v.z); // RVO version + } + + + Vec3 operator -(const Vec3 & v) const + { + return Vec3(x - v.x, y - v.y, z - v.z); // RVO version + } + + + + Vec3 operator *(VecReal f) const + { + return Vec3(x * f, y * f, z * f); // RVO version + } + + + Vec3 operator /(VecReal f) const + { + f = VecReal(1.0) / f; return Vec3(x * f, y * f, z * f); + } + + + Vec3& operator +=(const Vec3& v) + { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + + Vec3& operator -=(const Vec3& v) + { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + + Vec3& operator *=(VecReal f) + { + x *= f; + y *= f; + z *= f; + + return *this; + } + + + Vec3& operator /=(VecReal f) + { + f = 1.0f/f; + x *= f; + y *= f; + z *= f; + + return *this; + } + + + Vec3 cross(const Vec3& v) const + { + Vec3 temp; + temp.cross(*this,v); + return temp; + } + + + Vec3 operator^(const Vec3& v) const + { + Vec3 temp; + temp.cross(*this,v); + return temp; + } + + + VecReal operator|(const Vec3& v) const + { + return x * v.x + y * v.y + z * v.z; + } +}; + + /** + scalar pre-multiplication + */ + +inline Vec3 operator *(VecReal f, const Vec3& v) + { + return Vec3(f * v.x, f * v.y, f * v.z); + } + + +} + /** @} */ +#endif |