How can i add collision detection in a voxel terrain

following the guide on three.js fundamentals on how to make a voxell terrain i made this


but you can only build and remove voxels by the orbit controls;
i’ve tryed to add a collision detection by adding the coordinates in an array, but with terrible results

for (var y = 0; y < cellSize; ++y) {
  for (var z = 0; z < cellSize; ++z) {
    for (var x = 0; x < cellSize; ++x) {
      var height = Math.round(noise.perlin2(x / freq, z / freq) * amp) < 0? 0 : Math.round(noise.perlin2(x / freq, z / freq) * amp);
      if(height <= 3) {
        world.setVoxel(x, height + 15, z, 3);
      }else {
        world.setVoxel(x, height + 15, z, 14);
      }
      world.setVoxel(x, height + 14, z, 7);
      world.setVoxel(x, height + 13, z, 7);
      world.setVoxel(x, height + 12, z, 7);
      world.setVoxel(x, height + 11, z, 7);
      world.setVoxel(x, height + 10, z, 5);
      world.setVoxel(x, height + 9, z, 5);
      world.setVoxel(x, height + 8, z, 5);
      world.setVoxel(x, height + 7, z, 5);
      world.setVoxel(x, height + 6, z, 5);
      world.setVoxel(x, height + 5, z, 5);
      world.setVoxel(x, height + 4, z, 5);
      world.setVoxel(x, height + 3, z, 5);
      world.setVoxel(x, height + 2, z, 15);
      world.setVoxel(x, height + 1, z, 15);
      world.setVoxel(x, height, z, 15);
      world.setVoxel(x, 16, z, 13);
      coordinates.push({x:x,y:height + 15,z:z})
    }
  }
}

this is the world generation code

I don’t know the Minecraft example but i guess the voxel data is stored in a 3D array, you can use this to compute a distance field to the surface, finding from your position the voxel index in the array and check the distance with the surrounding 27 voxels for example which would be quite cheap since it’s static and doesn’t need interpolation, each non-surface voxel can be skipped right away.

But to collide with the actual blocky block surface and not the smooth distance field you need to use the plain distance to the block.

Edit: i see it uses a Uint8Array so the original distance field noise isn’t involved anyway. Just check which blocks around you are solid and if, get the distance from your player to it’s surface, doing this with all 27 blocks and always take the shortest distance like before testing the next shortestDistance = Math.min( shortestDistance, distance );

how can i get the distance from the voxel

Converting the voxel position into it’s world position, i don’t know how the example exactly is implemented, but if the neighbour voxel on your voxel position X + 1 is solid for example, you use the neighbours world position, then simply subtract the voxel from the player world position. If the neighbour on X - 1 is solid you add the world size of a voxel to the position too to not go inside by 1 block on negative axes.

If the volume is defined by a positive distance field, values above zero, you’ll look for the longest distance btw.

okay, so if i understand i should check the voxels which are close to the one where the player is and if there is consider it as solid block, but the problem is the y axis becouse it’s different the y of the array form the y of the world