irrlicht/source/Irrlicht.NET/Matrix4.h

616 lines
21 KiB
C++

// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrMath.h"
#include "..\\..\\include\\matrix4.h"
#include "Vector3D.h"
namespace Irrlicht
{
namespace Core
{
/// <summary>
/// 4x4 matrix. Mostly used as transformation matrix for 3d calculations.
/// Matrix4 is mainly used by the Irrlicht engine for doing transformations.
/// The matrix is a D3D style matrix, row major with translations in the 4th row.
/// This class has been ported directly from the native C++ Irrlicht Engine, so it may not
/// be 100% complete yet and the design may not be 100% .NET like.
/// </summary>
public __value struct Matrix4
{
public:
/// <summary> Constructor </summary>
Matrix4()
{
//Members = new float __gc[16];
MakeIdentity();
}
/// <summary> Set matrix to identity. </summary>
void MakeIdentity()
{
for (int i=0; i<16; ++i)
Members[i] = 0.0f;
Members[0] = Members[5] = Members[10] = Members[15] = 1;
}
/// <summary> Direct accessing every row and colum of the matrix values </summary>
__property inline float get_M(int row, int col)
{
if (row < 0 || row >= 4 ||
col < 0 || col >= 4)
throw new System::Exception(new System::String("Invalid index for accessing matrix members"));
return Members[col * 4 + row];
}
/// <summary> Direct accessing every row and colum of the matrix values </summary>
inline void set_M(int row, int col, float v)
{
if (row < 0 || row >= 4 ||
col < 0 || col >= 4)
throw new System::Exception(new System::String("Invalid index for accessing matrix members"));
Members[col * 4 + row] = v;
}
/*
/// <summary> Sets this matrix equal to the other matrix.</summary>
matrix4& operator=(const matrix4 &other);
/// <summary> Returns true if other matrix is equal to this matrix.</summary>
bool operator==(const matrix4 &other) const;
/// <summary> Returns true if other matrix is not equal to this matrix.</summary>
bool operator!=(const matrix4 &other) const;
/// <summary> Multiply by another matrix.</summary>
matrix4& operator*=(const matrix4& other);
*/
/// <summary> Multiply by another matrix. </summary>
static Matrix4 op_Multiply(Matrix4 a, Matrix4 b)
{
Matrix4 tmtrx;
#define m1 a.Members
#define m2 b.Members
#define m3 tmtrx.Members
m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
#undef m1
#undef m2
#undef m3
return tmtrx;
}
/// <summary> Returns true if the matrix is the identity matrix. </summary>
inline bool IsIdentity()
{
for (int i=0; i<4; ++i)
for (int j=0; j<4; ++j)
if (j != i)
{
if (get_M(i,j) < -0.0000001f ||
get_M(i,j) > 0.0000001f)
return false;
}
else
{
if (get_M(i,j) < 0.9999999f ||
get_M(i,j) > 1.0000001f)
return false;
}
return true;
}
/// <summary> Set the translation of the current matrix. Will erase any previous values.</summary>
void SetTranslation( const Vector3D translation )
{
Members[12] = translation.X;
Members[13] = translation.Y;
Members[14] = translation.Z;
}
/// <summary> Gets the current translation</summary>
Vector3D GetTranslation()
{
return Vector3D(Members[12], Members[13], Members[14]);
}
/// <summary> Set the inverse translation of the current matrix.
/// Will erase any previous values.</summary>
void SetInverseTranslation( const Vector3D translation )
{
Members[12] = -translation.X;
Members[13] = -translation.Y;
Members[14] = -translation.Z;
}
/// <summary> Make a rotation matrix from Euler angles.
/// The 4th row and column are unmodified.</summary>
void SetRotationRadians( const Vector3D rotation )
{
double cr = Math::Cos( rotation.X );
double sr = Math::Sin( rotation.X );
double cp = Math::Cos( rotation.Y );
double sp = Math::Sin( rotation.Y );
double cy = Math::Cos( rotation.Z );
double sy = Math::Sin( rotation.Z );
Members[0] = (float)( cp*cy );
Members[1] = (float)( cp*sy );
Members[2] = (float)( -sp );
double srsp = sr*sp;
double crsp = cr*sp;
Members[4] = (float)( srsp*cy-cr*sy );
Members[5] = (float)( srsp*sy+cr*cy );
Members[6] = (float)( sr*cp );
Members[8] = (float)( crsp*cy+sr*sy );
Members[9] = (float)( crsp*sy-sr*cy );
Members[10] = (float)( cr*cp );
}
/// <summary> Make a rotation matrix from Euler angles.
/// The 4th row and column are unmodified.</summary>
void SetRotationDegrees( const Vector3D rotation )
{
SetRotationRadians( rotation * (float)(3.1415926535897932384626433832795 / 180.0) );
}
/// <summary> Returns the rotation, as set by setRotation().
/// This code was orginally written by by Chev.</summary>
Vector3D GetRotationDegrees()
{
Matrix4 &mat = *this;
double Y = -asin(mat.get_M(2,0));
double D = Y;
double C = cos(Y);
Y *= GRAD_PI;
double rotx, roty, X, Z;
if (fabs(C) > 0.0005f)
{
rotx = mat.get_M(2,2) / C;
roty = mat.get_M(2,1) / C;
X = atan2( roty, rotx ) * GRAD_PI;
rotx = mat.get_M(0,0) / C;
roty = mat.get_M(1,0) / C;
Z = atan2( roty, rotx ) * GRAD_PI;
}
else
{
X = 0.0f;
rotx = mat.get_M(1,1);
roty = -mat.get_M(0,1);
Z = atan2( roty, rotx ) * GRAD_PI;
}
// fix values that get below zero
// before it would set (!) values to 360
// that where above 360:
if (X < 0.00) X += 360.00;
if (Y < 0.00) Y += 360.00;
if (Z < 0.00) Z += 360.00;
return Vector3D((float)X, (float)Y, (float)Z);
}
/*
/// <summary> Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified.</summary>
void setInverseRotationRadians( const Vector3D& rotation );
/// <summary> Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified.</summary>
void setInverseRotationDegrees( const Vector3D& rotation );
*/
/// <summary> Set Scale </summary>
void SetScale( Vector3D scale )
{
Members[0] = scale.X;
Members[5] = scale.Y;
Members[10] = scale.Z;
}
/*
/// <summary> Translate a vector by the inverse of the translation part of this matrix.</summary>
void inverseTranslateVect( Vector3D& vect ) const;
/// <summary> Rotate a vector by the inverse of the rotation part of this matrix.</summary>
void inverseRotateVect( Vector3D& vect ) const;
/// <summary> Rotate a vector by the rotation part of this matrix.</summary>
void rotateVect( Vector3D& vect ) const;
*/
/// <summary> Transforms the vector by this matrix </summary>
void TransformVect( Vector3D& vect)
{
float vector[3];
vector[0] = vect.X*Members[0] + vect.Y*Members[4] + vect.Z*Members[8] + Members[12];
vector[1] = vect.X*Members[1] + vect.Y*Members[5] + vect.Z*Members[9] + Members[13];
vector[2] = vect.X*Members[2] + vect.Y*Members[6] + vect.Z*Members[10] + Members[14];
vect.X = vector[0];
vect.Y = vector[1];
vect.Z = vector[2];
}
/// <summary> Transforms input vector by this matrix and stores result in output vector </summary>
void TransformVect( const Vector3D& in, Vector3D& out)
{
out.X = in.X*Members[0] + in.Y*Members[4] + in.Z*Members[8] + Members[12];
out.Y = in.X*Members[1] + in.Y*Members[5] + in.Z*Members[9] + Members[13];
out.Z = in.X*Members[2] + in.Y*Members[6] + in.Z*Members[10] + Members[14];
}
/// <summary> Translate a vector by the translation part of this matrix.</summary>
void TranslateVect( Vector3D& vect )
{
vect.X = vect.X+Members[12];
vect.Y = vect.Y+Members[13];
vect.Z = vect.Z+Members[14];
}
/*
/// <summary> Transforms a plane by this matrix </summary>
void transformPlane( core::plane3d<float> &plane) const
/// <summary> Transforms a plane by this matrix</summary>
void transformPlane( const core::plane3d<float> &in, core::plane3d<float> &out) const;
/// <summary> Transforms a axis aligned bounding box</summary>
void transformBox( core::aabbox3d<float> &box) const;
/// <summary> Multiplies this matrix by a 1x4 matrix</summary>
void multiplyWith1x4Matrix(float* matrix) const;
*/
/// <summary> Calculates inverse of matrix. Slow.</summary>
/// <returns> Returns false if there is no inverse matrix.</returns>
bool MakeInverse()
{
Matrix4 temp;
if (GetInverse(temp))
{
*this = temp;
return true;
}
return false;
}
/// <summary> returns the inversed matrix of this one</summary>
/// <param name="Target"> where result matrix is written to.</param>
/// <returns>Returns false if there is no inverse matrix.</returns>
bool GetInverse(Matrix4& out)
{
/// Calculates the inverse of this Matrix
/// The inverse is calculated using Cramers rule.
/// If no inverse exists then 'false' is returned.
#define m getMInsecure
#define out out.setMInsecure
float d = (m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1)) * (m(2, 2) * m(3, 3) - m(3, 2) * m(2, 3)) - (m(0, 0) * m(2, 1) - m(2, 0) * m(0, 1)) * (m(1, 2) * m(3, 3) - m(3, 2) * m(1, 3))
+ (m(0, 0) * m(3, 1) - m(3, 0) * m(0, 1)) * (m(1, 2) * m(2, 3) - m(2, 2) * m(1, 3)) + (m(1, 0) * m(2, 1) - m(2, 0) * m(1, 1)) * (m(0, 2) * m(3, 3) - m(3, 2) * m(0, 3))
- (m(1, 0) * m(3, 1) - m(3, 0) * m(1, 1)) * (m(0, 2) * m(2, 3) - m(2, 2) * m(0, 3)) + (m(2, 0) * m(3, 1) - m(3, 0) * m(2, 1)) * (m(0, 2) * m(1, 3) - m(1, 2) * m(0, 3));
if (d == 0.f)
return false;
d = 1.f / d;
out(0, 0, d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(3, 2) * m(2, 3)) + m(2, 1) * (m(3, 2) * m(1, 3) - m(1, 2) * m(3, 3)) + m(3, 1) * (m(1, 2) * m(2, 3) - m(2, 2) * m(1, 3))));
out(1, 0, d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(3, 0) * m(2, 3)) + m(2, 2) * (m(3, 0) * m(1, 3) - m(1, 0) * m(3, 3)) + m(3, 2) * (m(1, 0) * m(2, 3) - m(2, 0) * m(1, 3))));
out(2, 0, d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(3, 0) * m(2, 1)) + m(2, 3) * (m(3, 0) * m(1, 1) - m(1, 0) * m(3, 1)) + m(3, 3) * (m(1, 0) * m(2, 1) - m(2, 0) * m(1, 1))));
out(3, 0, d * (m(1, 0) * (m(3, 1) * m(2, 2) - m(2, 1) * m(3, 2)) + m(2, 0) * (m(1, 1) * m(3, 2) - m(3, 1) * m(1, 2)) + m(3, 0) * (m(2, 1) * m(1, 2) - m(1, 1) * m(2, 2))));
out(0, 1, d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(3, 2) * m(0, 3)) + m(3, 1) * (m(2, 2) * m(0, 3) - m(0, 2) * m(2, 3)) + m(0, 1) * (m(3, 2) * m(2, 3) - m(2, 2) * m(3, 3))));
out(1, 1, d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(3, 0) * m(0, 3)) + m(3, 2) * (m(2, 0) * m(0, 3) - m(0, 0) * m(2, 3)) + m(0, 2) * (m(3, 0) * m(2, 3) - m(2, 0) * m(3, 3))));
out(2, 1, d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(3, 0) * m(0, 1)) + m(3, 3) * (m(2, 0) * m(0, 1) - m(0, 0) * m(2, 1)) + m(0, 3) * (m(3, 0) * m(2, 1) - m(2, 0) * m(3, 1))));
out(3, 1, d * (m(2, 0) * (m(3, 1) * m(0, 2) - m(0, 1) * m(3, 2)) + m(3, 0) * (m(0, 1) * m(2, 2) - m(2, 1) * m(0, 2)) + m(0, 0) * (m(2, 1) * m(3, 2) - m(3, 1) * m(2, 2))));
out(0, 2, d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(1, 2) * m(0, 3)) + m(0, 1) * (m(1, 2) * m(3, 3) - m(3, 2) * m(1, 3)) + m(1, 1) * (m(3, 2) * m(0, 3) - m(0, 2) * m(3, 3))));
out(1, 2, d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(1, 0) * m(0, 3)) + m(0, 2) * (m(1, 0) * m(3, 3) - m(3, 0) * m(1, 3)) + m(1, 2) * (m(3, 0) * m(0, 3) - m(0, 0) * m(3, 3))));
out(2, 2, d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1)) + m(0, 3) * (m(1, 0) * m(3, 1) - m(3, 0) * m(1, 1)) + m(1, 3) * (m(3, 0) * m(0, 1) - m(0, 0) * m(3, 1))));
out(3, 2, d * (m(3, 0) * (m(1, 1) * m(0, 2) - m(0, 1) * m(1, 2)) + m(0, 0) * (m(3, 1) * m(1, 2) - m(1, 1) * m(3, 2)) + m(1, 0) * (m(0, 1) * m(3, 2) - m(3, 1) * m(0, 2))));
out(0, 3, d * (m(0, 1) * (m(2, 2) * m(1, 3) - m(1, 2) * m(2, 3)) + m(1, 1) * (m(0, 2) * m(2, 3) - m(2, 2) * m(0, 3)) + m(2, 1) * (m(1, 2) * m(0, 3) - m(0, 2) * m(1, 3))));
out(1, 3, d * (m(0, 2) * (m(2, 0) * m(1, 3) - m(1, 0) * m(2, 3)) + m(1, 2) * (m(0, 0) * m(2, 3) - m(2, 0) * m(0, 3)) + m(2, 2) * (m(1, 0) * m(0, 3) - m(0, 0) * m(1, 3))));
out(2, 3, d * (m(0, 3) * (m(2, 0) * m(1, 1) - m(1, 0) * m(2, 1)) + m(1, 3) * (m(0, 0) * m(2, 1) - m(2, 0) * m(0, 1)) + m(2, 3) * (m(1, 0) * m(0, 1) - m(0, 0) * m(1, 1))));
out(3, 3, d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) + m(1, 0) * (m(2, 1) * m(0, 2) - m(0, 1) * m(2, 2)) + m(2, 0) * (m(0, 1) * m(1, 2) - m(1, 1) * m(0, 2))));
return true;
}
/// <summary> Builds a right-handed perspective projection matrix based on a field of view</summary>
void buildProjectionMatrixPerspectiveFovRH(float fieldOfViewRadians, float aspectRatio, float zNear, float zFar)
{
float h = (float)(Math::Cos(fieldOfViewRadians/2) / Math::Sin(fieldOfViewRadians/2));
float w = h / aspectRatio;
setMInsecure(0,0,2*zNear/w);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2*zNear/h);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,zFar/(zFar-zNear));
setMInsecure(3,2,-1);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear*zFar/(zNear-zFar));
setMInsecure(3,3,0);
}
/// <summary> Builds a left-handed perspective projection matrix based on a field of view</summary>
void buildProjectionMatrixPerspectiveFovLH(float fieldOfViewRadians, float aspectRatio, float zNear, float zFar)
{
float h = (float)(Math::Cos(fieldOfViewRadians/2) / Math::Sin(fieldOfViewRadians/2));
float w = h / aspectRatio;
setMInsecure(0,0,2*zNear/w);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2*zNear/h);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,zFar/(zFar-zNear));
setMInsecure(3,2,1);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear*zFar/(zNear-zFar));
setMInsecure(3,3,0);
}
/// <summary> Builds a right-handed perspective projection matrix.</summary>
void buildProjectionMatrixPerspectiveRH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar)
{
setMInsecure(0,0,2*zNear/widthOfViewVolume);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2*zNear/heightOfViewVolume);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,zFar/(zNear-zFar));
setMInsecure(3,2,-1);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear*zFar/(zNear-zFar));
setMInsecure(3,3,0);
}
/// <summary> Builds a left-handed perspective projection matrix.</summary>
void buildProjectionMatrixPerspectiveLH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar)
{
setMInsecure(0,0,2*zNear/widthOfViewVolume);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2*zNear/heightOfViewVolume);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,zFar/(zNear-zFar));
setMInsecure(3,2,1);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear*zFar/(zNear-zFar));
setMInsecure(3,3,0);
}
/// <summary> Builds a left-handed orthogonal projection matrix.</summary>
void buildProjectionMatrixOrthoLH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar)
{
setMInsecure(0,0,2/widthOfViewVolume);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2/heightOfViewVolume);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,1/(zNear-zFar));
setMInsecure(3,2,0);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear/(zNear-zFar));
setMInsecure(3,3,1);
}
/// <summary> Builds a right-handed orthogonal projection matrix.</summary>
void buildProjectionMatrixOrthoRH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar)
{
setMInsecure(0,0,2/widthOfViewVolume);
setMInsecure(1,0,0);
setMInsecure(2,0,0);
setMInsecure(3,0,0);
setMInsecure(0,1,0);
setMInsecure(1,1,2/heightOfViewVolume);
setMInsecure(2,1,0);
setMInsecure(3,1,0);
setMInsecure(0,2,0);
setMInsecure(1,2,0);
setMInsecure(2,2,1/(zNear-zFar));
setMInsecure(3,2,0);
setMInsecure(0,3,0);
setMInsecure(1,3,0);
setMInsecure(2,3,zNear/(zNear-zFar));
setMInsecure(3,3,-1);
}
/// <summary> Builds a left-handed look-at matrix.</summary>
void buildCameraLookAtMatrixLH(Vector3D position, Vector3D target, Vector3D upVector)
{
Vector3D zaxis = target - position;
zaxis.Normalize();
Vector3D xaxis = upVector.CrossProduct(zaxis);
xaxis.Normalize();
Vector3D yaxis = zaxis.CrossProduct(xaxis);
setMInsecure(0,0,xaxis.X);
setMInsecure(1,0,yaxis.X);
setMInsecure(2,0,zaxis.X);
setMInsecure(3,0,0);
setMInsecure(0,1,xaxis.Y);
setMInsecure(1,1,yaxis.Y);
setMInsecure(2,1,zaxis.Y);
setMInsecure(3,1,0);
setMInsecure(0,2,xaxis.Z);
setMInsecure(1,2,yaxis.Z);
setMInsecure(2,2,zaxis.Z);
setMInsecure(3,2,0);
setMInsecure(0,3,-xaxis.DotProduct(position));
setMInsecure(1,3,-yaxis.DotProduct(position));
setMInsecure(2,3,-zaxis.DotProduct(position));
setMInsecure(3,3,1.0f);
}
/// <summary> Builds a right-handed look-at matrix.</summary>
void buildCameraLookAtMatrixRH(Vector3D position, Vector3D target, Vector3D upVector)
{
Vector3D zaxis = position - target;
zaxis.Normalize();
Vector3D xaxis = upVector.CrossProduct(zaxis);
xaxis.Normalize();
Vector3D yaxis = zaxis.CrossProduct(xaxis);
setMInsecure(0,0,xaxis.X);
setMInsecure(1,0,yaxis.X);
setMInsecure(2,0,zaxis.X);
setMInsecure(3,0,0);
setMInsecure(0,1,xaxis.Y);
setMInsecure(1,1,yaxis.Y);
setMInsecure(2,1,zaxis.Y);
setMInsecure(3,1,0);
setMInsecure(0,2,xaxis.Z);
setMInsecure(1,2,yaxis.Z);
setMInsecure(2,2,zaxis.Z);
setMInsecure(3,2,0);
setMInsecure(0,3,-xaxis.DotProduct(position));
setMInsecure(1,3,-yaxis.DotProduct(position));
setMInsecure(2,3,-zaxis.DotProduct(position));
setMInsecure(3,3,1.0f);
}
/// <summary> Returns the transposed matrix. </summary>
Matrix4 GetTransposed()
{
Matrix4 t;
for (int r=0; r<4; ++r)
for (int c=0; c<4; ++c)
t.set_M(r, c, this->get_M( c, r ));
return t;
}
/// <summary> Returns array of floats representing the matrix </summary>
float GetFloats() __gc[]
{
float f __gc[] = new float __gc [16];
for (int i=0; i<16; ++i)
f[i] = Members[i];
return f;
}
/// <summary> Matrix data, stored in column-major order </summary>
float Members __nogc [16];
//float Members __gc [];
private:
/// <summary>
/// Direct accessing every row and colum of the matrix values without boundary checking
/// </summary>
inline float getMInsecure(int row, int col)
{
return Members[col * 4 + row];
}
/// <summary>
/// Direct accessing every row and colum of the matrix values without boundary checking
/// </summary>
inline void setMInsecure(int row, int col, float v)
{
Members[col * 4 + row] = v;
}
};
}
}