From a376c13f2a6f38930a77cb667bd1de8e40a5f4cb Mon Sep 17 00:00:00 2001 From: Dmitry Kostenko Date: Wed, 27 Jan 2021 00:47:31 +0100 Subject: [PATCH] Add brushes * Select brush in configuration (left click) * Cube and Sphere * Adjusted spheres * Prepare for non-uniform sizes --- init.lua | 80 ++++++++++++++++++++-------- textures/terraform_brush_cube.png | Bin 0 -> 332 bytes textures/terraform_brush_sphere.png | Bin 0 -> 542 bytes textures/terraform_selection.png | Bin 0 -> 204 bytes 4 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 textures/terraform_brush_cube.png create mode 100644 textures/terraform_brush_sphere.png create mode 100644 textures/terraform_selection.png diff --git a/init.lua b/init.lua index 2ac1296..da705e9 100644 --- a/init.lua +++ b/init.lua @@ -104,20 +104,26 @@ terraform:register_tool("sculptor", { short_description = "Sculptor", inventory_image = "terraform_tool_brush.png", render_config = function(self, player, settings) - return + local function selection(texture, selected) + if selected then return texture.."^terraform_selection.png" end + return texture + end + + spec = "formspec_version[3]".. "size[13,9]".. "position[0.1,0.15]".. "anchor[0,0]".. "no_prepend[]".. + "container[0,0]".. -- shape - "label[0,0; Shape]".. - "checkbox[0,1;sphere;( );false]".. - "checkbox[2,1;cube;[ ];false]".. - "checkbox[0,2;hollow;Hollow;false]".. + "label[0.2,0.5; Shape:]".. + "image_button[0,1;1,1;"..selection("terraform_brush_sphere.png",settings:get_string("brush") == "sphere")..";brush_sphere;]".. + "image_button[1,1;1,1;"..selection("terraform_brush_cube.png", settings:get_string("brush") == "cube")..";brush_cube;]".. "container_end[]".. + "container[0,3]".. -- size - "field[3,0;2,1;size;Size;3]".. + "field[3,0;2,1;size;Size;"..(settings:get_int("size") or 3).."]".. "container_end[]".. "container[4,0]".. -- creative "label[0,0; All items]".. @@ -132,14 +138,24 @@ terraform:register_tool("sculptor", { "label[0,0; Mask]".. "list[current_player;main;0,1;10,1]".. "container_end[]" + return spec end, config_input = function(self, player, fields, settings) - if fields.radius ~= nil then - minetest.chat_send_all("input: "..fields.radius) - local event = minetest.explode_scrollbar_event(fields.radius) - settings:set_int("radius", math.floor(event.value * 30 / 1000)) - return true + minetest.chat_send_all("fields: "..dump(fields)) + local refresh = false + if fields.size ~= nil then + minetest.chat_send_all("input: "..fields.size) + settings:set_int("size", tonumber(fields.size)) end + if fields.brush_sphere ~= nil then + settings:set_string("brush", "sphere") + refresh = true + end + if fields.brush_cube ~= nil then + settings:set_string("brush", "cube") + refresh = true + end + return refresh end, execute = function(self, player, target, settings) local target_pos = minetest.get_pointed_thing_position(target) @@ -147,9 +163,10 @@ terraform:register_tool("sculptor", { return end - local radius = settings:get_int("radius") or 3 - local minp = { x = target_pos.x - radius, y = target_pos.y - radius, z = target_pos.z - radius } - local maxp = { x = target_pos.x + radius, y = target_pos.y + radius, z = target_pos.z + radius } + local size = settings:get_int("size") or 3 + local size_3d = { x = size, y = size, z = size } + local minp = { x = target_pos.x - size_3d.x, y = target_pos.y - size_3d.y, z = target_pos.z - size_3d.z } + local maxp = { x = target_pos.x + size_3d.x, y = target_pos.y + size_3d.y, z = target_pos.z + size_3d.z } local v = minetest.get_voxel_manip() local minv, maxv = v:read_from_map(minp, maxp) local a = VoxelArea:new({MinEdge = minv, MaxEdge = maxv }) @@ -159,16 +176,33 @@ terraform:register_tool("sculptor", { air = minetest.CONTENT_AIR, solid = data[a:index(target_pos.x, target_pos.y, target_pos.z)] } - local sqr = radius * radius - for i in a:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z) do - local ip = a:position(i) - local delta = { x = ip.x - target_pos.x, y = ip.y - target_pos.y, z = ip.z - target_pos.z } - delta.x = delta.x * delta.x delta.y = delta.y * delta.y delta.z = delta.z * delta.z - if sqr > delta.x + delta.y + delta.z and data[i] == cid.air then - data[i] = cid.solid - end - end + local brushes = { + cube = function() + for i in a:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z) do + data[i] = cid.solid + end + end, + sphere = function() + for i in a:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z) do + local ip = a:position(i) + local epsilon = 0.3 + local delta = { x = ip.x - target_pos.x, y = ip.y - target_pos.y, z = ip.z - target_pos.z } + delta = { x = delta.x / (size_3d.x + epsilon), y = delta.y / (size_3d.y + epsilon), z = delta.z / (size_3d.z + epsilon) } + delta = { x = delta.x^2, y = delta.y^2, z = delta.z^2 } + + if 1 > delta.x + delta.y + delta.z and data[i] == cid.air then + data[i] = cid.solid + end + end + end, + } + + local brush = settings:get_string("brush") or "sphere" + if not brushes[brush] then brush = "sphere" end + + brushes[brush]() + v:set_data(data) v:write_to_map() end diff --git a/textures/terraform_brush_cube.png b/textures/terraform_brush_cube.png new file mode 100644 index 0000000000000000000000000000000000000000..65aec08c068fb19328fd44ffd571c7b23d30f3be GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP#qm&rGY{?oyKA@0nW=KSdbAE1aYF-JD%fR4Vl$uzQ znxasiS(2gP?&%wlqL<1J6yM`M@hj-!|7Q+udDJpwe zm$}^B``*5dao0Lw2fOp1qxOg#)y!DSnlMX^p{QZ4it49>sz1L82`@dc;()mAF~R3| z61^qupYgL?UuAT^!T0ivgem#CyQNnxFFvTQmrx>Jb202eb9P_Y)^)Ehm)0@Xhitcy S>&jdS@|35mpUXO@geCy+h<0iK literal 0 HcmV?d00001 diff --git a/textures/terraform_brush_sphere.png b/textures/terraform_brush_sphere.png new file mode 100644 index 0000000000000000000000000000000000000000..ca56bc3f3b0da20a7a7ae535398374588e410cd7 GIT binary patch literal 542 zcmV+(0^$9MP)03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00DwYL_t(I%bk-!ZsIT$ zhCkv;6sdN$h-F90rt}8f0CRvMj?!7p90kz>;3IH?&MsnYWmROmQj$fWi@{My5hKmN zvi$u1_x!*A4Nj*MU1+TzfCaDuX6Nf2um-lqn9uI}L6<;l{UU_eD5X$JF&qx5>l*Jp z-g}y+0azMi-o6oNt$#@=Uw=G4lBQ{!?3|;lDgdmtgb)CJ8)JU91X}ACDdlGR^hBDb z^x>T2<8bJcER8X5gZX^^AcP3d(<$TenBo0BS(X8i=Q;JcdQlW@C;RDHV^41XxAEZlN3R5Udhl76prKhY$!Mkmq@u6yrUz*jsc)hgTe~DWM4fnUpuh literal 0 HcmV?d00001