Skip to content

Instantly share code, notes, and snippets.

@Uberi

Uberi/raycast3d.lua

Last active Feb 28, 2016
Embed
What would you like to do?
3D voxel raycasting example
raycast3D = function(pos, dir, callback)
local base = {x=math.floor(pos.x), y=math.floor(pos.y), z=math.floor(pos.z)}
local stepx, stepy, stepz = 0, 0, 0
local componentx, componenty, componentz = 0, 0, 0
local intersectx, intersecty, intersectz = 0, 0, 0
if dir.x == 0 then
intersectx = math.huge
elseif dir.x > 0 then
stepx = 1
componentx = 1 / dir.x
intersectx = ((base.x - pos.x) + 1) * componentx
else
stepx = -1
componentx = 1 / -dir.x
intersectx = (pos.x - base.x) * componentx
end
if dir.y == 0 then
intersecty = math.huge
elseif dir.y > 0 then
stepy = 1
componenty = 1 / dir.y
intersecty = ((base.y - pos.y) + 1) * componenty
else
stepy = -1
componenty = 1 / -dir.y
intersecty = (pos.y - base.y) * componenty
end
if dir.z == 0 then
intersectz = math.huge
elseif dir.z > 0 then
stepz = 1
componentz = 1 / dir.z
intersectz = ((base.z - pos.z) + 1) * componentz
else
stepz = -1
componentz = 1 / -dir.z
intersectz = (pos.z - base.z) * componentz
end
local distance = 0
local nearest = {x=base.x, y=base.y, z=base.z}
while true do
local values = {callback(base, nearest, distance)}
if #values > 0 then
return unpack(values)
end
nearest.x, nearest.y, nearest.z = base.x, base.y, base.z
if intersectx < intersecty then
if intersectx < intersectz then
base.x = base.x + stepx
distance = intersectx
intersectx = intersectx + componentx
else
base.z = base.z + stepz
distance = intersectz
intersectz = intersectz + componentz
end
elseif intersecty < intersectz then
base.y = base.y + stepy
distance = intersecty
intersecty = intersecty + componenty
else
base.z = base.z + stepz
distance = intersectz
intersectz = intersectz + componentz
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment