Compare commits

...

7 Commits

Author SHA1 Message Date
Starbeamrainbowlabs 558fc1c04b
//revolve: try :round() instead of :floor()
not sure if ti helps or not tho
2023-02-12 03:32:10 +00:00
Starbeamrainbowlabs 1d53233621
typo 2023-02-12 02:19:53 +00:00
Starbeamrainbowlabs 66aab7ba64
Changelog: add //revolve 2023-02-12 02:18:15 +00:00
Starbeamrainbowlabs fcde8e581c
cloud wand: right clicking now resets all WEA multipoints 2023-02-12 02:18:04 +00:00
Starbeamrainbowlabs cfef411bbd
//revolve: write initial docs 2023-02-12 02:08:57 +00:00
Starbeamrainbowlabs cf8406b80f
//revolve: don't rotate air nodes
this is important because when rotating multiple times it can easily overwrite parts of the structure with pointless air nodes where it shouldn't do
2023-02-12 02:08:44 +00:00
Starbeamrainbowlabs e942e4fb2f
Finish initial implementation of //revolve
it's not quite done yet - got docs to go
2023-02-12 01:40:29 +00:00
7 changed files with 127 additions and 26 deletions

View File

@ -7,6 +7,7 @@ Note to self: See the bottom of this file for the release template text.
## v1.14: The untitled update (unreleased)
- Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once
- Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest
- Add `//revolve`, which makes multiple evenly-spaced rotated copies of the defined region
- Migrate from `depends.txt` to `mod.conf`
- `//sculpt`: Fix undefined `default` brush
- Commands that modify the terrain now ignore liquids
@ -15,6 +16,9 @@ Note to self: See the bottom of this file for the release template text.
- Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. **Not currently compatible with other wands**, as it's a work-in-progress (commands that support/require more than 2 points are hopefully coming soon)
- Add `//spline`, for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)**
### Bugfixes
- Cloud wand: fix typo in item description.
## v1.13: The transformational update (2nd January 2022)
- Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now.

View File

