From c319be5840c426d3c1cce870729d175e48639c85 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 25 Sep 2022 17:07:37 +0100 Subject: [PATCH] fix //spline :D --- worldeditadditions/lib/spline.lua | 47 ++++++++++++++++--- .../commands/spline.lua | 8 ++-- worldeditadditions_core/utils/chaikin.lua | 6 +-- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/worldeditadditions/lib/spline.lua b/worldeditadditions/lib/spline.lua index 896041c..e3b4437 100644 --- a/worldeditadditions/lib/spline.lua +++ b/worldeditadditions/lib/spline.lua @@ -59,17 +59,52 @@ function worldeditadditions.spline(pos_list, width_start, width_end, steps, targ --- local pos_prev = pos_list_chaikin[1]:floor() - for i = 1, #pos_list_chaikin do + local width_prev = widths_lerped[1] + for i = 2, #pos_list_chaikin do local pos_next = pos_list_chaikin[i]:floor() local width_next = widths_lerped[i] - print("DEBUG:spline DRAW pos", pos_next, "width", width_next, "length", (pos_next - pos_prev):length()) -- For now, just plot a point at each node - local index_node = area:index(pos_next.x, pos_next.y, pos_next.z) - data[index_node] = node_id + data[area:indexp(pos_next)] = node_id + data[area:indexp(pos_prev)] = node_id - count = count + 1 - pos_prev = pos_next:clone() + local subline_length = (pos_next - pos_prev):length() + print("DEBUG:spline DRAW pos", pos_next, "width", width_next, "length", subline_length) + if subline_length > 0 then + + -- Iterate a box around the subline and draw it + local width_max = math.ceil(math.max(width_prev, width_next)) + local subpos1, subpos2 = Vector3.sort(pos_next, pos_prev) + subpos1 = subpos1 - width_max + subpos2 = subpos2 + width_max + + print("subpos1", subpos1, "subpos2", subpos2, "width_prev", width_prev, "width_next", width_next) + + for z = subpos2.z, subpos1.z, -1 do + for y = subpos2.y, subpos1.y, -1 do + for x = subpos2.x, subpos1.x, -1 do + local here = Vector3.new(x, y, z) + local D = (pos_next - pos_prev):normalise() + local d = Vector3.dot(here - pos_prev, D) + local closest_on_line = pos_prev + (D * d) + local distance = (here - closest_on_line):length() + + local distance_to_prev = (closest_on_line - pos_prev):length() + + local percentage_along_line = distance_to_prev / subline_length + local width_here = wea_c.lerp(width_prev, width_next, percentage_along_line) + if distance < width_here then + -- print("POINT ", here, "width_here", width_here, "distance from line", distance) + data[area:indexp(here)] = node_id + -- May hit some nodes multiplle times, but there's nothing doing about that without a big performance (and/or memory) hit + count = count + 1 + end + end + end + end + pos_prev = pos_next:clone() + width_prev = width_next + end end --- diff --git a/worldeditadditions_commands/commands/spline.lua b/worldeditadditions_commands/commands/spline.lua index c91c8f1..7449329 100644 --- a/worldeditadditions_commands/commands/spline.lua +++ b/worldeditadditions_commands/commands/spline.lua @@ -35,18 +35,18 @@ worldeditadditions_core.register_command("spline", { width_start = tonumber(parts[2]) if not width_start then - return false, "Error: width_start must be an integer greater than or equal to 1." + return false, "Error: width_start must be an integer greater than or equal to 0." end - if width_start < 1 then + if width_start < 0 then return false, "Error: width_start must be an integer greater than 0, but you passed '"..parts[2].."'." end if #parts >= 3 then width_end = tonumber(parts[3]) if not width_end then - return false, "Error: width_end must be an integer greater than or equal to 1." + return false, "Error: width_end must be an integer greater than or equal to 0." end - if width_end < 1 then + if width_end < 0 then return false, "Error: width_end must be an integer greater than 0, but you passed '"..parts[3].."'." end else diff --git a/worldeditadditions_core/utils/chaikin.lua b/worldeditadditions_core/utils/chaikin.lua index 474652e..6fdb82e 100644 --- a/worldeditadditions_core/utils/chaikin.lua +++ b/worldeditadditions_core/utils/chaikin.lua @@ -17,7 +17,7 @@ end -- @param steps number The number of interpolatioon passes to do. -- @returns Vector3[] A (longer) list of interpolated points. local function chaikin(arr_pos, steps) - print("DEBUG:chaikin START", wea_c.inspect(arr_pos)) + -- print("DEBUG:chaikin START", wea_c.inspect(arr_pos)) local result = wea_c.table.shallowcopy(arr_pos) local pos_start = result[1] @@ -29,7 +29,7 @@ local function chaikin(arr_pos, steps) for i = 1,#result-1,1 do local pos_cur = result[i] local pos_next = result[i+1] - print("DEBUG:chaikin SUBSTEP i", i, "pos_cur", pos_cur, "pos_next", pos_next) + -- print("DEBUG:chaikin SUBSTEP i", i, "pos_cur", pos_cur, "pos_next", pos_next) table.insert(result_nextpass, linear_interpolate(pos_cur, pos_next, 0.25)) table.insert(result_nextpass, linear_interpolate(pos_cur, pos_next, 0.75)) @@ -45,7 +45,7 @@ local function chaikin(arr_pos, steps) result[1] = pos_start result[#result] = pos_end - print("DEBUG:chakin STEP", wea_c.inspect(result)) + -- print("DEBUG:chakin STEP", wea_c.inspect(result)) end return result