I’m trying to raycast through a lua table of voxels, using this algorithm http://www.cse.yorku.ca/~amana/research/grid.pdf
My solution is slightly incorrect though.
(The purple line is the theoretical line, the transparent blocks are where it traversed, as shown, it didn’t traverse all blocks inside of the line.)
function WorldController:Raycast(Origin : Vector3, Direction : Vector3)
workspace.RaycastDebug:ClearAllChildren()
local MaxDistance = Direction.Magnitude
local End = Origin+Direction
local RayPosition = Vector3.new(math.floor(Origin.X), math.floor(Origin.Y), math.floor(Origin.Z))
Direction = (End-RayPosition).Unit
local Step = Direction:Sign()
local tDelta = Vector3.new(
math.abs(1/Direction.X),
math.abs(1/Direction.Y),
math.abs(1/Direction.Z)
)
local tMax = Vector3.new(
Direction.X < 0 and ((Origin.X - RayPosition.X) * tDelta.X) or ((RayPosition.X + 1) - Origin.X) * tDelta.X,
Direction.Y < 0 and ((Origin.Y - RayPosition.Y) * tDelta.Y) or ((RayPosition.Y + 1) - Origin.Y) * tDelta.Y,
Direction.Z < 0 and ((Origin.Z - RayPosition.Z) * tDelta.Z) or ((RayPosition.Z + 1) - Origin.Z) * tDelta.Z
)
MakeLine(Origin, Origin+Direction*MaxDistance, 0.3)
print("tMax: ", tMax)
local function IsBlockPositionJustInBounds(Position)
return (
Position.X <= BlockLibrary.WorldBorder-1
and Position.X >= -BlockLibrary.WorldBorder
and Position.Y >= 0
and Position.Y <= BlockLibrary.WorldBorder-1
and Position.Z <= BlockLibrary.WorldBorder-1
and Position.Z >= -BlockLibrary.WorldBorder
)
end
local p = Instance.new("Part", workspace.RaycastDebug)
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(4, 4, 4)
p.Transparency = 0.4
p.Color = Color3.fromRGB(24, 97, 255)
p.Position = RayPosition * 4
local Distance = 0
local Block
while Distance < MaxDistance and Block == nil do
if tMax.X < tMax.Y then
if tMax.X < tMax.Z then
RayPosition+=Vector3.new(Step.X, 0, 0)
tMax+=Vector3.new(tDelta.X, 0, 0)
Distance = tMax.X
else
RayPosition+=Vector3.new(0, 0, Step.Z)
tMax+=Vector3.new(0, 0, tDelta.Z)
Distance = tMax.Z
end
else
if tMax.Y < tMax.Z then
RayPosition+=Vector3.new(0, Step.Y, 0)
tMax+=Vector3.new(0, tDelta.Y, 0)
Distance = tMax.Y
else
RayPosition+=Vector3.new(0, 0, Step.Z)
tMax+=Vector3.new(0, 0, tDelta.Z)
Distance = tMax.Z
end
end
local p = Instance.new("Part", workspace.RaycastDebug)
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(4, 4, 4)
p.Transparency = 0.4
p.Position = RayPosition * 4
Block = WorldController:GetBlock(RayPosition)
if IsBlockPositionJustInBounds(RayPosition) ~= true then
break
end
end
local Normal = Vector3.new(
Distance == tMax.X and -Step.X or 0,
Distance == tMax.Y and -Step.Y or 0,
Distance == tMax.Z and -Step.Z or 0
)
print("Normal: ", Normal)
local p = Instance.new("Part", workspace.RaycastDebug)
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(2, 2, 2)
p.Transparency = 0.1
p.Color = Color3.fromRGB(229, 255, 0)
p.Position = Origin*4+Direction*Distance * 4
return {
BlockPosition = RayPosition,
Block = Block,
Position = Origin*4+Direction*tDelta * 4,
Normal = Normal
}
end
(sorry the code is a bit of a mess, from debugging and constantly rewriting stuff.)
Does anyone know why? I suspect it might be the calculation of tMax, I’ve tried countless of different methods for calculating it.