b4f17b968a
- Add frustum class and bezier evaluation functions. - Add component accessors to vector. - Add matrix constructors. - Fix errors in sparse solvers. - Better robust orthogonalization. - Fix montecarlo distribution.
873 lines
18 KiB
C++
873 lines
18 KiB
C++
// This code is in the public domain -- castanyo@yahoo.es
|
|
|
|
#ifndef NV_MATH_VECTOR_H
|
|
#define NV_MATH_VECTOR_H
|
|
|
|
#include <nvmath/nvmath.h>
|
|
#include <nvcore/Algorithms.h> // min, max
|
|
|
|
namespace nv
|
|
{
|
|
|
|
enum zero_t { zero };
|
|
enum identity_t { identity };
|
|
|
|
// I should probably use templates.
|
|
typedef float scalar;
|
|
|
|
class NVMATH_CLASS Vector2
|
|
{
|
|
public:
|
|
typedef Vector2 const & Arg;
|
|
|
|
Vector2();
|
|
explicit Vector2(zero_t);
|
|
explicit Vector2(scalar f);
|
|
Vector2(scalar x, scalar y);
|
|
Vector2(Vector2::Arg v);
|
|
|
|
const Vector2 & operator=(Vector2::Arg v);
|
|
void setComponent(uint idx, scalar f);
|
|
|
|
scalar x() const;
|
|
scalar y() const;
|
|
|
|
scalar component(uint idx) const;
|
|
|
|
const scalar * ptr() const;
|
|
|
|
void set(scalar x, scalar y);
|
|
|
|
Vector2 operator-() const;
|
|
void operator+=(Vector2::Arg v);
|
|
void operator-=(Vector2::Arg v);
|
|
void operator*=(scalar s);
|
|
void operator*=(Vector2::Arg v);
|
|
|
|
friend bool operator==(Vector2::Arg a, Vector2::Arg b);
|
|
friend bool operator!=(Vector2::Arg a, Vector2::Arg b);
|
|
|
|
private:
|
|
scalar m_x, m_y;
|
|
};
|
|
|
|
|
|
class NVMATH_CLASS Vector3
|
|
{
|
|
public:
|
|
typedef Vector3 const & Arg;
|
|
|
|
Vector3();
|
|
explicit Vector3(zero_t);
|
|
Vector3(scalar x, scalar y, scalar z);
|
|
Vector3(Vector2::Arg v, scalar z);
|
|
Vector3(Vector3::Arg v);
|
|
|
|
const Vector3 & operator=(Vector3::Arg v);
|
|
|
|
scalar x() const;
|
|
scalar y() const;
|
|
scalar z() const;
|
|
|
|
const Vector2 & xy() const;
|
|
|
|
scalar component(uint idx) const;
|
|
void setComponent(uint idx, scalar f);
|
|
|
|
const scalar * ptr() const;
|
|
|
|
void set(scalar x, scalar y, scalar z);
|
|
|
|
Vector3 operator-() const;
|
|
void operator+=(Vector3::Arg v);
|
|
void operator-=(Vector3::Arg v);
|
|
void operator*=(scalar s);
|
|
void operator/=(scalar s);
|
|
void operator*=(Vector3::Arg v);
|
|
|
|
friend bool operator==(Vector3::Arg a, Vector3::Arg b);
|
|
friend bool operator!=(Vector3::Arg a, Vector3::Arg b);
|
|
|
|
private:
|
|
scalar m_x, m_y, m_z;
|
|
};
|
|
|
|
|
|
class NVMATH_CLASS Vector4
|
|
{
|
|
public:
|
|
typedef Vector4 const & Arg;
|
|
|
|
Vector4();
|
|
explicit Vector4(zero_t);
|
|
Vector4(scalar x, scalar y, scalar z, scalar w);
|
|
Vector4(Vector2::Arg v, scalar z, scalar w);
|
|
Vector4(Vector3::Arg v, scalar w);
|
|
Vector4(Vector4::Arg v);
|
|
// Vector4(const Quaternion & v);
|
|
|
|
const Vector4 & operator=(Vector4::Arg v);
|
|
|
|
scalar x() const;
|
|
scalar y() const;
|
|
scalar z() const;
|
|
scalar w() const;
|
|
|
|
const Vector2 & xy() const;
|
|
const Vector3 & xyz() const;
|
|
|
|
scalar component(uint idx) const;
|
|
void setComponent(uint idx, scalar f);
|
|
|
|
const scalar * ptr() const;
|
|
|
|
void set(scalar x, scalar y, scalar z, scalar w);
|
|
|
|
Vector4 operator-() const;
|
|
void operator+=(Vector4::Arg v);
|
|
void operator-=(Vector4::Arg v);
|
|
void operator*=(scalar s);
|
|
void operator*=(Vector4::Arg v);
|
|
|
|
friend bool operator==(Vector4::Arg a, Vector4::Arg b);
|
|
friend bool operator!=(Vector4::Arg a, Vector4::Arg b);
|
|
|
|
private:
|
|
scalar m_x, m_y, m_z, m_w;
|
|
};
|
|
|
|
|
|
// Vector2
|
|
|
|
inline Vector2::Vector2() {}
|
|
inline Vector2::Vector2(zero_t) : m_x(0.0f), m_y(0.0f) {}
|
|
inline Vector2::Vector2(scalar f) : m_x(f), m_y(f) {}
|
|
inline Vector2::Vector2(scalar x, scalar y) : m_x(x), m_y(y) {}
|
|
inline Vector2::Vector2(Vector2::Arg v) : m_x(v.x()), m_y(v.y()) {}
|
|
|
|
inline const Vector2 & Vector2::operator=(Vector2::Arg v)
|
|
{
|
|
m_x = v.x();
|
|
m_y = v.y();
|
|
return *this;
|
|
}
|
|
|
|
inline scalar Vector2::x() const { return m_x; }
|
|
inline scalar Vector2::y() const { return m_y; }
|
|
|
|
inline scalar Vector2::component(uint idx) const
|
|
{
|
|
nvDebugCheck(idx < 2);
|
|
if (idx == 0) return x();
|
|
if (idx == 1) return y();
|
|
nvAssume(false);
|
|
return 0.0f;
|
|
}
|
|
|
|
inline void Vector2::setComponent(uint idx, float f)
|
|
{
|
|
nvDebugCheck(idx < 2);
|
|
if (idx == 0) m_x = f;
|
|
else if (idx == 1) m_y = f;
|
|
}
|
|
|
|
|
|
inline const scalar * Vector2::ptr() const
|
|
{
|
|
return &m_x;
|
|
}
|
|
|
|
inline void Vector2::set(scalar x, scalar y)
|
|
{
|
|
m_x = x;
|
|
m_y = y;
|
|
}
|
|
|
|
inline Vector2 Vector2::operator-() const
|
|
{
|
|
return Vector2(-m_x, -m_y);
|
|
}
|
|
|
|
inline void Vector2::operator+=(Vector2::Arg v)
|
|
{
|
|
m_x += v.m_x;
|
|
m_y += v.m_y;
|
|
}
|
|
|
|
inline void Vector2::operator-=(Vector2::Arg v)
|
|
{
|
|
m_x -= v.m_x;
|
|
m_y -= v.m_y;
|
|
}
|
|
|
|
inline void Vector2::operator*=(scalar s)
|
|
{
|
|
m_x *= s;
|
|
m_y *= s;
|
|
}
|
|
|
|
inline void Vector2::operator*=(Vector2::Arg v)
|
|
{
|
|
m_x *= v.m_x;
|
|
m_y *= v.m_y;
|
|
}
|
|
|
|
inline bool operator==(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return a.m_x == b.m_x && a.m_y == b.m_y;
|
|
}
|
|
inline bool operator!=(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return a.m_x != b.m_x || a.m_y != b.m_y;
|
|
}
|
|
|
|
|
|
// Vector3
|
|
|
|
inline Vector3::Vector3() {}
|
|
inline Vector3::Vector3(zero_t) : m_x(0.0f), m_y(0.0f), m_z(0.0f) {}
|
|
inline Vector3::Vector3(scalar x, scalar y, scalar z) : m_x(x), m_y(y), m_z(z) {}
|
|
inline Vector3::Vector3(Vector2::Arg v, scalar z) : m_x(v.x()), m_y(v.y()), m_z(z) {}
|
|
inline Vector3::Vector3(Vector3::Arg v) : m_x(v.x()), m_y(v.y()), m_z(v.z()) {}
|
|
|
|
inline const Vector3 & Vector3::operator=(Vector3::Arg v)
|
|
{
|
|
m_x = v.m_x;
|
|
m_y = v.m_y;
|
|
m_z = v.m_z;
|
|
return *this;
|
|
}
|
|
|
|
inline scalar Vector3::x() const { return m_x; }
|
|
inline scalar Vector3::y() const { return m_y; }
|
|
inline scalar Vector3::z() const { return m_z; }
|
|
|
|
inline const Vector2 & Vector3::xy() const
|
|
{
|
|
return *(Vector2 *)this;
|
|
}
|
|
|
|
inline scalar Vector3::component(uint idx) const
|
|
{
|
|
nvDebugCheck(idx < 3);
|
|
if (idx == 0) return m_x;
|
|
if (idx == 1) return m_y;
|
|
if (idx == 2) return m_z;
|
|
nvAssume(false);
|
|
return 0.0f;
|
|
}
|
|
|
|
inline void Vector3::setComponent(uint idx, float f)
|
|
{
|
|
nvDebugCheck(idx < 3);
|
|
if (idx == 0) m_x = f;
|
|
else if (idx == 1) m_y = f;
|
|
else if (idx == 2) m_z = f;
|
|
}
|
|
|
|
inline const scalar * Vector3::ptr() const
|
|
{
|
|
return &m_x;
|
|
}
|
|
|
|
inline void Vector3::set(scalar x, scalar y, scalar z)
|
|
{
|
|
m_x = x;
|
|
m_y = y;
|
|
m_z = z;
|
|
}
|
|
|
|
inline Vector3 Vector3::operator-() const
|
|
{
|
|
return Vector3(-m_x, -m_y, -m_z);
|
|
}
|
|
|
|
inline void Vector3::operator+=(Vector3::Arg v)
|
|
{
|
|
m_x += v.m_x;
|
|
m_y += v.m_y;
|
|
m_z += v.m_z;
|
|
}
|
|
|
|
inline void Vector3::operator-=(Vector3::Arg v)
|
|
{
|
|
m_x -= v.m_x;
|
|
m_y -= v.m_y;
|
|
m_z -= v.m_z;
|
|
}
|
|
|
|
inline void Vector3::operator*=(scalar s)
|
|
{
|
|
m_x *= s;
|
|
m_y *= s;
|
|
m_z *= s;
|
|
}
|
|
|
|
inline void Vector3::operator/=(scalar s)
|
|
{
|
|
float is = 1.0f / s;
|
|
m_x *= is;
|
|
m_y *= is;
|
|
m_z *= is;
|
|
}
|
|
|
|
inline void Vector3::operator*=(Vector3::Arg v)
|
|
{
|
|
m_x *= v.m_x;
|
|
m_y *= v.m_y;
|
|
m_z *= v.m_z;
|
|
}
|
|
|
|
inline bool operator==(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z;
|
|
}
|
|
inline bool operator!=(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return a.m_x != b.m_x || a.m_y != b.m_y || a.m_z != b.m_z;
|
|
}
|
|
|
|
|
|
// Vector4
|
|
|
|
inline Vector4::Vector4() {}
|
|
inline Vector4::Vector4(zero_t) : m_x(0.0f), m_y(0.0f), m_z(0.0f), m_w(0.0f) {}
|
|
inline Vector4::Vector4(scalar x, scalar y, scalar z, scalar w) : m_x(x), m_y(y), m_z(z), m_w(w) {}
|
|
inline Vector4::Vector4(Vector2::Arg v, scalar z, scalar w) : m_x(v.x()), m_y(v.y()), m_z(z), m_w(w) {}
|
|
inline Vector4::Vector4(Vector3::Arg v, scalar w) : m_x(v.x()), m_y(v.y()), m_z(v.z()), m_w(w) {}
|
|
inline Vector4::Vector4(Vector4::Arg v) : m_x(v.x()), m_y(v.y()), m_z(v.z()), m_w(v.w()) {}
|
|
|
|
inline const Vector4 & Vector4::operator=(const Vector4 & v)
|
|
{
|
|
m_x = v.m_x;
|
|
m_y = v.m_y;
|
|
m_z = v.m_z;
|
|
m_w = v.m_w;
|
|
return *this;
|
|
}
|
|
|
|
inline scalar Vector4::x() const { return m_x; }
|
|
inline scalar Vector4::y() const { return m_y; }
|
|
inline scalar Vector4::z() const { return m_z; }
|
|
inline scalar Vector4::w() const { return m_w; }
|
|
|
|
inline const Vector2 & Vector4::xy() const
|
|
{
|
|
return *(Vector2 *)this;
|
|
}
|
|
|
|
inline const Vector3 & Vector4::xyz() const
|
|
{
|
|
return *(Vector3 *)this;
|
|
}
|
|
|
|
inline scalar Vector4::component(uint idx) const
|
|
{
|
|
nvDebugCheck(idx < 4);
|
|
if (idx == 0) return x();
|
|
if (idx == 1) return y();
|
|
if (idx == 2) return z();
|
|
if (idx == 3) return w();
|
|
nvAssume(false);
|
|
return 0.0f;
|
|
}
|
|
|
|
inline void Vector4::setComponent(uint idx, float f)
|
|
{
|
|
nvDebugCheck(idx < 4);
|
|
if (idx == 0) m_x = f;
|
|
else if (idx == 1) m_y = f;
|
|
else if (idx == 2) m_z = f;
|
|
else if (idx == 3) m_w = f;
|
|
}
|
|
|
|
inline const scalar * Vector4::ptr() const
|
|
{
|
|
return &m_x;
|
|
}
|
|
|
|
inline void Vector4::set(scalar x, scalar y, scalar z, scalar w)
|
|
{
|
|
m_x = x;
|
|
m_y = y;
|
|
m_z = z;
|
|
m_w = w;
|
|
}
|
|
|
|
inline Vector4 Vector4::operator-() const
|
|
{
|
|
return Vector4(-m_x, -m_y, -m_z, -m_w);
|
|
}
|
|
|
|
inline void Vector4::operator+=(Vector4::Arg v)
|
|
{
|
|
m_x += v.m_x;
|
|
m_y += v.m_y;
|
|
m_z += v.m_z;
|
|
m_w += v.m_w;
|
|
}
|
|
|
|
inline void Vector4::operator-=(Vector4::Arg v)
|
|
{
|
|
m_x -= v.m_x;
|
|
m_y -= v.m_y;
|
|
m_z -= v.m_z;
|
|
m_w -= v.m_w;
|
|
}
|
|
|
|
inline void Vector4::operator*=(scalar s)
|
|
{
|
|
m_x *= s;
|
|
m_y *= s;
|
|
m_z *= s;
|
|
m_w *= s;
|
|
}
|
|
|
|
inline void Vector4::operator*=(Vector4::Arg v)
|
|
{
|
|
m_x *= v.m_x;
|
|
m_y *= v.m_y;
|
|
m_z *= v.m_z;
|
|
m_w *= v.m_w;
|
|
}
|
|
|
|
inline bool operator==(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z && a.m_w == b.m_w;
|
|
}
|
|
inline bool operator!=(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return a.m_x != b.m_x || a.m_y != b.m_y || a.m_z != b.m_z || a.m_w != b.m_w;
|
|
}
|
|
|
|
|
|
|
|
// Functions
|
|
|
|
|
|
// Vector2
|
|
|
|
inline Vector2 add(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return Vector2(a.x() + b.x(), a.y() + b.y());
|
|
}
|
|
inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return add(a, b);
|
|
}
|
|
|
|
inline Vector2 sub(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return Vector2(a.x() - b.x(), a.y() - b.y());
|
|
}
|
|
inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return sub(a, b);
|
|
}
|
|
|
|
inline Vector2 scale(Vector2::Arg v, scalar s)
|
|
{
|
|
return Vector2(v.x() * s, v.y() * s);
|
|
}
|
|
|
|
inline Vector2 scale(Vector2::Arg v, Vector2::Arg s)
|
|
{
|
|
return Vector2(v.x() * s.x(), v.y() * s.y());
|
|
}
|
|
|
|
inline Vector2 operator*(Vector2::Arg v, scalar s)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2)
|
|
{
|
|
return Vector2(v1.x()*v2.x(), v1.y()*v2.y());
|
|
}
|
|
|
|
inline Vector2 operator*(scalar s, Vector2::Arg v)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline scalar dot(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return a.x() * b.x() + a.y() * b.y();
|
|
}
|
|
|
|
inline scalar length_squared(Vector2::Arg v)
|
|
{
|
|
return v.x() * v.x() + v.y() * v.y();
|
|
}
|
|
|
|
inline scalar length(Vector2::Arg v)
|
|
{
|
|
return sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline scalar inverse_length(Vector2::Arg v)
|
|
{
|
|
return 1.0f / sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON)
|
|
{
|
|
return equal(length(v), 1, epsilon);
|
|
}
|
|
|
|
inline Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
nvDebugCheck(!isZero(l, epsilon));
|
|
Vector2 n = scale(v, 1.0f / l);
|
|
nvDebugCheck(isNormalized(n));
|
|
return n;
|
|
}
|
|
|
|
inline Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
if (isZero(l, epsilon)) {
|
|
return fallback;
|
|
}
|
|
return scale(v, 1.0f / l);
|
|
}
|
|
|
|
|
|
inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON)
|
|
{
|
|
return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon);
|
|
}
|
|
|
|
inline Vector2 min(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return Vector2(min(a.x(), b.x()), min(a.y(), b.y()));
|
|
}
|
|
|
|
inline Vector2 max(Vector2::Arg a, Vector2::Arg b)
|
|
{
|
|
return Vector2(max(a.x(), b.x()), max(a.y(), b.y()));
|
|
}
|
|
|
|
inline bool isValid(Vector2::Arg v)
|
|
{
|
|
return isFinite(v.x()) && isFinite(v.y());
|
|
}
|
|
|
|
|
|
// Vector3
|
|
|
|
inline Vector3 add(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return Vector3(a.x() + b.x(), a.y() + b.y(), a.z() + b.z());
|
|
}
|
|
inline Vector3 add(Vector3::Arg a, float b)
|
|
{
|
|
return Vector3(a.x() + b, a.y() + b, a.z() + b);
|
|
}
|
|
inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return add(a, b);
|
|
}
|
|
inline Vector3 operator+(Vector3::Arg a, float b)
|
|
{
|
|
return add(a, b);
|
|
}
|
|
|
|
inline Vector3 sub(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return Vector3(a.x() - b.x(), a.y() - b.y(), a.z() - b.z());
|
|
}
|
|
inline Vector3 sub(Vector3::Arg a, float b)
|
|
{
|
|
return Vector3(a.x() - b, a.y() - b, a.z() - b);
|
|
}
|
|
inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return sub(a, b);
|
|
}
|
|
inline Vector3 operator-(Vector3::Arg a, float b)
|
|
{
|
|
return sub(a, b);
|
|
}
|
|
|
|
inline Vector3 cross(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return Vector3(a.y() * b.z() - a.z() * b.y(), a.z() * b.x() - a.x() * b.z(), a.x() * b.y() - a.y() * b.x());
|
|
}
|
|
|
|
inline Vector3 scale(Vector3::Arg v, scalar s)
|
|
{
|
|
return Vector3(v.x() * s, v.y() * s, v.z() * s);
|
|
}
|
|
|
|
inline Vector3 scale(Vector3::Arg v, Vector3::Arg s)
|
|
{
|
|
return Vector3(v.x() * s.x(), v.y() * s.y(), v.z() * s.z());
|
|
}
|
|
|
|
inline Vector3 operator*(Vector3::Arg v, scalar s)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector3 operator*(scalar s, Vector3::Arg v)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector3 operator/(Vector3::Arg v, scalar s)
|
|
{
|
|
return scale(v, 1.0f/s);
|
|
}
|
|
|
|
inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, scalar s)
|
|
{
|
|
return Vector3(a.x() + b.x() * s, a.y() + b.y() * s, a.z() + b.z() * s);
|
|
}
|
|
|
|
inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, scalar t)
|
|
{
|
|
const scalar s = 1.0f - t;
|
|
return Vector3(v1.x() * s + t * v2.x(), v1.y() * s + t * v2.y(), v1.z() * s + t * v2.z());
|
|
}
|
|
|
|
inline scalar dot(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return a.x() * b.x() + a.y() * b.y() + a.z() * b.z();
|
|
}
|
|
|
|
inline scalar length_squared(Vector3::Arg v)
|
|
{
|
|
return v.x() * v.x() + v.y() * v.y() + v.z() * v.z();
|
|
}
|
|
|
|
inline scalar length(Vector3::Arg v)
|
|
{
|
|
return sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline scalar inverse_length(Vector3::Arg v)
|
|
{
|
|
return 1.0f / sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON)
|
|
{
|
|
return equal(length(v), 1, epsilon);
|
|
}
|
|
|
|
inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
nvDebugCheck(!isZero(l, epsilon));
|
|
Vector3 n = scale(v, 1.0f / l);
|
|
nvDebugCheck(isNormalized(n));
|
|
return n;
|
|
}
|
|
|
|
inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
if (isZero(l, epsilon)) {
|
|
return fallback;
|
|
}
|
|
return scale(v, 1.0f / l);
|
|
}
|
|
|
|
inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON)
|
|
{
|
|
return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon) && equal(v1.z(), v2.z(), epsilon);
|
|
}
|
|
|
|
inline Vector3 min(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return Vector3(min(a.x(), b.x()), min(a.y(), b.y()), min(a.z(), b.z()));
|
|
}
|
|
|
|
inline Vector3 max(Vector3::Arg a, Vector3::Arg b)
|
|
{
|
|
return Vector3(max(a.x(), b.x()), max(a.y(), b.y()), max(a.z(), b.z()));
|
|
}
|
|
|
|
inline Vector3 clamp(Vector3::Arg v, float min, float max)
|
|
{
|
|
return Vector3(clamp(v.x(), min, max), clamp(v.y(), min, max), clamp(v.z(), min, max));
|
|
}
|
|
|
|
inline bool isValid(Vector3::Arg v)
|
|
{
|
|
return isFinite(v.x()) && isFinite(v.y()) && isFinite(v.z());
|
|
}
|
|
|
|
/*
|
|
Vector3 transform(Quaternion, vector3);
|
|
Vector3 transform_point(matrix34, vector3);
|
|
Vector3 transform_vector(matrix34, vector3);
|
|
Vector3 transform_point(matrix44, vector3);
|
|
Vector3 transform_vector(matrix44, vector3);
|
|
*/
|
|
|
|
// Vector4
|
|
|
|
inline Vector4 add(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return Vector4(a.x() + b.x(), a.y() + b.y(), a.z() + b.z(), a.w() + b.w());
|
|
}
|
|
inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return add(a, b);
|
|
}
|
|
|
|
inline Vector4 sub(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return Vector4(a.x() - b.x(), a.y() - b.y(), a.z() - b.z(), a.w() - b.w());
|
|
}
|
|
inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return sub(a, b);
|
|
}
|
|
|
|
inline Vector4 scale(Vector4::Arg v, scalar s)
|
|
{
|
|
return Vector4(v.x() * s, v.y() * s, v.z() * s, v.w() * s);
|
|
}
|
|
|
|
inline Vector4 scale(Vector4::Arg v, Vector4::Arg s)
|
|
{
|
|
return Vector4(v.x() * s.x(), v.y() * s.y(), v.z() * s.z(), v.w() * s.w());
|
|
}
|
|
|
|
inline Vector4 operator*(Vector4::Arg v, scalar s)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector4 operator*(scalar s, Vector4::Arg v)
|
|
{
|
|
return scale(v, s);
|
|
}
|
|
|
|
inline Vector4 operator/(Vector4::Arg v, scalar s)
|
|
{
|
|
return scale(v, 1.0f/s);
|
|
}
|
|
|
|
inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, scalar s)
|
|
{
|
|
return Vector4(a.x() + b.x() * s, a.y() + b.y() * s, a.z() + b.z() * s, a.w() + b.w() * s);
|
|
}
|
|
|
|
inline scalar dot(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return a.x() * b.x() + a.y() * b.y() + a.z() * b.z() + a.w() * b.w();
|
|
}
|
|
|
|
inline scalar length_squared(Vector4::Arg v)
|
|
{
|
|
return v.x() * v.x() + v.y() * v.y() + v.z() * v.z() + v.w() * v.w();
|
|
}
|
|
|
|
inline scalar length(Vector4::Arg v)
|
|
{
|
|
return sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline scalar inverse_length(Vector4::Arg v)
|
|
{
|
|
return 1.0f / sqrtf(length_squared(v));
|
|
}
|
|
|
|
inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON)
|
|
{
|
|
return equal(length(v), 1, epsilon);
|
|
}
|
|
|
|
inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
nvDebugCheck(!isZero(l, epsilon));
|
|
Vector4 n = scale(v, 1.0f / l);
|
|
nvDebugCheck(isNormalized(n));
|
|
return n;
|
|
}
|
|
|
|
inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON)
|
|
{
|
|
float l = length(v);
|
|
if (isZero(l, epsilon)) {
|
|
return fallback;
|
|
}
|
|
return scale(v, 1.0f / l);
|
|
}
|
|
|
|
inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON)
|
|
{
|
|
return equal(v1.x(), v2.x(), epsilon) && equal(v1.y(), v2.y(), epsilon) && equal(v1.z(), v2.z(), epsilon) && equal(v1.w(), v2.w(), epsilon);
|
|
}
|
|
|
|
inline Vector4 min(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return Vector4(min(a.x(), b.x()), min(a.y(), b.y()), min(a.z(), b.z()), min(a.w(), b.w()));
|
|
}
|
|
|
|
inline Vector4 max(Vector4::Arg a, Vector4::Arg b)
|
|
{
|
|
return Vector4(max(a.x(), b.x()), max(a.y(), b.y()), max(a.z(), b.z()), max(a.w(), b.w()));
|
|
}
|
|
|
|
inline bool isValid(Vector4::Arg v)
|
|
{
|
|
return isFinite(v.x()) && isFinite(v.y()) && isFinite(v.z()) && isFinite(v.w());
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
vector4 transform(matrix34, vector4);
|
|
vector4 transform(matrix44, vector4);
|
|
*/
|
|
|
|
/*
|
|
Quaternion mul(Quaternion, Quaternion); // rotational composition
|
|
Quaternion conjugate(Quaternion);
|
|
Quaternion inverse(Quaternion);
|
|
Quaternion axis_angle(const Vector3 & v, scalar s);
|
|
*/
|
|
|
|
/*
|
|
matrix34 add(matrix34, matrix34); // note: implicit '1' stays as '1'
|
|
matrix34 operator+(matrix34, matrix34);
|
|
matrix34 sub(matrix34, matrix34); // note: implicit '1' stays as '1'
|
|
matrix34 operator-(matrix34, matrix34);
|
|
matrix34 mul(matrix34, matrix34);
|
|
matrix34 operator*(matrix34, matrix34);
|
|
matrix34 mul(matrix34, quaternion4); // rotation multiplication
|
|
matrix34 operator*(matrix34, quaternion4); // rotation multiplication
|
|
matrix34 translation(vector3);
|
|
matrix34 rotation(quaternion4);
|
|
matrix34 rotation(vector3, scalar); // axis/angle
|
|
|
|
matrix44 add(matrix44, matrix44);
|
|
matrix44 operator+(matrix44, matrix44);
|
|
matrix44 sub(matrix44, matrix44);
|
|
matrix44 operator-(matrix44, matrix44);
|
|
matrix44 mul(matrix44, matrix44);
|
|
matrix44 operator*(matrix44, matrix44);
|
|
matrix44 mul(matrix44, quaternion4); // rotation multiplication
|
|
matrix44 operator*(matrix44, quaternion4); // rotation multiplication
|
|
matrix44 invert(matrix34);
|
|
matrix44 invert(matrix44);
|
|
matrix44 transpose(matrix34);
|
|
matrix44 transpose(matrix44);
|
|
*/
|
|
|
|
} // nv namespace
|
|
|
|
#endif // NV_MATH_VECTOR_H
|