raycaster

4

1bir (1 Block Interactive Raycaster)

A 3D engine developed by demogroup Crescent for the Commodore 64, which has a kind of minimalist beauty in itself - video embedded below:

This is a simple raycaster for our beloved C64 featuring the following:

- Size of one C64 disk block (254 bytes)
- Joystick controlled (port 2)
- Simple collision detection
- 256 step rotation in 2 PI
- Open (wrapped) and closed map areas

Download links can be found at Pouet here

The raytracer I’m writing uses voxelised geometry to speed up raycasting - the scene is split up into boxes, where each box stores a list of the triangles that intersect with it. When you shoot a ray, you can walk along the voxels that the ray hits very quickly, and then you only need to check for ray-triangle intersections with the triangles contained by those voxels (rather than checking against all the triangles in the scene). This is pretty standard for most forms of raytracing.

You might want to use voxel traversal for operations other than just ‘finding the closest intersection’ - for example, you can do a fast inside/outside check by counting the number of intersections along a ray (the starting point of the ray is inside the geometry if the number of intersections is odd).

In terms of implementation, it might look like this:

using traversal_callback = std::function<bool(
        const geo::ray&, const aligned::vector<size_t>&, float)>;

void traverse(const voxel_collection& voxels,
              const ray& the_ray,
              const traversal_callback& fun);

The callback takes a ray, and a vector of primitives inside the current voxel, and returns whether or not the traversal should continue. In the callback, you can either ask to quit as soon as you find an intersection, or you can ask to keep going, storing some count of intersections. Pretty flexible.

Here’s the problem: That’s all C++14, and I need to do the traversal in OpenCL C which doesn’t even have function pointers. I’m not sure how to simulate passing in a callback, but I really don’t want to duplicate the traversal algorithm for each operation I might need it for. Macros to the rescue?