]> git.lizzy.rs Git - worldedit.git/commitdiff
Dual-based cylinder
authorKyle <kyle.kylina@gmail.com>
Fri, 19 Oct 2012 01:10:30 +0000 (18:10 -0700)
committersfan5 <sfan5@live.de>
Thu, 31 Aug 2017 14:25:22 +0000 (16:25 +0200)
ChatCommands.md
WorldEdit API.md
worldedit/primitives.lua
worldedit_commands/init.lua

index be885c0a05a38d14bd10278ef52cea8237a8fc7d..9d3f9d8901bc65348dce8685c4f3e344760230ab 100644 (file)
@@ -175,23 +175,35 @@ Add dome centered at WorldEdit position 1 with radius `<radius>`, composed of `<
     //dome -12 glass\r
     //dome 17 mesecons:wire_00000000_off\r
 \r
-### `//hollowcylinder x/y/z/? <length> <radius> <node>`\r
+### `//hollowcylinder x/y/z/? <length> <radius1> [radius2] <node>`\r
 \r
-Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>` and radius `<radius>`, composed of `<node>`.\r
+Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>`, base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.\r
+\r
+Despite its name this command allows you to create cones (`radius2` = 0) as well as any shapes inbetween (0 < `radius2` < `radius1`).\r
+Swapping `radius1` and `radius2` will create the same object but upside-down.\r
 \r
     //hollowcylinder x +5 8 Bronze Block\r
     //hollowcylinder y 28 10 glass\r
     //hollowcylinder z -12 3 mesecons:wire_00000000_off\r
     //hollowcylinder ? 2 4 default:stone\r
 \r
-### `//cylinder x/y/z/? <length> <radius> <node>`\r
+    //hollowcylinder y 10 10 0 walls:cobble\r
+    //hollowcylinder x 6 0 5 Dirt\r
+    //hollowcylinder z 20 10 20 default:desert_stone\r
+\r
+### `//cylinder x/y/z/? <length> <radius1> [radius2] <node>`\r
 \r
-Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>` and radius `<radius>`, composed of `<node>`.\r
+Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>`, base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.\r
+Can also create shapes other than cylinders, e.g. cones (see documentation above).\r
 \r
     //cylinder x +5 8 Bronze Block\r
     //cylinder y 28 10 glass\r
     //cylinder z -12 3 mesecons:wire_00000000_off\r
     //cylinder ? 2 4 default:stone\r
+\r
+    //cylinder y 10 10 0 walls:cobble\r
+    //cylinder x 6 0 5 Dirt\r
+    //cylinder z 20 10 20 default:desert_stone\r
     \r
 ### `//hollowpyramid x/y/z? <height> <node>`\r
 \r
@@ -432,4 +444,4 @@ or vertically in the y axis `[v]`.
 Contracts the selection in all directions by `<amount>`. If specified, the selection can be contracted horizontally in the x and z axes `[h]`\r
 or vertically in the y axis `[v]`.\r
 \r
-               //outset v 5
\ No newline at end of file
+               //outset v 5\r
index 5867dfc9710b93167d637b257b66307984ac4fb6..8488305c7bac843b2cb89834be0fc0b9585a2be8 100644 (file)
@@ -127,9 +127,9 @@ Adds a dome centered at `pos` with radius `radius`, composed of `node_name`.
 \r
 Returns the number of nodes added.\r
 \r
-### count = worldedit.cylinder(pos, axis, length, radius, node_name, hollow)\r
+### count = worldedit.cylinder(pos, axis, length, radius1, radius2, node_name, hollow)\r
 \r
