1684 lines
30 KiB
C++
1684 lines
30 KiB
C++
#include "StdAfx.h"
|
|
/* Copyright (C) Dante Treglia II and Mark A. DeLoura, 2000.
|
|
* All rights reserved worldwide.
|
|
*
|
|
* This software is provided "as is" without express or implied
|
|
* warranties. You may freely copy and compile this source into
|
|
* applications you distribute provided that the copyright text
|
|
* below is included in the resulting source code, for example:
|
|
* "Portions Copyright (C) Dante Treglia II and Mark A. DeLoura, 2000"
|
|
*/
|
|
//==========================================================
|
|
// C++ Matrix Library
|
|
// Version: 2.3 <FINAL>
|
|
// Date: March 19, 2000
|
|
// Authors: Dante Treglia II and Mark A. DeLoura
|
|
// Thanks to: Miguel Gomez, Stan Melax, Pete Isensee,
|
|
// Gabor Nagy, Scott Bilas, James Boer
|
|
//==========================================================
|
|
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <cassert>
|
|
#include "mtxlib.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// vector2 class
|
|
//
|
|
|
|
// Constructor with initializing float values
|
|
vector2::vector2(float inX, float inY)
|
|
{
|
|
x = inX;
|
|
y = inY;
|
|
}
|
|
|
|
// Constructor with initializing vector2
|
|
vector2::vector2(const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
}
|
|
|
|
// Array indexing
|
|
float &vector2::operator [] (unsigned int i)
|
|
{
|
|
assert (i<2);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Array indexing
|
|
const float &vector2::operator [] (unsigned int i) const
|
|
{
|
|
assert (i<2);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Assign
|
|
vector2 &vector2::operator = (const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Add a vector2 to this one
|
|
vector2 &vector2::operator += (const vector2 &v)
|
|
{
|
|
x += v.x;
|
|
y += v.y;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Subtract a vector2 from this one
|
|
vector2 &vector2::operator -= (const vector2 &v)
|
|
{
|
|
x -= v.x;
|
|
y -= v.y;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the vector2 by a float
|
|
vector2 &vector2::operator *= (float f)
|
|
{
|
|
x *= f;
|
|
y *= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Divide the vector2 by a float
|
|
vector2 &vector2::operator /= (float f)
|
|
{
|
|
x /= f;
|
|
y /= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Are these two vector2's equal?
|
|
bool operator == (const vector2 &a, const vector2 &b)
|
|
{
|
|
return ((a.x == b.x) && (a.y == b.y));
|
|
}
|
|
|
|
// Are these two vector2's not equal?
|
|
bool operator != (const vector2 &a, const vector2 &b)
|
|
{
|
|
return ((a.x != b.x) || (a.y != b.y));
|
|
}
|
|
|
|
// Add two vector2's
|
|
vector2 operator + (const vector2 &a, const vector2 &b)
|
|
{
|
|
vector2 ret(a);
|
|
|
|
ret += b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Subtract one vector2 from another
|
|
vector2 operator - (const vector2 &a, const vector2 &b)
|
|
{
|
|
vector2 ret(a);
|
|
|
|
ret -= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply vector2 by a float
|
|
vector2 operator * (const vector2 &v, float f)
|
|
{
|
|
return vector2(f * v.x, f * v.y);
|
|
}
|
|
|
|
// Multiply vector2 by a float
|
|
vector2 operator * (float f, const vector2 &v)
|
|
{
|
|
return vector2(f * v.x, f * v.y);
|
|
}
|
|
|
|
// Divide vector2 by a float
|
|
vector2 operator / (const vector2 &v, float f)
|
|
{
|
|
return vector2(v.x / f, v.y / f);
|
|
}
|
|
|
|
// Negate a vector2
|
|
vector2 operator - (const vector2 &a)
|
|
{
|
|
return vector2(-a.x, -a.y);
|
|
}
|
|
|
|
// Get length of a vector2
|
|
float vector2::length() const
|
|
{
|
|
return (float) sqrt(x*x + y*y);
|
|
}
|
|
|
|
// Get squared length of a vector2
|
|
float vector2::lengthSqr() const
|
|
{
|
|
return (x*x + y*y);
|
|
}
|
|
|
|
// Does vector2 equal (0, 0)?
|
|
bool vector2::isZero() const
|
|
{
|
|
return ((x == 0.0F) && (y == 0.0F));
|
|
}
|
|
|
|
// Normalize a vector2
|
|
vector2 &vector2::normalize()
|
|
{
|
|
float m = length();
|
|
|
|
if (m > 0.0F)
|
|
m = 1.0F / m;
|
|
else
|
|
m = 0.0F;
|
|
x *= m;
|
|
y *= m;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// vector3 class
|
|
//
|
|
|
|
// Constructor with initializing float values
|
|
vector3::vector3(float inX, float inY, float inZ)
|
|
{
|
|
x = inX;
|
|
y = inY;
|
|
z = inZ;
|
|
}
|
|
|
|
// Constructor with initializing vector3
|
|
vector3::vector3(const vector3 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
}
|
|
|
|
// Constructor with initializing vector2
|
|
vector3::vector3(const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = 0.0F;
|
|
}
|
|
|
|
// Array indexing
|
|
float &vector3::operator [] (unsigned int i)
|
|
{
|
|
assert (i<3);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Array indexing
|
|
const float &vector3::operator [] (unsigned int i) const
|
|
{
|
|
assert (i<3);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Assign
|
|
vector3 &vector3::operator = (const vector3 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Assign from a vector2
|
|
vector3 &vector3::operator = (const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = 0.0F;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Add a vector3 to this one
|
|
vector3 &vector3::operator += (const vector3 &v)
|
|
{
|
|
x += v.x;
|
|
y += v.y;
|
|
z += v.z;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Subtract a vector3 from this one
|
|
vector3 &vector3::operator -= (const vector3 &v)
|
|
{
|
|
x -= v.x;
|
|
y -= v.y;
|
|
z -= v.z;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the vector3 by a float
|
|
vector3 &vector3::operator *= (float f)
|
|
{
|
|
x *= f;
|
|
y *= f;
|
|
z *= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Divide the vector3 by a float
|
|
vector3 &vector3::operator /= (float f)
|
|
{
|
|
x /= f;
|
|
y /= f;
|
|
z /= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Are these two vector3's equal?
|
|
bool operator == (const vector3 &a, const vector3 &b)
|
|
{
|
|
return ((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
|
|
}
|
|
|
|
// Are these two vector3's not equal?
|
|
bool operator != (const vector3 &a, const vector3 &b)
|
|
{
|
|
return ((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
|
|
}
|
|
|
|
// Add two vector3's
|
|
vector3 operator + (const vector3 &a, const vector3 &b)
|
|
{
|
|
vector3 ret(a);
|
|
|
|
ret += b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Subtract one vector3 from another
|
|
vector3 operator - (const vector3 &a, const vector3 &b)
|
|
{
|
|
vector3 ret(a);
|
|
|
|
ret -= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply vector3 by a float
|
|
vector3 operator * (const vector3 &v, float f)
|
|
{
|
|
return vector3(f * v.x, f * v.y, f * v.z);
|
|
}
|
|
|
|
// Multiply vector3 by a float
|
|
vector3 operator * (float f, const vector3 &v)
|
|
{
|
|
return vector3(f * v.x, f * v.y, f * v.z);
|
|
}
|
|
|
|
// Divide vector3 by a float
|
|
vector3 operator / (const vector3 &v, float f)
|
|
{
|
|
return vector3(v.x / f, v.y / f, v.z / f);
|
|
}
|
|
|
|
// Negate a vector3
|
|
vector3 operator - (const vector3 &a)
|
|
{
|
|
return vector3(-a.x, -a.y, -a.z);
|
|
}
|
|
|
|
// Get length of a vector3
|
|
float vector3::length() const
|
|
{
|
|
return (float) sqrt(x*x + y*y + z*z);
|
|
}
|
|
|
|
// Get squared length of a vector3
|
|
float vector3::lengthSqr() const
|
|
{
|
|
return (x*x + y*y + z*z);
|
|
}
|
|
|
|
// Does vector3 equal (0, 0, 0)?
|
|
bool vector3::isZero() const
|
|
{
|
|
return ((x == 0.0F) && (y == 0.0F) && (z == 0.0F));
|
|
}
|
|
|
|
// Normalize a vector3
|
|
vector3 &vector3::normalize()
|
|
{
|
|
float m = length();
|
|
|
|
if (m > 0.0F)
|
|
m = 1.0F / m;
|
|
else
|
|
m = 0.0F;
|
|
x *= m;
|
|
y *= m;
|
|
z *= m;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// vector4 class
|
|
//
|
|
|
|
// Constructor with initializing float values
|
|
vector4::vector4(float inX, float inY, float inZ, float inW)
|
|
{
|
|
x = inX;
|
|
y = inY;
|
|
z = inZ;
|
|
w = inW;
|
|
}
|
|
|
|
// Constructor with initializing vector4
|
|
vector4::vector4(const vector4 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
w = v.w;
|
|
}
|
|
|
|
// Constructor with initializing vector3
|
|
vector4::vector4(const vector3 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
w = 0.0F;
|
|
}
|
|
|
|
// Constructor with initializing vector2
|
|
vector4::vector4(const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = 0.0F;
|
|
w = 0.0F;
|
|
}
|
|
|
|
// Array indexing
|
|
float &vector4::operator [] (unsigned int i)
|
|
{
|
|
assert (i<4);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Array indexing
|
|
const float &vector4::operator [] (unsigned int i) const
|
|
{
|
|
assert (i<4);
|
|
|
|
return *(&x+i);
|
|
}
|
|
|
|
// Assign
|
|
vector4 &vector4::operator = (const vector4 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
w = v.w;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Assign from a vector3
|
|
vector4 &vector4::operator = (const vector3 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
w = 0.0F;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Assign from a vector2
|
|
vector4 &vector4::operator = (const vector2 &v)
|
|
{
|
|
x = v.x;
|
|
y = v.y;
|
|
z = 0.0F;
|
|
w = 0.0F;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Add a vector4 to this one
|
|
vector4 &vector4::operator += (const vector4 &v)
|
|
{
|
|
x += v.x;
|
|
y += v.y;
|
|
z += v.z;
|
|
w += v.w;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Subtract a vector4 from this one
|
|
vector4 &vector4::operator -= (const vector4 &v)
|
|
{
|
|
x -= v.x;
|
|
y -= v.y;
|
|
z -= v.z;
|
|
w -= v.w;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the vector4 by a float
|
|
vector4 &vector4::operator *= (float f)
|
|
{
|
|
x *= f;
|
|
y *= f;
|
|
z *= f;
|
|
w *= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Divide the vector4 by a float
|
|
vector4 &vector4::operator /= (float f)
|
|
{
|
|
x /= f;
|
|
y /= f;
|
|
z /= f;
|
|
w /= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Are these two vector4's equal?
|
|
bool operator == (const vector4 &a, const vector4 &b)
|
|
{
|
|
return ((a.x == b.x) && (a.y == b.y) &&
|
|
(a.z == b.z) && (a.w == b.w));
|
|
}
|
|
|
|
// Are these two vector4's not equal?
|
|
bool operator != (const vector4 &a, const vector4 &b)
|
|
{
|
|
return ((a.x != b.x) || (a.y != b.y) ||
|
|
(a.z != b.z) || (a.w != b.w));
|
|
}
|
|
|
|
// Add two vector4's
|
|
vector4 operator + (const vector4 &a, const vector4 &b)
|
|
{
|
|
vector4 ret(a);
|
|
|
|
ret += b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Subtract one vector4 from another
|
|
vector4 operator - (const vector4 &a, const vector4 &b)
|
|
{
|
|
vector4 ret(a);
|
|
|
|
ret -= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply vector4 by a float
|
|
vector4 operator * (const vector4 &v, float f)
|
|
{
|
|
return vector4(f * v.x, f * v.y, f * v.z, f * v.w);
|
|
}
|
|
|
|
// Multiply vector4 by a float
|
|
vector4 operator * (float f, const vector4 &v)
|
|
{
|
|
return vector4(f * v.x, f * v.y, f * v.z, f * v.w);
|
|
}
|
|
|
|
// Divide vector4 by a float
|
|
vector4 operator / (const vector4 &v, float f)
|
|
{
|
|
return vector4(v.x / f, v.y / f, v.z / f, v.w / f);
|
|
}
|
|
|
|
// Negate a vector4
|
|
vector4 operator - (const vector4 &a)
|
|
{
|
|
return vector4(-a.x, -a.y, -a.z, -a.w);
|
|
}
|
|
|
|
// Get length of a vector4
|
|
float vector4::length() const
|
|
{
|
|
return (float) sqrt(x*x + y*y + z*z + w*w);
|
|
}
|
|
|
|
// Get squared length of a vector4
|
|
float vector4::lengthSqr() const
|
|
{
|
|
return (x*x + y*y + z*z + w*w);
|
|
}
|
|
|
|
// Does vector4 equal (0, 0, 0, 0)?
|
|
bool vector4::isZero() const
|
|
{
|
|
return ((x == 0.0F) && (y == 0.0F) && (z == 0.0F) && (w == 0.0F));
|
|
}
|
|
|
|
// Normalize a vector4
|
|
vector4 &vector4::normalize()
|
|
{
|
|
float m = length();
|
|
|
|
if (m > 0.0F)
|
|
m = 1.0F / m;
|
|
else
|
|
m = 0.0F;
|
|
x *= m;
|
|
y *= m;
|
|
z *= m;
|
|
w *= m;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Miscellaneous vector functions
|
|
//
|
|
|
|
// Dot product of two vector2's
|
|
float DotProduct(const vector2 &a, const vector2 &b)
|
|
{
|
|
return a.x*b.x + a.y*b.y;
|
|
}
|
|
|
|
// Dot product of two vector3's
|
|
float DotProduct(const vector3 &a, const vector3 &b)
|
|
{
|
|
return a.x*b.x + a.y*b.y + a.z*b.z;
|
|
}
|
|
|
|
// Dot product of two vector4's
|
|
float DotProduct(const vector4 &a, const vector4 &b)
|
|
{
|
|
return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
|
|
}
|
|
|
|
// Swap two vector2's
|
|
void SwapVec(vector2 &a, vector2 &b)
|
|
{
|
|
vector2 tmp(a);
|
|
|
|
a = b;
|
|
b = tmp;
|
|
}
|
|
|
|
// Swap two vector3's
|
|
void SwapVec(vector3 &a, vector3 &b)
|
|
{
|
|
vector3 tmp(a);
|
|
|
|
a = b;
|
|
b = tmp;
|
|
}
|
|
|
|
// Swap two vector4's
|
|
void SwapVec(vector4 &a, vector4 &b)
|
|
{
|
|
vector4 tmp(a);
|
|
|
|
a = b;
|
|
b = tmp;
|
|
}
|
|
|
|
// Cross product of two vector3's
|
|
vector3 CrossProduct(const vector3 &a, const vector3 &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);
|
|
}
|
|
|
|
// Are these two vector2's nearly equal?
|
|
bool nearlyEquals( const vector2& a, const vector2& b, float r )
|
|
{
|
|
vector2 diff = a - b; // difference
|
|
|
|
return (DotProduct(diff, diff) < r*r); // radius
|
|
}
|
|
|
|
// Are these two vector3's nearly equal?
|
|
bool nearlyEquals( const vector3& a, const vector3& b, float r )
|
|
{
|
|
vector3 diff = a - b; // difference
|
|
|
|
return (DotProduct(diff, diff) < r*r); // radius
|
|
}
|
|
|
|
// Are these two vector4's nearly equal?
|
|
bool nearlyEquals( const vector4& a, const vector4& b, float r )
|
|
{
|
|
vector4 diff = a - b; // difference
|
|
|
|
return (DotProduct(diff, diff) < r*r); // radius
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// matrix33 class
|
|
//
|
|
|
|
// Constructor with initializing matrix33
|
|
matrix33::matrix33(const matrix33 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
}
|
|
|
|
// Constructor with initializing vector3's
|
|
matrix33::matrix33(const vector3 &v0, const vector3 &v1, const vector3 &v2)
|
|
{
|
|
col[0] = v0;
|
|
col[1] = v1;
|
|
col[2] = v2;
|
|
}
|
|
|
|
// Array indexing
|
|
vector3 &matrix33::operator [] (unsigned int i)
|
|
{
|
|
assert (i<3);
|
|
|
|
return (vector3&)col[i];
|
|
}
|
|
|
|
// Array indexing
|
|
const vector3 &matrix33::operator [] (unsigned int i) const
|
|
{
|
|
assert (i<3);
|
|
|
|
return (vector3&)col[i];
|
|
}
|
|
|
|
// Assign
|
|
matrix33 &matrix33::operator = (const matrix33 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Add a matrix33 to this one
|
|
matrix33 &matrix33::operator += (const matrix33 &m)
|
|
{
|
|
col[0] += m[0];
|
|
col[1] += m[1];
|
|
col[2] += m[2];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Subtract a matrix33 from this one
|
|
matrix33 &matrix33::operator -= (const matrix33 &m)
|
|
{
|
|
col[0] -= m[0];
|
|
col[1] -= m[1];
|
|
col[2] -= m[2];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the matrix33 by another matrix33
|
|
matrix33 &matrix33::operator *= (const matrix33 &m)
|
|
{
|
|
matrix33 t;
|
|
|
|
for (unsigned int r = 0; r < 3; r++)
|
|
{
|
|
for (unsigned int c = 0; c < 3; c++)
|
|
{
|
|
float f = 0;
|
|
|
|
f += col[0][r] * m[c][0];
|
|
f += col[1][r] * m[c][1];
|
|
f += col[2][r] * m[c][2];
|
|
|
|
t[c][r] = f;
|
|
}
|
|
}
|
|
|
|
*this = t;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the matrix33 by a float
|
|
matrix33 &matrix33::operator *= (float f)
|
|
{
|
|
col[0] *= f;
|
|
col[1] *= f;
|
|
col[2] *= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Are these two matrix33's equal?
|
|
bool operator == (const matrix33 &a, const matrix33 &b)
|
|
{
|
|
return ((a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]));
|
|
}
|
|
|
|
// Are these two matrix33's not equal?
|
|
bool operator != (const matrix33 &a, const matrix33 &b)
|
|
{
|
|
return ((a[0] != b[0]) || (a[1] != b[1]) || (a[2] != b[2]));
|
|
}
|
|
|
|
// Add two matrix33's
|
|
matrix33 operator + (const matrix33 &a, const matrix33 &b)
|
|
{
|
|
matrix33 ret(a);
|
|
|
|
ret += b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Subtract one matrix33 from another
|
|
matrix33 operator - (const matrix33 &a, const matrix33 &b)
|
|
{
|
|
matrix33 ret(a);
|
|
|
|
ret -= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply matrix33 by another matrix33
|
|
matrix33 operator * (const matrix33 &a, const matrix33 &b)
|
|
{
|
|
matrix33 ret(a);
|
|
|
|
ret *= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply a vector3 by this matrix33
|
|
vector3 operator * (const matrix33 &m, const vector3 &v)
|
|
{
|
|
vector3 ret;
|
|
matrix33 pose(TransposeMatrix33(m));
|
|
|
|
ret.x = DotProduct(pose[0], v);
|
|
ret.y = DotProduct(pose[1], v);
|
|
ret.z = DotProduct(pose[2], v);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply a vector3 by this matrix33
|
|
vector3 operator * (const vector3 &v, const matrix33 &m)
|
|
{
|
|
vector3 ret;
|
|
|
|
ret.x = DotProduct(m[0], v);
|
|
ret.y = DotProduct(m[1], v);
|
|
ret.z = DotProduct(m[2], v);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply matrix33 by a float
|
|
matrix33 operator * (float f, const matrix33 &m)
|
|
{
|
|
matrix33 ret(m);
|
|
|
|
ret *= f;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply matrix33 by a float
|
|
matrix33 operator * (const matrix33 &m, float f)
|
|
{
|
|
matrix33 ret(m);
|
|
|
|
ret *= f;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Set matrix33 to the identity matrix
|
|
matrix33 &matrix33::identity()
|
|
{
|
|
for (unsigned int c = 0; c < 3; c++)
|
|
{
|
|
for (unsigned int r = 0; r < 3; r++)
|
|
{
|
|
if (c == r)
|
|
col[c][r] = 1.0F;
|
|
else
|
|
col[c][r] = 0.0F;
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Transpose the matrix33
|
|
matrix33 &matrix33::transpose()
|
|
{
|
|
float t;
|
|
|
|
for (unsigned int c = 0; c < 3; c++)
|
|
{
|
|
for (unsigned int r = c + 1; r < 3; r++)
|
|
{
|
|
t = col[c][r];
|
|
col[c][r] = col[r][c];
|
|
col[r][c] = t;
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Invert the matrix33
|
|
matrix33 &matrix33::invert()
|
|
{
|
|
matrix33 a(*this);
|
|
matrix33 b(IdentityMatrix33());
|
|
|
|
unsigned int c, r;
|
|
unsigned int cc;
|
|
unsigned int rowMax; // Points to max abs value row in this column
|
|
unsigned int row;
|
|
float tmp;
|
|
|
|
// Go through columns
|
|
for (c=0; c<3; c++)
|
|
{
|
|
// Find the row with max value in this column
|
|
rowMax = c;
|
|
for (r=c+1; r<3; r++)
|
|
{
|
|
if (fabs(a[c][r]) > fabs(a[c][rowMax]))
|
|
{
|
|
rowMax = r;
|
|
}
|
|
}
|
|
|
|
// If the max value here is 0, we can't invert. Return identity.
|
|
if (a[rowMax][c] == 0.0F)
|
|
return (identity());
|
|
|
|
// Swap row "rowMax" with row "c"
|
|
for (cc=0; cc<3; cc++)
|
|
{
|
|
tmp = a[cc][c];
|
|
a[cc][c] = a[cc][rowMax];
|
|
a[cc][rowMax] = tmp;
|
|
tmp = b[cc][c];
|
|
b[cc][c] = b[cc][rowMax];
|
|
b[cc][rowMax] = tmp;
|
|
}
|
|
|
|
// Now everything we do is on row "c".
|
|
// Set the max cell to 1 by dividing the entire row by that value
|
|
tmp = a[c][c];
|
|
for (cc=0; cc<3; cc++)
|
|
{
|
|
a[cc][c] /= tmp;
|
|
b[cc][c] /= tmp;
|
|
}
|
|
|
|
// Now do the other rows, so that this column only has a 1 and 0's
|
|
for (row = 0; row < 3; row++)
|
|
{
|
|
if (row != c)
|
|
{
|
|
tmp = a[c][row];
|
|
for (cc=0; cc<3; cc++)
|
|
{
|
|
a[cc][row] -= a[cc][c] * tmp;
|
|
b[cc][row] -= b[cc][c] * tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
*this = b;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Return a matrix33 set to the identity matrix
|
|
matrix33 IdentityMatrix33()
|
|
{
|
|
matrix33 ret;
|
|
|
|
return ret.identity();
|
|
}
|
|
|
|
// Return the transpose of the matrix33
|
|
matrix33 TransposeMatrix33(const matrix33 &m)
|
|
{
|
|
matrix33 ret(m);
|
|
|
|
return ret.transpose();
|
|
}
|
|
|
|
// Return the inverted matrix33
|
|
matrix33 InvertMatrix33(const matrix33 &m)
|
|
{
|
|
matrix33 ret(m);
|
|
|
|
return ret.invert();
|
|
}
|
|
|
|
// Return a 2D rotation matrix33
|
|
matrix33 RotateRadMatrix33(float rad)
|
|
{
|
|
matrix33 ret;
|
|
float sinA, cosA;
|
|
|
|
sinA = (float)sin(rad);
|
|
cosA = (float)cos(rad);
|
|
|
|
ret[0][0] = cosA; ret[1][0] = -sinA; ret[2][0] = 0.0F;
|
|
ret[0][1] = sinA; ret[1][1] = cosA; ret[2][1] = 0.0F;
|
|
ret[0][2] = 0.0F; ret[1][2] = 0.0F; ret[2][2] = 1.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a 2D translation matrix33
|
|
matrix33 TranslateMatrix33(float x, float y)
|
|
{
|
|
matrix33 ret;
|
|
|
|
ret.identity();
|
|
ret[2][0] = x;
|
|
ret[2][1] = y;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a 2D/3D scale matrix33
|
|
matrix33 ScaleMatrix33(float x, float y, float z)
|
|
{
|
|
matrix33 ret;
|
|
|
|
ret.identity();
|
|
ret[0][0] = x;
|
|
ret[1][1] = y;
|
|
ret[2][2] = z;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// matrix44 class
|
|
//
|
|
|
|
// Constructor with initializing matrix44
|
|
matrix44::matrix44(const matrix44 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
col[3] = m[3];
|
|
}
|
|
|
|
// Constructor with initializing matrix33
|
|
matrix44::matrix44(const matrix33 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
col[3] = vector4(0.0, 0.0, 0.0, 1.0);
|
|
}
|
|
|
|
// Constructor with initializing vector4's
|
|
matrix44::matrix44(const vector4 &v0, const vector4 &v1,
|
|
const vector4 &v2, const vector4 &v3)
|
|
{
|
|
col[0] = v0;
|
|
col[1] = v1;
|
|
col[2] = v2;
|
|
col[3] = v3;
|
|
}
|
|
|
|
// Array indexing
|
|
vector4 &matrix44::operator [] (unsigned int i)
|
|
{
|
|
assert (i<4);
|
|
|
|
return (vector4&) col[i];
|
|
}
|
|
|
|
// Array indexing
|
|
const vector4 &matrix44::operator [] (unsigned int i) const
|
|
{
|
|
assert (i<4);
|
|
|
|
return (vector4&) col[i];
|
|
}
|
|
|
|
// Assign
|
|
matrix44 &matrix44::operator = (const matrix44 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
col[3] = m[3];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Assign a matrix33 to the matrix44
|
|
matrix44 &matrix44::operator = (const matrix33 &m)
|
|
{
|
|
col[0] = m[0];
|
|
col[1] = m[1];
|
|
col[2] = m[2];
|
|
col[3] = vector4(0.0, 0.0, 0.0, 1.0);
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Add a matrix44 to this one
|
|
matrix44 &matrix44::operator += (const matrix44 &m)
|
|
{
|
|
col[0] += m[0];
|
|
col[1] += m[1];
|
|
col[2] += m[2];
|
|
col[3] += m[3];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Subtract a matrix44 from this one
|
|
matrix44 &matrix44::operator -= (const matrix44 &m)
|
|
{
|
|
col[0] -= m[0];
|
|
col[1] -= m[1];
|
|
col[2] -= m[2];
|
|
col[3] -= m[3];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the matrix44 by another matrix44
|
|
matrix44 &matrix44::operator *= (const matrix44 &m)
|
|
{
|
|
matrix44 t;
|
|
|
|
for (unsigned int r = 0; r < 4; r++)
|
|
{
|
|
for (unsigned int c = 0; c < 4; c++)
|
|
{
|
|
float f = 0;
|
|
|
|
f += col[0][r] * m[c][0];
|
|
f += col[1][r] * m[c][1];
|
|
f += col[2][r] * m[c][2];
|
|
f += col[3][r] * m[c][3];
|
|
|
|
t[c][r] = f;
|
|
}
|
|
}
|
|
|
|
*this = t;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Multiply the matrix44 by a float
|
|
matrix44 &matrix44::operator *= (float f)
|
|
{
|
|
col[0] *= f;
|
|
col[1] *= f;
|
|
col[2] *= f;
|
|
col[3] *= f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Are these two matrix44's equal?
|
|
bool operator == (const matrix44 &a, const matrix44 &b)
|
|
{
|
|
return ((a[0] == b[0]) && (a[1] == b[1]) &&
|
|
(a[2] == b[2]) && (a[3] == b[3]));
|
|
}
|
|
|
|
// Are these two matrix44's not equal?
|
|
bool operator != (const matrix44 &a, const matrix44 &b)
|
|
{
|
|
return ((a[0] != b[0]) || (a[1] != b[1]) ||
|
|
(a[2] != b[2]) || (a[3] != b[3]));
|
|
}
|
|
|
|
// Add two matrix44's
|
|
matrix44 operator + (const matrix44 &a, const matrix44 &b)
|
|
{
|
|
matrix44 ret(a);
|
|
|
|
ret += b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Subtract one matrix44 from another
|
|
matrix44 operator - (const matrix44 &a, const matrix44 &b)
|
|
{
|
|
matrix44 ret(a);
|
|
|
|
ret -= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply matrix44 by another matrix44
|
|
matrix44 operator * (const matrix44 &a, const matrix44 &b)
|
|
{
|
|
matrix44 ret(a);
|
|
|
|
ret *= b;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply a vector4 by this matrix44
|
|
vector4 operator * (const matrix44 &m, const vector4 &v)
|
|
{
|
|
vector4 ret;
|
|
matrix44 pose(TransposeMatrix44(m));
|
|
|
|
ret.x = DotProduct(pose[0], v);
|
|
ret.y = DotProduct(pose[1], v);
|
|
ret.z = DotProduct(pose[2], v);
|
|
ret.w = DotProduct(pose[3], v);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply a vector4 by this matrix44
|
|
vector4 operator * (const vector4 &v, const matrix44 &m)
|
|
{
|
|
vector4 ret;
|
|
|
|
ret.x = DotProduct(m[0], v);
|
|
ret.y = DotProduct(m[1], v);
|
|
ret.z = DotProduct(m[2], v);
|
|
ret.w = DotProduct(m[3], v);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Multiply matrix44 by a float
|
|
matrix44 operator * (float f, const matrix44 &m)
|
|
{
|
|
matrix44 ret(m);
|
|
|
|
ret *= f;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Set matrix44 to the identity matrix
|
|
matrix44 &matrix44::identity()
|
|
{
|
|
for (unsigned int c = 0; c < 4; c++)
|
|
{
|
|
for (unsigned int r = 0; r < 4; r++)
|
|
{
|
|
if (c == r)
|
|
col[c][r] = 1.0F;
|
|
else
|
|
col[c][r] = 0.0F;
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Transpose the matrix44
|
|
matrix44 &matrix44::transpose()
|
|
{
|
|
float t;
|
|
|
|
for (unsigned int c = 0; c < 4; c++)
|
|
{
|
|
for (unsigned int r = c + 1; r < 4; r++)
|
|
{
|
|
t = col[c][r];
|
|
col[c][r] = col[r][c];
|
|
col[r][c] = t;
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Invert the matrix44
|
|
matrix44 &matrix44::invert()
|
|
{
|
|
matrix44 a(*this);
|
|
matrix44 b(IdentityMatrix44());
|
|
|
|
unsigned int r, c;
|
|
unsigned int cc;
|
|
unsigned int rowMax; // Points to max abs value row in this column
|
|
unsigned int row;
|
|
float tmp;
|
|
|
|
// Go through columns
|
|
for (c=0; c<4; c++)
|
|
{
|
|
|
|
// Find the row with max value in this column
|
|
rowMax = c;
|
|
for (r=c+1; r<4; r++)
|
|
{
|
|
if (fabs(a[c][r]) > fabs(a[c][rowMax]))
|
|
{
|
|
rowMax = r;
|
|
}
|
|
}
|
|
|
|
// If the max value here is 0, we can't invert. Return identity.
|
|
if (a[rowMax][c] == 0.0F)
|
|
return (identity());
|
|
|
|
// Swap row "rowMax" with row "c"
|
|
for (cc=0; cc<4; cc++)
|
|
{
|
|
tmp = a[cc][c];
|
|
a[cc][c] = a[cc][rowMax];
|
|
a[cc][rowMax] = tmp;
|
|
tmp = b[cc][c];
|
|
b[cc][c] = b[cc][rowMax];
|
|
b[cc][rowMax] = tmp;
|
|
}
|
|
|
|
// Now everything we do is on row "c".
|
|
// Set the max cell to 1 by dividing the entire row by that value
|
|
tmp = a[c][c];
|
|
for (cc=0; cc<4; cc++)
|
|
{
|
|
a[cc][c] /= tmp;
|
|
b[cc][c] /= tmp;
|
|
}
|
|
|
|
// Now do the other rows, so that this column only has a 1 and 0's
|
|
for (row = 0; row < 4; row++)
|
|
{
|
|
if (row != c)
|
|
{
|
|
tmp = a[c][row];
|
|
for (cc=0; cc<4; cc++)
|
|
{
|
|
a[cc][row] -= a[cc][c] * tmp;
|
|
b[cc][row] -= b[cc][c] * tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
*this = b;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Return a matrix44 set to the identity matrix
|
|
matrix44 IdentityMatrix44()
|
|
{
|
|
matrix44 ret;
|
|
|
|
return ret.identity();
|
|
}
|
|
|
|
// Return the transpose of the matrix44
|
|
matrix44 TransposeMatrix44(const matrix44 &m)
|
|
{
|
|
matrix44 ret(m);
|
|
|
|
return ret.transpose();
|
|
}
|
|
|
|
// Return the inverted matrix44
|
|
matrix44 InvertMatrix44(const matrix44 &m)
|
|
{
|
|
matrix44 ret(m);
|
|
|
|
return ret.invert();
|
|
}
|
|
|
|
// Return a 3D axis-rotation matrix44
|
|
// Pass in 'x', 'y', or 'z' for the axis.
|
|
matrix44 RotateRadMatrix44(char axis, float rad)
|
|
{
|
|
matrix44 ret;
|
|
float sinA, cosA;
|
|
|
|
sinA = (float)sin(rad);
|
|
cosA = (float)cos(rad);
|
|
|
|
switch(axis)
|
|
{
|
|
case 'x':
|
|
case 'X':
|
|
ret[0][0] = 1.0F; ret[1][0] = 0.0F; ret[2][0] = 0.0F;
|
|
ret[0][1] = 0.0F; ret[1][1] = cosA; ret[2][1] = -sinA;
|
|
ret[0][2] = 0.0F; ret[1][2] = sinA; ret[2][2] = cosA;
|
|
break;
|
|
|
|
case 'y':
|
|
case 'Y':
|
|
ret[0][0] = cosA; ret[1][0] = 0.0F; ret[2][0] = sinA;
|
|
ret[0][1] = 0.0F; ret[1][1] = 1.0F; ret[2][1] = 0.0F;
|
|
ret[0][2] = -sinA; ret[1][2] = 0.0F; ret[2][2] = cosA;
|
|
break;
|
|
|
|
case 'z':
|
|
case 'Z':
|
|
ret[0][0] = cosA; ret[1][0] = -sinA; ret[2][0] = 0.0F;
|
|
ret[0][1] = sinA; ret[1][1] = cosA; ret[2][1] = 0.0F;
|
|
ret[0][2] = 0.0F; ret[1][2] = 0.0F; ret[2][2] = 1.0F;
|
|
break;
|
|
}
|
|
|
|
ret[0][3] = 0.0F; ret[1][3] = 0.0F; ret[2][3] = 0.0F;
|
|
ret[3][0] = 0.0F;
|
|
ret[3][1] = 0.0F;
|
|
ret[3][2] = 0.0F;
|
|
ret[3][3] = 1.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a 3D axis-rotation matrix44
|
|
// Pass in an arbitrary vector3 axis.
|
|
matrix44 RotateRadMatrix44(const vector3 &axis, float rad)
|
|
{
|
|
matrix44 ret;
|
|
float sinA, cosA;
|
|
float invCosA;
|
|
vector3 nrm = axis;
|
|
float x, y, z;
|
|
float xSq, ySq, zSq;
|
|
|
|
nrm.normalize();
|
|
sinA = (float)sin(rad);
|
|
cosA = (float)cos(rad);
|
|
invCosA = 1.0F - cosA;
|
|
|
|
x = nrm.x;
|
|
y = nrm.y;
|
|
z = nrm.z;
|
|
|
|
xSq = x * x;
|
|
ySq = y * y;
|
|
zSq = z * z;
|
|
|
|
ret[0][0] = (invCosA * xSq) + (cosA);
|
|
ret[1][0] = (invCosA * x * y) - (sinA * z );
|
|
ret[2][0] = (invCosA * x * z) + (sinA * y );
|
|
ret[3][0] = 0.0F;
|
|
|
|
ret[0][1] = (invCosA * x * y) + (sinA * z);
|
|
ret[1][1] = (invCosA * ySq) + (cosA);
|
|
ret[2][1] = (invCosA * y * z) - (sinA * x);
|
|
ret[3][1] = 0.0F;
|
|
|
|
ret[0][2] = (invCosA * x * z) - (sinA * y);
|
|
ret[1][2] = (invCosA * y * z) + (sinA * x);
|
|
ret[2][2] = (invCosA * zSq) + (cosA);
|
|
ret[3][2] = 0.0F;
|
|
|
|
ret[0][3] = 0.0F;
|
|
ret[1][3] = 0.0F;
|
|
ret[2][3] = 0.0F;
|
|
ret[3][3] = 1.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a 3D translation matrix44
|
|
matrix44 TranslateMatrix44(float x, float y, float z)
|
|
{
|
|
matrix44 ret;
|
|
|
|
ret.identity();
|
|
ret[3][0] = x;
|
|
ret[3][1] = y;
|
|
ret[3][2] = z;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a 3D/4D scale matrix44
|
|
matrix44 ScaleMatrix44(float x, float y, float z, float w)
|
|
{
|
|
matrix44 ret;
|
|
|
|
ret.identity();
|
|
ret[0][0] = x;
|
|
ret[1][1] = y;
|
|
ret[2][2] = z;
|
|
ret[3][3] = w;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a "lookat" matrix44 given the current camera position (vector3),
|
|
// camera-up vector3, and camera-target vector3.
|
|
matrix44 LookAtMatrix44(const vector3 &camPos, const vector3 &camUp,
|
|
const vector3 &target )
|
|
{
|
|
matrix44 ret;
|
|
|
|
vector3 F = target - camPos;
|
|
F.normalize();
|
|
|
|
vector3 upNorm = camUp;
|
|
upNorm.normalize();
|
|
|
|
vector3 s = CrossProduct(F, upNorm);
|
|
vector3 u = CrossProduct(s, F);
|
|
|
|
ret[0][0] = s[0]; ret[1][0] = s[1]; ret[2][0] = s[2]; ret[3][0] = 0.0F;
|
|
ret[0][1] = u[0]; ret[1][1] = u[1]; ret[2][1] = u[2]; ret[3][1] = 0.0F;
|
|
ret[0][2] =-F[0]; ret[1][2] =-F[1]; ret[2][2] =-F[2]; ret[3][2] = 0.0F;
|
|
ret[0][3] = 0.0F; ret[1][3] = 0.0F; ret[2][3] = 0.0F; ret[3][3] = 1.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a frustum matrix44 given the left, right, bottom, top,
|
|
// near, and far values for the frustum boundaries.
|
|
matrix44 FrustumMatrix44(float l, float r,
|
|
float b, float t, float n, float f)
|
|
{
|
|
matrix44 ret;
|
|
float width = r-l;
|
|
float height = t-b;
|
|
float depth = f-n;
|
|
|
|
ret[0][0] = (2*n) / width;
|
|
ret[0][1] = 0.0F;
|
|
ret[0][2] = 0.0F;
|
|
ret[0][3] = 0.0F;
|
|
|
|
ret[1][0] = 0.0F;
|
|
ret[1][1] = (2*n) / height;
|
|
ret[1][2] = 0.0F;
|
|
ret[1][3] = 0.0F;
|
|
|
|
ret[2][0] = (r + l) / width;
|
|
ret[2][1] = (t + b) / height;
|
|
ret[2][2] = -(f + n) / depth;
|
|
ret[2][3] = -1.0F;
|
|
|
|
ret[3][0] = 0.0F;
|
|
ret[3][1] = 0.0F;
|
|
ret[3][2] = -(2*f*n) / depth;
|
|
ret[3][3] = 0.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return a perspective matrix44 given the field-of-view in the Y
|
|
// direction in degrees, the aspect ratio of Y/X, and near and
|
|
// far plane distances.
|
|
matrix44 PerspectiveMatrix44(float fovY, float aspect, float n, float f)
|
|
{
|
|
matrix44 ret;
|
|
float angle;
|
|
float cot;
|
|
|
|
angle = fovY / 2.0F;
|
|
angle = DegToRad( angle );
|
|
|
|
cot = (float) cos(angle) / (float) sin(angle);
|
|
|
|
ret[0][0] = cot / aspect;
|
|
ret[0][1] = 0.0F;
|
|
ret[0][2] = 0.0F;
|
|
ret[0][3] = 0.0F;
|
|
|
|
ret[1][0] = 0.0F;
|
|
ret[1][1] = cot;
|
|
ret[1][2] = 0.0F;
|
|
ret[1][3] = 0.0F;
|
|
|
|
ret[2][0] = 0.0F;
|
|
ret[2][1] = 0.0F;
|
|
ret[2][2] = -(f + n) / (f - n);
|
|
ret[2][3] = -1.0F;
|
|
|
|
|
|
ret[3][0] = 0.0F;
|
|
ret[3][1] = 0.0F;
|
|
ret[3][2] = -(2*f*n) / (f - n);
|
|
ret[3][3] = 0.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Return an orthographic matrix44 given the left, right, bottom, top,
|
|
// near, and far values for the frustum boundaries.
|
|
matrix44 OrthoMatrix44(float l, float r,
|
|
float b, float t, float n, float f)
|
|
{
|
|
matrix44 ret;
|
|
float width = r-l;
|
|
float height = t-b;
|
|
float depth = f-n;
|
|
|
|
ret[0][0] = 2.0F / width;
|
|
ret[0][1] = 0.0F;
|
|
ret[0][2] = 0.0F;
|
|
ret[0][3] = 0.0F;
|
|
|
|
ret[1][0] = 0.0F;
|
|
ret[1][1] = 2.0F / height;
|
|
ret[1][2] = 0.0F;
|
|
ret[1][3] = 0.0F;
|
|
|
|
ret[2][0] = 0.0F;
|
|
ret[2][1] = 0.0F;
|
|
ret[2][2] = -(2.0F) / depth;
|
|
ret[2][3] = 0.0F;
|
|
|
|
ret[3][0] = -(r + l) / width;
|
|
ret[1][3] = -(t + b) / height;
|
|
ret[3][2] = -(f + n) / depth;
|
|
ret[3][3] = 1.0F;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Debug functions
|
|
//
|
|
|
|
// Print a vector2 to a file
|
|
void vector2::fprint(FILE* file, char* str) const
|
|
{
|
|
fprintf(file, "%svector2: <%f, %f>\n", str, x, y);
|
|
}
|
|
|
|
// Print a vector3 to a file
|
|
void vector3::fprint(FILE* file, char* str) const
|
|
{
|
|
fprintf(file, "%svector3: <%f, %f, %f>\n", str, x, y, z);
|
|
}
|
|
|
|
// Print a vector4 to a file
|
|
void vector4::fprint(FILE* file, char* str) const
|
|
{
|
|
fprintf(file, "%svector4: <%f, %f, %f, %f>\n", str, x, y, z, w);
|
|
}
|
|
|
|
// Print a matrix33 to a file
|
|
void matrix33::fprint(FILE* file, char * str) const
|
|
{
|
|
fprintf(file, "%smatrix33:\n", str);
|
|
col[0].fprint(file, "\t");
|
|
col[1].fprint(file, "\t");
|
|
col[2].fprint(file, "\t");
|
|
}
|
|
|
|
// Print a matrix44 to a file
|
|
void matrix44::fprint(FILE* file, char* str) const
|
|
{
|
|
fprintf(file, "%smatrix44:\n", str);
|
|
col[0].fprint(file, "\t");
|
|
col[1].fprint(file, "\t");
|
|
col[2].fprint(file, "\t");
|
|
col[3].fprint(file, "\t");
|
|
}
|