Add love.graphics.transformPoint and love.graphics.inverseTransformPoint.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2016-10-20 18:13:20 -03:00
parent be1a59fb18
commit 4c122e6581
5 changed files with 218 additions and 33 deletions
+168 -33
View File
@@ -27,6 +27,43 @@
namespace love
{
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
void Matrix4::multiply(const Matrix4 &a, const Matrix4 &b, float t[16])
{
t[0] = (a.e[0]*b.e[0]) + (a.e[4]*b.e[1]) + (a.e[8]*b.e[2]) + (a.e[12]*b.e[3]);
t[4] = (a.e[0]*b.e[4]) + (a.e[4]*b.e[5]) + (a.e[8]*b.e[6]) + (a.e[12]*b.e[7]);
t[8] = (a.e[0]*b.e[8]) + (a.e[4]*b.e[9]) + (a.e[8]*b.e[10]) + (a.e[12]*b.e[11]);
t[12] = (a.e[0]*b.e[12]) + (a.e[4]*b.e[13]) + (a.e[8]*b.e[14]) + (a.e[12]*b.e[15]);
t[1] = (a.e[1]*b.e[0]) + (a.e[5]*b.e[1]) + (a.e[9]*b.e[2]) + (a.e[13]*b.e[3]);
t[5] = (a.e[1]*b.e[4]) + (a.e[5]*b.e[5]) + (a.e[9]*b.e[6]) + (a.e[13]*b.e[7]);
t[9] = (a.e[1]*b.e[8]) + (a.e[5]*b.e[9]) + (a.e[9]*b.e[10]) + (a.e[13]*b.e[11]);
t[13] = (a.e[1]*b.e[12]) + (a.e[5]*b.e[13]) + (a.e[9]*b.e[14]) + (a.e[13]*b.e[15]);
t[2] = (a.e[2]*b.e[0]) + (a.e[6]*b.e[1]) + (a.e[10]*b.e[2]) + (a.e[14]*b.e[3]);
t[6] = (a.e[2]*b.e[4]) + (a.e[6]*b.e[5]) + (a.e[10]*b.e[6]) + (a.e[14]*b.e[7]);
t[10] = (a.e[2]*b.e[8]) + (a.e[6]*b.e[9]) + (a.e[10]*b.e[10]) + (a.e[14]*b.e[11]);
t[14] = (a.e[2]*b.e[12]) + (a.e[6]*b.e[13]) + (a.e[10]*b.e[14]) + (a.e[14]*b.e[15]);
t[3] = (a.e[3]*b.e[0]) + (a.e[7]*b.e[1]) + (a.e[11]*b.e[2]) + (a.e[15]*b.e[3]);
t[7] = (a.e[3]*b.e[4]) + (a.e[7]*b.e[5]) + (a.e[11]*b.e[6]) + (a.e[15]*b.e[7]);
t[11] = (a.e[3]*b.e[8]) + (a.e[7]*b.e[9]) + (a.e[11]*b.e[10]) + (a.e[15]*b.e[11]);
t[15] = (a.e[3]*b.e[12]) + (a.e[7]*b.e[13]) + (a.e[11]*b.e[14]) + (a.e[15]*b.e[15]);
}
void Matrix4::multiply(const Matrix4 &a, const Matrix4 &b, Matrix4 &t)
{
multiply(a, b, t.e);
}
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
@@ -46,46 +83,18 @@ Matrix4::~Matrix4()
{
}
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
Matrix4 Matrix4::operator * (const Matrix4 &m) const
{
Matrix4 t;
t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]);
t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]);
t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]);
t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]);
t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]);
t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]);
t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]);
t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]);
t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]);
t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]);
t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]);
t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]);
t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]);
t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]);
multiply(*this, m, t);
return t;
}
void Matrix4::operator *= (const Matrix4 &m)
{
Matrix4 t = (*this) * m;
memcpy(this->e, t.e, sizeof(float)*16);
float t[16];
multiply(*this, m, t);
memcpy(this->e, t, sizeof(float)*16);
}
const float *Matrix4::getElements() const
@@ -96,7 +105,7 @@ const float *Matrix4::getElements() const
void Matrix4::setIdentity()
{
memset(e, 0, sizeof(float)*16);
e[0] = e[5] = e[10] = e[15] = 1;
e[15] = e[10] = e[5] = e[0] = 1;
}
void Matrix4::setTranslation(float x, float y)
@@ -177,6 +186,132 @@ void Matrix4::shear(float kx, float ky)
this->operator *=(t);
}
Matrix4 Matrix4::inverse() const
{
Matrix4 inv;
inv.e[0] = e[5] * e[10] * e[15] -
e[5] * e[11] * e[14] -
e[9] * e[6] * e[15] +
e[9] * e[7] * e[14] +
e[13] * e[6] * e[11] -
e[13] * e[7] * e[10];
inv.e[4] = -e[4] * e[10] * e[15] +
e[4] * e[11] * e[14] +
e[8] * e[6] * e[15] -
e[8] * e[7] * e[14] -
e[12] * e[6] * e[11] +
e[12] * e[7] * e[10];
inv.e[8] = e[4] * e[9] * e[15] -
e[4] * e[11] * e[13] -
e[8] * e[5] * e[15] +
e[8] * e[7] * e[13] +
e[12] * e[5] * e[11] -
e[12] * e[7] * e[9];
inv.e[12] = -e[4] * e[9] * e[14] +
e[4] * e[10] * e[13] +
e[8] * e[5] * e[14] -
e[8] * e[6] * e[13] -
e[12] * e[5] * e[10] +
e[12] * e[6] * e[9];
inv.e[1] = -e[1] * e[10] * e[15] +
e[1] * e[11] * e[14] +
e[9] * e[2] * e[15] -
e[9] * e[3] * e[14] -
e[13] * e[2] * e[11] +
e[13] * e[3] * e[10];
inv.e[5] = e[0] * e[10] * e[15] -
e[0] * e[11] * e[14] -
e[8] * e[2] * e[15] +
e[8] * e[3] * e[14] +
e[12] * e[2] * e[11] -
e[12] * e[3] * e[10];
inv.e[9] = -e[0] * e[9] * e[15] +
e[0] * e[11] * e[13] +
e[8] * e[1] * e[15] -
e[8] * e[3] * e[13] -
e[12] * e[1] * e[11] +
e[12] * e[3] * e[9];
inv.e[13] = e[0] * e[9] * e[14] -
e[0] * e[10] * e[13] -
e[8] * e[1] * e[14] +
e[8] * e[2] * e[13] +
e[12] * e[1] * e[10] -
e[12] * e[2] * e[9];
inv.e[2] = e[1] * e[6] * e[15] -
e[1] * e[7] * e[14] -
e[5] * e[2] * e[15] +
e[5] * e[3] * e[14] +
e[13] * e[2] * e[7] -
e[13] * e[3] * e[6];
inv.e[6] = -e[0] * e[6] * e[15] +
e[0] * e[7] * e[14] +
e[4] * e[2] * e[15] -
e[4] * e[3] * e[14] -
e[12] * e[2] * e[7] +
e[12] * e[3] * e[6];
inv.e[10] = e[0] * e[5] * e[15] -
e[0] * e[7] * e[13] -
e[4] * e[1] * e[15] +
e[4] * e[3] * e[13] +
e[12] * e[1] * e[7] -
e[12] * e[3] * e[5];
inv.e[14] = -e[0] * e[5] * e[14] +
e[0] * e[6] * e[13] +
e[4] * e[1] * e[14] -
e[4] * e[2] * e[13] -
e[12] * e[1] * e[6] +
e[12] * e[2] * e[5];
inv.e[3] = -e[1] * e[6] * e[11] +
e[1] * e[7] * e[10] +
e[5] * e[2] * e[11] -
e[5] * e[3] * e[10] -
e[9] * e[2] * e[7] +
e[9] * e[3] * e[6];
inv.e[7] = e[0] * e[6] * e[11] -
e[0] * e[7] * e[10] -
e[4] * e[2] * e[11] +
e[4] * e[3] * e[10] +
e[8] * e[2] * e[7] -
e[8] * e[3] * e[6];
inv.e[11] = -e[0] * e[5] * e[11] +
e[0] * e[7] * e[9] +
e[4] * e[1] * e[11] -
e[4] * e[3] * e[9] -
e[8] * e[1] * e[7] +
e[8] * e[3] * e[5];
inv.e[15] = e[0] * e[5] * e[10] -
e[0] * e[6] * e[9] -
e[4] * e[1] * e[10] +
e[4] * e[2] * e[9] +
e[8] * e[1] * e[6] -
e[8] * e[2] * e[5];
float det = e[0] * inv.e[0] + e[1] * inv.e[4] + e[2] * inv.e[8] + e[3] * inv.e[12];
float invdet = 1.0f / det;
for (int i = 0; i < 16; i++)
inv.e[i] *= invdet;
return inv;
}
Matrix4 Matrix4::ortho(float left, float right, float bottom, float top)
{
Matrix4 m;
+8
View File
@@ -34,8 +34,14 @@ namespace love
**/
class Matrix4
{
private:
static void multiply(const Matrix4 &a, const Matrix4 &b, float t[16]);
public:
static void multiply(const Matrix4 &a, const Matrix4 &b, Matrix4 &result);
/**
* Creates a new identity matrix.
**/
@@ -156,6 +162,8 @@ public:
template <typename V>
void transform(V *dst, const V *src, int size) const;
Matrix4 inverse() const;
/**
* Creates a new orthographic projection matrix with depth in the range of
* [-1, 1].
+16
View File
@@ -1789,6 +1789,22 @@ void Graphics::origin()
pixelSizeStack.back() = 1;
}
Vector Graphics::transformPoint(Vector point)
{
Vector p;
gl.getTransform().transform(&p, &point, 1);
return p;
}
Vector Graphics::inverseTransformPoint(Vector point)
{
Vector p;
// TODO: We should probably cache the inverse transform so we don't have to
// re-calculate it every time this is called.
gl.getTransform().inverse().transform(&p, &point, 1);
return p;
}
} // opengl
} // graphics
} // love
+2
View File
@@ -459,6 +459,8 @@ public:
void translate(float x, float y);
void shear(float kx, float ky);
void origin();
Vector transformPoint(Vector point);
Vector inverseTransformPoint(Vector point);
private:
@@ -1960,6 +1960,28 @@ int w_origin(lua_State * /*L*/)
return 0;
}
int w_transformPoint(lua_State *L)
{
Vector p;
p.x = (float) luaL_checknumber(L, 1);
p.y = (float) luaL_checknumber(L, 2);
p = instance()->transformPoint(p);
lua_pushnumber(L, p.x);
lua_pushnumber(L, p.y);
return 2;
}
int w_inverseTransformPoint(lua_State *L)
{
Vector p;
p.x = (float) luaL_checknumber(L, 1);
p.y = (float) luaL_checknumber(L, 2);
p = instance()->inverseTransformPoint(p);
lua_pushnumber(L, p.x);
lua_pushnumber(L, p.y);
return 2;
}
// List of functions to wrap.
static const luaL_Reg functions[] =
@@ -2060,6 +2082,8 @@ static const luaL_Reg functions[] =
{ "translate", w_translate },
{ "shear", w_shear },
{ "origin", w_origin },
{ "transformPoint", w_transformPoint },
{ "inverseTransformPoint", w_inverseTransformPoint },
{ 0, 0 }
};