mirror of
				https://github.com/sbrl/Minetest-WorldEditAdditions
				synced 2025-10-30 19:53:06 +01:00 
			
		
		
		
	Implement scale_up
Next up: testing!
This commit is contained in:
		
							parent
							
								
									756c1c12f2
								
							
						
					
					
						commit
						2a268d9ff8
					
				| @ -11,65 +11,68 @@ | ||||
| -- @param	direction	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. | ||||
| -- @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. | ||||
| function worldeditadditions.scale_up(pos1, pos2, scale, direction) | ||||
| 	return false, "Error: Scaling up isn't implemented yet." | ||||
| 	-- pos1, pos2 = worldedit.sort_pos(pos1, pos2) | ||||
| 	-- if scale.x > 1 or scale.y > 1 or scale.z > 1 or scale.x < -1 or scale.y < -1 or 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 | ||||
| 	-- if direction.x == 0 or direction.y == 0 or direction.z == 0 then | ||||
| 	-- 	return false, "Error: One of the components of the direction vector was 0 (direction components should either be greater than or less than 0 to indicate the direction to scale in.)" | ||||
| 	-- end | ||||
| 	--  | ||||
| 	-- local scale_down = { | ||||
| 	-- 	x = math.floor(1 / scale.x), | ||||
| 	-- 	y = math.floor(1 / scale.y), | ||||
| 	-- 	z = math.floor(1 / scale.z) | ||||
| 	-- } | ||||
| 	-- local size = vector.subtract(pos2, pos1) | ||||
| 	--  | ||||
| 	-- local data = manip:get_data() | ||||
| 	-- local data_copy = worldeditadditions.shallowcopy(data) | ||||
| 	--  | ||||
| 	-- local node_id_air = minetest.get_content_id("air") | ||||
| 	--  | ||||
| 	--  | ||||
| 	-- local count = 0 -- The number of nodes replaced | ||||
| 	--  | ||||
| 	-- -- Zero out the area we're scaling down into | ||||
| 	-- for i in area:iterp(pos1, pos2) do | ||||
| 	-- 	data_copy[i] = node_id_air | ||||
| 	-- end | ||||
| 	--  | ||||
| 	-- local changes = { replaced = 0 } | ||||
| 	-- for z = pos2.z, pos1.z, -1 do | ||||
| 	-- 	for y = pos2.y, pos1.y, -1 do | ||||
| 	-- 		for x = pos2.x, pos1.x, -1 do | ||||
| 	-- 			local posi_rel = vector.subtract({ x = x, y = y, z = z }, pos1) | ||||
| 	--  | ||||
| 	-- 			local posi_copy = worldeditadditions.shallowcopy(posi_rel) | ||||
| 	-- 			posi_copy = vector.floor(vector.divide(scale_down)) | ||||
| 	--  | ||||
| 	-- 			if direction.x < 0 then posi_copy.x = size.x - posi_copy.x end | ||||
| 	-- 			if direction.y < 0 then posi_copy.y = size.y - posi_copy.y end | ||||
| 	-- 			if direction.z < 0 then posi_copy.z = size.z - posi_copy.z end | ||||
| 	--  | ||||
| 	-- 			local posi_copy = vector.add(pos1, posi_copy) | ||||
| 	--  | ||||
| 	-- 			local i_source = area:index(x, y, z) | ||||
| 	-- 			local i_target = area:index(posi_copy.x, posi_copy.y, posi_copy.z) | ||||
| 	--  | ||||
| 	-- 			-- Technically we could save some operations here by not setting | ||||
| 	-- 			-- the target multiple times per copy, but the calculations | ||||
| 	-- 			-- above are probably a lot more taxing | ||||
| 	-- 			-- TODO Be more intelligent about deciding what node to replace with here | ||||
| 	-- 			data_copy[i_target] = data[i_source] | ||||
| 	-- 		end | ||||
| 	-- 	end | ||||
| 	-- end | ||||
| 	--  | ||||
| 	--  | ||||
| 	-- -- Save the modified nodes back to disk & return | ||||
| 	-- worldedit.manip_helpers.finish(manip, data_copy) | ||||
| 	--  | ||||
| 	-- return true, changes | ||||
| 	pos1, pos2 = worldedit.sort_pos(pos1, pos2) | ||||
| 	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 | ||||
| 	if direction.x == 0 or direction.y == 0 or direction.z == 0 then | ||||
| 		return false, "Error: One of the components of the direction vector was 0 (direction components should either be greater than or less than 0 to indicate the direction to scale in.)" | ||||
| 	end | ||||
| 	 | ||||
| 	local size = vector.subtract(pos2, pos1) | ||||
| 	 | ||||
| 	local pos1_big = vector.new(pos1) | ||||
| 	local pos2_big = vector(pos2) | ||||
| 	 | ||||
| 	if direction.x < 1 then pos1_big.x = pos1_big.x - size.x | ||||
| 	else pos2_big.x = pos2_big.x + size.x end | ||||
| 	if direction.y < 1 then pos1_big.y = pos1_big.y - size.y | ||||
| 	else pos2_big.y = pos2_big.y + size.y end | ||||
| 	if direction.z < 1 then pos1_big.z = pos1_big.z - size.z | ||||
| 	else pos2_big.z = pos2_big.z + size.z end | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	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") | ||||
| 	 | ||||
| 	local kern_volume = math.abs(scale.x) * math.abs(scale.y) * math.abs(scale.z) | ||||
| 	 | ||||
| 	local changes = { updated = 0, scale = "scale_up" } | ||||
| 	for z = pos2.z, pos1.z, -1 do | ||||
| 		for y = pos2.y, pos1.y, -1 do | ||||
| 			for x = pos2.x, pos1.x, -1 do | ||||
| 				local posi_rel = vector.subtract({ x = x, y = y, z = z }, pos1) | ||||
| 				 | ||||
| 				local kern_anchor = vector.add( | ||||
| 					pos1_big, | ||||
| 					vector.cross( | ||||
| 						vector.add(posi_rel, 1), | ||||
| 						scale | ||||
| 					) | ||||
| 				) | ||||
| 				 | ||||
| 				local source_val = data_source[area_small:index(x, y, z)] | ||||
| 				 | ||||
| 				for kz = kern_anchor.z, kern_anchor.z - scale.z, -1 do | ||||
| 					for ky = kern_anchor.y, kern_anchor.y - scale.y, -1 do | ||||
| 						for kx = kern_anchor.x, kern_anchor.x - scale.x, -1 do | ||||
| 							data_target[area_big:index(kx, ky, kz)] = source_val | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 				 | ||||
| 				changes.updated = changes.updated + kern_volume | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	 | ||||
| 	-- Save the region back to disk & return | ||||
| 	worldedit.manip_helpers.finish(manip_big, data_target) | ||||
| 	 | ||||
| 	return true, changes | ||||
| end | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user