Optimisation of liquid level check code

This commit is contained in:
WillConker 2024-06-09 13:26:48 +01:00
parent 4d591cf3fb
commit 4548ee4000
2 changed files with 45 additions and 41 deletions

View File

@ -188,21 +188,30 @@ end
-- Based on https://github.com/minetest/minetest/blob/master/src/client/content_mapblock.cpp#L536-L813 -- Based on https://github.com/minetest/minetest/blob/master/src/client/content_mapblock.cpp#L536-L813
local function get_liquid_corner_heights(pos) local function get_liquid_corner_heights(pos)
local stime = minetest.get_us_time() -- debug
local cur_liquid = {} local cur_liquid = {}
local node = get_node(pos) local node = get_node(pos)
local ndef = registered_nodes[node.name] local ndef = registered_nodes[node.name]
if not (get_item_group(node.name, "liquid") > 0) then return end if not (get_item_group(node.name, "liquid") > 0) then return end
local node_above = get_node({x=pos.x, y=pos.y+1, z=pos.z}) local node_above = get_node({x=pos.x, y=pos.y+1, z=pos.z})
local node_below = get_node({x=pos.x, y=pos.y+1, z=pos.z})
minetest.debug("glch1", minetest.get_us_time() - stime)
stime = minetest.get_us_time()
-- BEGIN prepareLiquidNodeDrawing -- BEGIN prepareLiquidNodeDrawing
cur_liquid.content = node.name cur_liquid.content = node.name
local c_flowing = ndef.liquid_alternative_flowing local c_flowing = ndef.liquid_alternative_flowing
local c_source = ndef.liquid_alternative_source local c_source = ndef.liquid_alternative_source
cur_liquid.top_is_same_liquid = (node_above.name == c_flowing or node_above.name == c_source) cur_liquid.top_is_same_liquid = (node_above.name == c_flowing or node_above.name == c_source)
-- cur_liquid.draw_bottom and lighting skipped -- quick return if the liquid above is the same
if cur_liquid.top_is_same_liquid then return {0.5, 0.5, 0.5, 0.5} end
-- END prepareLiquidNodeDrawing -- END prepareLiquidNodeDrawing
minetest.debug("glch2", minetest.get_us_time() - stime)
stime = minetest.get_us_time()
local c_flowing_ndef = registered_nodes[c_flowing] local c_flowing_ndef = registered_nodes[c_flowing]
@ -219,8 +228,6 @@ local function get_liquid_corner_heights(pos)
local neighbor_node = get_node({x=pos.x + u, y=pos.y, z=pos.z + w}) local neighbor_node = get_node({x=pos.x + u, y=pos.y, z=pos.z + w})
neighbor.content = neighbor_node.name neighbor.content = neighbor_node.name
neighbor.level = -0.5 neighbor.level = -0.5
neighbor.is_same_liquid = false
neighbor.top_is_same_liquid = false
if neighbor.content == c_source then if neighbor.content == c_source then
neighbor.is_same_liquid = true neighbor.is_same_liquid = true
@ -241,57 +248,46 @@ local function get_liquid_corner_heights(pos)
end end
--END getLiquidNeighborhood --END getLiquidNeighborhood
cur_liquid.corner_levels = {{}, {}}
--BEGIN calculateCornerLevels
for z=1,2 do
for x=1,2 do
cur_liquid.corner_levels[z][x] = get_corner_level(x, z, c_flowing, c_source, neighbors)
end
end
--END calculateCornerLevels
--BEGIN drawLiquidTop minetest.debug("glch3", minetest.get_us_time() - stime)
local corner_resolve = {{0, 1}, {1, 1}, {1, 0}, {0, 0}} stime = minetest.get_us_time()
--BEGIN drawLiquidTop calculateCornerLevels
local vertices = { local vertices = {
{x=-0.5, y=0, z= 0.5}, get_corner_level(1, 2, c_flowing, c_source, neighbors),
{x= 0.5, y=0, z= 0.5}, get_corner_level(2, 2, c_flowing, c_source, neighbors),
{x= 0.5, y=0, z=-0.5}, get_corner_level(2, 1, c_flowing, c_source, neighbors),
{x=-0.5, y=0, z=-0.5}, get_corner_level(1, 1, c_flowing, c_source, neighbors),
} }
for i=1,4 do
local u = corner_resolve[i][1]
local w = corner_resolve[i][2]
if cur_liquid.top_is_same_liquid then
vertices[i].y = 0.5
else
vertices[i].y = vertices[i].y + cur_liquid.corner_levels[w+1][u+1]
end
end
--first 3 vertices are connected, so are last 2 and first --first 3 vertices are connected, so are last 2 and first
--END drawLiquidTop minetest.debug("glch4", minetest.get_us_time() - stime)
stime = minetest.get_us_time()
--END drawLiquidTop calculateCornerLevels
return vertices return vertices
end end
local function get_liquid_height(pos_origin, pos_offset) local function get_liquid_height(pos_origin, pos_offset)
local stime = minetest.get_us_time() -- debug
local corner_heights = get_liquid_corner_heights(pos_origin) local corner_heights = get_liquid_corner_heights(pos_origin)
minetest.debug("glh1", minetest.get_us_time() - stime)
stime = minetest.get_us_time()
if corner_heights == nil then return end if corner_heights == nil then return end
-- order: -+ ++ +- -- -- order: -+ ++ +- --
if pos_offset.x + pos_offset.z > 0 then if pos_offset.x + pos_offset.z > 0 then
-- first triangle -- first triangle
pos_offset = {x=0.5, y=0, z=0.5} - pos_offset pos_offset = {x=0.5, y=0, z=0.5} - pos_offset
local height_centre = corner_heights[2].y local height_centre = corner_heights[2]
local height_x = corner_heights[1].y local height_x = corner_heights[1]
local height_z = corner_heights[3].y local height_z = corner_heights[3]
local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z
return height + pos_origin.y return height + pos_origin.y
else else
-- second triangle -- second triangle
pos_offset = {x=0.5, y=0, z=0.5} + pos_offset pos_offset = {x=0.5, y=0, z=0.5} + pos_offset
local height_centre = corner_heights[4].y local height_centre = corner_heights[4]
local height_x = corner_heights[3].y local height_x = corner_heights[3]
local height_z = corner_heights[1].y local height_z = corner_heights[1]
local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z
return height + pos_origin.y return height + pos_origin.y
end end

