mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-26 17:23:45 +01:00
B3D: Add calculate_absolute_bone_properties
This commit is contained in:
parent
c00d014041
commit
b8a3e162cc
60
b3d.lua
60
b3d.lua
@ -260,7 +260,8 @@ function read(stream)
|
|||||||
node_type = "bone"
|
node_type = "bone"
|
||||||
node.bone = elem
|
node.bone = elem
|
||||||
elseif type == "KEYS" then
|
elseif type == "KEYS" then
|
||||||
table.insert(node.keys, elem)
|
assert((node.keys[#node.keys] or {}).frame ~= (elem[1] or {}).frame, "duplicate frame")
|
||||||
|
modlib.table.append(node.keys, elem)
|
||||||
elseif type == "NODE" then
|
elseif type == "NODE" then
|
||||||
table.insert(node.children, elem)
|
table.insert(node.children, elem)
|
||||||
elseif type == "ANIM" then
|
elseif type == "ANIM" then
|
||||||
@ -322,3 +323,60 @@ function read(stream)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- TODO function write(self, stream)
|
-- TODO function write(self, stream)
|
||||||
|
|
||||||
|
local binary_search_frame = modlib.table.binary_search_comparator(function(a, b)
|
||||||
|
return modlib.table.default_comparator(a, b.frame)
|
||||||
|
end)
|
||||||
|
function calculate_absolute_bone_properties(self, keyframe, interpolate)
|
||||||
|
local function get_frame_values(keys)
|
||||||
|
local values = keys[keyframe]
|
||||||
|
if values and values.frame == keyframe then
|
||||||
|
return {
|
||||||
|
position = values.position,
|
||||||
|
rotation = values.rotation,
|
||||||
|
scale = values.scale
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local index = binary_search_frame(keys, keyframe)
|
||||||
|
if index > 0 then
|
||||||
|
return keys[index]
|
||||||
|
end
|
||||||
|
index = -index
|
||||||
|
assert(index > 1 and index <= #keys)
|
||||||
|
local a, b = keys[index - 1], keys[index]
|
||||||
|
if not interpolate then
|
||||||
|
return a
|
||||||
|
end
|
||||||
|
local ratio = (keyframe - a.frame) / (b.frame - a.frame)
|
||||||
|
return {
|
||||||
|
position = (a.position and b.position and modlib.vector.interpolate(a.position, b.position, ratio)) or a.position or b.position,
|
||||||
|
rotation = (a.rotation and b.rotation and modlib.quaternion.interpolate(a.rotation, b.rotation, ratio)) or a.rotation or b.rotation,
|
||||||
|
scale = (a.scale and b.scale and modlib.vector.interpolate(a.scale, b.scale, ratio)) or a.scale or b.scale,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local absolute_bone_properties = {}
|
||||||
|
local function calculate_absolute_properties(self, parent_properties)
|
||||||
|
local properties = {
|
||||||
|
name = self.name,
|
||||||
|
position = self.position,
|
||||||
|
rotation = self.rotation,
|
||||||
|
scale = self.scale
|
||||||
|
}
|
||||||
|
if self.keys and next(self.keys) ~= nil then
|
||||||
|
properties = modlib.table.add_all(properties, get_frame_values(self.keys))
|
||||||
|
end
|
||||||
|
if parent_properties then
|
||||||
|
properties.position = modlib.vector.add(parent_properties.position, properties.position)
|
||||||
|
properties.rotation = modlib.quaternion.multiply(parent_properties.rotation, properties.rotation)
|
||||||
|
properties.scale = modlib.vector.multiply(parent_properties.scale, properties.scale)
|
||||||
|
end
|
||||||
|
if self.bone then
|
||||||
|
table.insert(absolute_bone_properties, properties)
|
||||||
|
end
|
||||||
|
for _, child in ipairs(self.children or {}) do
|
||||||
|
calculate_absolute_properties(child, properties)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
calculate_absolute_properties(self.node)
|
||||||
|
return absolute_bone_properties
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user