fix //spline :D

This commit is contained in:
Starbeamrainbowlabs 2022-09-25 17:07:37 +01:00
parent fe30fd5c51
commit c319be5840
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 48 additions and 13 deletions

View file

@ -59,17 +59,52 @@ function worldeditadditions.spline(pos_list, width_start, width_end, steps, targ
--- ---
local pos_prev = pos_list_chaikin[1]:floor() 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 pos_next = pos_list_chaikin[i]:floor()
local width_next = widths_lerped[i] 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 -- For now, just plot a point at each node
local index_node = area:index(pos_next.x, pos_next.y, pos_next.z) data[area:indexp(pos_next)] = node_id
data[index_node] = node_id data[area:indexp(pos_prev)] = node_id
count = count + 1 local subline_length = (pos_next - pos_prev):length()
pos_prev = pos_next:clone() 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 end
--- ---

View file

@ -35,18 +35,18 @@ worldeditadditions_core.register_command("spline", {
width_start = tonumber(parts[2]) width_start = tonumber(parts[2])
if not width_start then 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 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].."'." return false, "Error: width_start must be an integer greater than 0, but you passed '"..parts[2].."'."
end end
if #parts >= 3 then if #parts >= 3 then
width_end = tonumber(parts[3]) width_end = tonumber(parts[3])
if not width_end then 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 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].."'." return false, "Error: width_end must be an integer greater than 0, but you passed '"..parts[3].."'."
end end
else else

View file

@ -17,7 +17,7 @@ end
-- @param steps number The number of interpolatioon passes to do. -- @param steps number The number of interpolatioon passes to do.
-- @returns Vector3[] A (longer) list of interpolated points. -- @returns Vector3[] A (longer) list of interpolated points.
local function chaikin(arr_pos, steps) 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 result = wea_c.table.shallowcopy(arr_pos)
local pos_start = result[1] local pos_start = result[1]
@ -29,7 +29,7 @@ local function chaikin(arr_pos, steps)
for i = 1,#result-1,1 do for i = 1,#result-1,1 do
local pos_cur = result[i] local pos_cur = result[i]
local pos_next = result[i+1] 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.25))
table.insert(result_nextpass, linear_interpolate(pos_cur, pos_next, 0.75)) 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[1] = pos_start
result[#result] = pos_end result[#result] = pos_end
print("DEBUG:chakin STEP", wea_c.inspect(result)) -- print("DEBUG:chakin STEP", wea_c.inspect(result))
end end
return result return result