mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Add love.graphics.transformPoint and love.graphics.inverseTransformPoint.
--HG-- branch : minor
This commit is contained in:
+168
-33
@@ -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;
|
||||
|
||||
@@ -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].
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user