Engine API Reference - v2.24.0-beta.29
    Preparing search index...

    Class VoxelOccupancy

    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.json file and a .voxel.bin file. 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.

    Index
    • 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.

      Parameters

      Returns Texture

      The texture.

    • Tests whether a position is inside a solid voxel.

      Parameters

      • position: Vec3

        The position, in the space of the voxels.

      Returns boolean

      True if the voxel at the position is solid.

      if (voxels.isSolid(position)) {
      position.copy(previousPosition);
      }
    • 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.

      Parameters

      • ix: number

        The x coordinate of the voxel.

      • iy: number

        The y coordinate of the voxel.

      • iz: number

        The z coordinate of the voxel.

      Returns boolean

      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.

      Parameters

      • ray: Ray

        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.

      Returns boolean

      True if the ray hits a solid voxel.

      camera.camera.screenToWorld(x, y, camera.camera.nearClip, ray.origin);
      camera.camera.screenToWorld(x, y, camera.camera.farClip, ray.direction);
      ray.direction.sub(ray.origin).normalize();
      if (voxels.raycast(ray, 100, hitPoint, hitNormal)) {
      marker.setPosition(hitPoint);
      }
    • 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.

      Parameters

      • bx: number

        The x coordinate of the block, the x coordinate of its voxels divided by 4.

      • by: number

        The y coordinate of the block.

      • bz: number

        The z coordinate of the block.

      • out: number[] | Uint32Array<ArrayBufferLike>

        Receives the two masks.

      Returns number[] | Uint32Array<ArrayBufferLike>

      The out array.