I was playing around with volume raycast and decided to write an example. The code creates a volume area max X max X max size. It creates 4 random volume cubes (green) in that area. From the raycast origin 0,0,0 (red cube in closest corner) it scans 3 areas looking for a cube. The first area is the imaginary wall to the right. The second is to the left. The third is the ceiling. When the raycast hits a cube, it prints out its location for that area. If a cube happens to appear on the boundary between the walls or wall and ceiling it will print in both areas. When printing, it can show multiple hits. Depending on how close a cube is to the origin, it can be hit multiple times during a scan area.
If you have questions about what I’m doing, just ask. It was confusing how raycast was working when I started writing this, but it makes sense to me now.
viewer.mode=STANDARD
function setup()
assert(OrbitViewer, "Please include Cameras as a dependency")
scene=craft.scene()
craft.scene.main=scene -- elimates draw function
v=scene.camera:add(OrbitViewer,vec3(10,0,0),300,0,800)
v.rx=10
v.ry=45
scene.voxels.blocks:addAssetPack("Blocks")
scene.voxels:resize(vec3(16,1,16))
scene.voxels.coordinates=vec3(40,0,40)
max=100
-- create volume area, max x max x max
volume=scene:entity():add(craft.volume,max,max,max)
print("volume size "..max.."x"..max.."x"..max)
-- draw voxel floor max x max
scene.voxels:fill(BLOCK_NAME,"Solid",COLOR,color(228, 175, 103))
scene.voxels:box(0,0,0,max,0,max)
-- set origin value
origin=vec3(0,0,0)
-- draw 4 random volume cubes
print("4 random volume cubes =====")
for x=1,4 do
c=vec3(math.random(max-1),math.random(max-1),math.random(max-1))
volume:set(c.x,c.y,c.z,COLOR,color(0, 255, 196),BLOCK_NAME,"Solid")
print(c.x.." "..c.y.." "..c.z)
end
print("============")
-- do a raycast range on 3 areas
print("scan right wall ======")
for x=0,max do -- right wall
for y=0,max do
maxDist=math.sqrt(x^2+y^2+max^2)-1
doRaycast(origin,vec3(x,y,max),maxDist)
end
end
print("scan left wall ======")
for y=0,max do -- left wall
for z=0,max do
maxDist=math.sqrt(max^2+y^2+z^2)-1
doRaycast(origin,vec3(max,y,z),maxDist)
end
end
print("scan ceiling ======")
for x=0,max do -- ceiling
for z=0,max do
maxDist=math.sqrt(x^2+max^2+z^2)-1
doRaycast(origin,vec3(x,max,z),maxDist)
end
end
-- draw the origin box
scene.voxels:fill(BLOCK_NAME,"Solid",COLOR,color(255, 19, 0))
scene.voxels:block(origin)
end
function doRaycast(origin,dir,dist)
volume:raycast(origin,dir,dist,
function(coord, id, face)
if coord and id ~= 0 then
print(coord)
return true
end
end)
end