-
-
Save GreenXenith/76e22d52d33e2f085c5cad893b8fe556 to your computer and use it in GitHub Desktop.
sideways world?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vector.ZERO = function() return {x = 0, y = 0, z = 0} end | |
local apply_rotation = function(dir, rot) | |
local axis_x = {x = 1, y = 0, z = 0} | |
local axis_y = {x = 0, y = 1, z = 0} | |
local axis_z = {x = 0, y = 0, z = 1} | |
dir = vector.rotate_around_axis(dir, axis_z, rot.z) | |
dir = vector.rotate_around_axis(dir, axis_y, rot.y) | |
dir = vector.rotate_around_axis(dir, axis_x, rot.x) | |
return dir | |
end | |
-- Rotate pos1 and rot1 about pos2 by rot2 | |
local rotate_about = function(pos1, pos2, rot1, rot2) | |
local r = vector.add(rot1, rot2) | |
local rot = vector.dir_to_rotation(apply_rotation({x = 0, y = 0, z = 1}, r), apply_rotation({x = 0, y = 1, z = 0}, r)) | |
local pos = vector.multiply(vector.rotate(vector.direction(pos2, pos1), rot2), vector.distance(pos2, pos1)) | |
return pos, rot | |
end | |
local cache = {} | |
-- This is the callback for emerge_area in on_generated | |
local function copy_and_restore(data) | |
local vm = minetest.get_voxel_manip() | |
local va = VoxelArea:new({MinEdge = data.source_minp, MaxEdge = data.source_maxp}) | |
-- Read our emerged source | |
local vmin, vmax = vm:read_from_map(data.source_minp, data.source_maxp) | |
local vdim = vector.subtract(vmax, vmin) | |
local source = vm:get_data() | |
-- Restore the original source mapblock | |
vm:set_data(cache[data.id]) | |
vm:write_to_map(true) | |
cache[data.id] = nil | |
local source_rotated = {} | |
local va_rotated = VoxelArea:new({MinEdge = data.minp, MaxEdge = data.maxp}) | |
-- Rotate the block | |
for idx, id in pairs(source) do | |
local pos = vector.subtract(va:position(idx), vmin) | |
local center = vector.add(pos, vector.divide(vdim, 2)) | |
local rotated = rotate_about(pos, center, vector.ZERO(), {x = -math.pi / 2, y = 0, z = 0}) | |
source_rotated[va_rotated:indexp(rotated)] = id | |
end | |
-- Paste rotated to target mapblock | |
vm:read_from_map(data.minp, data.maxp) | |
vm:set_data(source_rotated) | |
vm:write_to_map(true) | |
end | |
minetest.register_on_generated(function(minp, maxp) | |
-- Rotate our "mapblock pos" about the world origin 90deg | |
local source_p1 = rotate_about(minp, vector.ZERO(), vector.ZERO(), {x = -math.pi / 2, y = 0, z = 0}) | |
local source_p2 = rotate_about(maxp, vector.ZERO(), vector.ZERO(), {x = -math.pi / 2, y = 0, z = 0}) | |
local source_minp, source_maxp = vector.sort(source_p1, source_p2) | |
-- Load the area to steal terrain | |
minetest.load_area(source_minp, source_maxp) | |
print(("loaded block at %s to replace block at %s"):format(minetest.pos_to_string(source_minp), minetest.pos_to_string(minp))) | |
-- Read and backup anything already there | |
local vm = minetest.get_voxel_manip() | |
vm:read_from_map(source_minp, source_maxp) | |
local id = #cache + 1 | |
cache[id] = vm:get_data() | |
-- Delete and re-gnerate it | |
minetest.delete_area(source_minp, source_maxp) | |
minetest.emerge_area(source_minp, source_maxp, function(_, _, remaining, data) | |
if remaining == 0 then | |
copy_and_restore(data) | |
end | |
end, {id = id, minp = minp, maxp = maxp, source_minp = source_minp, source_maxp = source_maxp}) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment