2022-09-18 23:58:33 +02:00
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
2024-01-02 17:59:51 +01:00
---
-- @module worldeditadditions
2022-09-18 23:58:33 +02:00
2021-02-08 00:39:09 +01:00
-- ███████ ██████ █████ ██ ███████ ██ ██ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ███████ ██ █████ ██ ██ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██████ ██ ██ ███████ ███████ ███████ ██████ ██
2024-01-02 17:59:51 +01:00
--- Scales the defined region up by the given scale factor in the given directions.
-- You probably want worldeditadditions.scale, which scales in both directions.
2021-02-08 00:39:09 +01:00
-- @param pos1 Vector Position 1 of the defined region,
-- @param pos2 Vector Position 2 of the defined region.
-- @param scale Vector The scale factor - as a vector - by which to scale down.
2021-02-18 01:30:24 +01:00
-- @param anchor Vector The direction to scale in - as a vector. e.g. { x = -1, y = 1, z = -1 } would mean scale in the negative x, positive y, and nevative z directions.
2021-02-08 00:39:09 +01:00
-- @return boolean, string|table Whether the operation was successful or not. If not, then an error messagea as a string is also passed. If it was, then a statistics object is returned instead.
2021-02-18 01:30:24 +01:00
function worldeditadditions . scale_up ( pos1 , pos2 , scale , anchor )
2022-09-18 23:58:33 +02:00
pos1 , pos2 = Vector3.sort ( pos1 , pos2 )
2021-02-18 00:46:03 +01:00
if ( scale.x < 1 and scale.x > - 1 ) and ( scale.y < 1 and scale.y > - 1 ) and ( scale.z < 1 and scale.z > - 1 ) then
return false , " Error: Scale factor vectors may not mix values -1 < factor < 1 and (1 < factor or factor < -1) - in other words, you can't scale both up and down at the same time (try worldeditadditions.scale, which automatically applies such scale factor vectors as 2 successive operations) "
end
2021-02-18 01:30:24 +01:00
if anchor.x == 0 or anchor.y == 0 or anchor.z == 0 then
return false , " Error: One of the components of the anchor vector was 0 (anchor components should either be greater than or less than 0 to indicate the anchor to scale in.) "
2021-02-18 00:46:03 +01:00
end
2022-09-18 23:58:33 +02:00
local size = ( pos2 - pos1 ) + 1
2021-02-18 00:46:03 +01:00
2022-09-19 19:54:53 +02:00
local pos1_big = Vector3.clone ( pos1 )
local pos2_big = Vector3.clone ( pos2 )
2021-02-18 00:46:03 +01:00
2021-02-18 02:24:53 +01:00
if anchor.x < 1 then pos1_big.x = pos1_big.x - ( size.x * ( scale.x - 1 ) )
else pos2_big.x = pos2_big.x + ( size.x * ( scale.x - 1 ) ) end
if anchor.y < 1 then pos1_big.y = pos1_big.y - ( size.y * ( scale.y - 1 ) )
else pos2_big.y = pos2_big.y + ( size.y * ( scale.y - 1 ) ) end
if anchor.z < 1 then pos1_big.z = pos1_big.z - ( size.z * ( scale.z - 1 ) )
else pos2_big.z = pos2_big.z + ( size.z * ( scale.z - 1 ) ) end
2021-02-18 00:46:03 +01:00
2022-09-18 23:58:33 +02:00
local size_big = ( pos2_big - pos1_big ) + 1
2021-02-18 00:46:03 +01:00
2022-09-18 23:58:33 +02:00
-- print("scale_up: scaling "..pos1.." to "..pos2.." (volume "..worldedit.volume(pos1, pos2).."; size "..size..") to "..pos1_big.." to "..pos2_big.." (volume "..worldedit.volume(pos1_big, pos2_big).."; size "..size_big..")")
2021-02-18 00:46:03 +01:00
local manip_small , area_small = worldedit.manip_helpers . init ( pos1 , pos2 )
local manip_big , area_big = worldedit.manip_helpers . init ( pos1_big , pos2_big )
local data_source = manip_small : get_data ( )
local data_target = manip_big : get_data ( )
local node_id_air = minetest.get_content_id ( " air " )
2021-02-18 03:18:34 +01:00
local stats = { updated = 0 , scale = scale , pos1 = pos1_big , pos2 = pos2_big }
2021-02-18 00:46:03 +01:00
for z = pos2.z , pos1.z , - 1 do
for y = pos2.y , pos1.y , - 1 do
for x = pos2.x , pos1.x , - 1 do
2022-09-18 23:58:33 +02:00
local posi_rel = Vector3.new ( x , y , z ) - pos1
2021-02-18 00:46:03 +01:00
2022-09-18 23:58:33 +02:00
local kern_anchor = Vector3.new (
pos1_big.x + ( posi_rel.x * scale.x ) + ( scale.x - 1 ) ,
pos1_big.y + ( posi_rel.y * scale.y ) + ( scale.y - 1 ) ,
pos1_big.z + ( posi_rel.z * scale.z ) + ( scale.z - 1 )
)
2021-02-18 02:24:53 +01:00
2021-02-18 03:18:34 +01:00
-- print(
2022-09-18 23:58:33 +02:00
-- "posi", Vector3.new(x, y, z)),
-- "posi_rel", posi_rel,
-- "kern_anchor", kern_anchor
2021-02-18 03:18:34 +01:00
-- )
2021-02-18 00:46:03 +01:00
local source_val = data_source [ area_small : index ( x , y , z ) ]
2021-02-18 02:24:53 +01:00
for kz = kern_anchor.z , kern_anchor.z - scale.z + 1 , - 1 do
for ky = kern_anchor.y , kern_anchor.y - scale.y + 1 , - 1 do
for kx = kern_anchor.x , kern_anchor.x - scale.x + 1 , - 1 do
2021-02-18 00:46:03 +01:00
data_target [ area_big : index ( kx , ky , kz ) ] = source_val
2021-02-18 03:18:34 +01:00
stats.updated = stats.updated + 1
2021-02-18 00:46:03 +01:00
end
end
end
end
end
end
-- Save the region back to disk & return
worldedit.manip_helpers . finish ( manip_big , data_target )
2021-02-18 03:18:34 +01:00
return true , stats
2021-02-08 00:39:09 +01:00
end