guns4d-cd2025/classes/Model_reader.lua
2023-08-29 12:40:36 -07:00

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