Switch to modlib quaternions
parent
bcef6d2e39
commit
c1741a1048
4
init.lua
4
init.lua
|
@ -1,8 +1,6 @@
|
|||
local mod = modlib.mod
|
||||
local namespace = mod.create_namespace()
|
||||
local quaternion = setmetatable({}, {__index = namespace})
|
||||
mod.include_env(mod.get_resource"quaternion.lua", quaternion)
|
||||
namespace.quaternion = quaternion
|
||||
namespace.quaternion = modlib.quaternion
|
||||
namespace.conf = mod.configuration()
|
||||
namespace.insecure_environment = minetest.request_insecure_environment() or _G
|
||||
mod.extend"importer"
|
||||
|
|
10
main.lua
10
main.lua
|
@ -1,9 +1,5 @@
|
|||
modeldata = minetest.deserialize(modlib.file.read(modlib.mod.get_resource"modeldata.lua"))
|
||||
|
||||
function linear_interpolation(vector, other_vector, ratio)
|
||||
return modlib.vector.add(modlib.vector.multiply_scalar(vector, ratio), modlib.vector.multiply_scalar(other_vector, 1 - ratio))
|
||||
end
|
||||
|
||||
function get_animation_value(animation, keyframe_index, is_rotation)
|
||||
local values = animation.values
|
||||
assert(keyframe_index >= 1 and keyframe_index <= #values, keyframe_index)
|
||||
|
@ -17,7 +13,7 @@ function get_animation_value(animation, keyframe_index, is_rotation)
|
|||
if is_rotation then
|
||||
return quaternion.slerp(prev_value, next_value, ratio)
|
||||
end
|
||||
return modlib.vector.add(modlib.vector.multiply_scalar(prev_value, ratio), modlib.vector.multiply_scalar(next_value, 1 - ratio))
|
||||
return modlib.vector.interpolate(prev_value, next_value, ratio)
|
||||
end
|
||||
|
||||
function is_interacting(player)
|
||||
|
@ -117,9 +113,9 @@ local function handle_player_animations(dtime, player)
|
|||
rotation[4] = -rotation[4]
|
||||
local values = bone_positions[parent]
|
||||
local absolute_rotation = quaternion.multiply(values.rotation, rotation)
|
||||
euler_rotation = vector.subtract(quaternion.to_rotation(absolute_rotation), values.euler_rotation)
|
||||
euler_rotation = vector.subtract(quaternion.to_euler_rotation(absolute_rotation), values.euler_rotation)
|
||||
else
|
||||
euler_rotation = quaternion.to_rotation(rotation)
|
||||
euler_rotation = quaternion.to_euler_rotation(rotation)
|
||||
end
|
||||
bone_positions[bone] = {position = position, rotation = rotation, euler_rotation = euler_rotation}
|
||||
end
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
function multiply(q, w)
|
||||
return {
|
||||
w[1] * q[1] - w[2] * q[2] - w[3] * q[3] - w[4] * q[4],
|
||||
w[1] * q[2] + w[2] * q[1] - w[3] * q[4] + w[4] * q[3],
|
||||
w[1] * q[3] + w[2] * q[4] + w[3] * q[1] - w[4] * q[2],
|
||||
w[1] * q[4] - w[2] * q[3] + w[3] * q[2] + w[4] * q[1]
|
||||
}
|
||||
end
|
||||
|
||||
function normalize(q)
|
||||
local q_1, q_2, q_3, q_4 = q[1], q[2], q[3], q[4]
|
||||
local len = math.sqrt(q_1 * q_1 + q_2 * q_2 + q_3 * q_3 + (q_4 ^ 4))
|
||||
local r = {}
|
||||
for key, value in pairs(q) do
|
||||
r[key] = value / len
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
function negate(q)
|
||||
for k, v in pairs(q) do
|
||||
q[k] = -v
|
||||
end
|
||||
end
|
||||
|
||||
function dot(q, w)
|
||||
return q[1] * w[1] + q[2] * w[2] + q[3] * w[3] + q[4] * w[4]
|
||||
end
|
||||
|
||||
-- assuming q & w are normalized
|
||||
function slerp(q, w, r)
|
||||
local d = dot(q, w)
|
||||
if d < 0 then
|
||||
d = -d
|
||||
negate(w)
|
||||
end
|
||||
-- Threshold beyond which linear interpolation is used
|
||||
if d > 1 - 1e-10 then
|
||||
return linear_interpolation(q, w, r)
|
||||
end
|
||||
local theta_0 = math.acos(d)
|
||||
local theta = theta_0 * r
|
||||
local sin_theta = math.sin(theta)
|
||||
local sin_theta_0 = math.sin(theta_0)
|
||||
local s_1 = sin_theta / sin_theta_0
|
||||
local s_0 = math.cos(theta) - d * s_1
|
||||
return modlib.vector.add(modlib.vector.multiply_scalar(q, s_0), modlib.vector.multiply_scalar(w, s_1))
|
||||
end
|
||||
|
||||
function to_rotation(q)
|
||||
local rotation = {}
|
||||
|
||||
local sinr_cosp = 2 * (q[4] * q[1] + q[2] * q[3])
|
||||
local cosr_cosp = 1 - 2 * (q[1] * q[1] + q[2] * q[2])
|
||||
rotation.x = math.atan2(sinr_cosp, cosr_cosp)
|
||||
|
||||
local sinp = 2 * (q[4] * q[2] - q[3] * q[1])
|
||||
if sinp <= -1 then
|
||||
rotation.y = -math.pi/2
|
||||
elseif sinp >= 1 then
|
||||
rotation.y = math.pi/2
|
||||
else
|
||||
rotation.y = math.asin(sinp)
|
||||
end
|
||||
|
||||
local siny_cosp = 2 * (q[4] * q[3] + q[1] * q[2])
|
||||
local cosy_cosp = 1 - 2 * (q[2] * q[2] + q[3] * q[3])
|
||||
rotation.z = math.atan2(siny_cosp, cosy_cosp)
|
||||
|
||||
return vector.apply(rotation, math.deg)
|
||||
end
|
Loading…
Reference in New Issue