Merge pull request 'Switch to set_bones_override, use rad instead of deg' (#4748) from bones into master

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4748
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
This commit is contained in:
the-real-herowl 2024-12-27 12:19:52 +01:00
commit f4d80f0b3f
5 changed files with 74 additions and 87 deletions

@ -558,12 +558,25 @@ function mcl_util.set_properties(obj, props)
end end
end end
-- Update bones, but only when changed
function mcl_util.set_bone_position(obj, bone, pos, rot) function mcl_util.set_bone_position(obj, bone, pos, rot)
local current_pos, current_rot = obj:get_bone_position(bone) if core.get_bone_override then -- minetest >= 5.9
local pos_equal = not pos or vector.equals(vector.round(current_pos), vector.round(pos)) local over = obj:get_bone_override(bone)
local rot_equal = not rot or vector.equals(vector.round(current_rot), vector.round(rot)) local pos_equal = not pos or not over.position.absolute or vector.equals(vector.round(over.position.vec), vector.round(pos))
if not pos_equal or not rot_equal then local rot_equal = not rot or not over.rotation.absolute or vector.equals(vector.round(over.rotation.vec), vector.round(rot))
obj:set_bone_position(bone, pos or current_pos, rot or current_rot) if not pos_equal or not rot_equal then
if pos then over.position = { vec = pos, absolute = true, interpolation = 0.1 } end
if rot then over.rotation = { vec = rot, absolute = true, interpolation = 0.1 } end
obj:set_bone_override(bone, over)
end
else -- minetest up to 5.8
rot = rot and rot:apply(math.deg)
local current_pos, current_rot = obj:get_bone_position(bone)
local pos_equal = not pos or vector.equals(vector.round(current_pos), vector.round(pos))
local rot_equal = not rot or vector.equals(vector.round(current_rot), vector.round(rot))
if not pos_equal or not rot_equal then
obj:set_bone_position(bone, pos or current_pos, rot or current_rot)
end
end end
end end

@ -81,7 +81,7 @@ local cod = {
fear_height = 4, fear_height = 4,
do_custom = function(self) do_custom = function(self)
--[[ this is supposed to make them jump out the water but doesn't appear to work very well --[[ this is supposed to make them jump out the water but doesn't appear to work very well
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) mcl_util.set_bone_position(self.object, "body", vector.new(0,1,0), vector.new(dir_to_pitch(self.object:get_velocity()) * -1 + math.pi/2,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 }) self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 })

@ -83,7 +83,7 @@ local dolphin = {
attack_type = "dogfight", attack_type = "dogfight",
--[[ this is supposed to make them jump out the water but doesn't appear to work very well --[[ this is supposed to make them jump out the water but doesn't appear to work very well
do_custom = function(self,dtime) do_custom = function(self,dtime)
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) mcl_util.set_bone_position(self.object, "body", vector.new(0,1,0), vector.new(dir_to_pitch(self.object:get_velocity()) * -1 + math.pi/2,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 }) self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 })

@ -110,16 +110,16 @@ local piglin = {
return return
elseif self.trading == true then elseif self.trading == true then
self.state = "trading" self.state = "trading"
self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,-20,18)) mcl_util.set_bone_position(self.object, "Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0.35,-0.35,0.315))
self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(-40,0,0)) mcl_util.set_bone_position(self.object, "Head", vector.new(0,6.3,0), vector.new(-0.7,0,0))
self.base_texture[2] = "default_gold_ingot.png" self.base_texture[2] = "default_gold_ingot.png"
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
else else
self.object:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) mcl_util.set_bone_position(self.object, "Wield_Item", vector.new(.5,4.5,-1.6), vector.new(1.57,0,0.35))
self.base_texture[2] = self.weapon self.base_texture[2] = self.weapon
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(0,0,0)) mcl_util.set_bone_position(self.object, "Head", vector.new(0,6.3,0), vector.new(0,0,0))
self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) mcl_util.set_bone_position(self.object, "Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0))
end end
if self.state ~= "attack" then if self.state ~= "attack" then
@ -139,7 +139,7 @@ local piglin = {
self.object:set_animation({x=0,y=79}) self.object:set_animation({x=0,y=79})
self.trading = true self.trading = true
self.gold_items = self.gold_items + 1 self.gold_items = self.gold_items + 1
self.object:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) mcl_util.set_bone_position(self.object, "Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(2.36,0,1.57))
minetest.after(5, function() minetest.after(5, function()
self.gold_items = self.gold_items - 1 self.gold_items = self.gold_items - 1
if self.gold_items == 0 then if self.gold_items == 0 then
@ -202,7 +202,7 @@ sword_piglin.textures = {"extra_mobs_piglin.png", "default_tool_goldsword.png"}
sword_piglin.on_spawn = function(self) sword_piglin.on_spawn = function(self)
self.gold_items = 0 self.gold_items = 0
self.weapon = self.base_texture[2] self.weapon = self.base_texture[2]
self.object:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) mcl_util.set_bone_position(self.object, "Wield_Item", vector.new(0,3.9,1.3), vector.new(1.57,0,0))
end end
sword_piglin.drops = { sword_piglin.drops = {
{name = "mcl_tools:sword_gold", {name = "mcl_tools:sword_gold",

@ -19,6 +19,9 @@ local playerphysics = playerphysics
local vector = vector local vector = vector
local math = math local math = math
local PI = math.pi
local TWOPI = math.pi * 2
-- Internal player state -- Internal player state
local mcl_playerplus_internal = {} local mcl_playerplus_internal = {}
@ -66,70 +69,46 @@ local function player_collision(player)
end end
local function walking_player(player, control) local function walking_player(player, control)
if control.up or control.down or control.left or control.right then return not not (control.up or control.down or control.left or control.right)
return true
else
return false
end
end
-- converts yaw to degrees
local function degrees(rad)
return rad * 180.0 / math.pi
end end
local function dir_to_pitch(dir) local function dir_to_pitch(dir)
--local dir2 = vector.normalize(dir) return -math.atan2(-dir.y, math.sqrt(dir.x * dir.x + dir.z * dir.z))
local xz = math.abs(dir.x) + math.abs(dir.z)
return -math.atan2(-dir.y, xz)
end end
local player_vel_yaws = {} local player_vel_yaws = {}
function limit_vel_yaw(player_vel_yaw, yaw) function limit_vel_yaw(player_vel_yaw, yaw)
if player_vel_yaw < 0 then player_vel_yaw = player_vel_yaw % TWOPI
player_vel_yaw = player_vel_yaw + 360 yaw = yaw % TWOPI
end
if yaw < 0 then if math.abs(player_vel_yaw - yaw) > 0.7 then
yaw = yaw + 360
end
if math.abs(player_vel_yaw - yaw) > 40 then
local player_vel_yaw_nm, yaw_nm = player_vel_yaw, yaw local player_vel_yaw_nm, yaw_nm = player_vel_yaw, yaw
if player_vel_yaw > yaw then if player_vel_yaw > yaw then
player_vel_yaw_nm = player_vel_yaw - 360 player_vel_yaw_nm = player_vel_yaw - TWOPI
else else
yaw_nm = yaw - 360 yaw_nm = yaw - TWOPI
end end
if math.abs(player_vel_yaw_nm - yaw_nm) > 40 then if math.abs(player_vel_yaw_nm - yaw_nm) > 0.7 then
local diff = math.abs(player_vel_yaw - yaw) local diff = math.abs(player_vel_yaw - yaw)
if diff > 180 and diff < 185 or diff < 180 and diff > 175 then if diff > PI and diff < 3.229 or diff < PI and diff > 3.054 then
player_vel_yaw = yaw player_vel_yaw = yaw
elseif diff < 180 then elseif diff < PI then
if player_vel_yaw < yaw then if player_vel_yaw < yaw then
player_vel_yaw = yaw - 40 player_vel_yaw = yaw - 0.7
else else
player_vel_yaw = yaw + 40 player_vel_yaw = yaw + 0.7
end end
else else
if player_vel_yaw < yaw then if player_vel_yaw < yaw then
player_vel_yaw = yaw + 40 player_vel_yaw = yaw + 0.7
else else
player_vel_yaw = yaw - 40 player_vel_yaw = yaw - 0.7
end end
end end
end end
end end
return player_vel_yaw % TWOPI
if player_vel_yaw < 0 then
player_vel_yaw = player_vel_yaw + 360
elseif player_vel_yaw > 360 then
player_vel_yaw = player_vel_yaw - 360
end
return player_vel_yaw
end end
local node_stand, node_stand_below, node_head, node_feet, node_head_top local node_stand, node_stand_below, node_head, node_feet, node_head_top
@ -138,13 +117,9 @@ local is_swimming
local set_bone_pos = mcl_util.set_bone_position local set_bone_pos = mcl_util.set_bone_position
local set_properties = mcl_util.set_properties local set_properties = mcl_util.set_properties
local function get_overall_velocity(vector)
local v = math.sqrt(vector.x^2 + vector.y^2 + vector.z^2)
return v
end
local function anglediff(a1, a2) local function anglediff(a1, a2)
local a = a1 - a2 local a = a1 - a2
return math.abs((a + math.pi) % (math.pi*2) - math.pi) return math.abs((a + math.pi) % (math.pi*2) - math.pi)
end end
local function clamp(num, min, max) local function clamp(num, min, max)
return math.min(max, math.max(num, min)) return math.min(max, math.max(num, min))
@ -210,10 +185,10 @@ minetest.register_globalstep(function(dtime)
end end
-- control head bone -- control head bone
local pitch = - degrees(player:get_look_vertical()) local pitch = -player:get_look_vertical()
local yaw = degrees(player:get_look_horizontal()) local yaw = player:get_look_horizontal()
local player_vel_yaw = degrees(dir_to_yaw(player_velocity)) local player_vel_yaw = dir_to_yaw(player_velocity)
if player_vel_yaw == 0 then if player_vel_yaw == 0 then
player_vel_yaw = player_vel_yaws[name] or yaw player_vel_yaw = player_vel_yaws[name] or yaw
end end
@ -310,46 +285,46 @@ minetest.register_globalstep(function(dtime)
end end
if wielded_def and wielded_def._mcl_toollike_wield then if wielded_def and wielded_def._mcl_toollike_wield then
set_bone_pos(player, "Wield_Item", vector.new(0, 4.7, 3.1), vector.new(-90, 225, 90)) set_bone_pos(player, "Wield_Item", vector.new(0, 4.7, 3.1), vector.new(-1.57, 3.93, 1.57))
elseif string.find(wielded:get_name(), "mcl_bows:bow") then elseif string.find(wielded:get_name(), "mcl_bows:bow") then
set_bone_pos(player, "Wield_Item", vector.new(1, 4, 0), vector.new(90, 130, 115)) set_bone_pos(player, "Wield_Item", vector.new(1, 4, 0), vector.new(1.57, 2.27, 2.01))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 73)) set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 3.1415, 1.27))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then
set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 45)) set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 3.1415, 0.78))
elseif wielded_def.inventory_image == "" then elseif wielded_def.inventory_image == "" then
set_bone_pos(player,"Wield_Item", vector.new(0, 6, 2), vector.new(180, -45, 0)) set_bone_pos(player, "Wield_Item", vector.new(0, 6, 2), vector.new(3.1415, -0.785, 0))
else else
set_bone_pos(player, "Wield_Item", vector.new(0, 5.3, 2), vector.new(90, 0, 0)) set_bone_pos(player, "Wield_Item", vector.new(0, 5.3, 2), vector.new(1.57, 0, 0))
end end
-- controls right and left arms pitch when shooting a bow or blocking -- controls right and left arms pitch when shooting a bow or blocking
if mcl_shields.is_blocking(player) == 2 then if mcl_shields.is_blocking(player) == 2 then
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, -20, 0)) set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(0.35, -0.35, 0))
elseif mcl_shields.is_blocking(player) == 1 then elseif mcl_shields.is_blocking(player) == 1 then
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(20, 20, 0)) set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(0.35, 0.35, 0))
elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then
local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) local right_arm_rot = vector.new(pitch + 1.57, -0.524, pitch * -1 * .35)
local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) local left_arm_rot = vector.new(pitch + 1.57, 0.75, pitch * .35)
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot)
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot)
-- controls right and left arms pitch when holing a loaded crossbow -- controls right and left arms pitch when holing a loaded crossbow
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) local right_arm_rot = vector.new(pitch + 1.57, -0.524, pitch * -1 * .35)
local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) local left_arm_rot = vector.new(pitch + 1.57, 0.75, pitch * .35)
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot)
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot)
-- controls right and left arms pitch when loading a crossbow -- controls right and left arms pitch when loading a crossbow
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(45, -20, 25)) set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(0.786, -0.35, 0.47))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(55, 20, -45)) set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(0.96, 0.35, -0.786))
-- when punching -- when punching
elseif control.LMB and not parent then elseif control.LMB and not parent then
set_bone_pos(player,"Arm_Right_Pitch_Control", nil, vector.new(pitch, 0, 0)) set_bone_pos(player,"Arm_Right_Pitch_Control", nil, vector.new(pitch, 0, 0))
set_bone_pos(player,"Arm_Left_Pitch_Control", nil, vector.zero()) set_bone_pos(player,"Arm_Left_Pitch_Control", nil, vector.zero())
-- when holding an item. -- when holding an item.
elseif wielded:get_name() ~= "" then elseif wielded:get_name() ~= "" then
set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, 0, 0)) set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(0.35, 0, 0))
set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero()) set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero())
-- resets arms pitch -- resets arms pitch
else else
@ -359,19 +334,18 @@ minetest.register_globalstep(function(dtime)
if elytra.active then if elytra.active then
-- set head pitch and yaw when flying -- set head pitch and yaw when flying
local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 50, player_vel_yaw - yaw, 0) local head_rot = vector.new(pitch - dir_to_pitch(player_velocity) + 0.87, player_vel_yaw - yaw, 0)
set_bone_pos(player,"Head_Control", nil, head_rot) set_bone_pos(player,"Head_Control", nil, head_rot)
-- sets eye height, and nametag color accordingly -- sets eye height, and nametag color accordingly
set_properties(player, player_props_elytra) set_properties(player, player_props_elytra)
-- control body bone when flying -- control body bone when flying
local body_rot = vector.new(degrees(dir_to_pitch(player_velocity)) + 110, -player_vel_yaw + yaw, 180) local body_rot = vector.new(dir_to_pitch(player_velocity) + 1.92, -player_vel_yaw + yaw, 3.1415)
set_bone_pos(player, "Body_Control", nil, body_rot) set_bone_pos(player, "Body_Control", nil, body_rot)
elseif parent then elseif parent then
set_properties(player, player_props_riding) set_properties(player, player_props_riding)
local parent_yaw = parent:get_yaw()
local parent_yaw = degrees(parent:get_yaw())
local head_rot = vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0) local head_rot = vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)
set_bone_pos(player, "Head_Control", nil, head_rot) set_bone_pos(player, "Head_Control", nil, head_rot)
set_bone_pos(player,"Body_Control", nil, vector.zero()) set_bone_pos(player,"Body_Control", nil, vector.zero())
@ -388,14 +362,14 @@ minetest.register_globalstep(function(dtime)
elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then
-- set head pitch and yaw when swimming -- set head pitch and yaw when swimming
is_swimming = true is_swimming = true
local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 20, player_vel_yaw - yaw, 0) local head_rot = vector.new(pitch - dir_to_pitch(player_velocity) + 0.35, player_vel_yaw - yaw, 0)
set_bone_pos(player, "Head_Control", nil, head_rot) set_bone_pos(player, "Head_Control", nil, head_rot)
-- sets eye height, and nametag color accordingly -- sets eye height, and nametag color accordingly
set_properties(player, player_props_swimming) set_properties(player, player_props_swimming)
-- control body bone when swimming -- control body bone when swimming
local body_rot = vector.new((75 + degrees(dir_to_pitch(player_velocity))), player_vel_yaw - yaw, 180) local body_rot = vector.new((1.3 + dir_to_pitch(player_velocity)), player_vel_yaw - yaw, 3.1415)
set_bone_pos(player,"Body_Control", nil, body_rot) set_bone_pos(player,"Body_Control", nil, body_rot)
elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0 elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0
and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then
@ -686,12 +660,12 @@ minetest.register_on_joinplayer(function(player)
} }
mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0} mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0}
-- Luanti bug: get_bone_position() returns all zeros vectors. -- Luanti limitation: get_bone_position() returns all zeros vectors, because models are client-side not server-side
-- Workaround: call set_bone_position() one time first. -- Workaround: call set_bone_position() one time first.
player:set_bone_position("Head_Control", vector.new(0, 6.75, 0)) set_bone_pos(player, "Head_Control", vector.new(0, 6.75, 0))
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0)) set_bone_pos(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0))
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3, 5.785, 0)) set_bone_pos(player, "Arm_Left_Pitch_Control", vector.new(3, 5.785, 0))
player:set_bone_position("Body_Control", vector.new(0, 6.75, 0)) set_bone_pos(player, "Body_Control", vector.new(0, 6.75, 0))
-- Respawn dead players on joining -- Respawn dead players on joining
if hp <= 0 then if hp <= 0 then
player:respawn() player:respawn()