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;
}
// 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)
{
lua_pushstring(L, "x");
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);
lua_pop(L, 1);
lua_pushstring(L, "y");
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);
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)
{
// top is table
const char* name = lua_tostring(L, 2);
if (strcmp(name, "width") == 0)
{ // t k
const char signature = lua_tostring(L, 2)[0];
int n = 0;
if (signature == 'x' || signature == 'w' || signature == 'u')
{
lua_pop(L, 1); // pop the old name
lua_pushstring(L, "x");
lua_pop(L, 1); // pop the string key
n = 1;
}
else if (strcmp(name, "height") == 0)
else if (signature == 'y' || signature == 'h' || signature == 'v')
{
lua_pop(L, 1);
lua_pushstring(L, "y");
lua_pop(L, 1); // pop the string key
n = 2;
}
lua_rawget(L, -2);
if (n)
lua_rawgeti(L, -1, n);
else
lua_pushnil(L);
return 1;
}
static int vec2_newindex(lua_State* L)
{
const char* name = lua_tostring(L, 2);
if (strcmp(name, "width") == 0)
{ // t k v
const char signature = lua_tostring(L, 2)[0];
int n = 0;
if (signature == 'x' || signature == 'w' || signature == 'u')
{
lua_remove(L, 2);
lua_pushstring(L, "x");
lua_insert(L, 2);
lua_remove(L, 2); // remove the string key
n = 1;
}
else if (strcmp(name, "height") == 0)
else if (signature == 'y' || signature == 'h' || signature == 'v')
{
lua_remove(L, 2);
lua_pushstring(L, "y");
lua_insert(L, 2);
lua_remove(L, 2); // remove the string key
n = 2;
}
lua_rawset(L, -3);
if (n)
lua_rawseti(L, -2, n);
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)
return;
lua_newtable(L); /* L: table */
lua_pushstring(L, "x"); /* L: table key */
lua_createtable(L, 2, 0); /* L: table */
lua_pushnumber(L, (lua_Number)vec2.x); /* L: table key value*/
lua_rawset(L, -3); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
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);
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_setmetatable(L, -2);
return 1;
}
void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3)
{
if (NULL == L)
return;
static int vec3_index(lua_State* L)
{ // t k
const char signature = lua_tostring(L, 2)[0];
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 */
lua_pushstring(L, "x"); /* L: table key */
return 0;
}
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_rawset(L, -3); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
lua_pushnumber(L, (lua_Number)vec3.y); /* L: table key value*/
lua_rawset(L, -3);
lua_pushstring(L, "z"); /* L: table key */
lua_rawseti(L, -2, 2);
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)
{
if (NULL == L)
return;
static int vec4_index(lua_State* L)
{ // t k
const char signature = lua_tostring(L, 2)[0];
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 */
lua_pushstring(L, "x"); /* L: table key */
return 0;
}
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_rawset(L, -3); /* table[key] = value, L: table */
lua_pushstring(L, "y"); /* L: table key */
lua_rawseti(L, -2, 1); /* table[key] = value, L: table */
lua_pushnumber(L, (lua_Number)vec4.y); /* L: table key value*/
lua_rawset(L, -3);
lua_pushstring(L, "z"); /* L: table key */
lua_rawseti(L, -2, 2);
lua_pushnumber(L, (lua_Number)vec4.z); /* L: table key value*/
lua_rawset(L, -3);
lua_pushstring(L, "w"); /* L: table key */
lua_rawseti(L, -2, 3);
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

View File

@ -897,7 +897,7 @@ extern bool luaval_to_std_map_string_string(lua_State* L,
* @param L the current lua_State.
* @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.
@ -906,7 +906,7 @@ extern void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2);
* @param L the current lua_State.
* @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.
@ -915,7 +915,7 @@ extern void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3);
* @param L the current lua_State.
* @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.

View File

@ -8188,6 +8188,23 @@ tolua_lerror:
#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)
{
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_createRotation", tolua_cocos2d_Mat4_createRotation);
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);
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_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_math_manual(lua_State* tolua_S);

View File