@ -437,6 +437,18 @@ Here are all the above examples together:
```
### `//revolve <times> [<pivot_point_number=last_point>]`
Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point.
For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point.
`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more.
```weacmd
//revolve 4
//revolve 6 6
```
## Terrain
<!--

View File

@ -31,6 +31,7 @@ dofile(wea.modpath.."/lib/spiral_square.lua")
dofile(wea.modpath.."/lib/spiral_circle.lua")
dofile(wea.modpath.."/lib/dome.lua")
dofile(wea.modpath.."/lib/spline.lua")
dofile(wea.modpath.."/lib/revolve.lua")
dofile(wea.modpath.."/lib/conv/conv.lua")
dofile(wea.modpath.."/lib/erode/erode.lua")
dofile(wea.modpath.."/lib/noise/init.lua")

View File

@ -16,48 +16,56 @@ local Vector3 = wea_c.Vector3
-- @param origin Vector3 The pivot point to rotate around.
-- @param times number The number of equally-spaces copies to make.
function worldeditadditions.revolve(pos1, pos2, origin, times)
local rotation_radians = wea_c.range(0, 1, 1 / times)
local rotation_radians = wea_c.table.filter(
wea_c.range(0, 1, 1 / times),
function (val) return val ~= 0 and val ~= 1 end
)
local pos1_source, pos2_source = Vector3.sort(pos1, pos2)
-- HACK: with some maths this could be much more efficient.
local pos1_target, pos2_target = wea_c.table.unpack(wea_c.table.reduce({
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi / 2)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi / 2)),
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi)),
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, -math.pi / 2)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, -math.pi / 2)),
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi / 2, 0)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi / 2, 0)),
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi, 0)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi, 0)),
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, -math.pi / 2, 0)),
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, -math.pi / 2, 0)),
}, function(acc, next)
return { next:expand_region(acc[1], acc[2]) }
end, { pos1_source, pos2_source }))
-- Fetch the nodes in the specified area
local manip_source, area_source = worldedit.manip_helpers.init(pos1_source, pos2_source)
local data_source = manip:get_data()
local data_source = manip_source:get_data()
local manip_target, area_target = worldedit.manip_helpers.init(pos1_target, pos2_target)
local data_target = manip:get_data()
local data_target = manip_target:get_data()
local changed = 0
for z = pos2_source.z, pos1_source.z, -1 do
for y = pos2_source.y, pos1_source.y, -1 do
for x = pos2_source.x, pos1_source.x, -1 do
for index, rotation in ipairs(rotation_radians) do
local pos_source = Vector3.new(x, y, z)
local pos_target = Vector3.rotate3d(
origin,
pos_source,
Vector3.new(0, 0, rotation) -- rotate on Z axis only
)
local i_source = area_source:index(x, y, z)
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
-- TODO: Rotate notes as appropriate
data_target[i_target] = data_source[i_source]
changed = changed + 1
local pos_source = Vector3.new(x, y, z)
local i_source = area_source:index(x, y, z)
-- Lua really sucks sometimes... a continue statement would be v useful here
if not wea_c.is_airlike(data_source[i_source]) then
for index, rotation in ipairs(rotation_radians) do
local pos_target = Vector3.rotate3d(
origin,
pos_source,
-- rotate on Z axis only, convert 0..1 → radians
-- TEST on Y axis, 'cause I'm confused
Vector3.new(0, rotation * math.pi * 2, 0)
):round()
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
-- TODO: Rotate notes as appropriate
data_target[i_target] = data_source[i_source]
changed = changed + 1
end
end
end
end

View File

@ -0,0 +1,73 @@
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ██████ ███████ ██ ██ ██████ ██ ██ ██ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ █████ ██ ██ ██ ██ ██ ██ ██ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ███████ ████ ██████ ███████ ████ ███████
worldeditadditions_core.register_command("revolve", {
params = "<times> [<pivot_point_number=last_point>]",
description = "Creates a number of copies of the defined region rotated at equal intervals.",
privs = { worldedit = true },
require_pos = 2,
parse = function (params_text)
if not params_text then params_text = "" end
local parts = wea_c.split_shell(params_text)
if #parts < 1 then
return false, "Error: No number of times specified. times should be a positive integer greater than 1"
end
local times = tonumber(parts[1])
local origin = -1 -- -1 = last point
if not times or times < 2 then
return false, "Error: Invalid number of times. The value for times must be a positive integer greater than 1."
end
if #parts > 1 then
origin = tonumber(parts[2])
if not origin then
return false, "Error: Invalid pivot point number. The pivot point number must be a positive integer greater than 2."
end
if origin == 1 or origin == 2 then
return false, "Error: Point numbers 1 and 2 are reserved for defining the region that should be cloned."
end
end
return true, times, origin
end,
nodes_needed = function(name, times)
-- TODO: Calculate the bounding box for everything, since we'll be grabbing a VoxelManip for the for entire area and then operating on that
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * times
end,
func = function(name, times, origin_point_number)
local start_time = wea_c.get_ms_time()
local pos1, pos2 = Vector3.sort(worldedit.pos1[name], worldedit.pos2[name])
local pos_count = wea_c.pos.count(name)
if pos_count < origin_point_number then
return false, "Error: You only have "..pos_count.." points defined, yet requested the origin/pivot point be point "..origin_point_number.."."
end
if origin_point_number == -1 then
origin_point_number = pos_count
end
local origin = wea_c.pos.get(name, origin_point_number)
local success, changed = worldeditadditions.revolve(
pos1, pos2,
origin,
times
)
if not success then return success, changed end
local time_taken = wea_c.get_ms_time() - start_time
minetest.log("action", name .. " used //revolve at "..pos1.." - "..pos2.." with origin "..origin..", replacing "..changed.." nodes in "..time_taken.."s")
return true, changed.." nodes replaced in "..wea_c.format.human_time(time_taken)
end
})

View File

@ -37,6 +37,7 @@ dofile(wea_cmd.modpath.."/commands/metaball.lua")
dofile(wea_cmd.modpath.."/commands/count.lua")
dofile(wea_cmd.modpath.."/commands/sculpt.lua")
dofile(wea_cmd.modpath.."/commands/spline.lua")
dofile(wea_cmd.modpath.."/commands/revolve.lua")
-- Meta Commands
dofile(wea_cmd.modpath.."/commands/meta/init.lua")

View File

@ -1,8 +1,8 @@
local wea = worldeditadditions
-- local wea_c = worldeditadditions_core
local wea_c = worldeditadditions_core
minetest.register_tool(":worldeditadditions:cloudwand", {
description = "WorldEditAdditions far-reaching additive selectior wand",
description = "WorldEditAdditions far-reaching additive selector wand",
inventory_image = "worldeditadditions_cloudwand.png",
on_place = function(itemstack, player, pointed_thing)
@ -26,6 +26,8 @@ minetest.register_tool(":worldeditadditions:cloudwand", {
-- Right click when pointing at nothing
-- print("[farwand] on_secondary_use", name)
-- TODO: Move over to wea_c.pos completely
wea.selection.clear_points(name)
wea_c.pos.clear(name)
end
})