-Adds a cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`, composed of `node_name`.\r
+Adds a cylinder-like at `pos` along the `axis` axis ("x" or "y" or "z") with length `length`, base radius `radius1` and top radius `radius2`, composed of `node_name`.\r
 \r
 Returns the number of nodes added.\r
 \r
index fe22fffe8f820acfa7be542e9a8b53b168925ae1..9b86cd884959112965ff3fb6b514d03f4bd107c9 100644 (file)
@@ -92,49 +92,60 @@ end
 -- @param pos Position to center base of cylinder at.\r
 -- @param axis Axis ("x", "y", or "z")\r
 -- @param length Cylinder length.\r
--- @param radius Cylinder radius.\r
+-- @param radius1 Cylinder base radius.\r
+-- @param radius2 Cylinder top radius.\r
 -- @param node_name Name of node to make cylinder of.\r
 -- @param hollow Whether the cylinder should be hollow.\r
 -- @return The number of nodes added.\r
-function worldedit.cylinder(pos, axis, length, radius, node_name, hollow)\r
+function worldedit.cylinder(pos, axis, length, radius1, radius2, node_name, hollow)\r
        local other1, other2 = worldedit.get_axis_others(axis)\r
 \r
+       -- Backwards compatibility\r
+       if type(radius2) == "string" then\r
+               hollow = node_name\r
+               node_name = radius2\r
+               radius2 = radius1 -- straight cylinder\r
+       end\r
+\r
        -- Handle negative lengths\r
        local current_pos = {x=pos.x, y=pos.y, z=pos.z}\r
        if length < 0 then\r
                length = -length\r
                current_pos[axis] = current_pos[axis] - length\r
+               radius1, radius2 = radius2, radius1\r
        end\r
 \r
        -- Set up voxel manipulator\r
-       local manip, area = mh.init_axis_radius_length(current_pos, axis, radius, length)\r
+       local manip, area = mh.init_axis_radius_length(current_pos, axis, math.max(radius1, radius2), length)\r
        local data = mh.get_empty_data(area)\r
 \r
-       -- Add cylinder\r
+       -- Add desired shape (anything inbetween cylinder & cone)\r
        local node_id = minetest.get_content_id(node_name)\r
-       local min_radius, max_radius = radius * (radius - 1), radius * (radius + 1)\r
        local stride = {x=1, y=area.ystride, z=area.zstride}\r
        local offset = {\r
                x = current_pos.x - area.MinEdge.x,\r
                y = current_pos.y - area.MinEdge.y,\r
                z = current_pos.z - area.MinEdge.z,\r
        }\r
-       local min_slice, max_slice = offset[axis], offset[axis] + length - 1\r
        local count = 0\r
-       for index2 = -radius, radius do\r
-               -- Offset contributed by other axis 1 plus 1 to make it 1-indexed\r
-               local new_index2 = (index2 + offset[other1]) * stride[other1] + 1\r
-               for index3 = -radius, radius do\r
-                       local new_index3 = new_index2 + (index3 + offset[other2]) * stride[other2]\r
-                       local squared = index2 * index2 + index3 * index3\r
-                       if squared <= max_radius and (not hollow or squared >= min_radius) then\r
-                               -- Position is in cylinder\r
-                               -- Add column along axis\r
-                               for index1 = min_slice, max_slice do\r
-                                       local vi = new_index3 + index1 * stride[axis]\r
+       for i = 0, length - 1 do\r
+               -- Calulate radius for this "height" in the cylinder\r
+               local radius = radius1 + (radius2 - radius1) * (i - 1) / (length - 1)\r
+               radius = math.floor(radius + 0.5) -- round\r
+               local min_radius, max_radius = radius * (radius - 1), radius * (radius + 1)\r
+\r
+               for index2 = -radius, radius do\r
+                       -- Offset contributed by other axis 1 plus 1 to make it 1-indexed\r
+                       local new_index2 = (index2 + offset[other1]) * stride[other1] + 1\r
+                       for index3 = -radius, radius do\r
+                               local new_index3 = new_index2 + (index3 + offset[other2]) * stride[other2]\r
+                               local squared = index2 * index2 + index3 * index3\r
+                               if squared <= max_radius and (not hollow or squared >= min_radius) then\r
+                                       -- Position is in cylinder, add node here\r
+                                       local vi = new_index3 + (offset[axis] + i) * stride[axis]\r
                                        data[vi] = node_id\r
+                                       count = count + 1\r
                                end\r
-                               count = count + length\r
                        end\r
                end\r
        end\r
index 325a31c78b98183c24d76f195f503cafb65c4085..f423d674f5cca5b414531dc812709a84f6f26944 100644 (file)
@@ -538,46 +538,65 @@ local check_cylinder = function(name, param)
                worldedit.player_notify(name, "no position 1 selected")\r
                return nil\r
        end\r
-       local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+       -- two radii\r
+       local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")\r
+       if found == nil then\r
+               -- single radius\r
+               found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+               radius2 = radius1\r
+       end\r
        if found == nil then\r
                worldedit.player_notify(name, "invalid usage: " .. param)\r
                return nil\r
        end\r
        local node = get_node(name, nodename)\r
        if not node then return nil end\r
-       return math.ceil(math.pi * (tonumber(radius) ^ 2) * tonumber(length))\r
+       local radius = math.max(tonumber(radius1), tonumber(radius2))\r
+       return math.ceil(math.pi * (radius ^ 2) * tonumber(length))\r
 end\r
 \r
 minetest.register_chatcommand("/hollowcylinder", {\r
-       params = "x/y/z/? <length> <radius> <node>",\r
-       description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
+       params = "x/y/z/? <length> <radius1> [radius2] <node>",\r
+       description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",\r
        privs = {worldedit=true},\r
        func = safe_region(function(name, param)\r
-               local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+               -- two radii\r
+               local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")\r
+               if found == nil then\r
+                       -- single radius\r
+                       found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+                       radius2 = radius1\r
+               end\r
                length = tonumber(length)\r
                if axis == "?" then\r
                        axis, sign = worldedit.player_axis(name)\r
                        length = length * sign\r
                end\r
                local node = get_node(name, nodename)\r
-               local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius), node, true)\r
+               local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius1), tonumber(radius2), node, true)\r
                worldedit.player_notify(name, count .. " nodes added")\r
        end, check_cylinder),\r
 })\r
 \r
 minetest.register_chatcommand("/cylinder", {\r
-       params = "x/y/z/? <length> <radius> <node>",\r
-       description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
+       params = "x/y/z/? <length> <radius1> [radius2] <node>",\r
+       description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",\r
        privs = {worldedit=true},\r
        func = safe_region(function(name, param)\r
-               local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+               -- two radii\r
+               local found, _, axis, length, radius1, radius2, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(%d+)%s+(.+)$")\r
+               if found == nil then\r
+                       -- single radius\r
+                       found, _, axis, length, radius1, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
+                       radius2 = radius1\r
+               end\r
                length = tonumber(length)\r
                if axis == "?" then\r
                        axis, sign = worldedit.player_axis(name)\r
                        length = length * sign\r
                end\r
                local node = get_node(name, nodename)\r
-               local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius), node)\r
+               local count = worldedit.cylinder(worldedit.pos1[name], axis, length, tonumber(radius1), tonumber(radius2), node)\r
                worldedit.player_notify(name, count .. " nodes added")\r
        end, check_cylinder),\r
 })\r