View File

@ -44,6 +44,10 @@ end
local time = 0 local time = 0
local function get_head_submerged_node(head_pos)
return flowlib.liquid_at_exact(head_pos)
end
local function get_player_nodes(player) local function get_player_nodes(player)
local player_pos = player:get_pos() local player_pos = player:get_pos()
local collisionbox = player:get_properties().collisionbox local collisionbox = player:get_properties().collisionbox
@ -62,25 +66,29 @@ local function get_player_nodes(player)
part_pos = get_playerpart_pos("head", player_pos, collisionbox, eye_height) part_pos = get_playerpart_pos("head", player_pos, collisionbox, eye_height)
infotable.node_head = node_ok(part_pos).name infotable.node_head = node_ok(part_pos).name
minetest.debug("player " .. player:get_player_name() .. " has head submerged in:", flowlib.liquid_at_exact(part_pos)) infotable.head_submerged_in = get_head_submerged_node(part_pos)
infotable.head_submerged_in = flowlib.liquid_at_exact(part_pos) minetest.debug("player " .. player:get_player_name() .. " has head submerged in:", infotable.head_submerged_in)
local lch = flowlib.get_liquid_corner_heights(part_pos) local lch = flowlib.get_liquid_corner_heights(part_pos)
local lh = flowlib.get_liquid_height(vector.round(part_pos), part_pos - vector.round(part_pos)) local lh = flowlib.get_liquid_height(vector.round(part_pos), part_pos - vector.round(part_pos))
if lch then if lch then
minetest.debug("current liquid corner heights: ", "-+", lch[1].y , "++", lch[2].y , "+-", lch[3].y , "--", lch[4].y) --minetest.debug("current liquid corner heights: ", "-+", lch[1].y , "++", lch[2].y , "+-", lch[3].y , "--", lch[4].y)
end end
for i,v in ipairs(minetest.get_objects_inside_radius(player_pos, 5)) do for i,v in ipairs(minetest.get_objects_inside_radius(player_pos, 5)) do
if (v:get_luaentity() or {}).name == "mcl_playerinfo:debug_marker" then if (v:get_luaentity() or {}).name == "mcl_playerinfo:debug_marker" then
v:remove() v:remove()
end end
end end
if lch then
minetest.add_entity(vector.add(vector.round(part_pos), {x=-0.5, y=lch[1], z= 0.5}), "mcl_playerinfo:debug_marker")
minetest.add_entity(vector.add(vector.round(part_pos), {x= 0.5, y=lch[2], z= 0.5}), "mcl_playerinfo:debug_marker")
minetest.add_entity(vector.add(vector.round(part_pos), {x= 0.5, y=lch[3], z=-0.5}), "mcl_playerinfo:debug_marker")
minetest.add_entity(vector.add(vector.round(part_pos), {x=-0.5, y=lch[4], z=-0.5}), "mcl_playerinfo:debug_marker")
end
for i=1,4 do for i=1,4 do
if lch then
minetest.add_entity(vector.add(vector.round(part_pos), vector.divide(lch[i], 1)), "mcl_playerinfo:debug_marker")
end
if lh then if lh then
minetest.add_entity({x=part_pos.x, y=lh, z=part_pos.z}, "mcl_playerinfo:debug_marker") minetest.add_entity({x=part_pos.x, y=lh, z=part_pos.z}, "mcl_playerinfo:debug_marker")
end end