Improve vec2, vec3, vec4 lua storage

a. store as fixed size array
b. use metatable access via: x, y, z, w
c. For vec2
- vec2[0] could be access via x or w(idth) or u
- vec2[1] could be access via y or h(eight) or v
This commit is contained in:
halx99 2022-01-03 22:06:49 +08:00
parent 5031f8f54c
commit 2819d4f10d
5 changed files with 199 additions and 94 deletions

View File

@ -359,15 +359,33 @@ bool luaval_to_vec2(lua_State* L, int lo, cocos2d::Vec2* outValue, const char* f
ok = false; ok = false;
} }
// assertion: since we only have vec2, you should never passing rect as vec2 to native
const auto objlen = lua_objlen(L, -1);
assert(objlen == 2);
if (ok) if (ok)
{ {
lua_pushstring(L, "x"); lua_pushstring(L, "x");
lua_gettable(L, lo); lua_gettable(L, lo);
if (lua_isnil(L, -1))
{
lua_pop(L, 1);
lua_pushstring(L, "width");
lua_gettable(L, lo);
}
outValue->x = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1); outValue->x = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
lua_pushstring(L, "y"); lua_pushstring(L, "y");
lua_gettable(L, lo); lua_gettable(L, lo);
if (lua_isnil(L, -1))
{
lua_pop(L, 1);
lua_pushstring(L, "height");
lua_gettable(L, lo);
}
outValue->y = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1); outValue->y = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
} }
@ -2079,54 +2097,53 @@ void vec2_array_to_luaval(lua_State* L, const cocos2d::Vec2* points, int count)
} }
static int vec2_index(lua_State* L) static int vec2_index(lua_State* L)
{ { // t k
// top is table const char signature = lua_tostring(L, 2)[0];
const char* name = lua_tostring(L, 2); int n = 0;
if (strcmp(name, "width") == 0) if (signature == 'x' || signature == 'w' || signature == 'u')
{ {
lua_pop(L, 1); // pop the old name lua_pop(L, 1); // pop the string key
lua_pushstring(L, "x"); n = 1;
} }
else if (strcmp(name, "height") == 0) else if (signature == 'y' || signature == 'h' || signature == 'v')
{ {
lua_pop(L, 1); lua_pop(L, 1); // pop the string key
lua_pushstring(L, "y"); n = 2;
} }
lua_rawget(L, -2); if (n)
lua_rawgeti(L, -1, n);
else
lua_pushnil(L);
return 1; return 1;
} }
static int vec2_newindex(lua_State* L) static int vec2_newindex(lua_State* L)
{ { // t k v
const char* name = lua_tostring(L, 2); const char signature = lua_tostring(L, 2)[0];
if (strcmp(name, "width") == 0) int n = 0;
if (signature == 'x' || signature == 'w' || signature == 'u')
{ {
lua_remove(L, 2); lua_remove(L, 2); // remove the string key
lua_pushstring(L, "x"); n = 1;
lua_insert(L, 2);
} }
else if (strcmp(name, "height") == 0) else if (signature == 'y' || signature == 'h' || signature == 'v')
{ {
lua_remove(L, 2); lua_remove(L, 2); // remove the string key
lua_pushstring(L, "y"); n = 2;
lua_insert(L, 2);
} }
lua_rawset(L, -3); if (n)
lua_rawseti(L, -2, n);
return 0; return 0;
} }
void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2) int vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2)
{ {
if (NULL == L) lua_createtable(L, 2, 0); /* L: table */
return;
lua_newtable(L); /* L: table */
lua_pushstring(L, "x"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec2.x); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec2.x); /* L: table key value*/
lua_rawset(L, -3); /* table[key] = value, L: table */ lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec2.y); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec2.y); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 2);
int top = lua_gettop(L); int top = lua_gettop(L);
luaL_getmetatable(L, "_vec2mt"); luaL_getmetatable(L, "_vec2mt");
@ -2140,43 +2157,102 @@ void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2)
lua_setfield(L, -2, "__newindex"); lua_setfield(L, -2, "__newindex");
} }
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
return 1;
} }
void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3) static int vec3_index(lua_State* L)
{ { // t k
if (NULL == L) const char signature = lua_tostring(L, 2)[0];
return; assert(signature >= 'x' || signature <= 'z');
lua_pop(L, 1); // pop the string key
const int n = signature - 'x' + 1;
lua_rawgeti(L, -1, n);
return 1;
}
static int vec3_newindex(lua_State* L)
{ // t k v
const char signature = lua_tostring(L, 2)[0];
assert(signature >= 'x' || signature <= 'z');
lua_remove(L, 2); // remove the string key
const int n = signature - 'x' + 1;
lua_rawseti(L, -2, n);
lua_newtable(L); /* L: table */ return 0;
lua_pushstring(L, "x"); /* L: table key */ }
int vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3)
{
lua_createtable(L, 3, 0); /* L: table */
lua_pushnumber(L, (lua_Number)vec3.x); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec3.x); /* L: table key value*/
lua_rawset(L, -3); /* table[key] = value, L: table */ lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec3.y); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec3.y); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 2);
lua_pushstring(L, "z"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec3.z); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec3.z); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 3);
int top = lua_gettop(L);
luaL_getmetatable(L, "_vec3mt");
if (!lua_istable(L, -1))
{
lua_settop(L, top); // restore stack
luaL_newmetatable(L, "_vec3mt");
lua_pushcfunction(L, vec3_index);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, vec3_newindex);
lua_setfield(L, -2, "__newindex");
}
lua_setmetatable(L, -2);
return 1;
} }
void vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4) static int vec4_index(lua_State* L)
{ { // t k
if (NULL == L) const char signature = lua_tostring(L, 2)[0];
return; assert(signature >= 'w' || signature <= 'z');
lua_pop(L, 1); // pop the string key
const int n = signature != 'w' ? signature - 'x' + 1 : 4;
lua_rawgeti(L, -1, n);
return 1;
}
static int vec4_newindex(lua_State* L)
{ // t k v
const char signature = lua_tostring(L, 2)[0];
assert(signature >= 'w' || signature <= 'z');
lua_remove(L, 2); // remove the string key
const int n = signature != 'w' ? signature - 'x' + 1 : 4;
lua_rawseti(L, -2, n);
lua_newtable(L); /* L: table */ return 0;
lua_pushstring(L, "x"); /* L: table key */ }
int vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4)
{
lua_createtable(L, 4, 0); /* L: table */
lua_pushnumber(L, (lua_Number)vec4.x); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec4.x); /* L: table key value*/
lua_rawset(L, -3); /* table[key] = value, L: table */ lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec4.y); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec4.y); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 2);
lua_pushstring(L, "z"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec4.z); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec4.z); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 3);
lua_pushstring(L, "w"); /* L: table key */
lua_pushnumber(L, (lua_Number)vec4.w); /* L: table key value*/ lua_pushnumber(L, (lua_Number)vec4.w); /* L: table key value*/
lua_rawset(L, -3); lua_rawseti(L, -2, 4);
int top = lua_gettop(L);
luaL_getmetatable(L, "_vec4mt");
if (!lua_istable(L, -1))
{
lua_settop(L, top); // restore stack
luaL_newmetatable(L, "_vec4mt");
lua_pushcfunction(L, vec4_index);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, vec4_newindex);
lua_setfield(L, -2, "__newindex");
}
lua_setmetatable(L, -2);
return 1;
} }
#if CC_USE_PHYSICS #if CC_USE_PHYSICS

