mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 09:03:01 +00:00
terrain.lua: add wea.calculate_slope()
This commit is contained in:
parent
a9b746986a
commit
1833e68ec5
1 changed files with 32 additions and 7 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
local wea = worldeditadditions
|
||||||
|
|
||||||
--- Given a manip object and associates, generates a 2D x/z heightmap.
|
--- Given a manip object and associates, generates a 2D x/z heightmap.
|
||||||
-- Note that pos1 and pos2 should have already been pushed through
|
-- Note that pos1 and pos2 should have already been pushed through
|
||||||
|
@ -20,7 +21,7 @@ function worldeditadditions.make_heightmap(pos1, pos2, manip, area, data)
|
||||||
-- Scan each column top to bottom
|
-- Scan each column top to bottom
|
||||||
for y = pos2.y+1, pos1.y, -1 do
|
for y = pos2.y+1, pos1.y, -1 do
|
||||||
local i = area:index(x, y, z)
|
local i = area:index(x, y, z)
|
||||||
if not (worldeditadditions.is_airlike(data[i]) or worldeditadditions.is_liquidlike(data[i])) then
|
if not (wea.is_airlike(data[i]) or wea.is_liquidlike(data[i])) then
|
||||||
-- It's the first non-airlike node in this column
|
-- It's the first non-airlike node in this column
|
||||||
-- Start heightmap values from 1 (i.e. there's at least 1 node in the column)
|
-- Start heightmap values from 1 (i.e. there's at least 1 node in the column)
|
||||||
heightmap[hi] = (y - pos1.y) + 1
|
heightmap[hi] = (y - pos1.y) + 1
|
||||||
|
@ -72,18 +73,42 @@ function worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
-- print("[normals] LEFT | index", z*heightmap_size.x + (x-1), "x", x, "x-1", x - 1, "left", left, "limit", 0)
|
-- print("[normals] LEFT | index", z*heightmap_size.x + (x-1), "x", x, "x-1", x - 1, "left", left, "limit", 0)
|
||||||
-- print("[normals] RIGHT | index", z*heightmap_size.x + (x+1), "x", x, "x+1", x + 1, "right", right, "limit", heightmap_size.x-1)
|
-- print("[normals] RIGHT | index", z*heightmap_size.x + (x+1), "x", x, "x+1", x + 1, "right", right, "limit", heightmap_size.x-1)
|
||||||
|
|
||||||
result[hi] = worldeditadditions.vector.normalize({
|
result[hi] = wea.vector3.new(
|
||||||
x = left - right,
|
left - right, -- x
|
||||||
y = 2, -- Z & Y are flipped
|
2, -- y - Z & Y are flipped
|
||||||
z = down - up
|
down - up -- z
|
||||||
})
|
):normalise()
|
||||||
|
|
||||||
-- print("[normals] at "..hi.." ("..x..", "..z..") normal "..worldeditadditions.vector.tostring(result[hi]))
|
-- print("[normals] at "..hi.." ("..x..", "..z..") normal "..result[hi])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Converts a 2d heightmap into slope values in radians.
|
||||||
|
-- Convert a radians to degrees by doing (radians*math.pi) / 180 for display,
|
||||||
|
-- but it is STRONGLY recommended to keep all internal calculations in radians.
|
||||||
|
-- @param heightmap table A ZERO indexed flat heightmap. See worldeditadditions.make_heightmap().
|
||||||
|
-- @param heightmap_size int[] The size of the heightmap in the form [ z, x ]
|
||||||
|
-- @return Vector[] The calculated slope map, in the same form as the input heightmap. Each element of the array is a (floating-point) number representing the slope in that cell in radians.
|
||||||
|
function worldeditadditions.calculate_slope(heightmap, heightmap_size)
|
||||||
|
local normals = worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
|
local slopes = { }
|
||||||
|
|
||||||
|
local up = wea.vector3(0, 1, 0) -- Z & Y are flipped
|
||||||
|
|
||||||
|
for z = heightmap_size.z-1, 0, -1 do
|
||||||
|
for x = heightmap_size.x-1, 0, -1 do
|
||||||
|
local hi = z*heightmap_size.x + x
|
||||||
|
|
||||||
|
-- Ref https://stackoverflow.com/a/16669463/1460422
|
||||||
|
slopes[hi] = wea.vector3.dot_product(normals[hi], up)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return slopes
|
||||||
|
end
|
||||||
|
|
||||||
--- Applies changes to a heightmap to a Voxel Manipulator data block.
|
--- Applies changes to a heightmap to a Voxel Manipulator data block.
|
||||||
-- @param pos1 vector Position 1 of the defined region
|
-- @param pos1 vector Position 1 of the defined region
|
||||||
-- @param pos2 vector Position 2 of the defined region
|
-- @param pos2 vector Position 2 of the defined region
|
||||||
|
|
Loading…
Reference in a new issue