118 lines
4.0 KiB
Lua
118 lines
4.0 KiB
Lua
local path_seperator = "/@/"
|
|
|
|
Guns4d.Model_bone_handler = Instantiatable_class:inherit({
|
|
construct = function(def)
|
|
if def.instance then
|
|
assert(def.modelpath, "no path provided")
|
|
if mtul.media_paths[def.modelpath] then def.modelpath = mtul.media_paths[def.modelpath] end
|
|
local stream = io.open(def.modelpath, "rb")
|
|
def.b3d_table = mtul.b3d.read(stream)
|
|
stream:close()
|
|
stream = minetest.request_insecure_environment().io.open(minetest.get_modpath("guns4d").."/test.gltf", "wb")
|
|
modlib.b3d.write_gltf(def.b3d_table, stream)
|
|
stream:close()
|
|
|
|
def.paths = {}
|
|
def:process_and_reformat()
|
|
end
|
|
end
|
|
})
|
|
local model_bones = Guns4d.Model_bone_handler
|
|
--this creates a list of bone paths, and changes the index from an int to names.
|
|
local function retrieve_hierarchy(node, out)
|
|
if not out then out = {node} end
|
|
if node.parent then
|
|
table.insert(out, 1, node.parent)
|
|
retrieve_hierarchy(node.parent, out)
|
|
end
|
|
return out
|
|
end
|
|
function model_bones:solve_global_transform(node)
|
|
assert(self.instance, "attempt to call object method on a class")
|
|
local global_transform
|
|
local hierarcy = retrieve_hierarchy(node)
|
|
print("start")
|
|
for i, v in pairs(hierarcy) do
|
|
print(i, v.name)
|
|
end
|
|
print("end")
|
|
for i, v in pairs(hierarcy) do
|
|
local pos_vec = v.position
|
|
local rot_vec = v.rotation
|
|
local scl_vec = v.scale
|
|
if v.keys[2] then
|
|
pos_vec = v.keys[2].position
|
|
rot_vec = v.keys[2].rotation
|
|
scl_vec = v.keys[2].scale
|
|
end
|
|
--rot_vec = {rot_vec[2], rot_vec[3], rot_vec[4], rot_vec[1]}
|
|
pos_vec = {-pos_vec[1], pos_vec[2], pos_vec[3]}
|
|
local pos = modlib.matrix4.translation(pos_vec)
|
|
rot_vec = {-rot_vec[1], rot_vec[2], rot_vec[3], rot_vec[4]}
|
|
local rot = modlib.matrix4.rotation(modlib.quaternion.normalize(rot_vec))
|
|
local scl = modlib.matrix4.scale(scl_vec)
|
|
local local_transform = scl:compose(rot):compose(pos)
|
|
|
|
if global_transform then
|
|
global_transform=global_transform:multiply(local_transform)
|
|
else
|
|
global_transform=local_transform
|
|
end
|
|
end
|
|
local pos
|
|
if node.keys[2] then
|
|
pos = node.position
|
|
else
|
|
pos = node.keys[2].position
|
|
end
|
|
--pos = global_transform:apply({pos[1], pos[2], pos[3], 1})
|
|
--print(dump(global_transform))
|
|
--return vector.new(pos[1], pos[2], pos[3])
|
|
return vector.new(global_transform[1][4], global_transform[2][4], global_transform[3][4])
|
|
end
|
|
function model_bones:get_bone_global(bone_name)
|
|
assert(self.instance, "attempt to call object method on a class")
|
|
for i, v in pairs(self.paths) do
|
|
local s, e = string.find(i, bone_name, #i-#bone_name)
|
|
--this needs to be fixed.
|
|
if s then
|
|
local v1, v2 = self:solve_global_transform(v)
|
|
return v1, v2
|
|
end
|
|
end
|
|
end
|
|
function model_bones:process_and_reformat(node, path)
|
|
assert(self.instance, "attempt to call object method on a class")
|
|
local first = false
|
|
if not node then
|
|
first = true
|
|
node = self.b3d_table.node
|
|
end
|
|
path = path or ""
|
|
node.mesh = nil --we wont be needing this
|
|
for i, v in pairs(node.children) do
|
|
if type(i) == "number" then
|
|
local newpath
|
|
if path ~= "" then
|
|
newpath = path.." @ "..v.name
|
|
else
|
|
newpath = v.name
|
|
end
|
|
self.paths[newpath] = v
|
|
v.mesh = nil
|
|
v.parent = node
|
|
node.children[v.name] = v
|
|
node.children[i] = nil
|
|
self:process_and_reformat(v, newpath)
|
|
end
|
|
end
|
|
if first then
|
|
for i, v in pairs(self.paths) do
|
|
print(i)
|
|
print(table.tostring(v.rotation))
|
|
print(table.tostring(v.position))
|
|
print(table.tostring(v.scale))
|
|
end
|
|
end
|
|
end
|