View File

@ -897,7 +897,7 @@ extern bool luaval_to_std_map_string_string(lua_State* L,
* @param L the current lua_State. * @param L the current lua_State.
* @param vec2 a cocos2d::Vec2 object. * @param vec2 a cocos2d::Vec2 object.
*/ */
extern void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2); extern int vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2);
/** /**
* Push a table converted from a cocos2d::Vec3 object into the Lua stack. * Push a table converted from a cocos2d::Vec3 object into the Lua stack.
@ -906,7 +906,7 @@ extern void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2);
* @param L the current lua_State. * @param L the current lua_State.
* @param vec3 a cocos2d::Vec3 object. * @param vec3 a cocos2d::Vec3 object.
*/ */
extern void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3); extern int vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3);
/** /**
* Push a table converted from a cocos2d::Vec4 object into the Lua stack. * Push a table converted from a cocos2d::Vec4 object into the Lua stack.
@ -915,7 +915,7 @@ extern void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3);
* @param L the current lua_State. * @param L the current lua_State.
* @param vec4 a cocos2d::Vec4 object. * @param vec4 a cocos2d::Vec4 object.
*/ */
extern void vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4); extern int vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4);
/** /**
* Push a table converted from a cocos2d::Vec2 array into the Lua stack. * Push a table converted from a cocos2d::Vec2 array into the Lua stack.

View File

@ -8188,6 +8188,23 @@ tolua_lerror:
#endif #endif
} }
static int tolua_cocos2d_Vec2_new(lua_State* L)
{
return vec2_to_luaval(L, Vec2{static_cast<float>(lua_tonumber(L, 1)), static_cast<float>(lua_tonumber(L, 2))});
}
static int tolua_cocos2d_Vec3_new(lua_State* L)
{
return vec3_to_luaval(L, Vec3{static_cast<float>(lua_tonumber(L, 1)), static_cast<float>(lua_tonumber(L, 2)),
static_cast<float>(lua_tonumber(L, 3))});
}
static int tolua_cocos2d_Vec4_new(lua_State* L)
{
return vec4_to_luaval(L, Vec4{static_cast<float>(lua_tonumber(L, 1)), static_cast<float>(lua_tonumber(L, 2)),
static_cast<float>(lua_tonumber(L, 3)), static_cast<float>(lua_tonumber(L, 4))});
}
int register_all_cocos2dx_math_manual(lua_State* tolua_S) int register_all_cocos2dx_math_manual(lua_State* tolua_S)
{ {
if (nullptr == tolua_S) if (nullptr == tolua_S)
@ -8205,6 +8222,9 @@ int register_all_cocos2dx_math_manual(lua_State* tolua_S)
tolua_function(tolua_S, "mat4_createTranslation", tolua_cocos2d_Mat4_createTranslation); tolua_function(tolua_S, "mat4_createTranslation", tolua_cocos2d_Mat4_createTranslation);
tolua_function(tolua_S, "mat4_createRotation", tolua_cocos2d_Mat4_createRotation); tolua_function(tolua_S, "mat4_createRotation", tolua_cocos2d_Mat4_createRotation);
tolua_function(tolua_S, "vec3_cross", tolua_cocos2d_Vec3_cross); tolua_function(tolua_S, "vec3_cross", tolua_cocos2d_Vec3_cross);
tolua_function(tolua_S, "vec2_new", tolua_cocos2d_Vec2_new);
tolua_function(tolua_S, "vec3_new", tolua_cocos2d_Vec3_new);
tolua_function(tolua_S, "vec4_new", tolua_cocos2d_Vec4_new);
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
return 0; return 0;
} }

View File

@ -58,8 +58,6 @@ USING_NS_CC;
TOLUA_API int register_all_cocos2dx_manual(lua_State* tolua_S); TOLUA_API int register_all_cocos2dx_manual(lua_State* tolua_S);
TOLUA_API int register_cocos2dx_event_releated(lua_State* tolua_S);
TOLUA_API int register_all_cocos2dx_module_manual(lua_State* tolua_S); TOLUA_API int register_all_cocos2dx_module_manual(lua_State* tolua_S);
TOLUA_API int register_all_cocos2dx_math_manual(lua_State* tolua_S); TOLUA_API int register_all_cocos2dx_math_manual(lua_State* tolua_S);

View File

@ -1,6 +1,13 @@
cc = cc or {} cc = cc or {}
-- Native vec2_new use array[2] to store x,y w,h u,v performance is better
-- p[1] alias: x w u width
-- p[2] alias: y h v height
local nvec2 = vec2_new
local nvec3 = vec3_new
local nvec4 = vec4_new
function cc.clampf(value, min_inclusive, max_inclusive) function cc.clampf(value, min_inclusive, max_inclusive)
-- body -- body
local temp = 0 local temp = 0
@ -19,33 +26,37 @@ function cc.clampf(value, min_inclusive, max_inclusive)
end end
end end
--Point --Vec2/Point
function cc.p(_x,_y) function cc.vec2(_x, _y)
if nil == _y then if nil == _y then
return { x = _x.x, y = _x.y } return nvec2(_x.x, _x.y)
else else
return { x = _x, y = _y } return nvec2(_x, _y)
end end
end
function cc.p(_x, ...)
return cc.vec2(_x, ...)
end end
function cc.pAdd(pt1,pt2) function cc.pAdd(pt1,pt2)
return {x = pt1.x + pt2.x , y = pt1.y + pt2.y } return cc.p(pt1.x + pt2.x , pt1.y + pt2.y )
end end
function cc.pSub(pt1,pt2) function cc.pSub(pt1,pt2)
return {x = pt1.x - pt2.x , y = pt1.y - pt2.y } return cc.p(pt1.x - pt2.x , pt1.y - pt2.y )
end end
function cc.pMul(pt1,factor) function cc.pMul(pt1,factor)
return { x = pt1.x * factor , y = pt1.y * factor } return cc.p( pt1.x * factor , pt1.y * factor )
end end
function cc.pMidpoint(pt1,pt2) function cc.pMidpoint(pt1,pt2)
return { x = (pt1.x + pt2.x) / 2.0 , y = ( pt1.y + pt2.y) / 2.0 } return cc.p( (pt1.x + pt2.x) / 2.0 , ( pt1.y + pt2.y) / 2.0 )
end end
function cc.pForAngle(a) function cc.pForAngle(a)
return { x = math.cos(a), y = math.sin(a) } return cc.p( math.cos(a), math.sin(a) )
end end
function cc.pGetLength(pt) function cc.pGetLength(pt)
@ -55,10 +66,10 @@ end
function cc.pNormalize(pt) function cc.pNormalize(pt)
local length = cc.pGetLength(pt) local length = cc.pGetLength(pt)
if 0 == length then if 0 == length then
return { x = 1.0,y = 0.0 } return cc.p( 1.0, 0.0 )
end end
return { x = pt.x / length, y = pt.y / length } return cc.p( pt.x / length, pt.y / length )
end end
function cc.pCross(self,other) function cc.pCross(self,other)
@ -119,23 +130,23 @@ function cc.pIsLineIntersect(A, B, C, D, s, t)
end end
function cc.pPerp(pt) function cc.pPerp(pt)
return { x = -pt.y, y = pt.x } return cc.p( -pt.y, pt.x )
end end
function cc.RPerp(pt) function cc.RPerp(pt)
return { x = pt.y, y = -pt.x } return cc.p( pt.y, -pt.x )
end end
function cc.pProject(pt1, pt2) function cc.pProject(pt1, pt2)
return { x = pt2.x * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) , y = pt2.y * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) } return cc.p( pt2.x * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) , pt2.y * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) )
end end
function cc.pRotate(pt1, pt2) function cc.pRotate(pt1, pt2)
return { x = pt1.x * pt2.x - pt1.y * pt2.y, y = pt1.x * pt2.y + pt1.y * pt2.x } return cc.p( pt1.x * pt2.x - pt1.y * pt2.y, pt1.x * pt2.y + pt1.y * pt2.x )
end end
function cc.pUnrotate(pt1, pt2) function cc.pUnrotate(pt1, pt2)
return { x = pt1.x * pt2.x + pt1.y * pt2.y, pt1.y * pt2.x - pt1.x * pt2.y } return cc.p( pt1.x * pt2.x + pt1.y * pt2.y, pt1.y * pt2.x - pt1.x * pt2.y )
end end
--Calculates the square length of pt --Calculates the square length of pt
function cc.pLengthSQ(pt) function cc.pLengthSQ(pt)
@ -147,11 +158,11 @@ function cc.pDistanceSQ(pt1,pt2)
end end
function cc.pGetClampPoint(pt1,pt2,pt3) function cc.pGetClampPoint(pt1,pt2,pt3)
return { x = cc.clampf(pt1.x, pt2.x, pt3.x), y = cc.clampf(pt1.y, pt2.y, pt3.y) } return cc.p( cc.clampf(pt1.x, pt2.x, pt3.x), cc.clampf(pt1.y, pt2.y, pt3.y) )
end end
function cc.pFromSize(sz) function cc.pFromSize(sz)
return { x = sz.width, y = sz.height } return cc.p( sz.width, sz.height )
end end
function cc.pLerp(pt1,pt2,alpha) function cc.pLerp(pt1,pt2,alpha)
@ -192,7 +203,7 @@ function cc.pGetIntersectPoint(pt1,pt2,pt3,pt4)
end end
--Size --Size
function cc.size( _width,_height ) function cc.size( _width,_height )
return { width = _width, height = _height } return cc.p(_width, _height)
end end
--Rect --Rect
@ -340,17 +351,17 @@ end
--Vertex2F --Vertex2F
function cc.vertex2F(_x,_y) function cc.vertex2F(_x,_y)
return { x = _x, y = _y } return cc.vec2(_x, _y )
end end
--Vertex3F --Vertex3F
function cc.Vertex3F(_x,_y,_z) function cc.Vertex3F(_x,_y,_z)
return { x = _x, y = _y, z = _z } return cc.vec3(_x, _y, _z)
end end
--Tex2F --Tex2F
function cc.tex2F(_u,_v) function cc.tex2F(_u,_v)
return { u = _u, v = _v } return cc.vec2( _u, _v )
end end
--PointSprite --PointSprite
@ -414,23 +425,23 @@ function cc.PhysicsMaterial(_density, _restitution, _friction)
end end
function cc.vec3(_x, _y, _z) function cc.vec3(_x, _y, _z)
return { x = _x, y = _y, z = _z } return nvec3( _x, _y, _z)
end end
function cc.vec4(_x, _y, _z, _w) function cc.vec4(_x, _y, _z, _w)
return { x = _x, y = _y, z = _z, w = _w } return nvec4( _x, _y, _z, _w )
end end
function cc.vec3add(vec3a, vec3b) function cc.vec3add(vec3a, vec3b)
return {x = vec3a.x + vec3b.x, y = vec3a.y + vec3b.y, z = vec3a.z + vec3b.z} return cc.vec3( vec3a.x + vec3b.x, vec3a.y + vec3b.y, vec3a.z + vec3b.z)
end end
function cc.vec3sub(vec3a, vec3b) function cc.vec3sub(vec3a, vec3b)
return {x = vec3a.x - vec3b.x, y = vec3a.y - vec3b.y, z = vec3a.z - vec3b.z} return cc.vec3( vec3a.x - vec3b.x, vec3a.y - vec3b.y, vec3a.z - vec3b.z)
end end
function cc.vec3mul(vec3, factor) function cc.vec3mul(vec3, factor)
return {x = vec3.x * factor, y = vec3.y * factor, z = vec3.z * factor} return cc.vec3( vec3.x * factor, vec3.y * factor, vec3.z * factor)
end end
function cc.vec3dot(vec3a, vec3b) function cc.vec3dot(vec3a, vec3b)
@ -453,7 +464,7 @@ function cc.vec3normalize(vec3)
end end
function cc.quaternion(_x, _y ,_z,_w) function cc.quaternion(_x, _y ,_z,_w)
return { x = _x, y = _y, z = _z, w = _w } return cc.vec4(_x, _y, _z, _w)
end end
function cc.quaternion_createFromAxisAngle(axis, angle) function cc.quaternion_createFromAxisAngle(axis, angle)