diff --git a/_math.lua b/_math.lua
index 44b646a..214b659 100644
--- a/_math.lua
+++ b/_math.lua
@@ -32,7 +32,7 @@ mat4 = {
-- newByteData is zero-initialized
local data = love.data.newByteData(16 * 4)
local m = ffi.cast('float*', data:getFFIPointer())
- value = {
+ local value = {
data = data,
m = m,
}
@@ -557,7 +557,7 @@ vec3 = {
-- newByteData is zero-initialized
local data = love.data.newByteData(3 * 4)
local f = ffi.cast('float*', data:getFFIPointer())
- value = {
+ local value = {
data = data,
f = f,
}
@@ -576,6 +576,18 @@ vec3 = {
return vec3(t[1], t[2], t[3])
end,
+ set_x = function(v, value)
+ return vec3(value, v.f[1], v.f[2])
+ end,
+
+ set_y = function(v, value)
+ return vec3(v.f[0], value, v.f[2])
+ end,
+
+ set_z = function(v, value)
+ return vec3(v.f[0], v.f[1], value)
+ end,
+
replicate = function(value)
return vec3(value, value, value)
end,
@@ -716,7 +728,7 @@ vec4 = {
-- newByteData is zero-initialized
local data = love.data.newByteData(4 * 4)
local f = ffi.cast('float*', data:getFFIPointer())
- value = {
+ local value = {
data = data,
f = f,
}
@@ -737,6 +749,22 @@ vec4 = {
return vec4(t[1], t[2], t[3], t[4])
end,
+ set_x = function(v, value)
+ return vec4(value, v.f[1], v.f[2], v.f[3])
+ end,
+
+ set_y = function(v, value)
+ return vec4(v.f[0], value, v.f[2], v.f[3])
+ end,
+
+ set_z = function(v, value)
+ return vec4(v.f[0], v.f[1], value, v.f[3])
+ end,
+
+ set_w = function(v, value)
+ return vec4(v.f[0], v.f[1], v.f[2], value)
+ end,
+
print = function(v)
print(tostring(v.f[0]) .. " " .. tostring(v.f[1]) .. " " .. tostring(v.f[2]) .. " " .. tostring(v.f[3]))
end,
diff --git a/collada_scene.lua b/collada_scene.lua
index ff27813..e6ccca9 100644
--- a/collada_scene.lua
+++ b/collada_scene.lua
@@ -53,104 +53,6 @@ collada_scene = {
end
end,
- load_transform = function(transform)
- if transform.type == collada_types.transform_type.LOOKAT then
- assert(false)
- elseif transform.type == collada_types.transform_type.MATRIX then
- return mat4.load_table(transform.matrix)
- elseif transform.type == collada_types.transform_type.ROTATE then
- return vec4.load_table(transform.rotate)
- elseif transform.type == collada_types.transform_type.SCALE then
- return vec3.load_table(transform.scale)
- elseif transform.type == collada_types.transform_type.TRANSLATE then
- return vec3.load_table(transform.translate)
- else
- assert(false)
- end
- end,
-
- transform_matrix = function (loaded_transform)
- local type = loaded_transform.type
- local value = loaded_transform.value
- if type == collada_types.transform_type.LOOKAT then
- assert(false)
- elseif type == collada_types.transform_type.MATRIX then
- return value
- elseif type == collada_types.transform_type.ROTATE then
- return mat4.rotation_axis(value, scalar.convert_to_radians(value.f[3]))
- elseif type == collada_types.transform_type.SCALE then
- return mat4.scaling_from_vector(value)
- elseif type == collada_types.transform_type.TRANSLATE then
- return mat4.translation_from_vector(value)
- else
- assert(false)
- end
- end,
-
- --
- -- node instance
- --
- -- {
- -- transforms = ..,
- -- transforms_count = ..,
- -- world = ..,
- -- }
-
- node_instance_initialize_transforms = function(node)
- local transforms = {}
-
- local transform_index = 0
- for _, transform in ipairs(node.transforms) do
- local value = collada_scene.load_transform(transform)
- local loaded_transform = {
- type = transform.type,
- value = value,
- }
- transforms[transform_index] = loaded_transform
- transform_index = transform_index + 1
- end
-
- return transforms, transform_index
- end,
-
- node_instance_world = function(node, transforms, transforms_count)
- local world
- if node.parent_index >= 0 then
- world = node_instances[node.parent_index].world
- assert(world ~= nil)
- else
- world = mat4.identity()
- end
-
- local transform_index = 0
- while transform_index < transforms_count do
- local m = collada_scene.transform_matrix(transforms[transform_index])
- world = m * world
- transform_index = transform_index + 1
- end
- return world
- end,
-
- node_instance_initialize = function(node)
- local transforms, transforms_count = collada_scene.node_instance_initialize_transforms(node)
- local world = collada_scene.node_instance_world(node, transforms, transforms_count)
- local node_instance = {
- transforms = transforms,
- transforms_count = transforms_count,
- world = world,
- }
- return node_instance
- end,
-
- load_node_instances = function(nodes)
- local node_index = 0
- for _, node in ipairs(nodes) do
- local node_instance = collada_scene.node_instance_initialize(node)
- node_instances[node_index] = node_instance
- node_index = node_index + 1
- end
- end,
-
set_color_or_texture = function(color_or_texture, color_uniform, sampler_uniform)
if color_or_texture.type == collada_types.color_or_texture_type.COLOR then
shader:send(color_uniform, color_or_texture.color)
@@ -211,7 +113,7 @@ collada_scene = {
end
end,
- draw_node = function(node_index, node, transform)
+ draw_node = function(node, node_instance, transform)
if node.type ~= collada_types.node_type.NODE then
return
end
@@ -220,7 +122,7 @@ collada_scene = {
return
end
- local world = node_instances[node_index].world
+ local world = node_instance.world
transform = world * transform
shader:send("world_transform", "column", world.data)
shader:send("transform", "column", transform.data)
@@ -230,14 +132,15 @@ collada_scene = {
end
end,
- draw_nodes = function(nodes, transform)
+ draw_nodes = function(node_state, transform)
love.graphics.setShader(shader)
shader:send("view_position", {-88.57101, -71.71298, 104.5738, 1.0})
shader:send("light_position", {0.0, -56.804, 58.237, 1.0})
local node_index = 0
- for _, node in ipairs(nodes) do
- collada_scene.draw_node(node_index, node, transform)
+ for _, node in ipairs(node_state.nodes) do
+ local node_instance = node_state.node_instances[node_index]
+ collada_scene.draw_node(node, node_instance, transform)
node_index = node_index + 1
end
end,
@@ -248,4 +151,5 @@ return {
load_buffers = collada_scene.load_buffers,
load_node_instances = collada_scene.load_node_instances,
load_images = collada_scene.load_images,
+ update = collada_scene.update,
}
diff --git a/collada_scene/animate.lua b/collada_scene/animate.lua
new file mode 100644
index 0000000..06d1834
--- /dev/null
+++ b/collada_scene/animate.lua
@@ -0,0 +1,123 @@
+local _math = require '_math'
+local mat4 = _math.mat4
+local vec3 = _math.vec3
+local vec4 = _math.vec4
+local scalar = _math.scalar
+
+local collada_types = require 'collada_types'
+
+local fract = function(f)
+ return f - math.floor(f)
+end
+
+local loop = function(f, n)
+ return fract(f / n) * n
+end
+
+local find_frame_ix = function(source, t)
+ for i = 1, source.count - 1 do
+ if source.float_array[i] <= t and source.float_array[i+1] > t then
+ return i - 1 -- 0-based index
+ end
+ end
+ return -1
+end
+
+local linear_interpolate_iv = function(source, frame_ix, t)
+ local prev = source.float_array[(frame_ix + 0) * source.stride + 1]
+ local next = source.float_array[(frame_ix + 1) * source.stride + 1]
+ return (t - prev) / (next - prev)
+end
+
+local linear_interpolate_value = function(source, frame_ix, parameter_ix, iv)
+ local prev = source.float_array[(frame_ix + 0) * source.stride + parameter_ix + 1]
+ local next = source.float_array[(frame_ix + 1) * source.stride + parameter_ix + 1]
+ return prev + iv * (next - prev)
+end
+
+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 channel_target_attribute == collada_types.target_attribute.X then
+ transform.value = vec3.set_x(transform.value, value)
+ elseif channel_target_attribute == collada_types.target_attribute.Y then
+ transform.value = vec3.set_y(transform.value, value)
+ elseif channel_target_attribute == collada_types.target_attribute.Z then
+ transform.value = vec3.set_z(transform.value, value)
+ else
+ assert(false)
+ end
+ elseif transform.type == collada_types.transform_type.ROTATE then
+ if channel_target_attribute == collada_types.target_attribute.X then
+ transform.value = vec4.set_x(transform.value, value)
+ elseif channel_target_attribute == collada_types.target_attribute.Y then
+ transform.value = vec4.set_y(transform.value, value)
+ elseif channel_target_attribute == collada_types.target_attribute.Z then
+ transform.value = vec4.set_z(transform.value, value)
+ elseif channel_target_attribute == collada_types.target_attribute.ANGLE then
+ transform.value = vec4.set_w(transform.value, value)
+ else
+ assert(false)
+ end
+ else
+ assert(false)
+ end
+end
+
+local animate_channel_segment = function(channel, transform, frame_ix, t)
+ local target_attributes = {channel.target_attribute}
+ if channel.target_attribute == collada_types.target_attribute.ALL then
+ if transform.type == collada_types.transform_type.TRANSLATE or transform.type == collada_types.transform_type.SCALE then
+ target_attributes = translate_scale_target_attributes
+ elseif transform.type == collada_types.transform_type.ROTATE then
+ target_attributes = rotate_target_attributes
+ else
+ assert(false)
+ end
+ end
+
+ target_attributes_count = #target_attributes
+
+ -- parameter_ix: 0-based index
+ for parameter_ix = 0, target_attributes_count-1 do
+ local interpolation = channel.source_sampler.interpolation.interpolation_array[frame_ix]
+ local value
+ if false then
+ else
+ 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)
+ end
+
+ apply_transform_target(transform, target_attributes[parameter_ix + 1], value)
+ end
+end
+
+local animate_node = function(node, node_instance, t)
+ for _, channel in ipairs(node.channels) do
+ local transform = node_instance.transforms[channel.target_transform_index]
+ assert(transform ~= nil)
+ -- frame_ix: 0-based index
+ local frame_ix = find_frame_ix(channel.source_sampler.input, t)
+ assert(frame_ix >= 0)
+ animate_channel_segment(channel, transform, frame_ix, t)
+ end
+end
+
+local update = function(_t, node_state)
+ local t = loop(_t / 2.0, 3.333333)
+
+ local node_index = 0
+ for _, node in ipairs(node_state.nodes) do
+ node_instance = node_state.node_instances[node_index]
+
+ animate_node(node, node_instance, t)
+
+ local world = node_state:node_instance_world(node, node_instance.transforms)
+ node_instance.world = world
+
+ node_index = node_index + 1
+ end
+end
+
+return {
+ update = update,
+}
diff --git a/collada_scene/node_state.lua b/collada_scene/node_state.lua
new file mode 100644
index 0000000..a951386
--- /dev/null
+++ b/collada_scene/node_state.lua
@@ -0,0 +1,116 @@
+local _math = require '_math'
+local mat4 = _math.mat4
+local vec3 = _math.vec3
+local vec4 = _math.vec4
+local scalar = _math.scalar
+
+local collada_types = require 'collada_types'
+
+local load_transform = function(transform)
+ if transform.type == collada_types.transform_type.LOOKAT then
+ assert(false)
+ elseif transform.type == collada_types.transform_type.MATRIX then
+ return mat4.load_table(transform.matrix)
+ elseif transform.type == collada_types.transform_type.ROTATE then
+ return vec4.load_table(transform.rotate)
+ elseif transform.type == collada_types.transform_type.SCALE then
+ return vec3.load_table(transform.scale)
+ elseif transform.type == collada_types.transform_type.TRANSLATE then
+ return vec3.load_table(transform.translate)
+ else
+ assert(false)
+ end
+end
+
+local transform_matrix = function (loaded_transform)
+ local type = loaded_transform.type
+ local value = loaded_transform.value
+ if type == collada_types.transform_type.LOOKAT then
+ assert(false)
+ elseif type == collada_types.transform_type.MATRIX then
+ return value
+ elseif type == collada_types.transform_type.ROTATE then
+ return mat4.rotation_axis(value, scalar.convert_to_radians(value.f[3]))
+ elseif type == collada_types.transform_type.SCALE then
+ return mat4.scaling_from_vector(value)
+ elseif type == collada_types.transform_type.TRANSLATE then
+ return mat4.translation_from_vector(value)
+ else
+ assert(false)
+ end
+end
+
+local instance_transforms_from_node = function(node)
+ local transforms = {}
+
+ local transform_index = 0
+ for _, transform in ipairs(node.transforms) do
+ local value = load_transform(transform)
+ local loaded_transform = {
+ type = transform.type,
+ value = value,
+ }
+ transforms[transform_index] = loaded_transform
+ transform_index = transform_index + 1
+ end
+
+ return transforms
+end
+
+local collada_scene_node_state
+
+collada_scene_node_state = {
+ __index = {
+ node_instance_world = function(this, node, transforms)
+ local world
+ if node.parent_index >= 0 then
+ world = this.node_instances[node.parent_index].world
+ assert(world ~= nil)
+ else
+ world = mat4.identity()
+ end
+
+ local transforms_count = #node.transforms
+ local transform_index = 0
+ while transform_index < transforms_count do
+ local m = transform_matrix(transforms[transform_index])
+ world = m * world
+ transform_index = transform_index + 1
+ end
+ return world
+ end,
+
+ node_instance_new = function(this, node)
+ local transforms = instance_transforms_from_node(node)
+ local world = this:node_instance_world(node, transforms)
+ local node_instance = {
+ transforms = transforms,
+ transforms_count = transforms_count,
+ world = world,
+ }
+ return node_instance
+ end,
+
+ node_instances_new = function(this, nodes)
+ local node_index = 0
+ for _, node in ipairs(nodes) do
+ local node_instance = this:node_instance_new(node)
+ this.node_instances[node_index] = node_instance
+ node_index = node_index + 1
+ end
+ end,
+ },
+
+ __call = function(_t, nodes)
+ local value = {
+ nodes = nodes,
+ node_instances = {},
+ }
+ setmetatable(value, collada_scene_node_state)
+ value:node_instances_new(nodes)
+ return value
+ end,
+}
+setmetatable(collada_scene_node_state, collada_scene_node_state)
+
+return collada_scene_node_state
diff --git a/collada_types.lua b/collada_types.lua
index f559aae..2ac649a 100644
--- a/collada_types.lua
+++ b/collada_types.lua
@@ -67,6 +67,19 @@ local target_attribute = {
ALL = {}
}
+local rotate_target_attributes = {
+ target_attribute.X,
+ target_attribute.Y,
+ target_attribute.Z,
+ target_attribute.ANGLE,
+}
+
+local translate_scale_target_attributes = {
+ target_attribute.X,
+ target_attribute.Y,
+ target_attribute.Z,
+}
+
return {
input_format = input_format,
light_type = light_type,
@@ -76,4 +89,6 @@ return {
node_type = node_type,
interpolation = interpolation,
target_attribute = target_attribute,
+ rotate_target_attributes = rotate_target_attributes,
+ translate_scale_target_attributes = translate_scale_target_attributes,
}
diff --git a/main.lua b/main.lua
index 0ab7777..356e7e8 100644
--- a/main.lua
+++ b/main.lua
@@ -9,16 +9,22 @@ local vec4 = _math.vec4
local scalar = _math.scalar
local scene_test = require 'scene.test.test'
local collada_scene = require 'collada_scene'
+local collada_scene_animate = require 'collada_scene.animate'
+local collada_scene_node_state = require 'collada_scene.node_state'
+
+local node_state
function love.load(args)
love.window.setMode(1024, 1024, {depth=true})
collada_scene.load_buffers()
collada_scene.load_images("scene/test", scene_test.descriptor.images)
- collada_scene.load_node_instances(scene_test.descriptor.nodes)
+
+ node_state = collada_scene_node_state(scene_test.descriptor.nodes)
end
local rotation = 0.0
+local t = 0.0
function love.draw()
local radius = 100
@@ -42,6 +48,9 @@ function love.draw()
local transform = view * projection
+ collada_scene_animate.update(t, node_state)
+ t = t + 0.016
+
love.graphics.setDepthMode("less", true)
- collada_scene.draw_nodes(scene_test.descriptor.nodes, transform)
+ collada_scene.draw_nodes(node_state, transform)
end
diff --git a/scene/test/test.DAE b/scene/test/test.DAE
index f826530..535c61a 100644
--- a/scene/test/test.DAE
+++ b/scene/test/test.DAE
@@ -6,8 +6,8 @@
OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68
file:///C:/Users/bilbo/Documents/wood/scenes/test/test.max
- 2026-02-23T22:42:05
- 2026-02-23T22:42:05
+ 2026-02-24T13:10:30
+ 2026-02-24T13:10:30
Z_UP
@@ -422,7 +422,7 @@
- -21.94384 -1.68812e-14 45.45129
+ -21.94384 -1.68812e-14 45.45129
-1 -2.22051e-16 -2.22051e-16 -90
0.5458366 0.5458366 0.5458366
@@ -443,7 +443,9 @@
3.281013 -28.30101 45.45129
- 0.9075136 -0.007434183 0.4199569 -178.1592
+ 0 0 1 -2.386906
+ 0 1 0 -49.62295
+ 1 0 0 -176.868
0.9893375 0 0.1456411 -1.382112
0.5458366 0.5458367 0.5458366
0.9893375 0 0.1456411 1.382112
@@ -522,6 +524,310 @@
+
+
+
+ 0 1 2 3 3.333333
+
+
+
+
+
+
+
+ -21.94384 17.57915 40.64392 -0.591423 -21.94384
+
+
+
+
+
+
+
+ -0.3329306 -21.94384 0.667 7.158293 1.667 40.64392 2.667 15.03987 3.222333 -21.94384
+
+
+
+
+
+
+
+
+ 0.333 -21.94384 1.333 28.00002 2.333 40.64392 3.111 -5.801854 3.666264 -21.94384
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+ 0 1 2 3 3.333333
+
+
+
+
+
+
+
+ -1.68812e-14 24.27013 -12.4935 9.835234 -1.68812e-14
+
+
+
+
+
+
+
+ -0.3329306 -1.68812e-14 0.667 24.27013 1.667 -12.4935 2.667 9.835234 3.222333 -1.68812e-14
+
+
+
+
+
+
+
+
+ 0.333 -1.68812e-14 1.333 24.27013 2.333 -12.4935 3.111 9.835234 3.666264 -1.68812e-14
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+ 0 1 2 3 3.333333
+
+
+
+
+
+
+
+ 45.45129 45.45129 45.45129 45.45129 45.45129
+
+
+
+
+
+
+
+ -0.3329306 45.45129 0.667 45.45129 1.667 45.45129 2.667 45.45129 3.222333 45.45129
+
+
+
+
+
+
+
+
+ 0.333 45.45129 1.333 45.45129 2.333 45.45129 3.111 45.45129 3.666264 45.45129
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+ 0 0.5 1 1.5 2 2.5 3.333333
+
+
+
+
+
+
+
+ -2.386905 -47.8331 -59.67817 -40.14935 -120.2731 -163.7238 -2.386905
+
+
+
+
+
+
+
+ -0.3329306 -2.386905 0.3335 -38.2941 0.8335 -59.67817 1.3335 -40.14935 1.8335 -99.69791 2.3335 -163.7238 3.055833 -2.386905
+
+
+
+
+
+
+
+
+ 0.1665 -2.386905 0.6665 -57.37209 1.1665 -59.67817 1.6665 -40.14935 2.1665 -140.8482 2.7775 -163.7238 3.666264 -2.386905
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+ 0 0.5 1 1.5 2 2.5 3.333333
+
+
+
+
+
+
+
+ -49.62293 -15.37984 34.11597 -56.85069 -56.85069 -170.1778 -49.62293
+
+
+
+
+
+
+
+ -0.3329306 -49.62293 0.3335 -29.32237 0.8335 34.11597 1.3335 -56.85069 1.8335 -56.85069 2.3335 -170.1778 3.055833 -49.62293
+
+
+
+
+
+
+
+
+ 0.1665 -49.62293 0.6665 -1.437308 1.1665 34.11597 1.6665 -56.85069 2.1665 -56.85069 2.7775 -170.1778 3.666264 -49.62293
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+ 0 0.5 1 1.5 2 2.5 3.333333
+
+
+
+
+
+
+
+ 183.132 256.4932 196.3711 133.4248 133.4248 152.3479 183.132
+
+
+
+
+
+
+
+ -0.3329306 183.132 0.3335 256.4932 0.8335 216.862 1.3335 133.4248 1.8335 133.4248 2.3335 146.1407 3.055833 183.132
+
+
+
+
+
+
+
+
+ 0.1665 183.132 0.6665 256.4932 1.1665 175.8802 1.6665 133.4248 2.1665 133.4248 2.7775 162.6932 3.666264 183.132
+
+
+
+
+
+
+
+
+ BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER BEZIER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scene/test/test.lua b/scene/test/test.lua
index 5641db2..227186d 100644
--- a/scene/test/test.lua
+++ b/scene/test/test.lua
@@ -15,6 +15,468 @@ local light_omni001_light = {
type = collada_types.light_type.POINT,
color = {1.0, 1.0, 1.0},
}
+local array_node_torus_knot23_translation_x_input_array = {
+ 0.0,
+ 1.0,
+ 2.0,
+ 3.0,
+ 3.333333,
+}
+local array_node_torus_knot23_translation_x_output_array = {
+ -21.94384,
+ 17.57915,
+ 40.64392,
+ -0.591423,
+ -21.94384,
+}
+local array_node_torus_knot23_translation_x_intangent_array = {
+ {-0.3329306, -21.94384},
+ {0.667, 7.158293},
+ {1.667, 40.64392},
+ {2.667, 15.03987},
+ {3.222333, -21.94384},
+}
+local array_node_torus_knot23_translation_x_outtangent_array = {
+ {0.333, -21.94384},
+ {1.333, 28.00002},
+ {2.333, 40.64392},
+ {3.111, -5.801854},
+ {3.666264, -21.94384},
+}
+local array_node_torus_knot23_translation_x_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torus_knot23_translation_x_sampler = {
+ -- node_torus_knot23_translation_x_input
+ input = {
+ float_array = array_node_torus_knot23_translation_x_input_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_x_output
+ output = {
+ float_array = array_node_torus_knot23_translation_x_output_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_x_intangent
+ in_tangent = {
+ float_array = array_node_torus_knot23_translation_x_intangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_x_outtangent
+ out_tangent = {
+ float_array = array_node_torus_knot23_translation_x_outtangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_x_interpolation
+ interpolation = {
+ interpolation_array = array_node_torus_knot23_translation_x_interpolation_array,
+ count = 5,
+ stride = 1,
+ },
+}
+local array_node_torus_knot23_translation_y_input_array = {
+ 0.0,
+ 1.0,
+ 2.0,
+ 3.0,
+ 3.333333,
+}
+local array_node_torus_knot23_translation_y_output_array = {
+ -1.68812e-14,
+ 24.27013,
+ -12.4935,
+ 9.835234,
+ -1.68812e-14,
+}
+local array_node_torus_knot23_translation_y_intangent_array = {
+ {-0.3329306, -1.68812e-14},
+ {0.667, 24.27013},
+ {1.667, -12.4935},
+ {2.667, 9.835234},
+ {3.222333, -1.68812e-14},
+}
+local array_node_torus_knot23_translation_y_outtangent_array = {
+ {0.333, -1.68812e-14},
+ {1.333, 24.27013},
+ {2.333, -12.4935},
+ {3.111, 9.835234},
+ {3.666264, -1.68812e-14},
+}
+local array_node_torus_knot23_translation_y_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torus_knot23_translation_y_sampler = {
+ -- node_torus_knot23_translation_y_input
+ input = {
+ float_array = array_node_torus_knot23_translation_y_input_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_y_output
+ output = {
+ float_array = array_node_torus_knot23_translation_y_output_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_y_intangent
+ in_tangent = {
+ float_array = array_node_torus_knot23_translation_y_intangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_y_outtangent
+ out_tangent = {
+ float_array = array_node_torus_knot23_translation_y_outtangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_y_interpolation
+ interpolation = {
+ interpolation_array = array_node_torus_knot23_translation_y_interpolation_array,
+ count = 5,
+ stride = 1,
+ },
+}
+local array_node_torus_knot23_translation_z_input_array = {
+ 0.0,
+ 1.0,
+ 2.0,
+ 3.0,
+ 3.333333,
+}
+local array_node_torus_knot23_translation_z_output_array = {
+ 45.45129,
+ 45.45129,
+ 45.45129,
+ 45.45129,
+ 45.45129,
+}
+local array_node_torus_knot23_translation_z_intangent_array = {
+ {-0.3329306, 45.45129},
+ {0.667, 45.45129},
+ {1.667, 45.45129},
+ {2.667, 45.45129},
+ {3.222333, 45.45129},
+}
+local array_node_torus_knot23_translation_z_outtangent_array = {
+ {0.333, 45.45129},
+ {1.333, 45.45129},
+ {2.333, 45.45129},
+ {3.111, 45.45129},
+ {3.666264, 45.45129},
+}
+local array_node_torus_knot23_translation_z_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torus_knot23_translation_z_sampler = {
+ -- node_torus_knot23_translation_z_input
+ input = {
+ float_array = array_node_torus_knot23_translation_z_input_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_z_output
+ output = {
+ float_array = array_node_torus_knot23_translation_z_output_array,
+ count = 5,
+ stride = 1,
+ },
+ -- node_torus_knot23_translation_z_intangent
+ in_tangent = {
+ float_array = array_node_torus_knot23_translation_z_intangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_z_outtangent
+ out_tangent = {
+ float_array = array_node_torus_knot23_translation_z_outtangent_array,
+ count = 5,
+ stride = 2,
+ },
+ -- node_torus_knot23_translation_z_interpolation
+ interpolation = {
+ interpolation_array = array_node_torus_knot23_translation_z_interpolation_array,
+ count = 5,
+ stride = 1,
+ },
+}
+local array_node_torusknot25_rotationz_angle_input_array = {
+ 0.0,
+ 0.5,
+ 1.0,
+ 1.5,
+ 2.0,
+ 2.5,
+ 3.333333,
+}
+local array_node_torusknot25_rotationz_angle_output_array = {
+ -2.386905,
+ -47.8331,
+ -59.67817,
+ -40.14935,
+ -120.2731,
+ -163.7238,
+ -2.386905,
+}
+local array_node_torusknot25_rotationz_angle_intangent_array = {
+ {-0.3329306, -2.386905},
+ {0.3335, -38.2941},
+ {0.8335, -59.67817},
+ {1.3335, -40.14935},
+ {1.8335, -99.69791},
+ {2.3335, -163.7238},
+ {3.055833, -2.386905},
+}
+local array_node_torusknot25_rotationz_angle_outtangent_array = {
+ {0.1665, -2.386905},
+ {0.6665, -57.37209},
+ {1.1665, -59.67817},
+ {1.6665, -40.14935},
+ {2.1665, -140.8482},
+ {2.7775, -163.7238},
+ {3.666264, -2.386905},
+}
+local array_node_torusknot25_rotationz_angle_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torusknot25_rotationz_angle_sampler = {
+ -- node_torusknot25_rotationz_angle_input
+ input = {
+ float_array = array_node_torusknot25_rotationz_angle_input_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationz_angle_output
+ output = {
+ float_array = array_node_torusknot25_rotationz_angle_output_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationz_angle_intangent
+ in_tangent = {
+ float_array = array_node_torusknot25_rotationz_angle_intangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationz_angle_outtangent
+ out_tangent = {
+ float_array = array_node_torusknot25_rotationz_angle_outtangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationz_angle_interpolation
+ interpolation = {
+ interpolation_array = array_node_torusknot25_rotationz_angle_interpolation_array,
+ count = 7,
+ stride = 1,
+ },
+}
+local array_node_torusknot25_rotationy_angle_input_array = {
+ 0.0,
+ 0.5,
+ 1.0,
+ 1.5,
+ 2.0,
+ 2.5,
+ 3.333333,
+}
+local array_node_torusknot25_rotationy_angle_output_array = {
+ -49.62293,
+ -15.37984,
+ 34.11597,
+ -56.85069,
+ -56.85069,
+ -170.1778,
+ -49.62293,
+}
+local array_node_torusknot25_rotationy_angle_intangent_array = {
+ {-0.3329306, -49.62293},
+ {0.3335, -29.32237},
+ {0.8335, 34.11597},
+ {1.3335, -56.85069},
+ {1.8335, -56.85069},
+ {2.3335, -170.1778},
+ {3.055833, -49.62293},
+}
+local array_node_torusknot25_rotationy_angle_outtangent_array = {
+ {0.1665, -49.62293},
+ {0.6665, -1.437308},
+ {1.1665, 34.11597},
+ {1.6665, -56.85069},
+ {2.1665, -56.85069},
+ {2.7775, -170.1778},
+ {3.666264, -49.62293},
+}
+local array_node_torusknot25_rotationy_angle_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torusknot25_rotationy_angle_sampler = {
+ -- node_torusknot25_rotationy_angle_input
+ input = {
+ float_array = array_node_torusknot25_rotationy_angle_input_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationy_angle_output
+ output = {
+ float_array = array_node_torusknot25_rotationy_angle_output_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationy_angle_intangent
+ in_tangent = {
+ float_array = array_node_torusknot25_rotationy_angle_intangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationy_angle_outtangent
+ out_tangent = {
+ float_array = array_node_torusknot25_rotationy_angle_outtangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationy_angle_interpolation
+ interpolation = {
+ interpolation_array = array_node_torusknot25_rotationy_angle_interpolation_array,
+ count = 7,
+ stride = 1,
+ },
+}
+local array_node_torusknot25_rotationx_angle_input_array = {
+ 0.0,
+ 0.5,
+ 1.0,
+ 1.5,
+ 2.0,
+ 2.5,
+ 3.333333,
+}
+local array_node_torusknot25_rotationx_angle_output_array = {
+ 183.132,
+ 256.4932,
+ 196.3711,
+ 133.4248,
+ 133.4248,
+ 152.3479,
+ 183.132,
+}
+local array_node_torusknot25_rotationx_angle_intangent_array = {
+ {-0.3329306, 183.132},
+ {0.3335, 256.4932},
+ {0.8335, 216.862},
+ {1.3335, 133.4248},
+ {1.8335, 133.4248},
+ {2.3335, 146.1407},
+ {3.055833, 183.132},
+}
+local array_node_torusknot25_rotationx_angle_outtangent_array = {
+ {0.1665, 183.132},
+ {0.6665, 256.4932},
+ {1.1665, 175.8802},
+ {1.6665, 133.4248},
+ {2.1665, 133.4248},
+ {2.7775, 162.6932},
+ {3.666264, 183.132},
+}
+local array_node_torusknot25_rotationx_angle_interpolation_array = {
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+ collada_types.interpolation.BEZIER,
+}
+local sampler_node_torusknot25_rotationx_angle_sampler = {
+ -- node_torusknot25_rotationx_angle_input
+ input = {
+ float_array = array_node_torusknot25_rotationx_angle_input_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationx_angle_output
+ output = {
+ float_array = array_node_torusknot25_rotationx_angle_output_array,
+ count = 7,
+ stride = 1,
+ },
+ -- node_torusknot25_rotationx_angle_intangent
+ in_tangent = {
+ float_array = array_node_torusknot25_rotationx_angle_intangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationx_angle_outtangent
+ out_tangent = {
+ float_array = array_node_torusknot25_rotationx_angle_outtangent_array,
+ count = 7,
+ stride = 2,
+ },
+ -- node_torusknot25_rotationx_angle_interpolation
+ interpolation = {
+ interpolation_array = array_node_torusknot25_rotationx_angle_interpolation_array,
+ count = 7,
+ stride = 1,
+ },
+}
+local node_channel_node_torus_knot23_translation_x = {
+ source_sampler = sampler_node_torus_knot23_translation_x_sampler,
+ target_transform_index = 0,
+ target_attribute = collada_types.target_attribute.X,
+}
+local node_channel_node_torus_knot23_translation_y = {
+ source_sampler = sampler_node_torus_knot23_translation_y_sampler,
+ target_transform_index = 0,
+ target_attribute = collada_types.target_attribute.Y,
+}
+local node_channel_node_torus_knot23_translation_z = {
+ source_sampler = sampler_node_torus_knot23_translation_z_sampler,
+ target_transform_index = 0,
+ target_attribute = collada_types.target_attribute.Z,
+}
+local node_channel_node_torusknot25_rotationz_angle = {
+ source_sampler = sampler_node_torusknot25_rotationz_angle_sampler,
+ target_transform_index = 1,
+ target_attribute = collada_types.target_attribute.ANGLE,
+}
+local node_channel_node_torusknot25_rotationy_angle = {
+ source_sampler = sampler_node_torusknot25_rotationy_angle_sampler,
+ target_transform_index = 2,
+ target_attribute = collada_types.target_attribute.ANGLE,
+}
+local node_channel_node_torusknot25_rotationx_angle = {
+ source_sampler = sampler_node_torusknot25_rotationx_angle_sampler,
+ target_transform_index = 3,
+ target_attribute = collada_types.target_attribute.ANGLE,
+}
-- logOnly_png
local image_logonly_png = {
uri = "./images/0_logOnly.png",
@@ -363,6 +825,9 @@ local instance_controllers_node_torus_knot23 = {
local instance_lights_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,
}
local node_node_torus_knot23 = {
parent_index = -1,
@@ -382,7 +847,7 @@ local node_node_torus_knot23 = {
instance_lights_count = 0,
channels = node_channels_node_torus_knot23,
- channels_count = 0,
+ channels_count = 3,
}
local transforms_node_torusknot25 = {
{
@@ -391,7 +856,15 @@ local transforms_node_torusknot25 = {
},
{
type = collada_types.transform_type.ROTATE,
- rotate = {0.9075136, -0.007434183, 0.4199569, -178.1592},
+ rotate = {0.0, 0.0, 1.0, -2.386906},
+ },
+ {
+ type = collada_types.transform_type.ROTATE,
+ rotate = {0.0, 1.0, 0.0, -49.62295},
+ },
+ {
+ type = collada_types.transform_type.ROTATE,
+ rotate = {1.0, 0.0, 0.0, -176.868},
},
{
type = collada_types.transform_type.ROTATE,
@@ -430,6 +903,9 @@ local instance_controllers_node_torusknot25 = {
local instance_lights_node_torusknot25 = {
}
local node_channels_node_torusknot25 = {
+ node_channel_node_torusknot25_rotationz_angle,
+ node_channel_node_torusknot25_rotationx_angle,
+ node_channel_node_torusknot25_rotationy_angle,
}
local node_node_torusknot25 = {
parent_index = -1,
@@ -437,7 +913,7 @@ local node_node_torusknot25 = {
type = collada_types.node_type.NODE,
transforms = transforms_node_torusknot25,
- transforms_count = 5,
+ transforms_count = 7,
instance_geometries = instance_geometries_node_torusknot25,
instance_geometries_count = 1,
@@ -449,7 +925,7 @@ local node_node_torusknot25 = {
instance_lights_count = 0,
channels = node_channels_node_torusknot25,
- channels_count = 0,
+ channels_count = 3,
}
local transforms_node_camerahelper = {
{