Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Gets default bone positions from glTF files (for Minetest)
-- helper function
local function quaternion_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)
end
-- call with glTF path & set of bones {bonename = true}
function bone_data(path, bones)
local file = io.open(path, "r")
local nodes = minetest.parse_json(file:read("*a")).nodes
file:close()
for _, node in ipairs(nodes) do
if bones[node.name] then
bones[node.name] = {
position = vector.new(unpack(node.translation)),
rotation = (node.rotation and quaternion_to_rotation(node.rotation)) or {x=0,y=0,z=0}
}
end
end
end
-- example call:
-- bone_data(minetest.get_modpath("this_mod").."/models/model.gltf", {Head = true})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment