Skip to content

Commit

Permalink
Mount Gen: cone can be used as truncated cone. Closes #1893
Browse files Browse the repository at this point in the history
  • Loading branch information
alek13 committed Jan 6, 2025
1 parent 8dfa8d0 commit c806cde
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 30 deletions.
53 changes: 34 additions & 19 deletions mods/lord/World/mountgen/algorithms/cone.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
local math_max, math_sqrt, math_floor
= math.max, math.sqrt, math.floor
local math_min, math_max, math_floor, math_ceil, math_sqrt, math_tan, math_rad
= math.min, math.max, math.floor, math.ceil, math.sqrt, math.tan, math.rad


local MIN_CONE_FOOT_DIAMETER = 3

--- @param diameter number
--- @return number[][]
local function fill_with_zeroes(diameter)
local map = {}
for i = 1, diameter do
Expand All @@ -12,27 +16,38 @@ local function fill_with_zeroes(diameter)
return map
end

---Generate mountain as cone
---@param diameter number desired width of the mountain
---@param height number mountain height
---@return table, number, number "height map, map size, center_coordinate"
mountgen.cone = function(diameter, height)
diameter = math_max(diameter, 1)
height = math_max(height, 1)
--- Generate mountain as cone
--- @param top_pos Position
--- @param config table
--- @return table, number, number "height map, map size, center_coordinate"
mountgen.cone = function(top_pos, config)
local H = top_pos.y - config.Y0 -- height of truncated cone
local W = 2 * (config.TOP_RADIUS + math_ceil( -- width (diameter) of cone foot
H * math_tan( math_rad(90 - config.ANGLE) )
))

local diameter = math_max(W, MIN_CONE_FOOT_DIAMETER)
local radius = diameter / 2
local height = math_ceil( radius * math_tan( math_rad(config.ANGLE) ) ) -- height of full cone (not truncated)

local height_map = fill_with_zeroes(diameter)
local height_map_size = math_min(W, 2 * config.MAX_RADIUS)
local height_map_radius = math_floor(height_map_size / 2)
local height_map = fill_with_zeroes(height_map_size)

local radius = diameter / 2
local l0 = math_sqrt(radius^2 + radius^2)
local l0 = math_sqrt(radius^2 + radius^2)

for z = 0, height_map_size - 1 do
for x = 0, height_map_size - 1 do
local px = x - height_map_radius
local pz = z - height_map_radius

for z = 0, diameter - 1 do
for x = 0, diameter - 1 do
local px = x - radius
local pz = z - radius
local l = math_sqrt(px^2 + pz^2)
local h = height * (1 - 2 * l / l0)
mountgen.set_value(height_map, z, x, h)
if l <= height_map_radius then
local h = height * (1 - 2 * l / l0)
mountgen.set_value(height_map, z, x, math_min(h, H))
end
end
end
return height_map, diameter, math_floor(radius) + 1

return height_map, height_map_size, height_map_radius
end
17 changes: 9 additions & 8 deletions mods/lord/World/mountgen/mountgen.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,27 @@ mountgen.mountgen = function(top, config)
return
end

local y1 = config.Y0
local y2 = top.y
local H = y2 - y1
local W = math_ceil(2 * H * math_tan(config.ANGLE * 3.141 / 180 / 2)) + 3

local height_map, width, center
if method_name == "cone" then
height_map, width, center = mountgen.cone(W, H)

height_map, width, center = mountgen.cone(top, config)

elseif method_name == "diamond-square" then

local H = top.y - config.Y0
local W = math_ceil(2 * H * math_tan(math.rad(90 - config.ANGLE))) + 3
height_map, width, center = mountgen.diamond_square(W, H,
config.rk_thr,
config.rk_small,
config.rk_big)

else
minetest.log("error", "unknown method: " .. tostring(method_name))
return
end

local p1 = { x = top.x + 1 - center, y = y1, z = top.z + 1 - center }
local p2 = { x = top.x + width - center, y = y2 + 16, z = top.z + width - center }
local p1 = { x = top.x + 1 - center, y = config.Y0, z = top.z + 1 - center }
local p2 = { x = top.x + width - center, y = top.y + 16, z = top.z + width - center }

local chunks = mountgen.list_chunks(p1, p2)
local voxel_manip = minetest.get_voxel_manip(p1, p2)
Expand Down
11 changes: 8 additions & 3 deletions mods/lord/World/mountgen/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ local esc = minetest.formspec_escape
mountgen = {
required_priv = "server",
config = {
ANGLE = 120,
-- for cone:
TOP_RADIUS = 10,
MAX_RADIUS = 20,
-- /for cone

ANGLE = 60,
Y0 = 0,
METHOD = "diamond-square",
METHOD = "cone",
SNOW_LINE = 50,
SNOW_LINE_RAND = 4,
GRASS_PERCENT = 10,
Expand Down Expand Up @@ -91,7 +96,7 @@ local function validate_config(config)
return false
end
end
if config.ANGLE >= 180 then
if config.ANGLE < 15 or config.ANGLE > 90 then
return false
end
return true
Expand Down

0 comments on commit c806cde

Please sign in to comment.