2023-07-05 16:57:41 +00:00
|
|
|
-- This is a 'micro' version of osci-render that
|
|
|
|
-- draws the default cube and allows you to rotate
|
|
|
|
-- it and also apply some basic audio effects.
|
|
|
|
--
|
|
|
|
-- The Lua sliders control the following:
|
|
|
|
-- - slider_a = frequency/drawing speed
|
|
|
|
-- - slider_b = camera z position
|
|
|
|
-- - slider_c = focal length of camera
|
|
|
|
-- - slider_d = rotation speed
|
|
|
|
-- - slider_e = trace effect
|
|
|
|
--
|
|
|
|
|
|
|
|
-- a=start point, b=end point, t=drawing progress
|
|
|
|
function line(a, b, t)
|
|
|
|
return {
|
|
|
|
a.x + t * (b.x - a.x),
|
|
|
|
a.y + t * (b.y - a.y)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
focal_length = slider_c
|
|
|
|
camera_z = slider_b * 3
|
|
|
|
|
|
|
|
-- projects a 3D point into 2D
|
|
|
|
function project(point)
|
|
|
|
return {
|
|
|
|
x=point.x * focal_length / (point.z - camera_z),
|
|
|
|
y=point.y * focal_length / (point.z - camera_z)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
-- rotates a point in 3D
|
|
|
|
function rotate(point, rotate_x, rotate_y, rotate_z)
|
|
|
|
x1 = point.x
|
|
|
|
y1 = point.y
|
|
|
|
z1 = point.z
|
|
|
|
|
|
|
|
-- rotate around x-axis
|
|
|
|
cos = math.cos(rotate_x)
|
|
|
|
sin = math.sin(rotate_x)
|
|
|
|
y2 = cos * y1 - sin * z1
|
|
|
|
z2 = sin * y1 + cos * z1
|
|
|
|
|
|
|
|
-- rotate around y-axis
|
|
|
|
cos = math.cos(rotate_y)
|
|
|
|
sin = math.sin(rotate_y)
|
|
|
|
x2 = cos * x1 + sin * z2
|
|
|
|
z3 = -sin * x1 + cos * z2
|
|
|
|
|
|
|
|
-- rotate around z-axis
|
|
|
|
cos = math.cos(rotate_z)
|
|
|
|
sin = math.sin(rotate_z)
|
|
|
|
x3 = cos * x2 - sin * y2
|
|
|
|
y3 = sin * x2 + cos * y2
|
|
|
|
|
|
|
|
return {
|
|
|
|
x=x3,
|
|
|
|
y=y3,
|
|
|
|
z=z3
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
num_points = 16
|
|
|
|
|
|
|
|
-- Percentage of the image that has currently been drawn.
|
|
|
|
-- The 'or' syntax sets 'drawing_progress' to 0 initially, or the
|
|
|
|
-- previous value of 'drawing_progress' the last time this script ran.
|
|
|
|
drawing_progress = drawing_progress or 0
|
|
|
|
drawing_progress = drawing_progress + 0.001 * slider_a
|
|
|
|
progress_cutoff = slider_e
|
|
|
|
|
|
|
|
if drawing_progress > progress_cutoff then
|
|
|
|
drawing_progress = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
-- get the index of the start point of the current line
|
|
|
|
start_index = math.floor(drawing_progress * num_points + 1)
|
|
|
|
-- end point of current line is the next in the points table
|
|
|
|
end_index = start_index + 1
|
|
|
|
if end_index > num_points then
|
|
|
|
end_index = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
-- doing this to avoid recomputation for every sample.
|
|
|
|
-- prev_start ~= start_index == true whenever a new line has started
|
|
|
|
if prev_start ~= start_index then
|
|
|
|
rotate_speed = slider_d * step / 50000
|
2023-07-21 19:04:10 +00:00
|
|
|
-- 3D cube draw path
|
|
|
|
points = {
|
|
|
|
{x=-1.0, y=-1.0, z=1.0},
|
|
|
|
{x=1.0, y=-1.0, z=1.0},
|
|
|
|
{x=1.0, y=-1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=-1.0, z=-1.0},
|
|
|
|
{x=1.0, y=-1.0, z=-1.0},
|
|
|
|
{x=1.0, y=1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=-1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=-1.0, z=1.0},
|
|
|
|
{x=1.0, y=-1.0, z=1.0},
|
|
|
|
{x=1.0, y=1.0, z=1.0},
|
|
|
|
{x=-1.0, y=1.0, z=1.0},
|
|
|
|
{x=1.0, y=1.0, z=1.0},
|
|
|
|
{x=1.0, y=1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=1.0, z=-1.0},
|
|
|
|
{x=-1.0, y=1.0, z=1.0}
|
|
|
|
}
|
2023-07-05 16:57:41 +00:00
|
|
|
-- rotate and project the start and end points
|
|
|
|
proj_start = project(rotate(points[start_index], rotate_speed, rotate_speed, 0))
|
|
|
|
proj_end = project(rotate(points[end_index], rotate_speed, rotate_speed, 0))
|
|
|
|
end
|
|
|
|
|
|
|
|
prev_start = start_index
|
|
|
|
|
|
|
|
-- work out what the relative progress drawn of the current line is
|
|
|
|
draw_length = 1.0 / num_points
|
|
|
|
line_progress = drawing_progress - (start_index - 1) * draw_length
|
|
|
|
line_progress = num_points * line_progress
|
|
|
|
|
|
|
|
return line(proj_start, proj_end, line_progress)
|