collada_scene/animate: implement bezier interpolation
This commit is contained in:
parent
ae351e1527
commit
e5148ac4b8
69
_math.lua
69
_math.lua
@ -552,6 +552,61 @@ mat4 = {
|
|||||||
|
|
||||||
setmetatable(mat4, mat4)
|
setmetatable(mat4, mat4)
|
||||||
|
|
||||||
|
vec2 = {
|
||||||
|
__call = function(_t, x, y, z)
|
||||||
|
-- newByteData is zero-initialized
|
||||||
|
local data = love.data.newByteData(2 * 4)
|
||||||
|
local f = ffi.cast('float*', data:getFFIPointer())
|
||||||
|
local value = {
|
||||||
|
data = data,
|
||||||
|
f = f,
|
||||||
|
}
|
||||||
|
f[0] = x
|
||||||
|
f[1] = y
|
||||||
|
setmetatable(value, vec2)
|
||||||
|
return value
|
||||||
|
end,
|
||||||
|
|
||||||
|
load_table = function(t)
|
||||||
|
assert(#t == 2)
|
||||||
|
assert(t[1] ~= nil)
|
||||||
|
assert(t[2] ~= nil)
|
||||||
|
return vec2(t[1], t[2])
|
||||||
|
end,
|
||||||
|
|
||||||
|
set_x = function(v, value)
|
||||||
|
return vec2(value, v.f[1])
|
||||||
|
end,
|
||||||
|
|
||||||
|
set_y = function(v, value)
|
||||||
|
return vec2(v.f[0], value)
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_x = function(v)
|
||||||
|
return v.f[0]
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_y = function(v)
|
||||||
|
return v.f[1]
|
||||||
|
end,
|
||||||
|
|
||||||
|
__mul = function(v, s)
|
||||||
|
return vec2(v.f[0] * s,
|
||||||
|
v.f[1] * s)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__add = function(v1, v2)
|
||||||
|
return vec2(v1.f[0] + v2.f[0],
|
||||||
|
v1.f[1] + v2.f[1])
|
||||||
|
end,
|
||||||
|
|
||||||
|
print = function(v)
|
||||||
|
print(tostring(v.f[0]) .. " " .. tostring(v.f[1]))
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(vec2, vec2)
|
||||||
|
|
||||||
vec3 = {
|
vec3 = {
|
||||||
__call = function(_t, x, y, z)
|
__call = function(_t, x, y, z)
|
||||||
-- newByteData is zero-initialized
|
-- newByteData is zero-initialized
|
||||||
@ -561,9 +616,9 @@ vec3 = {
|
|||||||
data = data,
|
data = data,
|
||||||
f = f,
|
f = f,
|
||||||
}
|
}
|
||||||
f[0] = x or 0
|
f[0] = x
|
||||||
f[1] = y or 0
|
f[1] = y
|
||||||
f[2] = z or 0
|
f[2] = z
|
||||||
setmetatable(value, vec3)
|
setmetatable(value, vec3)
|
||||||
return value
|
return value
|
||||||
end,
|
end,
|
||||||
@ -732,10 +787,10 @@ vec4 = {
|
|||||||
data = data,
|
data = data,
|
||||||
f = f,
|
f = f,
|
||||||
}
|
}
|
||||||
f[0] = x or 0
|
f[0] = x
|
||||||
f[1] = y or 0
|
f[1] = y
|
||||||
f[2] = z or 0
|
f[2] = z
|
||||||
f[3] = w or 0
|
f[3] = w
|
||||||
setmetatable(value, vec4)
|
setmetatable(value, vec4)
|
||||||
return value
|
return value
|
||||||
end,
|
end,
|
||||||
|
|||||||
@ -35,6 +35,82 @@ local linear_interpolate_value = function(source, frame_ix, parameter_ix, iv)
|
|||||||
return prev + iv * (next - prev)
|
return prev + iv * (next - prev)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local pow3 = function(f)
|
||||||
|
return f * f * f
|
||||||
|
end
|
||||||
|
|
||||||
|
local pow2 = function(f)
|
||||||
|
return f * f
|
||||||
|
end
|
||||||
|
|
||||||
|
local bezier = function(p0, c0, c1, p1, s)
|
||||||
|
return
|
||||||
|
(p0 * pow3(1 - s))
|
||||||
|
+ (c0 * 3 * s * pow2(1 - s))
|
||||||
|
+ (c1 * 3 * pow2(s) * (1 - s))
|
||||||
|
+ (p1 * pow3(s))
|
||||||
|
end
|
||||||
|
|
||||||
|
local bezier_binary_search = function(p0, c0, c1, p1, want)
|
||||||
|
local low = 0.0
|
||||||
|
local high = 1.0
|
||||||
|
|
||||||
|
local iterations = 0
|
||||||
|
while iterations < 20 do
|
||||||
|
iterations = iterations + 1
|
||||||
|
|
||||||
|
local s = (high + low) * 0.5
|
||||||
|
local bs = bezier(p0, c0, c1, p1, s)
|
||||||
|
local t = vec2.get_x(bs)
|
||||||
|
|
||||||
|
local epsilon = 0.001
|
||||||
|
if (math.abs(t - want) < epsilon) then
|
||||||
|
return vec2.get_y(bs)
|
||||||
|
end
|
||||||
|
|
||||||
|
if t > want then
|
||||||
|
high = s
|
||||||
|
else
|
||||||
|
low = s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print(vec2.get_x(p0), vec2.get_y(p0))
|
||||||
|
print(vec2.get_x(c0), vec2.get_y(c0))
|
||||||
|
print(vec2.get_x(c1), vec2.get_y(c1))
|
||||||
|
print(vec2.get_x(p1), vec2.get_y(p1))
|
||||||
|
assert(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
local tangent_index = function(source, frame_ix, parameter_ix)
|
||||||
|
local ix = frame_ix * source.stride + parameter_ix * 2
|
||||||
|
x = source.float_array[ix + 0 + 1]
|
||||||
|
y = source.float_array[ix + 1 + 1]
|
||||||
|
return {x, y}
|
||||||
|
end
|
||||||
|
|
||||||
|
local bezier_sampler = function(sampler, frame_ix, parameter_ix, t)
|
||||||
|
-- P0 is (INPUT[i] , OUTPUT[i])
|
||||||
|
-- C0 (or T0) is (OUT_TANGENT[i][0] , OUT_TANGENT[i][1])
|
||||||
|
-- C1 (or T1) is (IN_TANGENT[i+1][0], IN_TANGENT[i+1][1])
|
||||||
|
-- P1 is (INPUT[i+1], OUTPUT[i+1])
|
||||||
|
|
||||||
|
local frame0_input = sampler.input.float_array[frame_ix + 0 + 1]
|
||||||
|
local frame1_input = sampler.input.float_array[frame_ix + 1 + 1]
|
||||||
|
|
||||||
|
local frame0_output = sampler.output.float_array[(frame_ix + 0) * sampler.output.stride + parameter_ix + 1]
|
||||||
|
local frame1_output = sampler.output.float_array[(frame_ix + 1) * sampler.output.stride + parameter_ix + 1]
|
||||||
|
|
||||||
|
local p0 = vec2(frame0_input, frame0_output)
|
||||||
|
local c0 = vec2.load_table(tangent_index(sampler.out_tangent, frame_ix + 0, parameter_ix))
|
||||||
|
local c1 = vec2.load_table(tangent_index(sampler.in_tangent, frame_ix + 1, parameter_ix))
|
||||||
|
local p1 = vec2(frame1_input, frame1_output)
|
||||||
|
|
||||||
|
return bezier_binary_search(p0, c0, c1, p1, t)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local apply_transform_target = function(transform, channel_target_attribute, value)
|
local apply_transform_target = function(transform, channel_target_attribute, value)
|
||||||
if transform.type == collada_types.transform_type.TRANSLATE or transform.type == collada_types.transform_type.SCALE then
|
if transform.type == collada_types.transform_type.TRANSLATE or transform.type == collada_types.transform_type.SCALE then
|
||||||
if channel_target_attribute == collada_types.target_attribute.X then
|
if channel_target_attribute == collada_types.target_attribute.X then
|
||||||
@ -81,7 +157,8 @@ local animate_channel_segment = function(channel, transform, frame_ix, t)
|
|||||||
for parameter_ix = 0, target_attributes_count-1 do
|
for parameter_ix = 0, target_attributes_count-1 do
|
||||||
local interpolation = channel.source_sampler.interpolation.interpolation_array[frame_ix]
|
local interpolation = channel.source_sampler.interpolation.interpolation_array[frame_ix]
|
||||||
local value
|
local value
|
||||||
if false then
|
if interpolation == collada_types.interpolation.BEZIER then
|
||||||
|
value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t)
|
||||||
else
|
else
|
||||||
local iv = linear_interpolate_iv(channel.source_sampler.input, frame_ix, t)
|
local iv = linear_interpolate_iv(channel.source_sampler.input, frame_ix, t)
|
||||||
value = linear_interpolate_value(channel.source_sampler.output, frame_ix, parameter_ix, iv)
|
value = linear_interpolate_value(channel.source_sampler.output, frame_ix, parameter_ix, iv)
|
||||||
|
|||||||
@ -30,18 +30,18 @@ local array_node_torus_knot23_translation_x_output_array = {
|
|||||||
-21.94384,
|
-21.94384,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_x_intangent_array = {
|
local array_node_torus_knot23_translation_x_intangent_array = {
|
||||||
{-0.3329306, -21.94384},
|
-0.3329306, -21.94384,
|
||||||
{0.667, 7.158293},
|
0.667, 7.158293,
|
||||||
{1.667, 40.64392},
|
1.667, 40.64392,
|
||||||
{2.667, 15.03987},
|
2.667, 15.03987,
|
||||||
{3.222333, -21.94384},
|
3.222333, -21.94384,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_x_outtangent_array = {
|
local array_node_torus_knot23_translation_x_outtangent_array = {
|
||||||
{0.333, -21.94384},
|
0.333, -21.94384,
|
||||||
{1.333, 28.00002},
|
1.333, 28.00002,
|
||||||
{2.333, 40.64392},
|
2.333, 40.64392,
|
||||||
{3.111, -5.801854},
|
3.111, -5.801854,
|
||||||
{3.666264, -21.94384},
|
3.666264, -21.94384,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_x_interpolation_array = {
|
local array_node_torus_knot23_translation_x_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -97,18 +97,18 @@ local array_node_torus_knot23_translation_y_output_array = {
|
|||||||
-1.68812e-14,
|
-1.68812e-14,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_y_intangent_array = {
|
local array_node_torus_knot23_translation_y_intangent_array = {
|
||||||
{-0.3329306, -1.68812e-14},
|
-0.3329306, -1.68812e-14,
|
||||||
{0.667, 24.27013},
|
0.667, 24.27013,
|
||||||
{1.667, -12.4935},
|
1.667, -12.4935,
|
||||||
{2.667, 9.835234},
|
2.667, 9.835234,
|
||||||
{3.222333, -1.68812e-14},
|
3.222333, -1.68812e-14,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_y_outtangent_array = {
|
local array_node_torus_knot23_translation_y_outtangent_array = {
|
||||||
{0.333, -1.68812e-14},
|
0.333, -1.68812e-14,
|
||||||
{1.333, 24.27013},
|
1.333, 24.27013,
|
||||||
{2.333, -12.4935},
|
2.333, -12.4935,
|
||||||
{3.111, 9.835234},
|
3.111, 9.835234,
|
||||||
{3.666264, -1.68812e-14},
|
3.666264, -1.68812e-14,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_y_interpolation_array = {
|
local array_node_torus_knot23_translation_y_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -164,18 +164,18 @@ local array_node_torus_knot23_translation_z_output_array = {
|
|||||||
45.45129,
|
45.45129,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_z_intangent_array = {
|
local array_node_torus_knot23_translation_z_intangent_array = {
|
||||||
{-0.3329306, 45.45129},
|
-0.3329306, 45.45129,
|
||||||
{0.667, 45.45129},
|
0.667, 45.45129,
|
||||||
{1.667, 45.45129},
|
1.667, 45.45129,
|
||||||
{2.667, 45.45129},
|
2.667, 45.45129,
|
||||||
{3.222333, 45.45129},
|
3.222333, 45.45129,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_z_outtangent_array = {
|
local array_node_torus_knot23_translation_z_outtangent_array = {
|
||||||
{0.333, 45.45129},
|
0.333, 45.45129,
|
||||||
{1.333, 45.45129},
|
1.333, 45.45129,
|
||||||
{2.333, 45.45129},
|
2.333, 45.45129,
|
||||||
{3.111, 45.45129},
|
3.111, 45.45129,
|
||||||
{3.666264, 45.45129},
|
3.666264, 45.45129,
|
||||||
}
|
}
|
||||||
local array_node_torus_knot23_translation_z_interpolation_array = {
|
local array_node_torus_knot23_translation_z_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -235,22 +235,22 @@ local array_node_torusknot25_rotationz_angle_output_array = {
|
|||||||
-2.386905,
|
-2.386905,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationz_angle_intangent_array = {
|
local array_node_torusknot25_rotationz_angle_intangent_array = {
|
||||||
{-0.3329306, -2.386905},
|
-0.3329306, -2.386905,
|
||||||
{0.3335, -38.2941},
|
0.3335, -38.2941,
|
||||||
{0.8335, -59.67817},
|
0.8335, -59.67817,
|
||||||
{1.3335, -40.14935},
|
1.3335, -40.14935,
|
||||||
{1.8335, -99.69791},
|
1.8335, -99.69791,
|
||||||
{2.3335, -163.7238},
|
2.3335, -163.7238,
|
||||||
{3.055833, -2.386905},
|
3.055833, -2.386905,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationz_angle_outtangent_array = {
|
local array_node_torusknot25_rotationz_angle_outtangent_array = {
|
||||||
{0.1665, -2.386905},
|
0.1665, -2.386905,
|
||||||
{0.6665, -57.37209},
|
0.6665, -57.37209,
|
||||||
{1.1665, -59.67817},
|
1.1665, -59.67817,
|
||||||
{1.6665, -40.14935},
|
1.6665, -40.14935,
|
||||||
{2.1665, -140.8482},
|
2.1665, -140.8482,
|
||||||
{2.7775, -163.7238},
|
2.7775, -163.7238,
|
||||||
{3.666264, -2.386905},
|
3.666264, -2.386905,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationz_angle_interpolation_array = {
|
local array_node_torusknot25_rotationz_angle_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -312,22 +312,22 @@ local array_node_torusknot25_rotationy_angle_output_array = {
|
|||||||
-49.62293,
|
-49.62293,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationy_angle_intangent_array = {
|
local array_node_torusknot25_rotationy_angle_intangent_array = {
|
||||||
{-0.3329306, -49.62293},
|
-0.3329306, -49.62293,
|
||||||
{0.3335, -29.32237},
|
0.3335, -29.32237,
|
||||||
{0.8335, 34.11597},
|
0.8335, 34.11597,
|
||||||
{1.3335, -56.85069},
|
1.3335, -56.85069,
|
||||||
{1.8335, -56.85069},
|
1.8335, -56.85069,
|
||||||
{2.3335, -170.1778},
|
2.3335, -170.1778,
|
||||||
{3.055833, -49.62293},
|
3.055833, -49.62293,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationy_angle_outtangent_array = {
|
local array_node_torusknot25_rotationy_angle_outtangent_array = {
|
||||||
{0.1665, -49.62293},
|
0.1665, -49.62293,
|
||||||
{0.6665, -1.437308},
|
0.6665, -1.437308,
|
||||||
{1.1665, 34.11597},
|
1.1665, 34.11597,
|
||||||
{1.6665, -56.85069},
|
1.6665, -56.85069,
|
||||||
{2.1665, -56.85069},
|
2.1665, -56.85069,
|
||||||
{2.7775, -170.1778},
|
2.7775, -170.1778,
|
||||||
{3.666264, -49.62293},
|
3.666264, -49.62293,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationy_angle_interpolation_array = {
|
local array_node_torusknot25_rotationy_angle_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -389,22 +389,22 @@ local array_node_torusknot25_rotationx_angle_output_array = {
|
|||||||
183.132,
|
183.132,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationx_angle_intangent_array = {
|
local array_node_torusknot25_rotationx_angle_intangent_array = {
|
||||||
{-0.3329306, 183.132},
|
-0.3329306, 183.132,
|
||||||
{0.3335, 256.4932},
|
0.3335, 256.4932,
|
||||||
{0.8335, 216.862},
|
0.8335, 216.862,
|
||||||
{1.3335, 133.4248},
|
1.3335, 133.4248,
|
||||||
{1.8335, 133.4248},
|
1.8335, 133.4248,
|
||||||
{2.3335, 146.1407},
|
2.3335, 146.1407,
|
||||||
{3.055833, 183.132},
|
3.055833, 183.132,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationx_angle_outtangent_array = {
|
local array_node_torusknot25_rotationx_angle_outtangent_array = {
|
||||||
{0.1665, 183.132},
|
0.1665, 183.132,
|
||||||
{0.6665, 256.4932},
|
0.6665, 256.4932,
|
||||||
{1.1665, 175.8802},
|
1.1665, 175.8802,
|
||||||
{1.6665, 133.4248},
|
1.6665, 133.4248,
|
||||||
{2.1665, 133.4248},
|
2.1665, 133.4248,
|
||||||
{2.7775, 162.6932},
|
2.7775, 162.6932,
|
||||||
{3.666264, 183.132},
|
3.666264, 183.132,
|
||||||
}
|
}
|
||||||
local array_node_torusknot25_rotationx_angle_interpolation_array = {
|
local array_node_torusknot25_rotationx_angle_interpolation_array = {
|
||||||
collada_types.interpolation.BEZIER,
|
collada_types.interpolation.BEZIER,
|
||||||
@ -825,9 +825,9 @@ local instance_controllers_node_torus_knot23 = {
|
|||||||
local instance_lights_node_torus_knot23 = {
|
local instance_lights_node_torus_knot23 = {
|
||||||
}
|
}
|
||||||
local node_channels_node_torus_knot23 = {
|
local node_channels_node_torus_knot23 = {
|
||||||
node_channel_node_torus_knot23_translation_y,
|
|
||||||
node_channel_node_torus_knot23_translation_x,
|
|
||||||
node_channel_node_torus_knot23_translation_z,
|
node_channel_node_torus_knot23_translation_z,
|
||||||
|
node_channel_node_torus_knot23_translation_x,
|
||||||
|
node_channel_node_torus_knot23_translation_y,
|
||||||
}
|
}
|
||||||
local node_node_torus_knot23 = {
|
local node_node_torus_knot23 = {
|
||||||
parent_index = -1,
|
parent_index = -1,
|
||||||
@ -903,9 +903,9 @@ local instance_controllers_node_torusknot25 = {
|
|||||||
local instance_lights_node_torusknot25 = {
|
local instance_lights_node_torusknot25 = {
|
||||||
}
|
}
|
||||||
local node_channels_node_torusknot25 = {
|
local node_channels_node_torusknot25 = {
|
||||||
|
node_channel_node_torusknot25_rotationy_angle,
|
||||||
node_channel_node_torusknot25_rotationz_angle,
|
node_channel_node_torusknot25_rotationz_angle,
|
||||||
node_channel_node_torusknot25_rotationx_angle,
|
node_channel_node_torusknot25_rotationx_angle,
|
||||||
node_channel_node_torusknot25_rotationy_angle,
|
|
||||||
}
|
}
|
||||||
local node_node_torusknot25 = {
|
local node_node_torusknot25 = {
|
||||||
parent_index = -1,
|
parent_index = -1,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user