Add brushes

* Select brush in configuration (left click)
* Cube and Sphere
* Adjusted spheres
* Prepare for non-uniform sizes
master
Dmitry Kostenko 2021-01-27 00:47:31 +01:00
parent 4b74515632
commit a376c13f2a
4 changed files with 57 additions and 23 deletions

View File

@ -104,20 +104,26 @@ terraform:register_tool("sculptor", {
short_description = "Sculptor", short_description = "Sculptor",
inventory_image = "terraform_tool_brush.png", inventory_image = "terraform_tool_brush.png",
render_config = function(self, player, settings) 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]".. "formspec_version[3]"..
"size[13,9]".. "size[13,9]"..
"position[0.1,0.15]".. "position[0.1,0.15]"..
"anchor[0,0]".. "anchor[0,0]"..
"no_prepend[]".. "no_prepend[]"..
"container[0,0]".. -- shape "container[0,0]".. -- shape
"label[0,0; Shape]".. "label[0.2,0.5; Shape:]"..
"checkbox[0,1;sphere;( );false]".. "image_button[0,1;1,1;"..selection("terraform_brush_sphere.png",settings:get_string("brush") == "sphere")..";brush_sphere;]"..
"checkbox[2,1;cube;[ ];false]".. "image_button[1,1;1,1;"..selection("terraform_brush_cube.png", settings:get_string("brush") == "cube")..";brush_cube;]"..
"checkbox[0,2;hollow;Hollow;false]"..
"container_end[]".. "container_end[]"..
"container[0,3]".. -- size "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_end[]"..
"container[4,0]".. -- creative "container[4,0]".. -- creative
"label[0,0; All items]".. "label[0,0; All items]"..
@ -132,14 +138,24 @@ terraform:register_tool("sculptor", {
"label[0,0; Mask]".. "label[0,0; Mask]"..
"list[current_player;main;0,1;10,1]".. "list[current_player;main;0,1;10,1]"..
"container_end[]" "container_end[]"
return spec
end, end,
config_input = function(self, player, fields, settings) config_input = function(self, player, fields, settings)
if fields.radius ~= nil then minetest.chat_send_all("fields: "..dump(fields))
minetest.chat_send_all("input: "..fields.radius) local refresh = false
local event = minetest.explode_scrollbar_event(fields.radius) if fields.size ~= nil then
settings:set_int("radius", math.floor(event.value * 30 / 1000)) minetest.chat_send_all("input: "..fields.size)
return true settings:set_int("size", tonumber(fields.size))
end 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, end,
execute = function(self, player, target, settings) execute = function(self, player, target, settings)
local target_pos = minetest.get_pointed_thing_position(target) local target_pos = minetest.get_pointed_thing_position(target)
@ -147,9 +163,10 @@ terraform:register_tool("sculptor", {
return return
end end
local radius = settings:get_int("radius") or 3 local size = settings:get_int("size") or 3
local minp = { x = target_pos.x - radius, y = target_pos.y - radius, z = target_pos.z - radius } local size_3d = { x = size, y = size, z = size }
local maxp = { x = target_pos.x + radius, y = target_pos.y + radius, z = target_pos.z + radius } 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 v = minetest.get_voxel_manip()
local minv, maxv = v:read_from_map(minp, maxp) local minv, maxv = v:read_from_map(minp, maxp)
local a = VoxelArea:new({MinEdge = minv, MaxEdge = maxv }) local a = VoxelArea:new({MinEdge = minv, MaxEdge = maxv })
@ -159,16 +176,33 @@ terraform:register_tool("sculptor", {
air = minetest.CONTENT_AIR, air = minetest.CONTENT_AIR,
solid = data[a:index(target_pos.x, target_pos.y, target_pos.z)] 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 local brushes = {
data[i] = cid.solid cube = function()
end for i in a:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z) do
end 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:set_data(data)
v:write_to_map() v:write_to_map()
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B