|
|
|
#ifndef FLOATS_HPP
|
|
|
|
#define FLOATS_HPP
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
inline float clamp(float f, float min, float max) { return (f < min) ? min : ((f > max) ? max : f); }
|
|
|
|
inline float saturate(float f) { return clamp(f, 0.0f, 1.0f); }
|
|
|
|
inline float lerp(float f1, float f2, float f) { return f1 + (f2 - f1) * f; }
|
|
|
|
inline float min(float f1, float f2) { return f1 < f2 ? f1 : f2; }
|
|
|
|
inline float max(float f1, float f2) { return f1 > f2 ? f1 : f2; }
|
|
|
|
inline float sign(float f) { return (f == 0.0f) ? 0.0f : ((f > 0.0f) ? 1.0f : -1.0f); }
|
|
|
|
|
|
|
|
// Vectors --------------------------------------------------------------------
|
|
|
|
|
|
|
|
// 2-dimensional vector -------------------------------------------------------
|
|
|
|
|
|
|
|
struct float2 {
|
|
|
|
typedef float value_type;
|
|
|
|
float x, y;
|
|
|
|
|
|
|
|
inline float2() : x(0.0), y(0.0) {}
|
|
|
|
inline float2(float f) : x(f), y(f) {}
|
|
|
|
constexpr inline float2(float x_, float y_) : x(x_), y(y_) {}
|
|
|
|
float2(const struct float3& v);
|
|
|
|
float2(const struct float4& v);
|
|
|
|
|
|
|
|
inline float2 operator +() const { return *this; }
|
|
|
|
inline float2 operator -() const { return float2(-x, -y); }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator ==(const float2& v1, const float2& v2) { return v1.x == v2.x && v1.y == v2.y; }
|
|
|
|
inline bool operator !=(const float2& v1, const float2& v2) { return v1.x != v2.x || v1.y != v2.y; }
|
|
|
|
|
|
|
|
inline float2 operator +(const float2& v1, const float2& v2) { return float2(v1.x + v2.x, v1.y + v2.y); }
|
|
|
|
inline float2 operator -(const float2& v1, const float2& v2) { return float2(v1.x - v2.x, v1.y - v2.y); }
|
|
|
|
inline float2 operator *(const float2& v1, const float2& v2) { return float2(v1.x * v2.x, v1.y * v2.y); }
|
|
|
|
inline float2 operator /(const float2& v1, const float2& v2) { return float2(v1.x / v2.x, v1.y / v2.y); }
|
|
|
|
|
|
|
|
inline float2 operator +(const float2& v, float f) { return float2(v.x + f, v.y + f); }
|
|
|
|
inline float2 operator +(float f, const float2& v) { return float2(v.x + f, v.y + f); }
|
|
|
|
inline float2 operator -(const float2& v, float f) { return float2(v.x - f, v.y - f); }
|
|
|
|
inline float2 operator -(float f, const float2& v) { return float2(f - v.x, f - v.y); }
|
|
|
|
inline float2 operator *(const float2& v, float f) { return float2(v.x * f, v.y * f); }
|
|
|
|
inline float2 operator *(float f, const float2& v) { return float2(v.x * f, v.y * f); }
|
|
|
|
inline float2 operator /(const float2& v, float f) { float inv = 1.0f / f; return float2(v.x * inv, v.y * inv); }
|
|
|
|
inline float2 operator /(float f, const float2& v) { return float2(f / v.x, f / v.y); }
|
|
|
|
|
|
|
|
inline float dot(const float2& v1, const float2& v2) { return v1.x * v2.x + v1.y * v2.y; }
|
|
|
|
inline float lengthsq(const float2& v) { return dot(v, v); }
|
|
|
|
inline float length(const float2& v) { return sqrt(lengthsq(v)); }
|
|
|
|
inline float2 lerp(const float2& v1, const float2& v2, float f) { return v1 + (v2 - v1) * f; }
|
|
|
|
inline float2 normalize(const float2& v) { return v * (1.0f / length(v)); }
|
|
|
|
inline float2 min(const float2& v1, const float2& v2) { return float2(min(v1.x, v2.x), min(v1.y, v2.y)); }
|
|
|
|
inline float2 max(const float2& v1, const float2& v2) { return float2(max(v1.x, v2.x), max(v1.y, v2.y)); }
|
|
|
|
inline float2 abs(const float2& v) { return float2(fabs(v.x), fabs(v.y)); }
|
|
|
|
|
|
|
|
inline float dist(const float2& v1, const float2& v2) { return sqrt(pow((v2.x - v1.x),2) + pow((v2.y - v1.y),2)); }
|
|
|
|
|
|
|
|
|
|
|
|
// 3-dimensional vector -------------------------------------------------------
|
|
|
|
|
|
|
|
struct float3 {
|
|
|
|
float x, y, z;
|
|
|
|
|
|
|
|
inline float3() : x(0.0), y(0.0), z(0.0) {}
|
|
|
|
inline float3(float f) : x(f), y(f), z(f) {}
|
|
|
|
inline float3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {}
|
|
|
|
inline float3(const float2& v, float z_) : x(v.x), y(v.y), z(z_) {}
|
|
|
|
float3(const struct float4& v);
|
|
|
|
|
|
|
|
inline float3 operator +() const { return *this; }
|
|
|
|
inline float3 operator -() const { return float3(-x, -y, -z); }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float3 operator +(const float3& v1, const float3& v2) { return float3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); }
|
|
|
|
inline float3 operator -(const float3& v1, const float3& v2) { return float3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); }
|
|
|
|
inline float3 operator *(const float3& v1, const float3& v2) { return float3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); }
|
|
|
|
inline float3 operator /(const float3& v1, const float3& v2) { return float3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); }
|
|
|
|
|
|
|
|
inline float3 operator +(const float3& v, float f) { return float3(v.x + f, v.y + f, v.z + f); }
|
|
|
|
inline float3 operator +(float f, const float3& v) { return float3(v.x + f, v.y + f, v.z + f); }
|
|
|
|
inline float3 operator -(const float3& v, float f) { return float3(v.x - f, v.y - f, v.z - f); }
|
|
|
|
inline float3 operator -(float f, const float3& v) { return float3(f - v.x, f - v.y, f - v.z); }
|
|
|
|
inline float3 operator *(const float3& v, float f) { return float3(v.x * f, v.y * f, v.z * f); }
|
|
|
|
inline float3 operator *(float f, const float3& v) { return float3(v.x * f, v.y * f, v.z * f); }
|
|
|
|
inline float3 operator /(const float3& v, float f) { float inv = 1.0f / f; return float3(v.x * inv, v.y * inv, v.z * inv); }
|
|
|
|
inline float3 operator /(float f, const float3& v) { return float3(f / v.x, f / v.y, f / v.z); }
|
|
|
|
|
|
|
|
inline float3 cross(const float3& v1, const float3& v2) { return float3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); }
|
|
|
|
inline float dot(const float3& v1, const float3& v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; }
|
|
|
|
inline float lengthsq(const float3& v) { return dot(v, v); }
|
|
|
|
inline float length(const float3& v) { return sqrt(lengthsq(v)); }
|
|
|
|
inline float3 lerp(const float3& v1, const float3& v2, float f) { return v1 + (v2 - v1) * f; }
|
|
|
|
inline float3 normalize(const float3& v) { return v * (1.0f / length(v)); }
|
|
|
|
inline float3 min(const float3& v1, const float3& v2) { return float3(min(v1.x, v2.x), min(v1.y, v2.y), min(v1.z, v2.z)); }
|
|
|
|
inline float3 max(const float3& v1, const float3& v2) { return float3(max(v1.x, v2.x), max(v1.y, v2.y), max(v1.z, v2.z)); }
|
|
|
|
inline float3 abs(const float3& v) { return float3(fabs(v.x), fabs(v.y), fabs(v.z)); }
|
|
|
|
|
|
|
|
inline float dist(const float3& v1, const float3& v2) { return sqrt(pow((v2.x - v1.x),2) + pow((v2.y - v1.y),2) + pow((v2.z - v1.z),2)); }
|
|
|
|
|
|
|
|
|
|
|
|
// 4-dimensional vector -------------------------------------------------------
|
|
|
|
|
|
|
|
struct float4 {
|
|
|
|
float x, y, z, w;
|
|
|
|
|
|
|
|
inline float4() : x(0.0), y(0.0), z(0.0), w(0.0) {}
|
|
|
|
inline float4(float f) : x(f), y(f), z(f), w(f) {}
|
|
|
|
inline float4(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_) {}
|
|
|
|
inline float4(const float2& v, float z_, float w_) : x(v.x), y(v.y), z(z_), w(w_) {}
|
|
|
|
inline float4(const float3& v, float w_) : x(v.x), y(v.y), z(v.z), w(w_) {}
|
|
|
|
|
|
|
|
inline float4 operator +() const { return *this; }
|
|
|
|
inline float4 operator -() const { return float4(-x, -y, -z, -w); }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float4 operator +(const float4& v1, const float4& v2) { return float4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); }
|
|
|
|
inline float4 operator -(const float4& v1, const float4& v2) { return float4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); }
|
|
|
|
inline float4 operator *(const float4& v1, const float4& v2) { return float4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); }
|
|
|
|
inline float4 operator /(const float4& v1, const float4& v2) { return float4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w); }
|
|
|
|
|
|
|
|
inline float4 operator +(const float4& v, float f) { return float4(v.x + f, v.y + f, v.z + f, v.w + f); }
|
|
|
|
inline float4 operator +(float f, const float4& v) { return float4(v.x + f, v.y + f, v.z + f, v.w + f); }
|
|
|
|
inline float4 operator -(const float4& v, float f) { return float4(v.x - f, v.y - f, v.z - f, v.w - f); }
|
|
|
|
inline float4 operator -(float f, const float4& v) { return float4(f - v.x, f - v.y, f - v.z, f - v.w); }
|
|
|
|
inline float4 operator *(const float4& v, float f) { return float4(v.x * f, v.y * f, v.z * f, v.w * f); }
|
|
|
|
inline float4 operator *(float f, const float4& v) { return float4(v.x * f, v.y * f, v.z * f, v.w * f); }
|
|
|
|
inline float4 operator /(const float4& v, float f) { float inv = 1.0f / f; return float4(v.x * inv, v.y * inv, v.z * inv, v.w * inv); }
|
|
|
|
inline float4 operator /(float f, const float4& v) { return float4(f / v.x, f / v.y, f / v.z, f / v.w); }
|
|
|
|
|
|
|
|
inline float dot(const float4& v1, const float4& v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; }
|
|
|
|
inline float lengthsq(const float4& v) { return dot(v, v); }
|
|
|
|
inline float length(const float4& v) { return sqrt(lengthsq(v)); }
|
|
|
|
inline float4 lerp(const float4& v1, const float4& v2, float f) { return v1 + (v2 - v1) * f; }
|
|
|
|
inline float4 normalize(const float4& v) { return v * (1.0f / length(v)); }
|
|
|
|
inline float4 min(const float4& v1, const float4& v2) { return float4(min(v1.x, v2.x), min(v1.y, v2.y), min(v1.z, v2.z), min(v1.w, v2.w)); }
|
|
|
|
inline float4 max(const float4& v1, const float4& v2) { return float4(max(v1.x, v2.x), max(v1.y, v2.y), max(v1.z, v2.z), max(v1.w, v2.w)); }
|
|
|
|
inline float4 abs(const float4& v) { return float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w)); }
|
|
|
|
|
|
|
|
inline float dist(const float4& v1, const float4& v2) { return sqrt(pow((v2.x - v1.x),2) + pow((v2.y - v1.y),2) + pow((v2.z - v1.z),2) + pow((v2.w - v1.w),2)); }
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
inline float2::float2(const struct float3& v) : x(v.x), y(v.y) { }
|
|
|
|
inline float2::float2(const struct float4& v) : x(v.x), y(v.y) { }
|
|
|
|
|
|
|
|
inline float3::float3(const struct float4& v) : x(v.x), y(v.y), z(v.z) { }
|
|
|
|
|
|
|
|
// Matrices -------------------------------------------------------------------
|
|
|
|
|
|
|
|
// 2x2-matrix -----------------------------------------------------------------
|
|
|
|
|
|
|
|
struct float2x2 {
|
|
|
|
float2 s, t; // rows
|
|
|
|
|
|
|
|
inline float2x2() : s(), t() {}
|
|
|
|
inline float2x2(const float2& s_, const float2& t_) : s(s_), t(t_) {}
|
|
|
|
inline float2x2(float sx, float sy,
|
|
|
|
float tx, float ty) : s(sx, sy), t(tx, ty) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float2x2 transpose(const float2x2& m) { return float2x2(float2(m.s.x, m.t.x), float2(m.s.y, m.t.y)); }
|
|
|
|
|
|
|
|
inline float2x2 operator *(const float2x2& m1, const float2x2& m2) {
|
|
|
|
const float2x2 m3 = transpose(m2);
|
|
|
|
return float2x2(float2(dot(m1.s, m3.s), dot(m1.s, m3.t)),
|
|
|
|
float2(dot(m1.t, m3.s), dot(m1.t, m3.t)));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float2 operator *(const float2x2& m, const float2& v) { return float2(dot(m.s, v), dot(m.t, v)); }
|
|
|
|
inline float2x2 operator *(const float2x2& m, float f) { return float2x2(m.s * f, m.t * f); }
|
|
|
|
inline float2x2 operator *(float f, const float2x2& m) { return float2x2(m.s * f, m.t * f); }
|
|
|
|
|
|
|
|
inline float determinant(const float2x2& m) { return m.s.x * m.t.y - m.s.y * m.t.x; }
|
|
|
|
inline float2x2 inverse(const float2x2& m) { return float2x2(float2(m.t.y, -m.s.y), float2(-m.t.x, m.s.x)) * (1.0f / determinant(m)); }
|
|
|
|
|
|
|
|
// 3x3-matrix -----------------------------------------------------------------
|
|
|
|
|
|
|
|
struct float3x3 {
|
|
|
|
float3 s, t, u; // rows
|
|
|
|
|
|
|
|
inline float3x3() : s(), t(), u() {}
|
|
|
|
inline float3x3(const float3& s_, const float3& t_, const float3& u_) : s(s_), t(t_), u(u_) {}
|
|
|
|
inline float3x3(float sx, float sy, float sz,
|
|
|
|
float tx, float ty, float tz,
|
|
|
|
float ux, float uy, float uz) : s(sx, sy, sz), t(tx, ty, tz), u(ux, uy, uz) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float3x3 transpose(const float3x3& m) {
|
|
|
|
return float3x3(float3(m.s.x, m.t.x, m.u.x),
|
|
|
|
float3(m.s.y, m.t.y, m.u.y),
|
|
|
|
float3(m.s.z, m.t.z, m.u.z));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float3x3 operator *(const float3x3& m1, const float3x3& m2) {
|
|
|
|
const float3x3 m3 = transpose(m2);
|
|
|
|
return float3x3(float3(dot(m1.s, m3.s), dot(m1.s, m3.t), dot(m1.s, m3.u)),
|
|
|
|
float3(dot(m1.t, m3.s), dot(m1.t, m3.t), dot(m1.t, m3.u)),
|
|
|
|
float3(dot(m1.u, m3.s), dot(m1.u, m3.t), dot(m1.u, m3.u)));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float3 operator *(const float3x3& m, const float3& v) { return float3(dot(m.s, v), dot(m.t, v), dot(m.u, v)); }
|
|
|
|
inline float3x3 operator *(const float3x3& m, float f) { return float3x3(m.s * f, m.t * f, m.u * f); }
|
|
|
|
inline float3x3 operator *(float f, const float3x3& m) { return float3x3(m.s * f, m.t * f, m.u * f); }
|
|
|
|
|
|
|
|
inline float determinant(const float3x3& m) {
|
|
|
|
return m.s.x * determinant(float2x2(m.t.y, m.t.z, m.u.y, m.u.z))
|
|
|
|
- m.s.y * determinant(float2x2(m.t.x, m.t.z, m.u.x, m.u.z))
|
|
|
|
+ m.s.z * determinant(float2x2(m.t.x, m.t.y, m.u.x, m.u.y));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float3x3 inverse(const float3x3& m) {
|
|
|
|
return float3x3(
|
|
|
|
determinant(float2x2(m.t.y, m.t.z, m.u.y, m.u.z)),
|
|
|
|
determinant(float2x2(m.s.z, m.s.y, m.u.z, m.u.y)),
|
|
|
|
determinant(float2x2(m.s.y, m.s.z, m.t.y, m.t.z)),
|
|
|
|
|
|
|
|
determinant(float2x2(m.t.z, m.t.x, m.u.z, m.u.x)),
|
|
|
|
determinant(float2x2(m.s.x, m.s.z, m.u.x, m.u.z)),
|
|
|
|
determinant(float2x2(m.s.z, m.s.x, m.t.z, m.t.x)),
|
|
|
|
|
|
|
|
determinant(float2x2(m.t.x, m.t.y, m.u.x, m.u.y)),
|
|
|
|
determinant(float2x2(m.s.y, m.s.x, m.u.y, m.u.x)),
|
|
|
|
determinant(float2x2(m.s.x, m.s.y, m.t.x, m.t.y)))
|
|
|
|
|
|
|
|
* (1.0f / determinant(m));
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4x4-matrix -----------------------------------------------------------------
|
|
|
|
|
|
|
|
struct float4x4 {
|
|
|
|
float4 s, t, u, v; // rows
|
|
|
|
|
|
|
|
inline float4x4() : s(), t(), u(), v() {}
|
|
|
|
inline float4x4(const float4& s_, const float4& t_, const float4& u_, const float4& v_) : s(s_), t(t_), u(u_), v(v_) {}
|
|
|
|
inline float4x4(float sx, float sy, float sz, float sw,
|
|
|
|
float tx, float ty, float tz, float tw,
|
|
|
|
float ux, float uy, float uz, float uw,
|
|
|
|
float vx, float vy, float vz, float vw) : s(sx, sy, sz, sw), t(tx, ty, tz, tw), u(ux, uy, uz, uw), v(vx, vy, vz, vw) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float4x4 transpose(const float4x4& m) {
|
|
|
|
return float4x4(float4(m.s.x, m.t.x, m.u.x, m.v.x),
|
|
|
|
float4(m.s.y, m.t.y, m.u.y, m.v.y),
|
|
|
|
float4(m.s.z, m.t.z, m.u.z, m.v.z),
|
|
|
|
float4(m.s.w, m.t.w, m.u.w, m.v.w));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float4x4 operator *(const float4x4& m1, const float4x4& m2) {
|
|
|
|
const float4x4 m3 = transpose(m2);
|
|
|
|
return float4x4(float4(dot(m1.s, m3.s), dot(m1.s, m3.t), dot(m1.s, m3.u), dot(m1.s, m3.v)),
|
|
|
|
float4(dot(m1.t, m3.s), dot(m1.t, m3.t), dot(m1.t, m3.u), dot(m1.t, m3.v)),
|
|
|
|
float4(dot(m1.u, m3.s), dot(m1.u, m3.t), dot(m1.u, m3.u), dot(m1.u, m3.v)),
|
|
|
|
float4(dot(m1.v, m3.s), dot(m1.v, m3.t), dot(m1.v, m3.u), dot(m1.v, m3.v)));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float4 operator *(const float4x4& m, const float4& v) { return float4(dot(m.s, v), dot(m.t, v), dot(m.u, v), dot(m.v, v)); }
|
|
|
|
inline float4x4 operator *(const float4x4& m, float f) { return float4x4(m.s * f, m.t * f, m.u * f, m.v * f); }
|
|
|
|
inline float4x4 operator *(float f, const float4x4& m) { return float4x4(m.s * f, m.t * f, m.u * f, m.v * f); }
|
|
|
|
|
|
|
|
inline float determinant(const float4x4& m) {
|
|
|
|
return m.s.x * determinant(float3x3(m.t.y, m.u.y, m.v.y, m.t.z, m.u.z, m.v.z, m.t.w, m.u.w, m.v.w))
|
|
|
|
- m.s.y * determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.z, m.u.z, m.v.z, m.t.w, m.u.w, m.v.w))
|
|
|
|
+ m.s.z * determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.y, m.u.y, m.v.y, m.t.w, m.u.w, m.v.w))
|
|
|
|
- m.s.w * determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.y, m.u.y, m.v.y, m.t.z, m.u.z, m.v.z));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float4x4 inverse(const float4x4& m) {
|
|
|
|
return float4x4(
|
|
|
|
determinant(float3x3(m.t.y, m.u.y, m.v.y, m.t.z, m.u.z, m.v.z, m.t.w, m.u.w, m.v.w)),
|
|
|
|
-determinant(float3x3(m.s.y, m.u.y, m.v.y, m.s.z, m.u.z, m.v.z, m.s.w, m.u.w, m.v.w)),
|
|
|
|
determinant(float3x3(m.s.y, m.t.y, m.v.y, m.s.z, m.t.z, m.v.z, m.s.w, m.t.w, m.v.w)),
|
|
|
|
-determinant(float3x3(m.s.y, m.t.y, m.u.y, m.s.z, m.t.z, m.u.z, m.s.w, m.t.w, m.u.w)),
|
|
|
|
|
|
|
|
-determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.z, m.u.z, m.v.z, m.t.w, m.u.w, m.v.w)),
|
|
|
|
determinant(float3x3(m.s.x, m.u.x, m.v.x, m.s.z, m.u.z, m.v.z, m.s.w, m.u.w, m.v.w)),
|
|
|
|
-determinant(float3x3(m.s.x, m.t.x, m.v.x, m.s.z, m.t.z, m.v.z, m.s.w, m.t.w, m.v.w)),
|
|
|
|
determinant(float3x3(m.s.x, m.t.x, m.u.x, m.s.z, m.t.z, m.u.z, m.s.w, m.t.w, m.u.w)),
|
|
|
|
|
|
|
|
determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.y, m.u.y, m.v.y, m.t.w, m.u.w, m.v.w)),
|
|
|
|
-determinant(float3x3(m.s.x, m.u.x, m.v.x, m.s.y, m.u.y, m.v.y, m.s.w, m.u.w, m.v.w)),
|
|
|
|
determinant(float3x3(m.s.x, m.t.x, m.v.x, m.s.y, m.t.y, m.v.y, m.s.w, m.t.w, m.v.w)),
|
|
|
|
-determinant(float3x3(m.s.x, m.t.x, m.u.x, m.s.y, m.t.y, m.u.y, m.s.w, m.t.w, m.u.w)),
|
|
|
|
|
|
|
|
-determinant(float3x3(m.t.x, m.u.x, m.v.x, m.t.y, m.u.y, m.v.y, m.t.z, m.u.z, m.v.z)),
|
|
|
|
determinant(float3x3(m.s.x, m.u.x, m.v.x, m.s.y, m.u.y, m.v.y, m.s.z, m.u.z, m.v.z)),
|
|
|
|
-determinant(float3x3(m.s.x, m.t.x, m.v.x, m.s.y, m.t.y, m.v.y, m.s.z, m.t.z, m.v.z)),
|
|
|
|
determinant(float3x3(m.s.x, m.t.x, m.u.x, m.s.y, m.t.y, m.u.y, m.s.z, m.t.z, m.u.z)))
|
|
|
|
|
|
|
|
* (1.0f / determinant(m));
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // FLOATS_HPP
|
|
|
|
|