Files
PhysX4.1/kaplademo/source/kaplaDemo/Vec/Vec3.h
2025-11-28 23:13:44 +05:30

518 lines
9.2 KiB
C++

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
#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