1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Extend bone override capabilities (#12388)

This commit is contained in:
Lars Müller 2023-12-20 21:21:53 +01:00 committed by GitHub
parent 61d0f613df
commit 0d61598d8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 375 additions and 80 deletions

View file

@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server/luaentity_sao.h"
#include "server/player_sao.h"
#include "server/serverinventorymgr.h"
#include "server/unit_sao.h"
/*
ObjectRef
@ -518,16 +519,25 @@ int ObjectRef::l_set_animation_frame_speed(lua_State *L)
int ObjectRef::l_set_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,"Deprecated call to set_bone_position, use set_bone_override instead");
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
std::string bone = readParam<std::string>(L, 2, "");
v3f position = readParam<v3f>(L, 3, v3f(0, 0, 0));
v3f rotation = readParam<v3f>(L, 4, v3f(0, 0, 0));
sao->setBonePosition(bone, position, rotation);
std::string bone;
if (!lua_isnil(L, 2))
bone = readParam<std::string>(L, 2);
BoneOverride props;
if (!lua_isnil(L, 3))
props.position.vector = check_v3f(L, 3);
if (!lua_isnil(L, 4))
props.rotation.next = core::quaternion(check_v3f(L, 4) * core::DEGTORAD);
props.position.absolute = true;
props.rotation.absolute = true;
sao->setBoneOverride(bone, props);
return 0;
}
@ -535,22 +545,144 @@ int ObjectRef::l_set_bone_position(lua_State *L)
int ObjectRef::l_get_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
log_deprecated(L,"Deprecated call to get_bone_position, use get_bone_override instead");
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == nullptr)
return 0;
std::string bone = readParam<std::string>(L, 2, "");
v3f position = v3f(0, 0, 0);
v3f rotation = v3f(0, 0, 0);
sao->getBonePosition(bone, &position, &rotation);
push_v3f(L, position);
push_v3f(L, rotation);
BoneOverride props = sao->getBoneOverride(bone);
push_v3f(L, props.position.vector);
v3f euler_rot;
props.rotation.next.toEuler(euler_rot);
push_v3f(L, euler_rot * core::RADTODEG);
return 2;
}
// set_bone_override(self, bone, override)
int ObjectRef::l_set_bone_override(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == NULL)
return 0;
std::string bone = readParam<std::string>(L, 2);
BoneOverride props;
if (lua_isnoneornil(L, 3)) {
sao->setBoneOverride(bone, props);
return 0;
}
auto read_prop_attrs = [L](auto &prop) {
lua_getfield(L, -1, "absolute");
prop.absolute = lua_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "interpolate");
if (lua_isnumber(L, -1))
prop.interp_timer = lua_tonumber(L, -1);
lua_pop(L, 1);
};
lua_getfield(L, 3, "position");
if (!lua_isnil(L, -1)) {
lua_getfield(L, -1, "vec");
if (!lua_isnil(L, -1))
props.position.vector = check_v3f(L, -1);
lua_pop(L, 1);
read_prop_attrs(props.position);
}
lua_pop(L, 1);
lua_getfield(L, 3, "rotation");
if (!lua_isnil(L, -1)) {
lua_getfield(L, -1, "vec");
if (!lua_isnil(L, -1))
props.rotation.next = core::quaternion(check_v3f(L, -1));
lua_pop(L, 1);
read_prop_attrs(props.rotation);
}
lua_pop(L, 1);
lua_getfield(L, 3, "scale");
if (!lua_isnil(L, -1)) {
lua_getfield(L, -1, "vec");
props.scale.vector = lua_isnil(L, -1) ? v3f(1) : check_v3f(L, -1);
lua_pop(L, 1);
read_prop_attrs(props.scale);
}
lua_pop(L, 1);
sao->setBoneOverride(bone, props);
return 0;
}
static void push_bone_override(lua_State *L, const BoneOverride &props)
{
lua_newtable(L);
auto push_prop = [L](const char *name, const auto &prop, v3f vec) {
lua_newtable(L);
push_v3f(L, vec);
lua_setfield(L, -2, "vec");
lua_pushnumber(L, prop.interp_timer);
lua_setfield(L, -2, "interpolate");
lua_pushboolean(L, prop.absolute);
lua_setfield(L, -2, "absolute");
lua_setfield(L, -2, name);
};
push_prop("position", props.position, props.position.vector);
v3f euler_rot;
props.rotation.next.toEuler(euler_rot);
push_prop("rotation", props.rotation, euler_rot);
push_prop("scale", props.scale, props.scale.vector);
// leave only override table on top of the stack
}
// get_bone_override(self, bone)
int ObjectRef::l_get_bone_override(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
ServerActiveObject *sao = getobject(ref);
if (sao == NULL)
return 0;
std::string bone = readParam<std::string>(L, 2);
push_bone_override(L, sao->getBoneOverride(bone));
return 1;
}
// get_bone_overrides(self)
int ObjectRef::l_get_bone_overrides(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
ServerActiveObject *co = getobject(ref);
if (co == NULL)
return 0;
lua_newtable(L);
for (const auto &bone_pos : co->getBoneOverrides()) {
push_bone_override(L, bone_pos.second);
lua_setfield(L, -2, bone_pos.first.c_str());
}
return 1;
}
// set_attach(self, parent, bone, position, rotation, force_visible)
int ObjectRef::l_set_attach(lua_State *L)
{
@ -2471,6 +2603,9 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_animation_frame_speed),
luamethod(ObjectRef, set_bone_position),
luamethod(ObjectRef, get_bone_position),
luamethod(ObjectRef, set_bone_override),
luamethod(ObjectRef, get_bone_override),
luamethod(ObjectRef, get_bone_overrides),
luamethod(ObjectRef, set_attach),
luamethod(ObjectRef, get_attach),
luamethod(ObjectRef, get_children),