init commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
typedef int64_t ifloat_t;
|
||||
//typedef int64_t ifloat2_t[2];
|
||||
//typedef int64_t ifloat3_t[3];
|
||||
|
||||
#define IFLOAT_SHIFT (16)
|
||||
#define IFLOAT_SCALE ((float64_t)(1<<IFLOAT_SHIFT))
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline ifloat_t ifloat_init(float32_t a)
|
||||
{
|
||||
return (ifloat_t)((float64_t)a * IFLOAT_SCALE + 0.5);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline ifloat_t ifloat_init(int32_t a)
|
||||
{
|
||||
return (int64_t)(a)<< IFLOAT_SHIFT;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline float32_t ifloat_get_float(ifloat_t a)
|
||||
{
|
||||
return (float32_t)((float64_t)a/ IFLOAT_SCALE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline ifloat_t ifloat_multiply(ifloat_t a, ifloat_t b)
|
||||
{
|
||||
return (ifloat_t)((a * b) >> IFLOAT_SHIFT);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
//inline void ifloat3_add(ifloat3_t& a, const ifloat3_t& b)
|
||||
//{
|
||||
// a[0] += b[0]; a[1] += b[1]; a[2] += b[2];
|
||||
//}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
//inline void ifloat3_sub(ifloat3_t& a, const ifloat3_t& b)
|
||||
//{
|
||||
// a[0] -= b[0]; a[1] -= b[1]; a[2] -= b[2];
|
||||
//}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
//inline void ifloat3_cpy(ifloat3_t& a, const ifloat3_t& b)
|
||||
//{
|
||||
// a[0] = b[0]; a[1] = b[1]; a[2] = b[2];
|
||||
//}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
struct ifloat2_t
|
||||
{
|
||||
ifloat_t x, y;
|
||||
|
||||
ifloat2_t() : x(0ll), y(0ll) {}
|
||||
ifloat2_t(const ifloat2_t& other) : x(other.x), y(other.y) {}
|
||||
ifloat2_t(float32_t _x, float32_t _y) : x(ifloat_init(_x)), y(ifloat_init(_y)) {}
|
||||
};
|
||||
|
||||
struct ifloat3_t
|
||||
{
|
||||
ifloat_t x, y, z;
|
||||
|
||||
inline void add(const ifloat3_t& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
z += other.z;
|
||||
}
|
||||
|
||||
inline void sub(const ifloat3_t& other) {
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
z -= other.z;
|
||||
}
|
||||
|
||||
inline ifloat_t operator [] (const size_t i) const {
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline ifloat_t& operator [] (const size_t i) {
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
ifloat3_t() : x(0ll), y(0ll), z(0ll) {}
|
||||
ifloat3_t(const ifloat3_t& other) : x(other.x), y(other.y), z(other.z) {}
|
||||
ifloat3_t(float32_t _x, float32_t _y, float32_t _z) : x(ifloat_init(_x)), y(ifloat_init(_y)), z(ifloat_init(_z)) {}
|
||||
ifloat3_t(ifloat_t _x, ifloat_t _y, ifloat_t _z) : x(_x), y(_y), z(_z) {}
|
||||
};
|
||||
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
class MathUtil
|
||||
{
|
||||
public:
|
||||
static size_t ComponentSize(ComponentType ct);
|
||||
static size_t DataTypeSize(DataType dt);
|
||||
|
||||
static bool floatEqual(float a, float b,
|
||||
float tolerance = std::numeric_limits<float>::epsilon()) {
|
||||
return std::abs(b - a) <= tolerance;
|
||||
}
|
||||
|
||||
//Square root function.
|
||||
static float sqrt(float f) {
|
||||
return std::sqrt(f);
|
||||
}
|
||||
|
||||
//min
|
||||
template<typename V>
|
||||
static V min2(const V& v1, const V& v2) {
|
||||
return (v1 < v2) ? v1 : v2;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
static V min3(const V& v1, const V& v2, const V& v3) {
|
||||
return (v1 < v2) ? ((v1 < v3) ? v1 : v3) : ((v2 < v3) ? v2 : v3);
|
||||
}
|
||||
|
||||
//max
|
||||
template<typename V>
|
||||
static V max2(const V& v1, const V& v2) {
|
||||
return (v1 > v2) ? v1 : v2;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
static V max3(const V& v1, const V& v2, const V& v3) {
|
||||
return (v1 > v2) ? ((v1 > v3) ? v1 : v3) : ((v2 > v3) ? v2 : v3);
|
||||
}
|
||||
|
||||
/* Simulate the shader function lerp which performers linear interpolation
|
||||
given 3 parameters v0, v1 and t the function returns the value of (1 - t)* v0 + t * v1.
|
||||
where v0 and v1 are matching vector or scalar types and t can be either a scalar or a
|
||||
vector of the same type as a and b.
|
||||
*/
|
||||
template <typename V, typename T>
|
||||
static V lerp(const V& v0, const V& v1, const T& t) {
|
||||
return v0 * (1 - t) + v1 * t;
|
||||
}
|
||||
|
||||
template <typename V, typename T>
|
||||
static V lerp3(const V& v0, const V& v1, const V& v2, const T& t) {
|
||||
return v0 * t[0] + v1 * t[1] + v2 * t[2];
|
||||
}
|
||||
|
||||
// A random number in the range from [0,1]
|
||||
static float DV_CORE_API unitRandom(void);
|
||||
// A random number in the range from [low, high].
|
||||
static float rangeRandom(float low, float high) {
|
||||
return (high - low)*unitRandom() + low;
|
||||
}
|
||||
static int32_t rangeRandom(int32_t low, int32_t high) {
|
||||
return ((high - low) >= RAND_MAX) ? ((rand()<<16|rand()) % (high - low) + low) : (rand() % (high - low) + low);
|
||||
}
|
||||
//clamps the specified value within the range of min to max.
|
||||
template <typename T>
|
||||
static T saturate(T v, const T& min=(T)0, const T& max=(T)1) {
|
||||
return (v < min) ? min : ((v > max) ? max : v);
|
||||
}
|
||||
|
||||
//cosine function
|
||||
static float cos(float a) {
|
||||
return std::cos(a);
|
||||
}
|
||||
//Sine function
|
||||
static float sin(float a) {
|
||||
return std::sin(a);
|
||||
}
|
||||
|
||||
//return a right-handed, look-at matrix.
|
||||
template<typename T>
|
||||
static TMatrix4<T> lookatRH(const TVector3<T>& eye, const TVector3<T>& lookat, const TVector3<T>& up);
|
||||
|
||||
//return a right-handed perspective projection matrix based on a field of view.
|
||||
template<typename T>
|
||||
static TMatrix4<T> perspectiveFovRH(T fov, T aspect, T zNear, T zFar);
|
||||
|
||||
static DV_CORE_API const float POS_INFINITY;
|
||||
static DV_CORE_API const float NEG_INFINITY;
|
||||
static DV_CORE_API const float PI;
|
||||
static DV_CORE_API const float PI_X2;
|
||||
static DV_CORE_API const float PI_DIV2;
|
||||
static DV_CORE_API const float PI_DIV4;
|
||||
static DV_CORE_API const float fDeg2Rad;
|
||||
static DV_CORE_API const float fRad2Deg;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> MathUtil::lookatRH(const TVector3<T>& eye, const TVector3<T>& lookat, const TVector3<T>& up)
|
||||
{
|
||||
assert(lookat != eye);
|
||||
assert(up != TVector3<T>::ZERO);
|
||||
|
||||
TVector3<T> zaxis = (eye - lookat).normalise();
|
||||
TVector3<T> xaxis = up.crossProduct(zaxis).normalise();
|
||||
TVector3<T> yaxis = zaxis.crossProduct(xaxis).normalise();
|
||||
|
||||
return TMatrix4<T>(
|
||||
xaxis.x, xaxis.y, xaxis.z, -xaxis.dotProduct(eye),
|
||||
yaxis.x, yaxis.y, yaxis.z, -yaxis.dotProduct(eye),
|
||||
zaxis.x, zaxis.y, zaxis.z, -zaxis.dotProduct(eye),
|
||||
0, 0, 0, 1.f);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> MathUtil::perspectiveFovRH(T fov, T aspect, T zNear, T zFar)
|
||||
{
|
||||
assert(zNear > T(0) && zFar > T(0));
|
||||
assert(!MathUtil::floatEqual(fov, T(0), T(0.00001) * 2));
|
||||
assert(!MathUtil::floatEqual(aspect, T(0), T(0.00001)));
|
||||
assert(!MathUtil::floatEqual(zNear, zFar, T(0.00001)));
|
||||
|
||||
T cotanHalfFovy = T(1.0) / tanf(fov * T(0.5));
|
||||
|
||||
return TMatrix4<T>(
|
||||
cotanHalfFovy / aspect, 0, 0, 0,
|
||||
0, cotanHalfFovy, 0, 0,
|
||||
0, 0, -zFar / (zFar - zNear), -(zFar * zNear) / (zFar - zNear),
|
||||
0, 0, T(-1), 0
|
||||
);
|
||||
}
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
template<typename T>
|
||||
class TMatrix3
|
||||
{
|
||||
protected:
|
||||
/* The matrix entries, indexed by [row][col].
|
||||
| m[0][0] m[0][1] m[0][2] |
|
||||
| m[1][0] m[1][1] m[1][2] |
|
||||
| m[2][0] m[2][1] m[2][2] |
|
||||
*/
|
||||
union {
|
||||
T m[3][3];
|
||||
T _m[9];
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor, It does NOT initialize the matrix for efficiency.
|
||||
TMatrix3() {}
|
||||
inline explicit TMatrix3(const T arr[3][3]) {
|
||||
memcpy(m, arr, 9 * sizeof(T));
|
||||
}
|
||||
inline TMatrix3(const TMatrix3& rkMatrix) {
|
||||
memcpy(m, rkMatrix.m, 9 * sizeof(T));
|
||||
}
|
||||
TMatrix3(
|
||||
T m00, T m01, T m02,
|
||||
T m10, T m11, T m12,
|
||||
T m20, T m21, T m22)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
|
||||
}
|
||||
|
||||
public:
|
||||
inline const T* operator[] (size_t iRow) const {
|
||||
assert(iRow < 3);
|
||||
return m[iRow];
|
||||
}
|
||||
|
||||
inline T* operator[] (size_t iRow) {
|
||||
assert(iRow < 3);
|
||||
return m[iRow];
|
||||
}
|
||||
public:
|
||||
// Operations
|
||||
inline TMatrix3& operator = (const TMatrix3& rkMatrix) {
|
||||
memcpy(m, rkMatrix.m, 9 * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (const TMatrix3& rkMatrix) const;
|
||||
inline bool operator != (const TMatrix3& rkMatrix) const {
|
||||
return !operator==(rkMatrix);
|
||||
}
|
||||
|
||||
// return this + rkMatrix
|
||||
TMatrix3 operator + (const TMatrix3& rkMatrix) const;
|
||||
|
||||
// return this - Matrix
|
||||
TMatrix3 operator - (const TMatrix3& rkMatrix) const;
|
||||
|
||||
// return this * rkMatrix
|
||||
TMatrix3 operator * (const TMatrix3& rkMatrix) const;
|
||||
|
||||
// return -this
|
||||
TMatrix3 operator - () const;
|
||||
|
||||
/* Matrix * Vector
|
||||
| m[0][0] m[0][1] m[0][2] | |x|
|
||||
| m[1][0] m[1][1] m[1][2] | * |y|
|
||||
| m[2][0] m[2][1] m[2][2] | |z|
|
||||
*/
|
||||
TVector3<T> operator * (const TVector3<T>& rkVector) const;
|
||||
|
||||
/* Vector * Matrix
|
||||
| m[0][0] m[0][1] m[0][2] |
|
||||
[x, y, z] * | m[1][0] m[1][1] m[1][2] |
|
||||
| m[2][0] m[2][1] m[2][2] |
|
||||
*/
|
||||
template<typename U>
|
||||
friend TVector3<U> operator * (const TVector3<U>& rkVector, const TMatrix3<U>& rkMatrix);
|
||||
|
||||
/// Matrix * scalar
|
||||
TMatrix3 operator * (T fScalar) const;
|
||||
|
||||
/// Scalar * matrix
|
||||
template<typename U>
|
||||
friend TMatrix3<U> operator * (U fScalar, const TMatrix3<U>& rkMatrix);
|
||||
|
||||
public:
|
||||
// Utilities
|
||||
|
||||
//return this^T
|
||||
TMatrix3 transpose(void) const;
|
||||
//rkInverse = this^{-1}?? return false mean no solution
|
||||
bool inverse(TMatrix3& rkInverse, T fTolerance = 1e-06f) const;
|
||||
//return this^{-1}, return ZERO if no solution
|
||||
TMatrix3 inverse(T fTolerance = 1e-06f) const;
|
||||
|
||||
public:
|
||||
static DV_CORE_API const TMatrix3 ZERO;
|
||||
static DV_CORE_API const TMatrix3 IDENTITY;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool TMatrix3<T>::operator== (const TMatrix3<T>& rkMatrix) const
|
||||
{
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++) {
|
||||
if (m[iRow][iCol] != rkMatrix.m[iRow][iCol])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::operator + (const TMatrix3<T>& rkMatrix) const
|
||||
{
|
||||
TMatrix3<T> kSum;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++) {
|
||||
kSum.m[iRow][iCol] = m[iRow][iCol] + rkMatrix.m[iRow][iCol];
|
||||
}
|
||||
}
|
||||
return kSum;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::operator - (const TMatrix3<T>& rkMatrix) const
|
||||
{
|
||||
TMatrix3<T> kDiff;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++) {
|
||||
kDiff.m[iRow][iCol] = m[iRow][iCol] - rkMatrix.m[iRow][iCol];
|
||||
}
|
||||
}
|
||||
return kDiff;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::operator * (const TMatrix3<T>& rkMatrix) const
|
||||
{
|
||||
TMatrix3<T> kProd;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++) {
|
||||
kProd.m[iRow][iCol] =
|
||||
m[iRow][0] * rkMatrix.m[0][iCol] +
|
||||
m[iRow][1] * rkMatrix.m[1][iCol] +
|
||||
m[iRow][2] * rkMatrix.m[2][iCol];
|
||||
}
|
||||
}
|
||||
return kProd;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::operator - () const
|
||||
{
|
||||
TMatrix3<T> kNeg;
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
kNeg._m[i] = -_m[i];
|
||||
}
|
||||
return kNeg;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TVector3<T> TMatrix3<T>::operator* (const TVector3<T>& rkPoint) const
|
||||
{
|
||||
TVector3<T> kProd(
|
||||
m[0][0] * rkPoint[0] + m[0][1] * rkPoint[1] + m[0][2] * rkPoint[2],
|
||||
m[1][0] * rkPoint[0] + m[1][1] * rkPoint[1] + m[1][2] * rkPoint[2],
|
||||
m[2][0] * rkPoint[0] + m[2][1] * rkPoint[1] + m[2][2] * rkPoint[2]);
|
||||
|
||||
return kProd;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline TVector3<T> operator* (const TVector3<T>& rkPoint, const TMatrix3<T>& rkMatrix)
|
||||
{
|
||||
TVector3<T> kProd(
|
||||
rkPoint[0] * rkMatrix.m[0][0] + rkPoint[1] * rkMatrix.m[1][0] + rkPoint[2] * rkMatrix.m[2][0],
|
||||
rkPoint[0] * rkMatrix.m[0][1] + rkPoint[1] * rkMatrix.m[1][1] + rkPoint[2] * rkMatrix.m[2][1],
|
||||
rkPoint[0] * rkMatrix.m[0][2] + rkPoint[1] * rkMatrix.m[1][2] + rkPoint[2] * rkMatrix.m[2][2]);
|
||||
|
||||
return kProd;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::operator* (T fScalar) const
|
||||
{
|
||||
TMatrix3<T> kProd;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++)
|
||||
kProd[iRow][iCol] = fScalar * m[iRow][iCol];
|
||||
}
|
||||
return kProd;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> operator* (T fScalar, const TMatrix3<T>& rkMatrix)
|
||||
{
|
||||
TMatrix3<T> kProd;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++)
|
||||
kProd[iRow][iCol] = fScalar * rkMatrix.m[iRow][iCol];
|
||||
}
|
||||
return kProd;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::transpose(void) const
|
||||
{
|
||||
TMatrix3<T> kTranspose;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++)
|
||||
kTranspose[iRow][iCol] = m[iCol][iRow];
|
||||
}
|
||||
return kTranspose;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool TMatrix3<T>::inverse(TMatrix3<T>& rkInverse, T fTolerance) const
|
||||
{
|
||||
// Invert a 3x3 using cofactors. This is about 8 times faster than
|
||||
// the Numerical Recipes code which uses Gaussian elimination.
|
||||
|
||||
rkInverse[0][0] = m[1][1] * m[2][2] -
|
||||
m[1][2] * m[2][1];
|
||||
rkInverse[0][1] = m[0][2] * m[2][1] -
|
||||
m[0][1] * m[2][2];
|
||||
rkInverse[0][2] = m[0][1] * m[1][2] -
|
||||
m[0][2] * m[1][1];
|
||||
rkInverse[1][0] = m[1][2] * m[2][0] -
|
||||
m[1][0] * m[2][2];
|
||||
rkInverse[1][1] = m[0][0] * m[2][2] -
|
||||
m[0][2] * m[2][0];
|
||||
rkInverse[1][2] = m[0][2] * m[1][0] -
|
||||
m[0][0] * m[1][2];
|
||||
rkInverse[2][0] = m[1][0] * m[2][1] -
|
||||
m[1][1] * m[2][0];
|
||||
rkInverse[2][1] = m[0][1] * m[2][0] -
|
||||
m[0][0] * m[2][1];
|
||||
rkInverse[2][2] = m[0][0] * m[1][1] -
|
||||
m[0][1] * m[1][0];
|
||||
|
||||
T fDet =
|
||||
m[0][0] * rkInverse[0][0] +
|
||||
m[0][1] * rkInverse[1][0] +
|
||||
m[0][2] * rkInverse[2][0];
|
||||
|
||||
if (std::abs(fDet) <= fTolerance)
|
||||
return false;
|
||||
|
||||
T fInvDet = T(1.0) / fDet;
|
||||
for (size_t iRow = 0; iRow < 3; iRow++) {
|
||||
for (size_t iCol = 0; iCol < 3; iCol++)
|
||||
rkInverse[iRow][iCol] *= fInvDet;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix3<T> TMatrix3<T>::inverse(T fTolerance) const
|
||||
{
|
||||
TMatrix3<T> kInverse = TMatrix3<T>::ZERO;
|
||||
inverse(kInverse, fTolerance);
|
||||
return kInverse;
|
||||
}
|
||||
|
||||
typedef TMatrix3<float32_t> fMatrix3;
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
template<typename T>
|
||||
class TMatrix4
|
||||
{
|
||||
protected:
|
||||
/*
|
||||
| m[0][0] m[0][1] m[0][2] m[0][3] |
|
||||
| m[1][0] m[1][1] m[1][2] m[1][3] |
|
||||
| m[2][0] m[2][1] m[2][2] m[2][3] |
|
||||
| m[3][0] m[3][1] m[3][2] m[3][3] |
|
||||
*/
|
||||
union {
|
||||
T m[4][4];
|
||||
T _m[16];
|
||||
};
|
||||
public:
|
||||
// constructor, It does NOT initialize the matrix for efficiency.
|
||||
TMatrix4() {}
|
||||
inline explicit TMatrix4(const T arr[4][4]) {
|
||||
memcpy(m, arr, 16 * sizeof(T));
|
||||
}
|
||||
inline TMatrix4(const TMatrix4& rkMatrix) {
|
||||
memcpy(m, rkMatrix.m, 16 * sizeof(T));
|
||||
}
|
||||
TMatrix4(
|
||||
T m00, T m01, T m02, T m03,
|
||||
T m10, T m11, T m12, T m13,
|
||||
T m20, T m21, T m22, T m23,
|
||||
T m30, T m31, T m32, T m33)
|
||||
{
|
||||
m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
|
||||
m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
|
||||
m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
|
||||
m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
|
||||
}
|
||||
|
||||
public:
|
||||
inline const T* operator[] (size_t iRow) const {
|
||||
assert(iRow < 4);
|
||||
return m[iRow];
|
||||
}
|
||||
|
||||
inline T* operator[] (size_t iRow) {
|
||||
assert(iRow < 4);
|
||||
return m[iRow];
|
||||
}
|
||||
|
||||
public:
|
||||
// Operators
|
||||
inline TMatrix4& operator = (const TMatrix4& rkMatrix) {
|
||||
memcpy(m, rkMatrix.m, 16 * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (const TMatrix4& rkMatrix) const;
|
||||
inline bool operator != (const TMatrix4& rkMatrix) const {
|
||||
return !operator==(rkMatrix);
|
||||
}
|
||||
|
||||
// return this + m2
|
||||
TMatrix4 operator + (const TMatrix4 &m2) const;
|
||||
// return this - m2
|
||||
TMatrix4 operator - (const TMatrix4 &m2) const;
|
||||
//return this * m2
|
||||
TMatrix4 operator * (const TMatrix4 &m2) const;
|
||||
//return this * scalar
|
||||
inline TMatrix4 operator*(T scalar) const {
|
||||
return TMatrix4(
|
||||
scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
|
||||
scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
|
||||
scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
|
||||
scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
|
||||
}
|
||||
|
||||
/// return scalar * matrix
|
||||
friend TMatrix4 operator* (T scalar, const TMatrix4& rkMatrix) {
|
||||
return TMatrix4(
|
||||
scalar*rkMatrix[0][0], scalar*rkMatrix[0][1], scalar*rkMatrix[0][2], scalar*rkMatrix[0][3],
|
||||
scalar*rkMatrix[1][0], scalar*rkMatrix[1][1], scalar*rkMatrix[1][2], scalar*rkMatrix[1][3],
|
||||
scalar*rkMatrix[2][0], scalar*rkMatrix[2][1], scalar*rkMatrix[2][2], scalar*rkMatrix[2][3],
|
||||
scalar*rkMatrix[3][0], scalar*rkMatrix[3][1], scalar*rkMatrix[3][2], scalar*rkMatrix[3][3]);
|
||||
}
|
||||
|
||||
// return -this
|
||||
TMatrix4 operator - () const {
|
||||
return TMatrix4(
|
||||
-m[0][0], -m[0][1], -m[0][2], -m[0][3],
|
||||
-m[1][0], -m[1][1], -m[1][2], -m[1][3],
|
||||
-m[2][0], -m[2][1], -m[2][2], -m[2][3],
|
||||
-m[3][0], -m[3][1], -m[3][2], -m[3][3]);
|
||||
}
|
||||
|
||||
/* return Matrix * fVector4
|
||||
| m[0][0] m[0][1] m[0][2] m[0][3] | |x|
|
||||
| m[1][0] m[1][1] m[1][2] m[1][3] | * |y|
|
||||
| m[2][0] m[2][1] m[2][2] m[2][3] | |z|
|
||||
| m[3][0] m[3][1] m[3][2] m[3][3] | |w|
|
||||
*/
|
||||
inline TVector4<T> operator * (const TVector4<T>& v) const {
|
||||
return TVector4<T>(
|
||||
(m[0][0] * v.x + m[0][1] * v.y) + (m[0][2] * v.z + m[0][3] * v.w),
|
||||
(m[1][0] * v.x + m[1][1] * v.y) + (m[1][2] * v.z + m[1][3] * v.w),
|
||||
(m[2][0] * v.x + m[2][1] * v.y) + (m[2][2] * v.z + m[2][3] * v.w),
|
||||
(m[3][0] * v.x + m[3][1] * v.y) + (m[3][2] * v.z + m[3][3] * v.w)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Transforms the given 3-D vector by the matrix, projecting the
|
||||
result back into <i>w</i> = 1.
|
||||
@note
|
||||
This means that the initial <i>w</i> is considered to be 1.0,
|
||||
and then all the tree elements of the resulting 3-D vector are
|
||||
divided by the resulting <i>w</i>.
|
||||
*/
|
||||
inline TVector3<T> operator * (const TVector3<T> &v) const {
|
||||
TVector3<T> r;
|
||||
T fInvW = 1.0f / (m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3]);
|
||||
|
||||
r.x = (m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3]) * fInvW;
|
||||
r.y = (m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3]) * fInvW;
|
||||
r.z = (m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]) * fInvW;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* return fVector4 * Matrix
|
||||
| m[0][0] m[0][1] m[0][2] m[0][3] |
|
||||
[x,y,z,w] * | m[1][0] m[1][1] m[1][2] m[1][3] |
|
||||
| m[2][0] m[2][1] m[2][2] m[2][3] |
|
||||
| m[3][0] m[3][1] m[3][2] m[3][3] |
|
||||
*/
|
||||
friend TVector4<T> operator * (const TVector4<T>& v, const TMatrix4& mat) {
|
||||
return TVector4<T>(
|
||||
(v.x*mat[0][0] + v.y*mat[1][0]) + (v.z*mat[2][0] + v.w*mat[3][0]),
|
||||
(v.x*mat[0][1] + v.y*mat[1][1]) + (v.z*mat[2][1] + v.w*mat[3][1]),
|
||||
(v.x*mat[0][2] + v.y*mat[1][2]) + (v.z*mat[2][2] + v.w*mat[3][2]),
|
||||
(v.x*mat[0][3] + v.y*mat[1][3]) + (v.z*mat[2][3] + v.w*mat[3][3])
|
||||
);
|
||||
}
|
||||
|
||||
friend TVector3<T> operator * (const TVector3<T>& v, const TMatrix4& mat) {
|
||||
TVector3<T> r;
|
||||
T fInvW = 1.0f / (mat.m[0][3] * v.x + mat.m[1][3] * v.y + mat.m[2][3] * v.z + mat.m[3][3]);
|
||||
|
||||
r.x = (mat.m[0][0] * v.x + mat.m[1][0] * v.y + mat.m[2][0] * v.z + mat.m[3][0]) * fInvW;
|
||||
r.y = (mat.m[0][1] * v.x + mat.m[1][1] * v.y + mat.m[2][1] * v.z + mat.m[3][1]) * fInvW;
|
||||
r.z = (mat.m[0][2] * v.x + mat.m[1][2] * v.y + mat.m[2][2] * v.z + mat.m[3][2]) * fInvW;
|
||||
return r;
|
||||
}
|
||||
public:
|
||||
static inline TMatrix4 makeTrans(T x, T y, T z) {
|
||||
return TMatrix4(
|
||||
1, 0, 0, x,
|
||||
0, 1, 0, y,
|
||||
0, 0, 1, z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static inline TMatrix4 makeTrans(const TVector3<T>& pos) {
|
||||
return TMatrix4(
|
||||
1, 0, 0, pos.x,
|
||||
0, 1, 0, pos.y,
|
||||
0, 0, 1, pos.z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static inline TMatrix4 makeScale(T x, T y, T z) {
|
||||
return TMatrix4(
|
||||
x, 0, 0, 0,
|
||||
0, y, 0, 0,
|
||||
0, 0, z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//rotate matrix(x), left multiplication
|
||||
static inline TMatrix4 makeRotate_X(T angle) {
|
||||
T s = sin(angle);
|
||||
T c = cos(angle);
|
||||
return TMatrix4(
|
||||
1, 0, 0, 0,
|
||||
0, c, -s, 0,
|
||||
0, s, c, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//rotate matrix(y), left multiplication
|
||||
static inline TMatrix4 makeRotate_Y(T angle) {
|
||||
T s = sin(angle);
|
||||
T c = cos(angle);
|
||||
return TMatrix4(
|
||||
c, 0, s, 0,
|
||||
0, 1, 0, 0,
|
||||
-s, 0, c, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//rotate matrix(z), left multiplication
|
||||
static inline TMatrix4 makeRotate_Z(T angle) {
|
||||
T s = sin(angle);
|
||||
T c = cos(angle);
|
||||
return TMatrix4(
|
||||
c, -s, 0, 0,
|
||||
s, c, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//rotate matrix(rotate angle about the v axis), left multiplication
|
||||
static TMatrix4 makeRotate(const TVector3<T>& v, T angle) {
|
||||
T c = cos(angle);
|
||||
T s = sin(angle);
|
||||
TMatrix4<T> result;
|
||||
|
||||
TVector3<T> axis = v.normalise();
|
||||
|
||||
result[0][0] = c + (T(1) - c) * axis.x * axis.x;
|
||||
result[1][0] = (T(1) - c) * axis.x * axis.y + s * axis.z;
|
||||
result[2][0] = (T(1) - c) * axis.x * axis.z - s * axis.y;
|
||||
result[3][0] = T(0);
|
||||
|
||||
result[0][1] = (T(1) - c) * axis.y * axis.x - s * axis.z;
|
||||
result[1][1] = c + (T(1) - c) * axis.y * axis.y;
|
||||
result[2][1] = (T(1) - c) * axis.y * axis.z + s * axis.x;
|
||||
result[3][1] = T(0);
|
||||
|
||||
result[0][2] = (T(1) - c) * axis.z * axis.x + s * axis.y;
|
||||
result[1][2] = (T(1) - c) * axis.z * axis.y - s * axis.x;
|
||||
result[2][2] = c + (T(1) - c) * axis.z * axis.z;
|
||||
result[3][2] = T(0);
|
||||
|
||||
result[0][3] = 0;
|
||||
result[1][3] = 0;
|
||||
result[2][3] = 0;
|
||||
result[3][3] = T(1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//rotate matrix(from quaternion)
|
||||
static TMatrix4 makeRotate(const TVector4<T>& q) {
|
||||
TMatrix4<T> result;
|
||||
|
||||
T qxx(q.x * q.x);
|
||||
T qyy(q.y * q.y);
|
||||
T qzz(q.z * q.z);
|
||||
T qxz(q.x * q.z);
|
||||
T qxy(q.x * q.y);
|
||||
T qyz(q.y * q.z);
|
||||
T qwx(q.w * q.x);
|
||||
T qwy(q.w * q.y);
|
||||
T qwz(q.w * q.z);
|
||||
|
||||
result[0][0] = T(1) - T(2) * (qyy + qzz);
|
||||
result[1][0] = T(2) * (qxy + qwz);
|
||||
result[2][0] = T(2) * (qxz - qwy);
|
||||
result[3][0] = 0;
|
||||
|
||||
result[0][1] = T(2) * (qxy - qwz);
|
||||
result[1][1] = T(1) - T(2) * (qxx + qzz);
|
||||
result[2][1] = T(2) * (qyz + qwx);
|
||||
result[3][1] = 0;
|
||||
|
||||
result[0][2] = T(2) * (qxz + qwy);
|
||||
result[1][2] = T(2) * (qyz - qwx);
|
||||
result[2][2] = T(1) - T(2) * (qxx + qyy);
|
||||
result[3][2] = 0;
|
||||
|
||||
result[0][3] = 0;
|
||||
result[1][3] = 0;
|
||||
result[2][3] = 0;
|
||||
result[3][3] = T(1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline TMatrix4 transpose(void) const {
|
||||
return TMatrix4(
|
||||
m[0][0], m[1][0], m[2][0], m[3][0],
|
||||
m[0][1], m[1][1], m[2][1], m[3][1],
|
||||
m[0][2], m[1][2], m[2][2], m[3][2],
|
||||
m[0][3], m[1][3], m[2][3], m[3][3]);
|
||||
}
|
||||
|
||||
//return this^{-1}, return ZERO if no solution
|
||||
TMatrix4 inverse(void) const;
|
||||
|
||||
public:
|
||||
static DV_CORE_API const TMatrix4 ZERO;
|
||||
static DV_CORE_API const TMatrix4 IDENTITY;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool TMatrix4<T>::operator == (const TMatrix4<T>& m2) const {
|
||||
if (
|
||||
m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
|
||||
m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
|
||||
m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
|
||||
m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> TMatrix4<T>::operator * (const TMatrix4<T>& m2) const
|
||||
{
|
||||
TMatrix4<T> r;
|
||||
r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
|
||||
r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
|
||||
r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
|
||||
r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
|
||||
|
||||
r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
|
||||
r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
|
||||
r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
|
||||
r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
|
||||
|
||||
r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
|
||||
r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
|
||||
r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
|
||||
r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
|
||||
|
||||
r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
|
||||
r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
|
||||
r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
|
||||
r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> TMatrix4<T>::operator + (const TMatrix4<T>& m2) const
|
||||
{
|
||||
TMatrix4<T> r;
|
||||
|
||||
r.m[0][0] = m[0][0] + m2.m[0][0];
|
||||
r.m[0][1] = m[0][1] + m2.m[0][1];
|
||||
r.m[0][2] = m[0][2] + m2.m[0][2];
|
||||
r.m[0][3] = m[0][3] + m2.m[0][3];
|
||||
|
||||
r.m[1][0] = m[1][0] + m2.m[1][0];
|
||||
r.m[1][1] = m[1][1] + m2.m[1][1];
|
||||
r.m[1][2] = m[1][2] + m2.m[1][2];
|
||||
r.m[1][3] = m[1][3] + m2.m[1][3];
|
||||
|
||||
r.m[2][0] = m[2][0] + m2.m[2][0];
|
||||
r.m[2][1] = m[2][1] + m2.m[2][1];
|
||||
r.m[2][2] = m[2][2] + m2.m[2][2];
|
||||
r.m[2][3] = m[2][3] + m2.m[2][3];
|
||||
|
||||
r.m[3][0] = m[3][0] + m2.m[3][0];
|
||||
r.m[3][1] = m[3][1] + m2.m[3][1];
|
||||
r.m[3][2] = m[3][2] + m2.m[3][2];
|
||||
r.m[3][3] = m[3][3] + m2.m[3][3];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> TMatrix4<T>::operator - (const TMatrix4<T>& m2) const
|
||||
{
|
||||
TMatrix4<T> r;
|
||||
r.m[0][0] = m[0][0] - m2.m[0][0];
|
||||
r.m[0][1] = m[0][1] - m2.m[0][1];
|
||||
r.m[0][2] = m[0][2] - m2.m[0][2];
|
||||
r.m[0][3] = m[0][3] - m2.m[0][3];
|
||||
|
||||
r.m[1][0] = m[1][0] - m2.m[1][0];
|
||||
r.m[1][1] = m[1][1] - m2.m[1][1];
|
||||
r.m[1][2] = m[1][2] - m2.m[1][2];
|
||||
r.m[1][3] = m[1][3] - m2.m[1][3];
|
||||
|
||||
r.m[2][0] = m[2][0] - m2.m[2][0];
|
||||
r.m[2][1] = m[2][1] - m2.m[2][1];
|
||||
r.m[2][2] = m[2][2] - m2.m[2][2];
|
||||
r.m[2][3] = m[2][3] - m2.m[2][3];
|
||||
|
||||
r.m[3][0] = m[3][0] - m2.m[3][0];
|
||||
r.m[3][1] = m[3][1] - m2.m[3][1];
|
||||
r.m[3][2] = m[3][2] - m2.m[3][2];
|
||||
r.m[3][3] = m[3][3] - m2.m[3][3];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TMatrix4<T> TMatrix4<T>::inverse(void) const
|
||||
{
|
||||
T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
|
||||
T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
|
||||
T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
|
||||
T m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
|
||||
|
||||
T v0 = m20 * m31 - m21 * m30;
|
||||
T v1 = m20 * m32 - m22 * m30;
|
||||
T v2 = m20 * m33 - m23 * m30;
|
||||
T v3 = m21 * m32 - m22 * m31;
|
||||
T v4 = m21 * m33 - m23 * m31;
|
||||
T v5 = m22 * m33 - m23 * m32;
|
||||
|
||||
T t00 = +(v5 * m11 - v4 * m12 + v3 * m13);
|
||||
T t10 = -(v5 * m10 - v2 * m12 + v1 * m13);
|
||||
T t20 = +(v4 * m10 - v2 * m11 + v0 * m13);
|
||||
T t30 = -(v3 * m10 - v1 * m11 + v0 * m12);
|
||||
|
||||
T invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
|
||||
|
||||
T d00 = t00 * invDet;
|
||||
T d10 = t10 * invDet;
|
||||
T d20 = t20 * invDet;
|
||||
T d30 = t30 * invDet;
|
||||
|
||||
T d01 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
T d11 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
T d21 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
T d31 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
v0 = m10 * m31 - m11 * m30;
|
||||
v1 = m10 * m32 - m12 * m30;
|
||||
v2 = m10 * m33 - m13 * m30;
|
||||
v3 = m11 * m32 - m12 * m31;
|
||||
v4 = m11 * m33 - m13 * m31;
|
||||
v5 = m12 * m33 - m13 * m32;
|
||||
|
||||
T d02 = +(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
T d12 = -(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
T d22 = +(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
T d32 = -(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
v0 = m21 * m10 - m20 * m11;
|
||||
v1 = m22 * m10 - m20 * m12;
|
||||
v2 = m23 * m10 - m20 * m13;
|
||||
v3 = m22 * m11 - m21 * m12;
|
||||
v4 = m23 * m11 - m21 * m13;
|
||||
v5 = m23 * m12 - m22 * m13;
|
||||
|
||||
T d03 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
|
||||
T d13 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
|
||||
T d23 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
|
||||
T d33 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
|
||||
|
||||
return TMatrix4<T>(
|
||||
d00, d01, d02, d03,
|
||||
d10, d11, d12, d13,
|
||||
d20, d21, d22, d23,
|
||||
d30, d31, d32, d33);
|
||||
}
|
||||
|
||||
typedef TMatrix4<float32_t> fMatrix4;
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
template<typename T>
|
||||
class TVector2
|
||||
{
|
||||
public:
|
||||
T x, y;
|
||||
|
||||
public:
|
||||
// Construct
|
||||
TVector2() : x(0), y(0) { }
|
||||
TVector2(T _x, T _y) : x(_x), y(_y){ }
|
||||
inline explicit TVector2(const T s) : x(s), y(s) { }
|
||||
inline explicit TVector2(const T f[2]) : x(f[0]), y(f[1]) { }
|
||||
inline explicit TVector2(T* const f) : x(f[0]), y(f[1]) { }
|
||||
inline explicit TVector2(const int32_t f[2]) : x((T)f[0]), y((T)f[1]) { }
|
||||
|
||||
public:
|
||||
inline T operator [] (const size_t i) const {
|
||||
assert(i < 2);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T& operator [] (const size_t i) {
|
||||
assert(i < 2);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T* ptr(void) {
|
||||
return &x;
|
||||
}
|
||||
|
||||
inline const T* ptr(void) const {
|
||||
return &x;
|
||||
}
|
||||
public:
|
||||
// Operations
|
||||
inline TVector2& operator = (const TVector2& rkVector) {
|
||||
x = rkVector.x;
|
||||
y = rkVector.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator = (const T fScalar) {
|
||||
x = fScalar;
|
||||
y = fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator == (const TVector2& rkVector) const {
|
||||
return (x == rkVector.x && y == rkVector.y);
|
||||
}
|
||||
|
||||
inline bool operator != (const TVector2& rkVector) const {
|
||||
return (x != rkVector.x || y != rkVector.y);
|
||||
}
|
||||
|
||||
public:
|
||||
// Arithmetic operations
|
||||
inline TVector2 operator + (const TVector2& rkVector) const {
|
||||
return TVector2( x + rkVector.x, y + rkVector.y);
|
||||
}
|
||||
|
||||
inline TVector2 operator - (const TVector2& rkVector) const {
|
||||
return TVector2( x - rkVector.x, y - rkVector.y);
|
||||
}
|
||||
|
||||
inline TVector2 operator * (const T fScalar) const {
|
||||
return TVector2( x * fScalar, y * fScalar);
|
||||
}
|
||||
|
||||
inline TVector2 operator * (const TVector2& rhs) const {
|
||||
return TVector2(x * rhs.x, y * rhs.y);
|
||||
}
|
||||
|
||||
inline TVector2 operator / (const T fScalar) const {
|
||||
assert(fScalar != 0.0);
|
||||
return TVector2(x / fScalar, y / fScalar);
|
||||
}
|
||||
|
||||
inline TVector2 operator / (const TVector2& rhs) const {
|
||||
return TVector2( x / rhs.x, y / rhs.y);
|
||||
}
|
||||
|
||||
inline const TVector2& operator + () const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2 operator - () const {
|
||||
return TVector2(-x, -y);
|
||||
}
|
||||
|
||||
public:
|
||||
// overloaded operators to help TVector2
|
||||
inline friend TVector2 operator * (const T fScalar, const TVector2& rkVector) {
|
||||
return TVector2(fScalar * rkVector.x, fScalar * rkVector.y);
|
||||
}
|
||||
|
||||
inline friend TVector2 operator / (const T fScalar, const TVector2& rkVector) {
|
||||
return TVector2( fScalar / rkVector.x, fScalar / rkVector.y);
|
||||
}
|
||||
|
||||
inline friend TVector2 operator + (const TVector2& lhs, const T rhs) {
|
||||
return TVector2( lhs.x + rhs, lhs.y + rhs);
|
||||
}
|
||||
|
||||
inline friend TVector2 operator + (const T lhs, const TVector2& rhs) {
|
||||
return TVector2( lhs + rhs.x, lhs + rhs.y);
|
||||
}
|
||||
|
||||
inline friend TVector2 operator - (const TVector2& lhs, const T rhs) {
|
||||
return TVector2( lhs.x - rhs, lhs.y - rhs);
|
||||
}
|
||||
|
||||
inline friend TVector2 operator - (const T lhs, const TVector2& rhs) {
|
||||
return TVector2( lhs - rhs.x, lhs - rhs.y);
|
||||
}
|
||||
|
||||
public:
|
||||
// arithmetic updates
|
||||
inline TVector2& operator += (const TVector2& rkVector) {
|
||||
x += rkVector.x;
|
||||
y += rkVector.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator += (const T fScaler) {
|
||||
x += fScaler;
|
||||
y += fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator -= (const TVector2& rkVector) {
|
||||
x -= rkVector.x;
|
||||
y -= rkVector.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator -= (const T fScaler) {
|
||||
x -= fScaler;
|
||||
y -= fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator *= (const T fScalar) {
|
||||
x *= fScalar;
|
||||
y *= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator *= (const TVector2& rkVector) {
|
||||
x *= rkVector.x;
|
||||
y *= rkVector.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator /= (const T fScalar) {
|
||||
assert(fScalar != 0.0);
|
||||
|
||||
x /= fScalar;
|
||||
y /= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& operator /= (const TVector2& rkVector) {
|
||||
x /= rkVector.x;
|
||||
y /= rkVector.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator < (const TVector2& rhs) const {
|
||||
return (x < rhs.x && y < rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator > (const TVector2& rhs) const {
|
||||
return (x > rhs.x && y > rhs.y);
|
||||
}
|
||||
|
||||
public:
|
||||
inline T length(void) const {
|
||||
return MathUtil::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
inline T squaredLength(void) const {
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
inline T distance(const TVector2& rhs) const {
|
||||
return (*this - rhs).length();
|
||||
}
|
||||
|
||||
inline T squaredDistance(const TVector2& rhs) const {
|
||||
return (*this - rhs).squaredLength();
|
||||
}
|
||||
|
||||
inline T dotProduct(const TVector2& vec) const {
|
||||
return x * vec.x + y * vec.y;
|
||||
}
|
||||
|
||||
inline T crossProduct(const TVector2& rkVector) const {
|
||||
return x * rkVector.y - y * rkVector.x;
|
||||
}
|
||||
|
||||
inline TVector2& normalise(void) {
|
||||
T fLength = length();
|
||||
if (fLength > 0.0f) {
|
||||
T invLength = T(1.0) / fLength;
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector2& saturate(void) {
|
||||
x = MathUtil::saturate(x);
|
||||
y = MathUtil::saturate(y);
|
||||
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
// special points
|
||||
static DV_CORE_API const TVector2 ZERO;
|
||||
static DV_CORE_API const TVector2 ONE;
|
||||
static DV_CORE_API const TVector2 UNIT_X;
|
||||
static DV_CORE_API const TVector2 UNIT_Y;
|
||||
static DV_CORE_API const TVector2 NEGATIVE_UNIT_X;
|
||||
static DV_CORE_API const TVector2 NEGATIVE_UNIT_Y;
|
||||
static DV_CORE_API const TVector2 UNIT_SCALE;
|
||||
};
|
||||
|
||||
|
||||
typedef TVector2<float32_t> fVector2;
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
@@ -0,0 +1,289 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
#include "dvc_math_util.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
template<typename T>
|
||||
class TVector3
|
||||
{
|
||||
public:
|
||||
T x, y, z;
|
||||
|
||||
public:
|
||||
// Construct
|
||||
TVector3() : x(0.), y(0.), z(0.) { }
|
||||
TVector3(T _x, T _y, T _z) : x(_x), y(_y), z(_z){ }
|
||||
TVector3(const TVector2<T>& _xy, T _z) : x(_xy.x), y(_xy.y), z(_z) { }
|
||||
TVector3(T _x, const TVector2<T>& _yz) : x(_x), y(_yz.x), z(_yz.y) { }
|
||||
inline explicit TVector3(const T s) : x(s), y(s), z(s) { }
|
||||
inline explicit TVector3(const T f[3]) : x(f[0]), y(f[1]), z(f[2]) { }
|
||||
inline explicit TVector3(T* const f) : x(f[0]), y(f[1]), z(f[2]) { }
|
||||
inline explicit TVector3(const int32_t f[3]) : x((T)f[0]), y((T)f[1]), z((T)f[2]) {}
|
||||
|
||||
public:
|
||||
inline T operator [] (const size_t i) const {
|
||||
assert(i < 3);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T& operator [] (const size_t i) {
|
||||
assert(i < 3);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T* ptr(void) {
|
||||
return &x;
|
||||
}
|
||||
|
||||
inline const T* ptr(void) const {
|
||||
return &x;
|
||||
}
|
||||
|
||||
inline TVector2<T> xy(void) const { return TVector2<T>(x, y); }
|
||||
inline TVector2<T> xz(void) const { return TVector2<T>(x, z); }
|
||||
inline TVector2<T> yz(void) const { return TVector2<T>(y, z); }
|
||||
|
||||
public:
|
||||
// Operations
|
||||
inline TVector3& operator = (const TVector3& rkVector) {
|
||||
x = rkVector.x;
|
||||
y = rkVector.y;
|
||||
z = rkVector.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator = (const T fScalar) {
|
||||
x = fScalar;
|
||||
y = fScalar;
|
||||
z = fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator == (const TVector3& rkVector) const {
|
||||
return (x == rkVector.x && y == rkVector.y && z == rkVector.z);
|
||||
}
|
||||
|
||||
inline bool operator != (const TVector3& rkVector) const {
|
||||
return (x != rkVector.x || y != rkVector.y || z != rkVector.z);
|
||||
}
|
||||
|
||||
public:
|
||||
// Arithmetic operations
|
||||
inline TVector3 operator + (const TVector3& rkVector) const {
|
||||
return TVector3( x + rkVector.x, y + rkVector.y, z + rkVector.z);
|
||||
}
|
||||
|
||||
inline TVector3 operator - (const TVector3& rkVector) const {
|
||||
return TVector3( x - rkVector.x, y - rkVector.y, z - rkVector.z);
|
||||
}
|
||||
|
||||
inline TVector3 operator * (const T fScalar) const {
|
||||
return TVector3( x * fScalar, y * fScalar, z * fScalar);
|
||||
}
|
||||
|
||||
inline TVector3 operator * (const TVector3& rhs) const {
|
||||
return TVector3(x * rhs.x, y * rhs.y, z * rhs.z);
|
||||
}
|
||||
|
||||
inline TVector3 operator / (const T fScalar) const {
|
||||
assert(fScalar != 0.0);
|
||||
return TVector3(x / fScalar, y / fScalar, z / fScalar);
|
||||
}
|
||||
|
||||
inline TVector3 operator / (const TVector3& rhs) const {
|
||||
return TVector3( x / rhs.x, y / rhs.y, z / rhs.z);
|
||||
}
|
||||
|
||||
inline const TVector3& operator + () const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3 operator - () const {
|
||||
return TVector3(-x, -y, -z);
|
||||
}
|
||||
|
||||
public:
|
||||
// overloaded operators to help TVector3
|
||||
inline friend TVector3 operator * (const T fScalar, const TVector3& rkVector) {
|
||||
return TVector3(fScalar * rkVector.x, fScalar * rkVector.y, fScalar * rkVector.z);
|
||||
}
|
||||
|
||||
inline friend TVector3 operator / (const T fScalar, const TVector3& rkVector) {
|
||||
return TVector3( fScalar / rkVector.x, fScalar / rkVector.y, fScalar / rkVector.z);
|
||||
}
|
||||
|
||||
inline friend TVector3 operator + (const TVector3& lhs, const T rhs) {
|
||||
return TVector3( lhs.x + rhs, lhs.y + rhs, lhs.z + rhs);
|
||||
}
|
||||
|
||||
inline friend TVector3 operator + (const T lhs, const TVector3& rhs) {
|
||||
return TVector3( lhs + rhs.x, lhs + rhs.y, lhs + rhs.z);
|
||||
}
|
||||
|
||||
inline friend TVector3 operator - (const TVector3& lhs, const T rhs) {
|
||||
return TVector3( lhs.x - rhs, lhs.y - rhs, lhs.z - rhs);
|
||||
}
|
||||
|
||||
inline friend TVector3 operator - (const T lhs, const TVector3& rhs) {
|
||||
return TVector3( lhs - rhs.x, lhs - rhs.y, lhs - rhs.z);
|
||||
}
|
||||
|
||||
inline friend TVector3 reflect(const TVector3& incident, const TVector3& normal) {
|
||||
return incident - 2.f * normal.dotProduct(incident) * normal;
|
||||
}
|
||||
public:
|
||||
// arithmetic updates
|
||||
inline TVector3& operator += (const TVector3& rkVector) {
|
||||
x += rkVector.x;
|
||||
y += rkVector.y;
|
||||
z += rkVector.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator += (const T fScaler) {
|
||||
x += fScaler;
|
||||
y += fScaler;
|
||||
z += fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator -= (const TVector3& rkVector) {
|
||||
x -= rkVector.x;
|
||||
y -= rkVector.y;
|
||||
z -= rkVector.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator -= (const T fScaler) {
|
||||
x -= fScaler;
|
||||
y -= fScaler;
|
||||
z -= fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator *= (const T fScalar) {
|
||||
x *= fScalar;
|
||||
y *= fScalar;
|
||||
z *= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator *= (const TVector3& rkVector) {
|
||||
x *= rkVector.x;
|
||||
y *= rkVector.y;
|
||||
z *= rkVector.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator /= (const T fScalar) {
|
||||
assert(fScalar != 0.0);
|
||||
|
||||
x /= fScalar;
|
||||
y /= fScalar;
|
||||
z /= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3& operator /= (const TVector3& rkVector) {
|
||||
x /= rkVector.x;
|
||||
y /= rkVector.y;
|
||||
z /= rkVector.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator < (const TVector3& rhs) const {
|
||||
return (x < rhs.x && y < rhs.y && z < rhs.z);
|
||||
}
|
||||
|
||||
inline bool operator > (const TVector3& rhs) const {
|
||||
return (x > rhs.x && y > rhs.y && z > rhs.z);
|
||||
}
|
||||
|
||||
public:
|
||||
inline T length(void) const {
|
||||
return MathUtil::sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline T squaredLength(void) const {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
inline T distance(const TVector3& rhs) const {
|
||||
return (*this - rhs).length();
|
||||
}
|
||||
|
||||
inline T squaredDistance(const TVector3& rhs) const {
|
||||
return (*this - rhs).squaredLength();
|
||||
}
|
||||
|
||||
inline T dotProduct(const TVector3& vec) const {
|
||||
return x * vec.x + y * vec.y + z * vec.z;
|
||||
}
|
||||
|
||||
inline TVector3 crossProduct(const TVector3& rkVector) const {
|
||||
return TVector3(
|
||||
y * rkVector.z - z * rkVector.y,
|
||||
z * rkVector.x - x * rkVector.z,
|
||||
x * rkVector.y - y * rkVector.x);
|
||||
}
|
||||
|
||||
inline TVector3& normalise(void) {
|
||||
T fLength = length();
|
||||
if (fLength > 0.0f) {
|
||||
T invLength = 1.f / fLength;
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector3 normalise(void) const {
|
||||
TVector3 result(x,y,z);
|
||||
|
||||
T fLength = length();
|
||||
if (fLength > 0.0f) {
|
||||
T invLength = 1.f / fLength;
|
||||
result.x *= invLength;
|
||||
result.y *= invLength;
|
||||
result.z *= invLength;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline TVector3& saturate(void) {
|
||||
x = MathUtil::saturate(x);
|
||||
y = MathUtil::saturate(y);
|
||||
z = MathUtil::saturate(z);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
// special points
|
||||
static DV_CORE_API const TVector3 ZERO;
|
||||
static DV_CORE_API const TVector3 ONE;
|
||||
static DV_CORE_API const TVector3 UNIT_X;
|
||||
static DV_CORE_API const TVector3 UNIT_Y;
|
||||
static DV_CORE_API const TVector3 UNIT_Z;
|
||||
static DV_CORE_API const TVector3 NEGATIVE_UNIT_X;
|
||||
static DV_CORE_API const TVector3 NEGATIVE_UNIT_Y;
|
||||
static DV_CORE_API const TVector3 NEGATIVE_UNIT_Z;
|
||||
static DV_CORE_API const TVector3 UNIT_SCALE;
|
||||
static DV_CORE_API const TVector3 WHITE;
|
||||
static DV_CORE_API const TVector3 BLACK;
|
||||
static DV_CORE_API const TVector3 RED;
|
||||
static DV_CORE_API const TVector3 GREEN;
|
||||
static DV_CORE_API const TVector3 BLUE;
|
||||
static DV_CORE_API const TVector3 PURPLE;
|
||||
static DV_CORE_API const TVector3 GRAY;
|
||||
};
|
||||
|
||||
typedef TVector3<float32_t> fVector3;
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
@@ -0,0 +1,249 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_pre_declare.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
template<typename T>
|
||||
class TVector4
|
||||
{
|
||||
public:
|
||||
T x, y, z, w;
|
||||
|
||||
public:
|
||||
// Construct
|
||||
TVector4() : x(0.f), y(0.f), z(0.f), w(0.f) { }
|
||||
TVector4(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w){ }
|
||||
TVector4(const TVector3<T>& _xyz, T _w) : x(_xyz.x), y(_xyz.y), z(_xyz.z), w(_w) { }
|
||||
inline explicit TVector4(const T s) : x(s), y(s), z(s), w(s) { }
|
||||
inline explicit TVector4(const T f[4]) : x(f[0]), y(f[1]), z(f[2]), w(f[3]) { }
|
||||
inline explicit TVector4(T* const f) : x(f[0]), y(f[1]), z(f[2]), w(f[3]) { }
|
||||
inline explicit TVector4(const int32_t f[4]) : x((T)f[0]), y((T)f[1]), z((T)f[2]), w((T)f[3]) { }
|
||||
//inline explicit TVector4(const uint8_t* f)
|
||||
// : x((T)(f[0] / T(std::numeric_limits<uint8_t>::max())))
|
||||
// , y((T)(f[1] / T(std::numeric_limits<uint8_t>::max())))
|
||||
// , z((T)(f[2] / T(std::numeric_limits<uint8_t>::max())))
|
||||
// , w((T)(f[3] / T(std::numeric_limits<uint8_t>::max())))
|
||||
//{
|
||||
//}
|
||||
//inline explicit TVector4(const uint16_t* f)
|
||||
// : x((T)(f[0] / T(std::numeric_limits<uint16_t>::max())))
|
||||
// , y((T)(f[1] / T(std::numeric_limits<uint16_t>::max())))
|
||||
// , z((T)(f[2] / T(std::numeric_limits<uint16_t>::max())))
|
||||
// , w((T)(f[3] / T(std::numeric_limits<uint16_t>::max())))
|
||||
//{
|
||||
//}
|
||||
public:
|
||||
inline T operator [] (const size_t i) const {
|
||||
assert(i < 4);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T& operator [] (const size_t i) {
|
||||
assert(i < 4);
|
||||
return *(&x + i);
|
||||
}
|
||||
|
||||
inline T* ptr(void) {
|
||||
return &x;
|
||||
}
|
||||
|
||||
inline const T* ptr(void) const {
|
||||
return &x;
|
||||
}
|
||||
|
||||
inline TVector3<T> xyz(void) const { return TVector3<T>(x, y, z); }
|
||||
|
||||
public:
|
||||
// Operations
|
||||
inline TVector4& operator = (const TVector4& rkVector) {
|
||||
x = rkVector.x;
|
||||
y = rkVector.y;
|
||||
z = rkVector.z;
|
||||
w = rkVector.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator = (const T fScalar) {
|
||||
x = fScalar;
|
||||
y = fScalar;
|
||||
z = fScalar;
|
||||
w = fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator == (const TVector4& rkVector) const {
|
||||
return (x == rkVector.x && y == rkVector.y && z == rkVector.z && w == rkVector.w);
|
||||
}
|
||||
|
||||
inline bool operator != (const TVector4& rkVector) const {
|
||||
return (x != rkVector.x || y != rkVector.y || z != rkVector.z || w != rkVector.w);
|
||||
}
|
||||
|
||||
public:
|
||||
// Arithmetic operations
|
||||
inline TVector4 operator + (const TVector4& rkVector) const {
|
||||
return TVector4( x + rkVector.x, y + rkVector.y, z + rkVector.z, w + rkVector.w);
|
||||
}
|
||||
|
||||
inline TVector4 operator - (const TVector4& rkVector) const {
|
||||
return TVector4( x - rkVector.x, y - rkVector.y, z - rkVector.z, w - rkVector.w);
|
||||
}
|
||||
|
||||
inline TVector4 operator * (const T fScalar) const {
|
||||
return TVector4( x * fScalar, y * fScalar, z * fScalar, w * fScalar);
|
||||
}
|
||||
|
||||
inline TVector4 operator * (const TVector4& rhs) const {
|
||||
return TVector4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w);
|
||||
}
|
||||
|
||||
inline TVector4 operator / (const T fScalar) const {
|
||||
assert(fScalar != 0.0);
|
||||
return TVector4(x / fScalar, y / fScalar, z / fScalar, w / fScalar);
|
||||
}
|
||||
|
||||
inline TVector4 operator / (const TVector4& rhs) const {
|
||||
return TVector4( x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
|
||||
}
|
||||
|
||||
inline const TVector4& operator + () const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4 operator - () const {
|
||||
return TVector4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
public:
|
||||
// overloaded operators to help TVector4
|
||||
inline friend TVector4 operator * (const T fScalar, const TVector4& rkVector) {
|
||||
return TVector4(fScalar * rkVector.x, fScalar * rkVector.y, fScalar * rkVector.z, fScalar * rkVector.w);
|
||||
}
|
||||
|
||||
inline friend TVector4 operator / (const T fScalar, const TVector4& rkVector) {
|
||||
return TVector4( fScalar / rkVector.x, fScalar / rkVector.y, fScalar / rkVector.z, fScalar / rkVector.w);
|
||||
}
|
||||
|
||||
inline friend TVector4 operator + (const TVector4& lhs, const T rhs) {
|
||||
return TVector4( lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
|
||||
}
|
||||
|
||||
inline friend TVector4 operator + (const T lhs, const TVector4& rhs) {
|
||||
return TVector4( lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w);
|
||||
}
|
||||
|
||||
inline friend TVector4 operator - (const TVector4& lhs, const T rhs) {
|
||||
return TVector4( lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
|
||||
}
|
||||
|
||||
inline friend TVector4 operator - (const T lhs, const TVector4& rhs) {
|
||||
return TVector4( lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.z);
|
||||
}
|
||||
|
||||
public:
|
||||
// arithmetic updates
|
||||
inline TVector4& operator += (const TVector4& rkVector) {
|
||||
x += rkVector.x;
|
||||
y += rkVector.y;
|
||||
z += rkVector.z;
|
||||
w += rkVector.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator += (const T fScaler) {
|
||||
x += fScaler;
|
||||
y += fScaler;
|
||||
z += fScaler;
|
||||
w += fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator -= (const TVector4& rkVector) {
|
||||
x -= rkVector.x;
|
||||
y -= rkVector.y;
|
||||
z -= rkVector.z;
|
||||
w -= rkVector.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator -= (const T fScaler) {
|
||||
x -= fScaler;
|
||||
y -= fScaler;
|
||||
z -= fScaler;
|
||||
w -= fScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator *= (const T fScalar) {
|
||||
x *= fScalar;
|
||||
y *= fScalar;
|
||||
z *= fScalar;
|
||||
w *= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator *= (const TVector4& rkVector) {
|
||||
x *= rkVector.x;
|
||||
y *= rkVector.y;
|
||||
z *= rkVector.z;
|
||||
w *= rkVector.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator /= (const T fScalar) {
|
||||
assert(fScalar != 0.0);
|
||||
|
||||
x /= fScalar;
|
||||
y /= fScalar;
|
||||
z /= fScalar;
|
||||
w /= fScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline TVector4& operator /= (const TVector4& rkVector) {
|
||||
x /= rkVector.x;
|
||||
y /= rkVector.y;
|
||||
z /= rkVector.z;
|
||||
w /= rkVector.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator < (const TVector4& rhs) const {
|
||||
return (x < rhs.x && y < rhs.y && z < rhs.z && w < rhs.w);
|
||||
}
|
||||
|
||||
inline bool operator > (const TVector4& rhs) const {
|
||||
return (x > rhs.x && y > rhs.y && z > rhs.z && w > rhs.w);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline T dotProduct(const TVector4& vec) const {
|
||||
return (x * vec.x + y * vec.y) + (z * vec.z + w * vec.w);
|
||||
}
|
||||
|
||||
inline TVector4& saturate(void) {
|
||||
x = MathUtil::saturate(x);
|
||||
y = MathUtil::saturate(y);
|
||||
z = MathUtil::saturate(z);
|
||||
w = MathUtil::saturate(w);
|
||||
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
// special points
|
||||
static DV_CORE_API const TVector4 ZERO;
|
||||
static DV_CORE_API const TVector4 WHITE;
|
||||
static DV_CORE_API const TVector4 BLACK;
|
||||
static DV_CORE_API const TVector4 RED;
|
||||
static DV_CORE_API const TVector4 GREEN;
|
||||
static DV_CORE_API const TVector4 BLUE;
|
||||
static DV_CORE_API const TVector4 PURPLE;
|
||||
static DV_CORE_API const TVector4 GRAY;
|
||||
};
|
||||
|
||||
typedef TVector4<float32_t> fVector4;
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
Reference in New Issue
Block a user