commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
319
include/framework/math/matrix3.cpp
Normal file
319
include/framework/math/matrix3.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include "math/matrix3.h"
|
||||
#include "math/matrix4.h"
|
||||
#include "metafile/nml.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::Math;
|
||||
|
||||
Matrix3 Matrix3::static_identity;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Matrix3::Inverse(Matrix3 &i) const
|
||||
{
|
||||
// Covariants.
|
||||
i.m[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
|
||||
i.m[0][1] = m[0][2] * m[2][1] - m[0][1] * m[2][2];
|
||||
i.m[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1];
|
||||
i.m[1][0] = m[1][2] * m[2][0] - m[1][0] * m[2][2];
|
||||
i.m[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0];
|
||||
i.m[1][2] = m[0][2] * m[1][0] - m[0][0] * m[1][2];
|
||||
i.m[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0];
|
||||
i.m[2][1] = m[0][1] * m[2][0] - m[0][0] * m[2][1];
|
||||
i.m[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
|
||||
|
||||
float k = m[0][0] * i.m[0][0] + m[0][1] * i.m[1][0] + m[0][2] * i.m[2][0];
|
||||
if (!k)
|
||||
return false;
|
||||
|
||||
k = 1.f / k;
|
||||
i.m[0][0] *= k; i.m[0][1] *= k; i.m[0][2] *= k;
|
||||
i.m[1][0] *= k; i.m[1][1] *= k; i.m[1][2] *= k;
|
||||
i.m[2][0] *= k; i.m[2][1] *= k; i.m[2][2] *= k;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::VectorMatrix(const Vector4 &v)
|
||||
{ return Matrix3(v.x, 0, 0, v.y, 0, 0, v.z, 0, 0); }
|
||||
Matrix3 Matrix3::CrossProductMatrix(const Vector4 &v)
|
||||
{ return Matrix3(0, -v.z, v.y, v.z, 0, -v.x, -v.y, v.x, 0); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::Normalized() const
|
||||
{
|
||||
Vector4 x(GetRow(0)), y(GetRow(1)), z(GetRow(2));
|
||||
|
||||
Matrix3 m;
|
||||
m.SetRow(0, x.Normalized());
|
||||
m.SetRow(1, y.Normalized());
|
||||
m.SetRow(2, z.Normalized());
|
||||
return m;
|
||||
}
|
||||
Matrix3 Matrix3::AsOrthonormalBase() const
|
||||
{
|
||||
Vector4 x(GetRow(0)), y(GetRow(1));
|
||||
|
||||
Matrix3 m;
|
||||
x = x.Normalized();
|
||||
m.SetRow(0, x);
|
||||
Vector4 z(x.Cross(y).Normalized());
|
||||
m.SetRow(2, z);
|
||||
y = z.Cross(x).Normalized();
|
||||
m.SetRow(1, y);
|
||||
return m;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Vector4 Matrix3::AsEuler(rOrder rorder) const
|
||||
{
|
||||
Vector4 euler(0, 0, 0);
|
||||
|
||||
switch (rorder)
|
||||
{
|
||||
case rOrder_ZYX:
|
||||
euler.y = ASin(-m[2][0]);
|
||||
euler.z = atan2(m[1][0], m[0][0]);
|
||||
euler.x = atan2(m[2][1], m[2][2]);
|
||||
break;
|
||||
|
||||
case rOrder_XZY:
|
||||
euler.z = ASin(-m[0][1]);
|
||||
euler.x = atan2(m[2][1], m[1][1]);
|
||||
euler.y = atan2(m[0][2], m[0][0]);
|
||||
break;
|
||||
|
||||
case rOrder_XYZ:
|
||||
euler.y = ASin(m[0][2]);
|
||||
euler.x = atan2(-m[1][2], m[2][2]);
|
||||
euler.z = atan2(-m[0][1], m[0][0]);
|
||||
break;
|
||||
|
||||
case rOrder_YZX:
|
||||
euler.z = ASin(m[1][0]);
|
||||
euler.x = atan2(-m[1][2], m[1][1]);
|
||||
euler.y = atan2(-m[2][0], m[0][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
case rOrder_YXZ: // Engine default.
|
||||
euler.x = ASin(-m[1][2]);
|
||||
euler.y = atan2(m[0][2], m[2][2]);
|
||||
euler.z = atan2(m[1][0], m[1][1]);
|
||||
break;
|
||||
|
||||
case rOrder_ZXY: // MAX default.
|
||||
euler.x = ASin(m[2][1]);
|
||||
euler.y = atan2(-m[2][0], m[2][2]);
|
||||
euler.z = atan2(-m[0][1], m[1][1]);
|
||||
break;
|
||||
|
||||
case rOrder_XY:
|
||||
euler.y = ACos(m[0][0]);
|
||||
euler.x = ACos(m[1][1]);
|
||||
euler.z = 0;
|
||||
break;
|
||||
}
|
||||
return euler;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::FromEuler(const Vector4 &euler, rOrder rorder)
|
||||
{ return Matrix3::FromEuler(euler.x, euler.y, euler.z, rorder); }
|
||||
Matrix3 Matrix3::FromEuler(float x, float y, float z, rOrder rorder)
|
||||
{
|
||||
float cx = Cos(x), cy = Cos(y), cz = Cos(z),
|
||||
sx = Sin(x), sy = Sin(y), sz = Sin(z);
|
||||
|
||||
switch (rorder)
|
||||
{
|
||||
case rOrder_XZY:
|
||||
return Matrix3 ( cy * cz, sx * sy + cx * cy * sz, -cx * sy + cy * sx * sz,
|
||||
-sz, cx * cz, cz * sx,
|
||||
cz * sy, -cy * sx + cx * sy * sz, cx * cy + sx * sy * sz );
|
||||
|
||||
case rOrder_ZYX:
|
||||
return Matrix3 ( cy * cz, cy * sz, -sy,
|
||||
cz * sx * sy - cx * sz, cx * cz + sx * sy * sz, cy * sx,
|
||||
cx *cz * sy + sx * sz, -cz * sx + cx * sy * sz, cx * cy );
|
||||
|
||||
case rOrder_XYZ:
|
||||
return Matrix3 ( cy * cz, cz * sx * sy + cx * sz, -cx * cz * sy + sx * sz,
|
||||
-cy * sz, cx * cz - sx * sy * sz, cz * sx + cx * sy * sz,
|
||||
sy, -cy * sx, cx * cy );
|
||||
|
||||
case rOrder_ZXY:
|
||||
return Matrix3 ( cy * cz - sx * sy * sz, cz * sx * sy + cy * sz, -cx * sy,
|
||||
-cx * sz, cx * cz, sx,
|
||||
cz * sy + cy * sx * sz, -cy * cz * sx + sy * sz, cx * cy );
|
||||
|
||||
case rOrder_YZX:
|
||||
return Matrix3 ( cy * cz, sz, -cz * sy,
|
||||
sx * sy - cx * cy * sz, cx * cz, cy * sx + cx * sy * sz,
|
||||
cx * sy + cy * sx * sz, -cz * sx, cx * cy - sx * sy * sz );
|
||||
|
||||
case rOrder_YXZ:
|
||||
return Matrix3 ( cy * cz + sx * sy * sz, cx * sz, -cz * sy + cy * sx * sz,
|
||||
cz * sx * sy - cy * sz, cx * cz, cy * cz * sx + sy * sz,
|
||||
cx * sy, -sx, cx * cy );
|
||||
|
||||
case rOrder_XY:
|
||||
return Matrix3 ( cy, sx * sy, -cx * sy,
|
||||
0, cx, sx,
|
||||
sy, -cy * sx, cx * cy );
|
||||
}
|
||||
return Matrix3::IdentityMatrix();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::TranslationMatrix(const Vector4 &t)
|
||||
{ return Matrix3(1, 0, 0, 0, 1, 0, t.x, t.y, 1); }
|
||||
Matrix3 Matrix3::TranslationMatrix(const Vector2 &t)
|
||||
{ return Matrix3(1, 0, 0, 0, 1, 0, t.x, t.y, 1); }
|
||||
Matrix3 Matrix3::ScaleMatrix(const Vector4 &s)
|
||||
{ return Matrix3(s.x, 0, 0, 0, s.y, 0, 0, 0, s.z); }
|
||||
Matrix3 Matrix3::ScaleMatrix(const Vector2 &s)
|
||||
{ return Matrix3(s.x, 0, 0, 0, s.y, 0, 0, 0, 1); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::RotationMatrixXAxis(float a)
|
||||
{ return Matrix3(1, 0, 0, 0, Cos(a), Sin(a), 0, -Sin(a), Cos(a)); }
|
||||
Matrix3 Matrix3::RotationMatrixYAxis(float a)
|
||||
{ return Matrix3(Cos(a), 0, -Sin(a), 0, 1, 0, Sin(a), 0, Cos(a)); }
|
||||
Matrix3 Matrix3::RotationMatrixZAxis(float a)
|
||||
{ return Matrix3(Cos(a), Sin(a), 0, -Sin(a), Cos(a), 0, 0, 0, 1); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Matrix3::SetRow(uint n, const Vector4 &row)
|
||||
{ m[0][n] = row.x; m[1][n] = row.y; m[2][n] = row.z; }
|
||||
void Matrix3::SetColumn(uint n, const Vector4 &col)
|
||||
{ m[n][0] = col.x; m[n][1] = col.y; m[n][2] = col.z; }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Matrix3 Matrix3::FromOrthonormalBasis(const Vector4 &w, const Vector4 *v)
|
||||
{
|
||||
Matrix3 mtx;
|
||||
|
||||
float l = w.Len();
|
||||
if (!l)
|
||||
return Matrix3::IdentityMatrix();
|
||||
|
||||
Vector4 wn = w / l, u;
|
||||
|
||||
if (!v)
|
||||
{
|
||||
if (!EqualZero(wn.x) || !EqualZero(wn.z))
|
||||
{
|
||||
u.Set(wn.z, 0, -wn.x); // Cross with up = {0,1,0}.
|
||||
u = u.Normalized();
|
||||
}
|
||||
else
|
||||
u.Set(-1, 0, 0);
|
||||
|
||||
Vector4 c(wn.Cross(u));
|
||||
mtx.SetRow(1, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector4 vn(v->Normalized());
|
||||
mtx.SetRow(1, vn);
|
||||
u = vn.Cross(wn);
|
||||
}
|
||||
|
||||
mtx.SetRow(0, u);
|
||||
mtx.SetRow(2, wn);
|
||||
return mtx;
|
||||
}
|
||||
Matrix3 Matrix3::FromMatrix4(const Matrix4 &mtx)
|
||||
{
|
||||
return Matrix3(
|
||||
mtx.m[0][0], mtx.m[1][0], mtx.m[2][0],
|
||||
mtx.m[0][1], mtx.m[1][1], mtx.m[2][1],
|
||||
mtx.m[0][2], mtx.m[1][2], mtx.m[2][2]
|
||||
);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Matrix3::Apply(Vector4 *o, const Vector4 *v, uint n) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
for (uint c = 0; c < n; c++)
|
||||
{
|
||||
float x = v->x, y = v->y, z = v->z;
|
||||
o->x = x * m[0][0] + y * m[0][1] + z * m[0][2];
|
||||
o->y = x * m[1][0] + y * m[1][1] + z * m[1][2];
|
||||
o->z = x * m[2][0] + y * m[2][1] + z * m[2][2];
|
||||
o->w = 1;
|
||||
o++; v++;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Matrix3::Set
|
||||
(
|
||||
float m00, float m10, float m20,
|
||||
float m01, float m11, float m21,
|
||||
float m02, float m12, float m22
|
||||
)
|
||||
{
|
||||
m[0][0] = m00; m[1][0] = m10; m[2][0] = m20;
|
||||
m[0][1] = m01; m[1][1] = m11; m[2][1] = m21;
|
||||
m[0][2] = m02; m[1][2] = m12; m[2][2] = m22;
|
||||
}
|
||||
void Matrix3::Set(const Vector4 &u, const Vector4 &v, const Vector4 &w)
|
||||
{
|
||||
m[0][0] = u.x; m[1][0] = u.y; m[2][0] = u.z;
|
||||
m[0][1] = v.x; m[1][1] = v.y; m[2][1] = v.z;
|
||||
m[0][2] = w.x; m[1][2] = w.y; m[2][2] = w.z;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
NML::Tag *Matrix3::AsMetaTag(const char *id) const
|
||||
{
|
||||
NML::Tag *root = new NML::Tag(id ? id : "Mtx3");
|
||||
root->AddChild(GetRow(0).AsMetaTag("R0"));
|
||||
root->AddChild(GetRow(1).AsMetaTag("R1"));
|
||||
root->AddChild(GetRow(2).AsMetaTag("R2"));
|
||||
return root;
|
||||
}
|
||||
bool Matrix3::FromMetaTag(NML::Tag &tag)
|
||||
{
|
||||
NML::Tag *t;
|
||||
Vector4 R;
|
||||
|
||||
List <NML::Tag *> ::Iterator i(tag.GetTags().GetRoot());
|
||||
|
||||
t = i.ObjectPtr();
|
||||
if (!t) return false;
|
||||
R.FromMetaTag(*t); SetRow(0, R);
|
||||
++i;
|
||||
|
||||
t = i.ObjectPtr();
|
||||
if (!t) return false;
|
||||
R.FromMetaTag(*t); SetRow(1, R);
|
||||
++i;
|
||||
|
||||
t = i.ObjectPtr();
|
||||
if (!t) return false;
|
||||
R.FromMetaTag(*t); SetRow(2, R);
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user