@ -1,6 +1,13 @@
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)
-- body
local temp = 0
@ -19,33 +26,37 @@ function cc.clampf(value, min_inclusive, max_inclusive)
end
end
--Point
function cc.p(_x,_y)
--Vec2/Point
function cc.vec2(_x, _y)
if nil == _y then
return { x = _x.x, y = _x.y }
return nvec2(_x.x, _x.y)
else
return { x = _x, y = _y }
return nvec2(_x, _y)
end
end
function cc.p(_x, ...)
return cc.vec2(_x, ...)
end
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
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
function cc.pMul(pt1,factor)
return { x = pt1.x * factor , y = pt1.y * factor }
return cc.p( pt1.x * factor , pt1.y * factor )
end
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
function cc.pForAngle(a)
return { x = math.cos(a), y = math.sin(a) }
return cc.p( math.cos(a), math.sin(a) )
end
function cc.pGetLength(pt)
@ -55,10 +66,10 @@ end
function cc.pNormalize(pt)
local length = cc.pGetLength(pt)
if 0 == length then
return { x = 1.0,y = 0.0 }
return cc.p( 1.0, 0.0 )
end
return { x = pt.x / length, y = pt.y / length }
return cc.p( pt.x / length, pt.y / length )
end
function cc.pCross(self,other)
@ -119,23 +130,23 @@ function cc.pIsLineIntersect(A, B, C, D, s, t)
end
function cc.pPerp(pt)
return { x = -pt.y, y = pt.x }
return cc.p( -pt.y, pt.x )
end
function cc.RPerp(pt)
return { x = pt.y, y = -pt.x }
return cc.p( pt.y, -pt.x )
end
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
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
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
--Calculates the square length of pt
function cc.pLengthSQ(pt)
@ -147,11 +158,11 @@ function cc.pDistanceSQ(pt1,pt2)
end
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
function cc.pFromSize(sz)
return { x = sz.width, y = sz.height }
return cc.p( sz.width, sz.height )
end
function cc.pLerp(pt1,pt2,alpha)
@ -192,7 +203,7 @@ function cc.pGetIntersectPoint(pt1,pt2,pt3,pt4)
end
--Size
function cc.size( _width,_height )
return { width = _width, height = _height }
return cc.p(_width, _height)
end
--Rect
@ -238,7 +249,7 @@ function cc.rectContainsPoint( rect, point )
local ret = false
if (point.x >= rect.x) and (point.x <= rect.x + rect.width) and
(point.y >= rect.y) and (point.y <= rect.y + rect.height) then
(point.y >= rect.y) and (point.y <= rect.y + rect.height) then
ret = true
end
@ -247,9 +258,9 @@ end
function cc.rectIntersectsRect( rect1, rect2 )
local intersect = not ( rect1.x > rect2.x + rect2.width or
rect1.x + rect1.width < rect2.x or
rect1.y > rect2.y + rect2.height or
rect1.y + rect1.height < rect2.y )
rect1.x + rect1.width < rect2.x or
rect1.y > rect2.y + rect2.height or
rect1.y + rect1.height < rect2.y )
return intersect
end
@ -340,17 +351,17 @@ end
--Vertex2F
function cc.vertex2F(_x,_y)
return { x = _x, y = _y }
return cc.vec2(_x, _y )
end
--Vertex3F
function cc.Vertex3F(_x,_y,_z)
return { x = _x, y = _y, z = _z }
return cc.vec3(_x, _y, _z)
end
--Tex2F
function cc.tex2F(_u,_v)
return { u = _u, v = _v }
return cc.vec2( _u, _v )
end
--PointSprite
@ -410,27 +421,27 @@ end
--PhysicsMaterial
function cc.PhysicsMaterial(_density, _restitution, _friction)
return { density = _density, restitution = _restitution, friction = _friction }
return { density = _density, restitution = _restitution, friction = _friction }
end
function cc.vec3(_x, _y, _z)
return { x = _x, y = _y, z = _z }
return nvec3( _x, _y, _z)
end
function cc.vec4(_x, _y, _z, _w)
return { x = _x, y = _y, z = _z, w = _w }
return nvec4( _x, _y, _z, _w )
end
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
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
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
function cc.vec3dot(vec3a, vec3b)
@ -453,7 +464,7 @@ function cc.vec3normalize(vec3)
end
function cc.quaternion(_x, _y ,_z,_w)
return { x = _x, y = _y, z = _z, w = _w }
return cc.vec4(_x, _y, _z, _w)
end
function cc.quaternion_createFromAxisAngle(axis, angle)
@ -521,9 +532,9 @@ end
function cc.mat4.createIdentity()
return cc.mat4.new(1.0 ,0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)
end
function cc.mat4.translate(self,vec3)