mirror of https://github.com/bjornbytes/lovr.git
vec4;
This commit is contained in:
parent
23bba1d59b
commit
122143b13a
|
@ -48,6 +48,7 @@ extern const luaL_Reg lovrTexture[];
|
|||
extern const luaL_Reg lovrTextureData[];
|
||||
extern const luaL_Reg lovrThread[];
|
||||
extern const luaL_Reg lovrVec2[];
|
||||
extern const luaL_Reg lovrVec4[];
|
||||
extern const luaL_Reg lovrVec3[];
|
||||
extern const luaL_Reg lovrWorld[];
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ int l_lovrRandomGeneratorGetSeed(lua_State* L);
|
|||
int l_lovrRandomGeneratorSetSeed(lua_State* L);
|
||||
int l_lovrVec2Set(lua_State* L);
|
||||
int l_lovrVec3Set(lua_State* L);
|
||||
int l_lovrVec4Set(lua_State* L);
|
||||
int l_lovrQuatSet(lua_State* L);
|
||||
int l_lovrMat4Set(lua_State* L);
|
||||
|
||||
|
@ -23,6 +24,7 @@ static LOVR_THREAD_LOCAL Pool* pool;
|
|||
static const luaL_Reg* lovrVectorMetatables[] = {
|
||||
[V_VEC2] = lovrVec2,
|
||||
[V_VEC3] = lovrVec3,
|
||||
[V_VEC4] = lovrVec4,
|
||||
[V_QUAT] = lovrQuat,
|
||||
[V_MAT4] = lovrMat4
|
||||
};
|
||||
|
@ -30,6 +32,7 @@ static const luaL_Reg* lovrVectorMetatables[] = {
|
|||
static int lovrVectorMetatableRefs[] = {
|
||||
[V_VEC2] = LUA_REFNIL,
|
||||
[V_VEC3] = LUA_REFNIL,
|
||||
[V_VEC4] = LUA_REFNIL,
|
||||
[V_QUAT] = LUA_REFNIL,
|
||||
[V_MAT4] = LUA_REFNIL
|
||||
};
|
||||
|
@ -37,6 +40,7 @@ static int lovrVectorMetatableRefs[] = {
|
|||
static const char* lovrVectorTypeNames[] = {
|
||||
[V_VEC2] = "vec2",
|
||||
[V_VEC3] = "vec3",
|
||||
[V_VEC4] = "vec4",
|
||||
[V_QUAT] = "quat",
|
||||
[V_MAT4] = "mat4"
|
||||
};
|
||||
|
@ -229,6 +233,12 @@ static int l_lovrMathNewVec3(lua_State* L) {
|
|||
return l_lovrVec3Set(L);
|
||||
}
|
||||
|
||||
static int l_lovrMathNewVec4(lua_State* L) {
|
||||
luax_newvector(L, V_VEC4, 4);
|
||||
lua_insert(L, 1);
|
||||
return l_lovrVec4Set(L);
|
||||
}
|
||||
|
||||
static int l_lovrMathNewQuat(lua_State* L) {
|
||||
luax_newvector(L, V_QUAT, 4);
|
||||
lua_insert(L, 1);
|
||||
|
@ -253,6 +263,12 @@ static int l_lovrMathVec3(lua_State* L) {
|
|||
return l_lovrVec3Set(L);
|
||||
}
|
||||
|
||||
static int l_lovrMathVec4(lua_State* L) {
|
||||
luax_newtempvector(L, V_VEC4);
|
||||
lua_insert(L, 1);
|
||||
return l_lovrVec4Set(L);
|
||||
}
|
||||
|
||||
static int l_lovrMathQuat(lua_State* L) {
|
||||
luax_newtempvector(L, V_QUAT);
|
||||
lua_insert(L, 1);
|
||||
|
@ -282,10 +298,12 @@ static const luaL_Reg lovrMath[] = {
|
|||
{ "linearToGamma", l_lovrMathLinearToGamma },
|
||||
{ "newVec2", l_lovrMathNewVec2 },
|
||||
{ "newVec3", l_lovrMathNewVec3 },
|
||||
{ "newVec4", l_lovrMathNewVec4 },
|
||||
{ "newQuat", l_lovrMathNewQuat },
|
||||
{ "newMat4", l_lovrMathNewMat4 },
|
||||
{ "vec2", l_lovrMathVec2 },
|
||||
{ "vec3", l_lovrMathVec3 },
|
||||
{ "vec4", l_lovrMathVec4 },
|
||||
{ "quat", l_lovrMathQuat },
|
||||
{ "mat4", l_lovrMathMat4 },
|
||||
{ "drain", l_lovrMathDrain },
|
||||
|
|
|
@ -433,12 +433,19 @@ static int l_lovrVec2__index(lua_State* L) {
|
|||
out[1] = v[swizzles[2][key[1]] - 1];
|
||||
out[2] = v[swizzles[2][key[2]] - 1];
|
||||
return 1;
|
||||
} else if (length == 4 && swizzles[2][key[0]] && swizzles[2][key[1]] && swizzles[2][key[2]] && swizzles[2][key[3]]) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
out[0] = v[swizzles[2][key[0]] - 1];
|
||||
out[1] = v[swizzles[2][key[1]] - 1];
|
||||
out[2] = v[swizzles[2][key[2]] - 1];
|
||||
out[3] = v[swizzles[2][key[3]] - 1];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to index property %q of vec2 (invalid property)", lua_tostring(L, -1));
|
||||
return luaL_error(L, "attempt to index field %q of vec2 (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
const luaL_Reg lovrVec2[] = {
|
||||
|
@ -758,12 +765,19 @@ static int l_lovrVec3__index(lua_State* L) {
|
|||
out[1] = v[swizzles[3][key[1]] - 1];
|
||||
out[2] = v[swizzles[3][key[2]] - 1];
|
||||
return 1;
|
||||
} else if (length == 4 && swizzles[3][key[0]] && swizzles[3][key[1]] && swizzles[3][key[2]] && swizzles[3][key[3]]) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
out[0] = v[swizzles[3][key[0]] - 1];
|
||||
out[1] = v[swizzles[3][key[1]] - 1];
|
||||
out[2] = v[swizzles[3][key[2]] - 1];
|
||||
out[3] = v[swizzles[3][key[3]] - 1];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to index property %q of vec2 (invalid property)", lua_tostring(L, -1));
|
||||
return luaL_error(L, "attempt to index field %q of vec3 (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
const luaL_Reg lovrVec3[] = {
|
||||
|
@ -791,6 +805,412 @@ const luaL_Reg lovrVec3[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// vec4
|
||||
|
||||
static int l_lovrVec4Unpack(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
lua_pushnumber(L, v[0]);
|
||||
lua_pushnumber(L, v[1]);
|
||||
lua_pushnumber(L, v[2]);
|
||||
lua_pushnumber(L, v[3]);
|
||||
return 4;
|
||||
}
|
||||
|
||||
int l_lovrVec4Set(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_isnoneornil(L, 2) || lua_type(L, 2) == LUA_TNUMBER) {
|
||||
v[0] = luax_optfloat(L, 2, 0.f);
|
||||
v[1] = luax_optfloat(L, 3, v[0]);
|
||||
v[2] = luax_optfloat(L, 4, v[0]);
|
||||
v[3] = luax_optfloat(L, 5, v[0]);
|
||||
} else {
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
v[0] = u[0];
|
||||
v[1] = u[1];
|
||||
v[2] = u[2];
|
||||
v[3] = u[3];
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Add(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 2);
|
||||
v[0] += x;
|
||||
v[1] += x;
|
||||
v[2] += x;
|
||||
v[3] += x;
|
||||
} else {
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
v[0] += u[0];
|
||||
v[1] += u[1];
|
||||
v[2] += u[2];
|
||||
v[3] += u[3];
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Sub(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 2);
|
||||
v[0] -= x;
|
||||
v[1] -= x;
|
||||
v[2] -= x;
|
||||
v[3] -= x;
|
||||
} else {
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
v[0] -= u[0];
|
||||
v[1] -= u[1];
|
||||
v[2] -= u[2];
|
||||
v[3] -= u[3];
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Mul(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 2);
|
||||
v[0] *= x;
|
||||
v[1] *= x;
|
||||
v[2] *= x;
|
||||
v[3] *= x;
|
||||
} else {
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
v[0] *= u[0];
|
||||
v[1] *= u[1];
|
||||
v[2] *= u[2];
|
||||
v[3] *= u[3];
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Div(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 2);
|
||||
v[0] /= x;
|
||||
v[1] /= x;
|
||||
v[2] /= x;
|
||||
v[3] /= x;
|
||||
} else {
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
v[0] /= u[0];
|
||||
v[1] /= u[1];
|
||||
v[2] /= u[2];
|
||||
v[3] /= u[3];
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Length(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
lua_pushnumber(L, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Normalize(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
|
||||
if (length != 0.f) {
|
||||
length = 1.f / sqrtf(length);
|
||||
v[0] *= length;
|
||||
v[1] *= length;
|
||||
v[2] *= length;
|
||||
v[3] *= length;
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Distance(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
float dx = v[0] - u[0];
|
||||
float dy = v[1] - u[1];
|
||||
float dz = v[2] - u[2];
|
||||
float dw = v[3] - u[3];
|
||||
lua_pushnumber(L, sqrtf(dx * dx + dy * dy + dz * dz + dw * dw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Dot(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
lua_pushnumber(L, v[0] * u[0] + v[1] * u[1] + v[2] * u[2] + v[3] * u[3]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Lerp(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
float t = luax_checkfloat(L, 3);
|
||||
v[0] = v[0] + (u[0] - v[0]) * t;
|
||||
v[1] = v[1] + (u[1] - v[1]) * t;
|
||||
v[2] = v[2] + (u[2] - v[2]) * t;
|
||||
v[3] = v[3] + (u[3] - v[3]) * t;
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__add(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 1);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
out[0] = u[0] + x;
|
||||
out[1] = u[1] + x;
|
||||
out[2] = u[2] + x;
|
||||
out[3] = u[3] + x;
|
||||
} else if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float x = lua_tonumber(L, 2);
|
||||
out[0] = v[0] + x;
|
||||
out[1] = v[1] + x;
|
||||
out[2] = v[2] + x;
|
||||
out[3] = v[3] + x;
|
||||
} else {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
out[0] = v[0] + u[0];
|
||||
out[1] = v[1] + u[1];
|
||||
out[2] = v[2] + u[2];
|
||||
out[3] = v[3] + u[3];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__sub(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 1);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
out[0] = u[0] - x;
|
||||
out[1] = u[1] - x;
|
||||
out[2] = u[2] - x;
|
||||
out[3] = u[3] - x;
|
||||
} else if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float x = lua_tonumber(L, 2);
|
||||
out[0] = v[0] - x;
|
||||
out[1] = v[1] - x;
|
||||
out[2] = v[2] - x;
|
||||
out[3] = v[3] - x;
|
||||
} else {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
out[0] = v[0] - u[0];
|
||||
out[1] = v[1] - u[1];
|
||||
out[2] = v[2] - u[2];
|
||||
out[3] = v[3] - u[3];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__mul(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 1);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
out[0] = u[0] * x;
|
||||
out[1] = u[1] * x;
|
||||
out[2] = u[2] * x;
|
||||
out[3] = u[3] * x;
|
||||
} else if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float x = lua_tonumber(L, 2);
|
||||
out[0] = v[0] * x;
|
||||
out[1] = v[1] * x;
|
||||
out[2] = v[2] * x;
|
||||
out[3] = v[3] * x;
|
||||
} else {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
out[0] = v[0] * u[0];
|
||||
out[1] = v[1] * u[1];
|
||||
out[2] = v[2] * u[2];
|
||||
out[3] = v[3] * u[3];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__div(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
float x = lua_tonumber(L, 1);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
out[0] = u[0] / x;
|
||||
out[1] = u[1] / x;
|
||||
out[2] = u[2] / x;
|
||||
out[3] = u[3] / x;
|
||||
} else if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float x = lua_tonumber(L, 2);
|
||||
out[0] = v[0] / x;
|
||||
out[1] = v[1] / x;
|
||||
out[2] = v[2] / x;
|
||||
out[3] = v[3] / x;
|
||||
} else {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
out[0] = v[0] / u[0];
|
||||
out[1] = v[1] / u[1];
|
||||
out[2] = v[2] / u[2];
|
||||
out[3] = v[3] / u[3];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__unm(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
out[0] = -v[0];
|
||||
out[1] = -v[1];
|
||||
out[2] = -v[2];
|
||||
out[3] = -v[3];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__len(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
lua_pushnumber(L, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__tostring(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
lua_pushfstring(L, "(%f, %f, %f, %f)", v[0], v[1], v[2], v[3]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__newindex(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
int index = lua_tointeger(L, 2);
|
||||
if (index >= 1 && index <= 4) {
|
||||
float x = luax_checkfloat(L, 3);
|
||||
v[index - 1] = x;
|
||||
return 0;
|
||||
}
|
||||
} else if (lua_type(L, 2) == LUA_TSTRING) {
|
||||
size_t length;
|
||||
const char* str = lua_tolstring(L, 2, &length);
|
||||
const unsigned char* key = (const unsigned char*) str;
|
||||
|
||||
if (length == 1 && swizzles[4][key[0]]) {
|
||||
v[swizzles[4][key[0]] - 1] = luax_checkfloat(L, 3);
|
||||
return 0;
|
||||
} else if (length == 2 && swizzles[4][key[0]] && swizzles[4][key[1]]) {
|
||||
float* u = luax_checkvector(L, 3, V_VEC2, NULL);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
v[swizzles[4][key[i]] - 1] = u[i];
|
||||
}
|
||||
return 0;
|
||||
} else if (length == 3 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]]) {
|
||||
float* u = luax_checkvector(L, 3, V_VEC3, NULL);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
v[swizzles[4][key[i]] - 1] = u[i];
|
||||
}
|
||||
return 0;
|
||||
} else if (length == 4 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]] && swizzles[4][key[3]]) {
|
||||
float* u = luax_checkvector(L, 3, V_VEC4, NULL);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
v[swizzles[4][key[i]] - 1] = u[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to assign property %q of vec4 (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
static int l_lovrVec4__index(lua_State* L) {
|
||||
if (lua_type(L, 1) == LUA_TUSERDATA) {
|
||||
lua_getmetatable(L, 1);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_isnil(L, -1)) {
|
||||
return 1;
|
||||
} else {
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
}
|
||||
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
int type = lua_type(L, 2);
|
||||
if (type == LUA_TNUMBER) {
|
||||
int index = lua_tointeger(L, 2);
|
||||
if (index >= 1 && index <= 4) {
|
||||
lua_pushnumber(L, v[index - 1]);
|
||||
return 1;
|
||||
}
|
||||
} else if (type == LUA_TSTRING) {
|
||||
size_t length;
|
||||
const char* str = lua_tolstring(L, 2, &length);
|
||||
const unsigned char* key = (const unsigned char*) str;
|
||||
|
||||
if (length == 1 && swizzles[4][key[0]]) {
|
||||
lua_pushnumber(L, v[swizzles[4][key[0]] - 1]);
|
||||
return 1;
|
||||
} else if (length == 2 && swizzles[4][key[0]] && swizzles[4][key[1]]) {
|
||||
float* out = luax_newtempvector(L, V_VEC2);
|
||||
out[0] = v[swizzles[4][key[0]] - 1];
|
||||
out[1] = v[swizzles[4][key[1]] - 1];
|
||||
return 1;
|
||||
} else if (length == 3 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]]) {
|
||||
float* out = luax_newtempvector(L, V_VEC3);
|
||||
out[0] = v[swizzles[4][key[0]] - 1];
|
||||
out[1] = v[swizzles[4][key[1]] - 1];
|
||||
out[2] = v[swizzles[4][key[2]] - 1];
|
||||
return 1;
|
||||
} else if (length == 4 && swizzles[4][key[0]] && swizzles[4][key[1]] && swizzles[4][key[2]] && swizzles[4][key[3]]) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
out[0] = v[swizzles[4][key[0]] - 1];
|
||||
out[1] = v[swizzles[4][key[1]] - 1];
|
||||
out[2] = v[swizzles[4][key[2]] - 1];
|
||||
out[3] = v[swizzles[4][key[3]] - 1];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to index field %q of vec4 (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
const luaL_Reg lovrVec4[] = {
|
||||
{ "unpack", l_lovrVec4Unpack },
|
||||
{ "set", l_lovrVec4Set },
|
||||
{ "add", l_lovrVec4Add },
|
||||
{ "sub", l_lovrVec4Sub },
|
||||
{ "mul", l_lovrVec4Mul },
|
||||
{ "div", l_lovrVec4Div },
|
||||
{ "length", l_lovrVec4Length },
|
||||
{ "normalize", l_lovrVec4Normalize },
|
||||
{ "distance", l_lovrVec4Distance },
|
||||
{ "dot", l_lovrVec4Dot },
|
||||
{ "lerp", l_lovrVec4Lerp },
|
||||
{ "__add", l_lovrVec4__add },
|
||||
{ "__sub", l_lovrVec4__sub },
|
||||
{ "__mul", l_lovrVec4__mul },
|
||||
{ "__div", l_lovrVec4__div },
|
||||
{ "__unm", l_lovrVec4__unm },
|
||||
{ "__len", l_lovrVec4__len },
|
||||
{ "__tostring", l_lovrVec4__tostring },
|
||||
{ "__newindex", l_lovrVec4__newindex },
|
||||
{ "__index", l_lovrVec4__index },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// quat
|
||||
|
||||
static int l_lovrQuatUnpack(lua_State* L) {
|
||||
|
@ -987,7 +1407,7 @@ static int l_lovrQuat__index(lua_State* L) {
|
|||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to index property %q of quat (invalid property)", lua_tostring(L, -1));
|
||||
return luaL_error(L, "attempt to index field %q of quat (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
const luaL_Reg lovrQuat[] = {
|
||||
|
@ -1242,7 +1662,7 @@ static int l_lovrMat4__index(lua_State* L) {
|
|||
lua_getglobal(L, "tostring");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 1, 1);
|
||||
return luaL_error(L, "attempt to index property %q of mat4 (invalid property)", lua_tostring(L, -1));
|
||||
return luaL_error(L, "attempt to index field %q of mat4 (invalid property)", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
const luaL_Reg lovrMat4[] = {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
static const size_t vectorComponents[] = {
|
||||
[V_VEC2] = 2,
|
||||
[V_VEC3] = 4,
|
||||
[V_VEC4] = 4,
|
||||
[V_QUAT] = 4,
|
||||
[V_MAT4] = 16
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ typedef enum {
|
|||
V_NONE,
|
||||
V_VEC2,
|
||||
V_VEC3,
|
||||
V_VEC4,
|
||||
V_QUAT,
|
||||
V_MAT4,
|
||||
MAX_VECTOR_TYPES
|
||||
|
|
|
@ -10,12 +10,14 @@ typedef enum {
|
|||
NONE,
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
QUAT,
|
||||
MAT4
|
||||
} VectorType;
|
||||
|
||||
typedef struct { uint8_t type; uint8_t generation; uint16_t index; } vec2;
|
||||
typedef struct { uint8_t type; uint8_t generation; uint16_t index; } vec3;
|
||||
typedef struct { uint8_t type; uint8_t generation; uint16_t index; } vec4;
|
||||
typedef struct { uint8_t type; uint8_t generation; uint16_t index; } quat;
|
||||
typedef struct { uint8_t type; uint8_t generation; uint16_t index; } mat4;
|
||||
|
||||
|
@ -75,18 +77,21 @@ end
|
|||
|
||||
local vec2_t = ffi.typeof('vec2')
|
||||
local vec3_t = ffi.typeof('vec3')
|
||||
local vec4_t = ffi.typeof('vec4')
|
||||
local quat_t = ffi.typeof('quat')
|
||||
local mat4_t = ffi.typeof('mat4')
|
||||
local checkvec2 = checktype(C.VEC2, 'vec2')
|
||||
local checkvec3 = checktype(C.VEC3, 'vec3')
|
||||
local checkvec4 = checktype(C.VEC4, 'vec4')
|
||||
local checkquat = checktype(C.QUAT, 'quat')
|
||||
local checkmat4 = checktype(C.MAT4, 'mat4')
|
||||
local isvec2 = istype(C.VEC2, 'vec2')
|
||||
local isvec3 = istype(C.VEC3, 'vec3')
|
||||
local isvec4 = istype(C.VEC4, 'vec4')
|
||||
local isquat = istype(C.QUAT, 'quat')
|
||||
local ismat4 = istype(C.MAT4, 'mat4')
|
||||
|
||||
local vec2, vec3, quat, mat4
|
||||
local vec2, vec3, vec4, quat, mat4
|
||||
|
||||
vec2 = {
|
||||
unpack = function(self)
|
||||
|
@ -299,6 +304,11 @@ vec2 = {
|
|||
if a and b and c then
|
||||
return lovr_math.vec3(v[a], v[b], v[c])
|
||||
end
|
||||
elseif #key == 4 then
|
||||
local a, b, c, d = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)], swizzles[key:sub(4, 4)]
|
||||
if a and b and c and d then
|
||||
return lovr_math.vec4(v[a], v[b], v[c], v[d])
|
||||
end
|
||||
end
|
||||
elseif key == 1 or key == 2 then
|
||||
return v[key - 1]
|
||||
|
@ -554,15 +564,295 @@ vec3 = {
|
|||
if a and b and c then
|
||||
return lovr_math.vec3(v[a], v[b], v[c])
|
||||
end
|
||||
elseif #key == 4 then
|
||||
local a, b, c, d = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)], swizzles[key:sub(4, 4)]
|
||||
if a and b and c and d then
|
||||
return lovr_math.vec4(v[a], v[b], v[c], v[d])
|
||||
end
|
||||
end
|
||||
elseif type(key) == 'number' and key >= 1 and key <= 3 then
|
||||
return v[key - 1]
|
||||
end
|
||||
|
||||
error(string.format('attempt to index vec3 using %s (invalid type)', type(key)), 2)
|
||||
error(string.format('attempt to index field %q of vec3 (invalid property)', type(key)), 2)
|
||||
end
|
||||
}
|
||||
|
||||
vec4 = {
|
||||
unpack = function(self)
|
||||
local v = checkvec4(self)
|
||||
return v[0], v[1], v[2], v[3]
|
||||
end,
|
||||
|
||||
set = function(self, x, y, z, w)
|
||||
local v = checkvec4(self)
|
||||
if x == nil then
|
||||
v[0], v[1], v[2], v[3] = 0, 0, 0, 0
|
||||
elseif type(x) == 'number' then
|
||||
v[0], v[1], v[2], v[3] = x, y or x, z or x, w or x
|
||||
else
|
||||
local u = checkvec4(x, 1, 'vec4 or number')
|
||||
v[0], v[1], v[2], v[3] = u[0], u[1], u[2], u[3]
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
add = function(self, x)
|
||||
local v = checkvec3(self)
|
||||
if type(x) == 'number' then
|
||||
v[0] = v[0] + x
|
||||
v[1] = v[1] + x
|
||||
v[2] = v[2] + x
|
||||
v[3] = v[3] + x
|
||||
else
|
||||
local u = checkvec4(x, 1, 'vec4 or number')
|
||||
v[0] = v[0] + u[0]
|
||||
v[1] = v[1] + u[1]
|
||||
v[2] = v[2] + u[2]
|
||||
v[3] = v[3] + u[3]
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
sub = function(self, x)
|
||||
local v = checkvec4(self)
|
||||
if type(x) == 'number' then
|
||||
v[0] = v[0] - x
|
||||
v[1] = v[1] - x
|
||||
v[2] = v[2] - x
|
||||
v[3] = v[3] - x
|
||||
else
|
||||
local u = checkvec4(x, 1, 'vec4 or number')
|
||||
v[0] = v[0] - u[0]
|
||||
v[1] = v[1] - u[1]
|
||||
v[2] = v[2] - u[2]
|
||||
v[3] = v[3] - u[3]
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
mul = function(self, x)
|
||||
local v = checkvec4(self)
|
||||
if type(x) == 'number' then
|
||||
v[0] = v[0] * x
|
||||
v[1] = v[1] * x
|
||||
v[2] = v[2] * x
|
||||
v[3] = v[3] * x
|
||||
else
|
||||
local u = checkvec4(x, 1, 'vec4 or number')
|
||||
v[0] = v[0] * u[0]
|
||||
v[1] = v[1] * u[1]
|
||||
v[2] = v[2] * u[2]
|
||||
v[3] = v[3] * u[3]
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
div = function(self, x)
|
||||
local v = checkvec4(self)
|
||||
if type(x) == 'number' then
|
||||
v[0] = v[0] / x
|
||||
v[1] = v[1] / x
|
||||
v[2] = v[2] / x
|
||||
v[3] = v[3] / x
|
||||
else
|
||||
local u = checkvec4(x, 1, 'vec4 or number')
|
||||
v[0] = v[0] / u[0]
|
||||
v[1] = v[1] / u[1]
|
||||
v[2] = v[2] / u[2]
|
||||
v[3] = v[3] / u[3]
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
length = function(self)
|
||||
local v = checkvec4(self)
|
||||
return math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3])
|
||||
end,
|
||||
|
||||
normalize = function(self)
|
||||
local v = checkvec4(self)
|
||||
local length2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]
|
||||
if length2 ~= 0 then
|
||||
local n = 1 / math.sqrt(length2)
|
||||
v[0] = v[0] * n
|
||||
v[1] = v[1] * n
|
||||
v[2] = v[2] * n
|
||||
v[3] = v[3] * n
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
distance = function(self, other)
|
||||
local v = checkvec4(self)
|
||||
local u = checkvec4(other, 1)
|
||||
local dx = v[0] - u[0]
|
||||
local dy = v[1] - u[1]
|
||||
local dz = v[2] - u[2]
|
||||
local dw = v[3] - u[3]
|
||||
return math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw)
|
||||
end,
|
||||
|
||||
dot = function(self, other)
|
||||
local v = checkvec4(self)
|
||||
local u = checkvec4(other, 1)
|
||||
return v[0] * u[0] + v[1] * u[1] + v[2] * u[2] + u[3] * v[3]
|
||||
end,
|
||||
|
||||
lerp = function(self, other, t)
|
||||
local v = checkvec4(self)
|
||||
local u = checkvec4(other, 1)
|
||||
v[0] = v[0] + (u[0] - v[0]) * t
|
||||
v[1] = v[1] + (u[1] - v[1]) * t
|
||||
v[2] = v[2] + (u[2] - v[2]) * t
|
||||
v[3] = v[3] + (u[3] - v[3]) * t
|
||||
return self
|
||||
end,
|
||||
|
||||
__add = function(a, b)
|
||||
checkvec4(a, 1)
|
||||
return lovr_math.vec4(a):add(b)
|
||||
end,
|
||||
|
||||
__sub = function(a, b)
|
||||
checkvec4(a, 1)
|
||||
return lovr_math.vec4(a):sub(b)
|
||||
end,
|
||||
|
||||
__mul = function(a, b)
|
||||
checkvec4(a, 1)
|
||||
return lovr_math.vec4(a):mul(b)
|
||||
end,
|
||||
|
||||
__div = function(a, b)
|
||||
checkvec4(a, 1)
|
||||
return lovr_math.vec4(a):div(b)
|
||||
end,
|
||||
|
||||
__unm = function(self)
|
||||
checkvec4(self)
|
||||
return lovr_math.vec4(self):mul(-1)
|
||||
end,
|
||||
|
||||
__len = function(self)
|
||||
checkvec4(self)
|
||||
return self:length()
|
||||
end,
|
||||
|
||||
__tostring = function(self)
|
||||
local v = checkvec4(self)
|
||||
return string.format('(%f, %f, %f, %f)', v[0], v[1], v[2], v[3])
|
||||
end,
|
||||
|
||||
__newindex = function(self, key, value)
|
||||
local v = checkvec3(self)
|
||||
|
||||
local swizzles = {
|
||||
x = 0,
|
||||
y = 1,
|
||||
z = 2,
|
||||
w = 3,
|
||||
r = 0,
|
||||
g = 1,
|
||||
b = 2,
|
||||
a = 3,
|
||||
s = 0,
|
||||
t = 1,
|
||||
p = 2,
|
||||
q = 3
|
||||
}
|
||||
|
||||
if type(key) == 'string' then
|
||||
if #key == 1 then
|
||||
local a = swizzles[key:sub(1, 1)]
|
||||
if a then
|
||||
v[a] = value
|
||||
return
|
||||
end
|
||||
elseif #key == 2 then
|
||||
local a, b = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)]
|
||||
if a and b then
|
||||
local u = checkvec2(value, 1)
|
||||
v[a], v[b] = u[0], u[1]
|
||||
return
|
||||
end
|
||||
elseif #key == 3 then
|
||||
local a, b, c = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)]
|
||||
if a and b and c then
|
||||
local u = checkvec3(value, 1)
|
||||
v[a], v[b], v[c] = u[0], u[1], u[2]
|
||||
return
|
||||
end
|
||||
elseif #key == 4 then
|
||||
local a, b, c, d = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)], swizzles[key:sub(4, 4)]
|
||||
if a and b and c and d then
|
||||
local u = checkvec4(value, 1)
|
||||
v[a], v[b], v[c], v[d] = u[0], u[1], u[2], u[3]
|
||||
return
|
||||
end
|
||||
end
|
||||
elseif type(key) == 'number' then
|
||||
if key >= 1 and key <= 4 then
|
||||
v[key - 1] = value
|
||||
end
|
||||
end
|
||||
|
||||
error(string.format('attempt to assign property %q of vec4 (invalid property)', key), 2)
|
||||
end,
|
||||
|
||||
__index = function(self, key)
|
||||
if vec4[key] then
|
||||
return vec4[key]
|
||||
end
|
||||
|
||||
local v = checkvec4(self)
|
||||
|
||||
if type(key) == 'string' then
|
||||
local swizzles = {
|
||||
x = 0,
|
||||
y = 1,
|
||||
z = 2,
|
||||
w = 3,
|
||||
r = 0,
|
||||
g = 1,
|
||||
b = 2,
|
||||
a = 3,
|
||||
s = 0,
|
||||
t = 1,
|
||||
p = 2,
|
||||
q = 3
|
||||
}
|
||||
|
||||
if #key == 1 then
|
||||
local a = swizzles[key:sub(1, 1)]
|
||||
if a then
|
||||
return v[a]
|
||||
end
|
||||
elseif #key == 2 then
|
||||
local a, b = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)]
|
||||
if a and b then
|
||||
return lovr_math.vec2(v[a], v[b])
|
||||
end
|
||||
elseif #key == 3 then
|
||||
local a, b, c = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)]
|
||||
if a and b and c then
|
||||
return lovr_math.vec3(v[a], v[b], v[c])
|
||||
end
|
||||
elseif #key == 4 then
|
||||
local a, b, c, d = swizzles[key:sub(1, 1)], swizzles[key:sub(2, 2)], swizzles[key:sub(3, 3)], swizzles[key:sub(4, 4)]
|
||||
if a and b and c and d then
|
||||
return lovr_math.vec4(v[a], v[b], v[c], v[d])
|
||||
end
|
||||
end
|
||||
elseif type(key) == 'number' and key >= 1 and key <= 4 then
|
||||
return v[key - 1]
|
||||
end
|
||||
|
||||
error(string.format('attempt to index field %q of vec4 (invalid property)', type(key)), 2)
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
quat = {
|
||||
unpack = function(self, raw)
|
||||
local q = checkquat(self)
|
||||
|
@ -748,7 +1038,7 @@ quat = {
|
|||
return q[3]
|
||||
end
|
||||
|
||||
error(string.format('attempt to index property %q of quat (invalid property)', key), 2)
|
||||
error(string.format('attempt to index field %q of quat (invalid property)', key), 2)
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -1062,18 +1352,20 @@ mat4 = {
|
|||
return m[key - 1]
|
||||
end
|
||||
|
||||
error(string.format('attempt to index property %q of mat4 (invalid property)', key), 2)
|
||||
error(string.format('attempt to index field %q of mat4 (invalid property)', key), 2)
|
||||
end
|
||||
}
|
||||
|
||||
ffi.metatype(vec2_t, vec2)
|
||||
ffi.metatype(vec3_t, vec3)
|
||||
ffi.metatype(vec4_t, vec4)
|
||||
ffi.metatype(quat_t, quat)
|
||||
ffi.metatype(mat4_t, mat4)
|
||||
|
||||
local new = ffi.new
|
||||
lovr_math.vec2 = function(...) return allocate(vec2_t, C.VEC2, 2):set(...) end
|
||||
lovr_math.vec3 = function(...) return allocate(vec3_t, C.VEC3, 4):set(...) end
|
||||
lovr_math.vec4 = function(...) return allocate(vec4_t, C.VEC4, 4):set(...) end
|
||||
lovr_math.quat = function(...) return allocate(quat_t, C.QUAT, 4):set(...) end
|
||||
lovr_math.mat4 = function(...) return allocate(mat4_t, C.MAT4, 16):set(...) end
|
||||
lovr_math.drain = function()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue