collision on voxel world is very simple.
First you have to calculate the player position and size divide by the block size
Example: player.position.x + player.size / block.size
Then if you're using any sort of grid then check that position/grid if it has a solid block type in it.
Here is the sample code from my voxel game:
void Camera::collision(float dx, float dy, float dz)
{
/* AABB collision checker */
float x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, y5;
x1 = floor((m_position.x - m_width) / m_block.getBlockSize());
y1 = floor((m_position.y - m_bottom) / m_block.getBlockSize());
z1 = floor((m_position.z - m_width) / m_block.getBlockSize());
x2 = floor((m_position.x + m_width) / m_block.getBlockSize());
y2 = floor((m_position.y + (m_top+2)) / m_block.getBlockSize());
z2 = floor((m_position.z + m_depth) / m_block.getBlockSize());
// stuck? go up
if(floor(m_position.y / m_block.getBlockSize()) < m_worldSize.y) {
while(Types::getSolidBlocks( m_map.getInPosition(floor(m_position.x / m_block.getBlockSize()), floor(m_position.y / m_block.getBlockSize()), floor(m_position.z / m_block.getBlockSize())) )) {
m_position.y += m_block.getBlockSize();
y1 = floor((m_position.y - m_bottom) / m_block.getBlockSize());
y2 = floor((m_position.y + (m_top+2)) / m_block.getBlockSize());
if(floor(m_position.y / m_block.getBlockSize()) > m_worldSize.y) break;
}
}
// vertical collision
if(Types::getSolidBlocks(m_map.getInPosition(x1, y1, z1)) || Types::getSolidBlocks(m_map.getInPosition(x2, y1, z1)) ||
Types::getSolidBlocks(m_map.getInPosition(x2, y1, z2)) || Types::getSolidBlocks(m_map.getInPosition(x1, y1, z2))) {
if(dy < 0) {
m_position.y = y1 * m_block.getBlockSize() + m_block.getBlockSize() + m_bottom;
m_direction.y = 0;
m_onGround = true;
}
m_collision[1] = true;
}
if(Types::getSolidBlocks(m_map.getInPosition(x1, y2, z1)) || Types::getSolidBlocks(m_map.getInPosition(x2, y2, z1)) ||
Types::getSolidBlocks(m_map.getInPosition(x2, y2, z2)) || Types::getSolidBlocks(m_map.getInPosition(x1, y2, z2))) {
if(dy > 0) {
m_position.y = y2 * m_block.getBlockSize() - (m_top+2) - .01;
m_direction.y = 0;
}
m_collision[1] = true;
}
// horizontal collision
x3 = floor((m_position.x - dx - m_width) / m_block.getBlockSize());
y3 = floor((m_position.y - dy - m_bottom) / m_block.getBlockSize());
z3 = floor((m_position.z - dz - m_width) / m_block.getBlockSize());
x4 = floor((m_position.x - dx + m_width) / m_block.getBlockSize());
y4 = floor((m_position.y - dy + (m_top+2)) / m_block.getBlockSize());
z4 = floor((m_position.z - dz + m_depth) / m_block.getBlockSize());
y5 = round(y3+(y4-y3)/2); // previous y position
if(Types::getSolidBlocks(m_map.getInPosition(x1, y3, z3)) || Types::getSolidBlocks(m_map.getInPosition(x1, y3, z4)) ||
Types::getSolidBlocks(m_map.getInPosition(x1, y4, z4)) || Types::getSolidBlocks(m_map.getInPosition(x1, y4, z3)) ||
Types::getSolidBlocks(m_map.getInPosition(x1, y5, z3)) || Types::getSolidBlocks(m_map.getInPosition(x1, y5, z4))) {
if(dx < 0) {
m_position.x = (x3-1) * m_block.getBlockSize() + m_block.getBlockSize() + m_width;
m_direction.x = 0;
}
m_collision[0] = true;
}
if(Types::getSolidBlocks(m_map.getInPosition(x2, y3, z3)) || Types::getSolidBlocks(m_map.getInPosition(x2, y3, z4)) ||
Types::getSolidBlocks(m_map.getInPosition(x2, y4, z4)) || Types::getSolidBlocks(m_map.getInPosition(x2, y4, z3)) ||
Types::getSolidBlocks(m_map.getInPosition(x2, y5, z3)) || Types::getSolidBlocks(m_map.getInPosition(x2, y5, z4))) {
if(dx > 0) {
m_position.x = (x4+1) * m_block.getBlockSize() - m_width - .01;
m_direction.x = 0;
}
m_collision[0] = true;
}
if(Types::getSolidBlocks(m_map.getInPosition(x3, y3, z1)) || Types::getSolidBlocks(m_map.getInPosition(x4, y3, z1)) ||
Types::getSolidBlocks(m_map.getInPosition(x4, y4, z1)) || Types::getSolidBlocks(m_map.getInPosition(x3, y4, z1)) ||
Types::getSolidBlocks(m_map.getInPosition(x3, y5, z1)) || Types::getSolidBlocks(m_map.getInPosition(x4, y5, z1))) {
if(dz < 0) {
m_position.z = (z3-1) * m_block.getBlockSize() + m_block.getBlockSize() + m_depth;
m_direction.z = 0;
}
m_collision[2] = true;
}
if(Types::getSolidBlocks(m_map.getInPosition(x3, y3, z2)) || Types::getSolidBlocks(m_map.getInPosition(x4, y3, z2)) ||
Types::getSolidBlocks(m_map.getInPosition(x4, y4, z2)) || Types::getSolidBlocks(m_map.getInPosition(x3, y4, z2)) ||
Types::getSolidBlocks(m_map.getInPosition(x3, y5, z2)) || Types::getSolidBlocks(m_map.getInPosition(x4, y5, z2))) {
if(dz > 0) {
m_position.z = (z4+1) * m_block.getBlockSize() - m_depth - .01;
m_direction.z = 0;
}
m_collision[2] = true;
}
}
Btw. The m_map is a grid that checks the block type in the world
and dx, dy, dz are the direction of the player
and here's how to use the collider:
// player movement
m_position.x += m_direction.x * dt;
collision(m_direction.x, 0, 0); // collision detector
m_position.y += m_direction.y * dt;
collision(0, m_direction.y, 0); // collision detector
m_position.z += m_direction.z * dt;
collision(0, 0, m_direction.z); // collision detector