mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Make getting bone overrides return the "same" euler angles (#15007)
This commit is contained in:
parent
ba65eb953c
commit
02db521c80
@ -184,3 +184,23 @@ unittests.register("test_objects_in_area", function(_, pos)
|
|||||||
return core.objects_in_area(pos:offset(-1, -1, -1), pos:offset(1, 1, 1))
|
return core.objects_in_area(pos:offset(-1, -1, -1), pos:offset(1, 1, 1))
|
||||||
end)
|
end)
|
||||||
end, {map=true})
|
end, {map=true})
|
||||||
|
|
||||||
|
-- Tests that bone rotation euler angles are preserved (see #14992)
|
||||||
|
local function test_get_bone_rot(_, pos)
|
||||||
|
local obj = core.add_entity(pos, "unittests:dummy")
|
||||||
|
for _ = 1, 100 do
|
||||||
|
local function assert_similar(euler_angles)
|
||||||
|
local _, rot = obj:get_bone_position("bonename")
|
||||||
|
assert(euler_angles:distance(rot) < 1e-3)
|
||||||
|
local override = obj:get_bone_override("bonename")
|
||||||
|
assert(euler_angles:distance(override.rotation.vec:apply(math.deg)) < 1e-3)
|
||||||
|
end
|
||||||
|
local deg = 1e3 * vector.new(math.random(), math.random(), math.random())
|
||||||
|
obj:set_bone_position("bonename", vector.zero(), deg)
|
||||||
|
assert_similar(deg)
|
||||||
|
local rad = 3 * math.pi * vector.new(math.random(), math.random(), math.random())
|
||||||
|
obj:set_bone_override("bonename", {rotation = {vec = rad}})
|
||||||
|
assert_similar(rad:apply(math.deg))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unittests.register("test_get_bone_rot", test_get_bone_rot, {map=true})
|
||||||
|
@ -96,6 +96,9 @@ struct BoneOverride
|
|||||||
{
|
{
|
||||||
core::quaternion previous;
|
core::quaternion previous;
|
||||||
core::quaternion next;
|
core::quaternion next;
|
||||||
|
// Redundantly store the euler angles serverside
|
||||||
|
// so that we can return them in the appropriate getters
|
||||||
|
v3f next_radians;
|
||||||
bool absolute = false;
|
bool absolute = false;
|
||||||
f32 interp_timer = 0;
|
f32 interp_timer = 0;
|
||||||
} rotation;
|
} rotation;
|
||||||
|
@ -561,8 +561,10 @@ int ObjectRef::l_set_bone_position(lua_State *L)
|
|||||||
BoneOverride props;
|
BoneOverride props;
|
||||||
if (!lua_isnoneornil(L, 3))
|
if (!lua_isnoneornil(L, 3))
|
||||||
props.position.vector = check_v3f(L, 3);
|
props.position.vector = check_v3f(L, 3);
|
||||||
if (!lua_isnoneornil(L, 4))
|
if (!lua_isnoneornil(L, 4)) {
|
||||||
props.rotation.next = core::quaternion(check_v3f(L, 4) * core::DEGTORAD);
|
props.rotation.next_radians = check_v3f(L, 4) * core::DEGTORAD;
|
||||||
|
props.rotation.next = core::quaternion(props.rotation.next_radians);
|
||||||
|
}
|
||||||
props.position.absolute = true;
|
props.position.absolute = true;
|
||||||
props.rotation.absolute = true;
|
props.rotation.absolute = true;
|
||||||
sao->setBoneOverride(bone, props);
|
sao->setBoneOverride(bone, props);
|
||||||
@ -584,9 +586,9 @@ int ObjectRef::l_get_bone_position(lua_State *L)
|
|||||||
std::string bone = readParam<std::string>(L, 2, "");
|
std::string bone = readParam<std::string>(L, 2, "");
|
||||||
BoneOverride props = sao->getBoneOverride(bone);
|
BoneOverride props = sao->getBoneOverride(bone);
|
||||||
push_v3f(L, props.position.vector);
|
push_v3f(L, props.position.vector);
|
||||||
v3f euler_rot;
|
// In order to give modders back the euler angles they passed in,
|
||||||
props.rotation.next.toEuler(euler_rot);
|
// this **must not** compute equivalent euler angles from the quaternion
|
||||||
push_v3f(L, euler_rot * core::RADTODEG);
|
push_v3f(L, props.rotation.next_radians * core::RADTODEG);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,8 +634,10 @@ int ObjectRef::l_set_bone_override(lua_State *L)
|
|||||||
lua_getfield(L, 3, "rotation");
|
lua_getfield(L, 3, "rotation");
|
||||||
if (!lua_isnil(L, -1)) {
|
if (!lua_isnil(L, -1)) {
|
||||||
lua_getfield(L, -1, "vec");
|
lua_getfield(L, -1, "vec");
|
||||||
if (!lua_isnil(L, -1))
|
if (!lua_isnil(L, -1)) {
|
||||||
props.rotation.next = core::quaternion(check_v3f(L, -1));
|
props.rotation.next_radians = check_v3f(L, -1);
|
||||||
|
props.rotation.next = core::quaternion(props.rotation.next_radians);
|
||||||
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
read_prop_attrs(props.rotation);
|
read_prop_attrs(props.rotation);
|
||||||
@ -671,9 +675,9 @@ static void push_bone_override(lua_State *L, const BoneOverride &props)
|
|||||||
|
|
||||||
push_prop("position", props.position, props.position.vector);
|
push_prop("position", props.position, props.position.vector);
|
||||||
|
|
||||||
v3f euler_rot;
|
// In order to give modders back the euler angles they passed in,
|
||||||
props.rotation.next.toEuler(euler_rot);
|
// this **must not** compute equivalent euler angles from the quaternion
|
||||||
push_prop("rotation", props.rotation, euler_rot);
|
push_prop("rotation", props.rotation, props.rotation.next_radians);
|
||||||
|
|
||||||
push_prop("scale", props.scale, props.scale.vector);
|
push_prop("scale", props.scale, props.scale.vector);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user