Creates a new VoxelOccupancy from the two files splat-transform writes, which load as a json asset and a binary asset.
The contents of the .voxel.json file.
The contents of the .voxel.bin file.
Gets the bounds of the grid of voxels. Do not modify it.
Gets the number of voxels of the grid along each axis. Do not modify it.
Gets the size of a voxel, in world units.
Frees the texture of the voxels.
Gets the texture of the voxels, for shaders to query them. It is a volume texture of the
format PIXELFORMAT_RG32U, with a texel for each block of 4x4x4 voxels, the size of
gridSize divided by 4. The red channel of a texel holds the low 32 bits and the green
channel the high 32 bits of the mask of its block, see readBlock. It is sampled with
nearest filtering, and would usually be read with textureLoad in WGSL and texelFetch in
GLSL. A shader finds the voxel at a position like this:
let voxel = vec3i(floor((position - gridMin) / voxelSize));
let masks = textureLoad(voxels, voxel >> vec3u(2u), 0).rg;
let bit = u32((voxel.x & 3) | ((voxel.y & 3) << 2) | ((voxel.z & 3) << 4));
let solid = ((select(masks.x, masks.y, bit >= 32u) >> (bit & 31u)) & 1u) != 0u;
ivec3 voxel = ivec3(floor((position - gridMin) / voxelSize));
uvec2 masks = texelFetch(voxels, voxel >> 2, 0).rg;
int bit = (voxel.x & 3) | ((voxel.y & 3) << 2) | ((voxel.z & 3) << 4);
bool solid = (((bit < 32 ? masks.x : masks.y) >> (bit & 31)) & 1u) != 0u;
The voxels outside of the grid are empty, which the shader tests for separately.
The texture is created on the first call, and is owned by the VoxelOccupancy, which destroys it in destroy. It holds no copy of the voxels in CPU memory, as the voxels are written to it again from the octree when the graphics device is restored after it was lost.
The graphics device.
The texture.
Tests whether a position is inside a solid voxel.
The position, in the space of the voxels.
True if the voxel at the position is solid.
Tests whether the voxel at the given voxel coordinates is solid, for the queries working on the grid, such as stepping between neighboring voxels. See isSolid for positions.
The x coordinate of the voxel.
The y coordinate of the voxel.
The z coordinate of the voxel.
True if the voxel is solid, false if it is empty or outside the grid.
Finds the first solid voxel along a ray. A ray starting inside a solid voxel hits it at its origin.
The ray, in the space of the voxels. Its direction must be normalized.
OptionalmaxDistance: number = Infinity
The distance along the ray to search to. Defaults to Infinity.
Optionalpoint: Vec3
Receives the position where the ray enters the solid voxel.
Optionalnormal: Vec3
Receives the normal of the face of the voxel the ray enters through, or the reversed direction of the ray when it starts inside the voxel.
True if the ray hits a solid voxel.
Reads the masks of a block of 4x4x4 voxels. The voxel at (x, y, z) within the block is bit
x + y * 4 + z * 16 of the 64 bit mask, of which out[0] holds the low 32 bits and
out[1] the high 32 bits. A block outside the grid is empty.
The x coordinate of the block, the x coordinate of its voxels divided by 4.
The y coordinate of the block.
The z coordinate of the block.
Receives the two masks.
The out array.
The solid voxels of a scene, which splat-transform generates from a gaussian splat in its voxel format: a grid of voxels, each of them either solid or empty, written as a
.voxel.jsonfile and a.voxel.binfile. A VoxelOccupancy answers queries on the CPU, such as whether a position is inside a solid voxel, or where a ray hits the first one, for collision logic such as character controllers to be built on. It also provides the voxels as a texture, for shaders to query them on the GPU.The voxels are kept in the sparse octree they are stored in, which takes a fraction of the memory of the full grid. The queries take positions in the space of the voxel data, which is the space of the gaussian splat they were generated from, rotated by 180 degrees around the Z axis. That is the usual rotation of a splat entity, so a splat entity rotated by it, and not otherwise transformed, lines up with the voxels.
The voxels outside of the grid are empty.