EinsDreiDreiSieben/mods/cozylights/shared.lua

649 lines
No EOL
22 KiB
Lua

local sphere_surfaces = {[19]=nil}
local c_light1 = minetest.get_content_id("cozylights:light1")
local c_lights = { c_light1, c_light1 + 1, c_light1 + 2, c_light1 + 3, c_light1 + 4, c_light1 + 5, c_light1 + 6,
c_light1 + 7, c_light1 + 8, c_light1 + 9, c_light1 + 10, c_light1 + 11, c_light1 + 12, c_light1 + 13 }
local c_light14 = c_lights[14]
local c_light_debug1 = c_light14 + 1
local c_light_debug14 = c_light_debug1 + 13
local c_air = minetest.get_content_id("air")
local mf = math.floor
function cozylights:clear(pos,size)
local t = os.clock()
local minp,maxp,vm,data,param2data,a = cozylights:getVoxelManipData(pos,size)
local count = 0
for i in a:iterp(minp, maxp) do
local cid = data[i]
if cid >= c_light1 and cid <= c_light_debug14 then
data[i] = c_air
param2data[i] = 0
count = count + 1
end
end
minetest.chat_send_all("cleared "..count.." cozy light nodes in area around pos: "..cozylights:dump(pos).." of radius: "..size)
if count> 0 then
cozylights:setVoxelManipData(vm,data,param2data,true)
end
return (os.clock() - t)
end
function cozylights:getVoxelManipData(pos, size)
local minp = vector.subtract(pos, size)
local maxp = vector.add(pos, size)
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(vector.subtract(minp, 1), vector.add(maxp, 1))
local data = vm:get_data()
local param2data = vm:get_param2_data()
local a = VoxelArea:new{
MinEdge = emin,
MaxEdge = emax
}
return minp,maxp,vm,data,param2data,a
end
function cozylights:setVoxelManipData(vm,data,param2data,update_liquids)
vm:set_data(data)
if param2data ~= nil then
vm:set_param2_data(param2data)
end
if update_liquids == true then
vm:update_liquids()
end
vm:write_to_map()
end
--todo: 6 directions of static slices or dynamic slices if its faster somehow(it wasnt so far)
function cozylights:slice_cake(surface,radius)
local sliced = {}
for k,v in pairs(surface) do
-- full sphere except for a cone from center to max -y of 45 degrees or like pi/2 radians or something
if v.y > -radius*0.7071 then
table.insert(sliced,v)
end
end
return sliced
end
-- radius*radius = x*x + y*y + z*z
function cozylights:get_sphere_surface(radius,sliced)
if sphere_surfaces[radius] == nil then
local sphere_surface = {}
local rad_pow2_min, rad_pow2_max = radius * (radius - 1), radius * (radius + 1)
for z = -radius, radius do
for y = -radius, radius do
for x = -radius, radius do
local pow2 = x * x + y * y + z * z
if pow2 >= rad_pow2_min and pow2 <= rad_pow2_max then
-- todo: could arrange these in a more preferable for optimization order
sphere_surface[#sphere_surface+1] = {x=x,y=y,z=z}
end
end
end
end
local t = {
full = sphere_surface
}
if radius < 30 then
t.minusyslice = cozylights:slice_cake(sphere_surface,radius) --typical wielded light
sphere_surfaces[radius] = t
if sliced == true then
return t.minusyslice
end
end
return sphere_surface
else
if sliced == true and sphere_surfaces[radius].minusyslice ~= nil then
return sphere_surfaces[radius].minusyslice
end
return sphere_surfaces[radius].full
end
end
function cozylights:calc_dims(cozy_item)
local brightness_mod = 0
local reach_mod = 0
local dim_mod = 0
if cozy_item.modifiers ~= nil then
brightness_mod = cozylights.coziest_table[cozy_item.modifiers].brightness
reach_mod = cozylights.coziest_table[cozy_item.modifiers].reach_factor
dim_mod = cozylights.coziest_table[cozy_item.modifiers].dim_factor
end
local max_light = mf(cozy_item.light_source + cozylights.brightness_factor + brightness_mod)
local r = mf(max_light*max_light/10*(cozylights.reach_factor+reach_mod))
--print("initial r: "..r)
local r_max = 0
local dim_levels = {}
local dim_factor = cozylights.dim_factor + dim_mod
for i = r , 1, -1 do
local dim = math.sqrt(math.sqrt(i)) * dim_factor
local light_i = max_light + 1 - mf(dim)
if light_i < 1 then
--light_i = 1
r_max = i
else
if light_i > 14 then
light_i = 14
end
dim_levels[i] = light_i
end
end
-- we cut the r only if max_r found is lower than r, so that we keep the ability to have huge radiuses
if r_max > 0 and r_max < r then
return r_max-1,dim_levels
end
return r,dim_levels
end
local cozycids_sunlight_propagates = {}
-- ensure cozy position in memory
-- default amount of lights sources: 194
-- in default game with moreblocks mod: 5134
--cozylights:prealloc(cozycids_sunlight_propagates, 194, true)
--cozycids_sunlight_propagates = {}
minetest.after(1, function()
cozycids_sunlight_propagates = cozylights.cozycids_sunlight_propagates
cozylights:finalize(cozycids_sunlight_propagates)
print(#cozycids_sunlight_propagates)
cozylights.cozycids_sunlight_propagates = {}
local version_welcome = minetest.settings:get("version_welcome")
if version_welcome ~= cozylights.version then
minetest.settings:set("version_welcome",cozylights.version)
minetest.chat_send_all(">.< Running Cozy Lights "..cozylights.version.." alpha. Some features are still missing or might not work properly and might be fixed tomorrow or next week."..
"\n>.< To learn more about what it can do check ContentDB page: https://content.minetest.net/packages/SingleDigitIQ/cozylights/"..
"\n>.< If you experience problems, appreciate if you report them on ContentDB, Minetest forum, Github or Discord."..
"\n>.< If you need more of original ideas and blazingly fast code in open source - leave a positive review on ContentDB or/and add to favorites."..
"\n>.< To open mod settings type in chat /cozysettings or /zs, hopefully tooltips are useful."..
"\n>.< This message displays only once per new downloaded update for Cozy Lights mod."..
"\n>.< Have fun :>"
)
end
end)
-- adjusting dirfloor might help with some nodes missing. probably the only acceptable way to to eliminate node
-- misses and not sacrifice performance too much or at all
local dirfloor = 0.5
-- raycast but normal
-- todo: if radius higher than i think 15, we need to somehow grab more nodes, without it it's not entirely accurate
-- i hope a cheaply computed offset based on dir will do
-- not to forget: what i mean by that is that + 0.5 in mf has to become a variable
-- while we have the opportunity to cut the amount of same node reruns in this loop,
-- we avoid that because luajit optimization breaks with one more branch and hashtable look up
-- at least on my machine, and so it becomes slower to run and at the same time grabs more memory
-- todo: actually check for the forth time the above is real
function cozylights:lightcast(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
local dim = (dim_levels[i] - light_nerf) >= 1 and (dim_levels[i] - light_nerf) or 1
local light = c_lights[dim]
if light > cid or param2data[idx] == 0 then
data[idx] = light
param2data[idx] = dim
end
else
light_nerf = light_nerf + 1
end
else
break
end
end
end
function cozylights:lightcast_erase(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid >= c_light1 and cid <= c_light14 then
local dim = (dim_levels[i] - light_nerf) >= 0 and (dim_levels[i] - light_nerf) or 0
local light = dim > 0 and c_lights[dim] or c_air
if light < cid then
data[idx] = light
param2data[idx] = dim
end
elseif cid ~= c_air then
light_nerf = light_nerf + 1
end
else
break
end
end
end
function cozylights:lightcast_override(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
data[idx] = c_lights[dim]
param2data[idx] = dim
else
light_nerf = light_nerf + 1
end
else
break
end
end
end
function cozylights:lightcast_lighten(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] > cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2+0.5)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
else
light_nerf = light_nerf + 1
end
else
break
end
end
end
function cozylights:lightcast_darken(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid >= c_light1 and cid <= c_light14 then
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] < cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
elseif cid ~= c_air then
light_nerf = light_nerf + 1
end
else
break
end
end
end
function cozylights:lightcast_blend(pos, dir, radius,data,param2data,a,dim_levels)
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
for i = 1, radius do
local x,y,z = mf(dx*i+dirfloor)+px, mf(dy*i+dirfloor)+py, mf(dz*i+dirfloor)+pz
local idx = a:index(x,y,z)
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
local original_light = cid - c_light1 --param2data[idx]
dim = mf((dim + original_light)/2+0.5)
if dim < 1 then break end
data[idx] = c_lights[dim]
param2data[idx] = dim
else
light_nerf = light_nerf + 1
end
else
break
end
end
end
-- removes some lights that light up the opposite side of an obstacle
-- it is weird and inaccurate as of now, i can make it accurate the expensive way,
-- still looking for a cheap way
function cozylights:lightcast_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius,2 do
local x,y,z = next_x, next_y, next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
local light = c_lights[dim]
if light > cid or param2data[idx] == 0 then
data[idx] = light
param2data[idx] = dim
end
end
else
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
local light = c_lights[dim]
if light > cid or param2data[idx] == 0 then
data[idx] = light
param2data[idx] = dim
end
end
else
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
--local next_idx = a:index(next_x,next_y,next_z)
--for n = 1, 6 do
-- if cozycids_sunlight_propagates[data[next_idx+dirs[n]]] == nil then
-- braking_brak = true
-- break
-- end
--end
--next_x,next_y,next_z = mf(dx*(i+2)+dirfloor)+px, mf(dy*(i+2)+dirfloor)+py, mf(dz*(i+2)+dirfloor)+pz
--local next_adj_indxs = {
-- a:index(next_x,y,z),
-- a:index(x,y,next_z),
-- a:index(x,next_y,z),
-- a:index(next_x,next_y,z),
-- a:index(x,next_y,next_z),
--}
--for _, j in pairs(next_adj_indxs) do
-- if cozycids_sunlight_propagates[data[j]] ~= true then
-- braking_brak = true
-- break
-- end
--end
end
end
function cozylights:lightcast_erase_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius do
local x,y,z = next_x, next_y, next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid >= c_light1 and cid <= c_light14 then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) >= 0 and (dim_levels[i] - light_nerf) or 0
local light = dim > 0 and c_lights[dim] or c_air
if light < cid then
data[idx] = light
param2data[idx] = dim
end
end
else
local dim = (dim_levels[i] - light_nerf) >= 0 and (dim_levels[i] - light_nerf) or 0
local light = dim > 0 and c_lights[dim] or c_air
if light < cid then
data[idx] = light
param2data[idx] = dim
end
end
elseif cid ~= c_air then
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
end
end
function cozylights:lightcast_override_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius do
local x = next_x
local y = next_y
local z = next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil -- they are probably still allocated though
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
data[idx] = c_lights[dim]
param2data[idx] = dim
end
else
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
data[idx] = c_lights[dim]
param2data[idx] = dim
end
else
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
end
end
function cozylights:lightcast_lighten_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius do
local x = next_x
local y = next_y
local z = next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil -- they are probably still allocated though
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] > cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2+0.5)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
end
else
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] > cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2+0.5)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
end
else
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
end
end
function cozylights:lightcast_darken_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius do
local x = next_x
local y = next_y
local z = next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil -- they are probably still allocated though
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] < cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
end
else
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
if c_lights[dim] < cid then
local original_light = cid - c_light1
dim = mf((dim + original_light)/2)
data[idx] = c_lights[dim]
param2data[idx] = dim
end
end
else
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
end
end
function cozylights:lightcast_blend_fix_edges(pos, dir, radius,data,param2data,a,dim_levels,visited_pos)
local dirs = { -1*a.ystride, 1*a.ystride,-1,1,-1*a.zstride,1*a.zstride}
local px, py, pz, dx, dy, dz = pos.x, pos.y, pos.z, dir.x, dir.y, dir.z
local light_nerf = 0
local halfrad, braking_brak = radius/2, false
local next_x, next_y, next_z = mf(dx+dirfloor) + px, mf(dy+dirfloor) + py, mf(dz+dirfloor) + pz
for i = 1, radius do
local x = next_x
local y = next_y
local z = next_z
local idx = a:index(x,y,z)
for n = 1, 6 do
if cozycids_sunlight_propagates[data[idx+dirs[n]]] == nil then
braking_brak = true
break
end
end
if braking_brak == true then break end
x,y,z = nil,nil,nil -- they are probably still allocated though
local cid = data[idx]
if cozycids_sunlight_propagates[cid] == true then
-- appears that hash lookup in a loop is as bad as math
if cid == c_air or (cid >= c_light1 and cid <= c_light14) then
if i < halfrad then
if not visited_pos[idx] then
visited_pos[idx] = true
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
local original_light = cid - c_light1
dim = mf((dim + original_light)/2+0.5)
if dim < 1 then break end
data[idx] = c_lights[dim]
param2data[idx] = dim
end
else
local dim = (dim_levels[i] - light_nerf) > 0 and (dim_levels[i] - light_nerf) or 1
local original_light = cid - c_light1
dim = mf((dim + original_light)/2+0.5)
if dim < 1 then break end
data[idx] = c_lights[dim]
param2data[idx] = dim
end
else
light_nerf = light_nerf + 1
end
else
break
end
next_x,next_y,next_z = mf(dx*(i+1)+dirfloor)+px, mf(dy*(i+1)+dirfloor)+py, mf(dz*(i+1)+dirfloor)+pz
end
end