Home Game Development tilemap – Voxel terrain vs AABB collision detection

tilemap – Voxel terrain vs AABB collision detection

0
tilemap – Voxel terrain vs AABB collision detection

[ad_1]

collision on voxel world could be very easy.
First it’s important to calculate the participant place and dimension divide by the block dimension
Instance: participant.place.x + participant.dimension / block.dimension
Then in the event you’re utilizing any type of grid then examine that place/grid if it has a strong block sort in it.

Right here is the pattern code from my voxel sport:

void Digicam::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 = flooring((m_position.x - m_width) / m_block.getBlockSize());
    y1 = flooring((m_position.y - m_bottom) / m_block.getBlockSize());
    z1 = flooring((m_position.z - m_width) / m_block.getBlockSize());
    x2 = flooring((m_position.x + m_width) / m_block.getBlockSize());
    y2 = flooring((m_position.y + (m_top+2)) / m_block.getBlockSize());
    z2 = flooring((m_position.z + m_depth) / m_block.getBlockSize());
    
    // caught? go up
    if(flooring(m_position.y / m_block.getBlockSize()) < m_worldSize.y) {
        whereas(Sorts::getSolidBlocks( m_map.getInPosition(flooring(m_position.x / m_block.getBlockSize()), flooring(m_position.y / m_block.getBlockSize()), flooring(m_position.z / m_block.getBlockSize())) )) {
            m_position.y += m_block.getBlockSize();
            y1 = flooring((m_position.y - m_bottom) / m_block.getBlockSize());
            y2 = flooring((m_position.y + (m_top+2)) / m_block.getBlockSize());
            if(flooring(m_position.y / m_block.getBlockSize()) > m_worldSize.y) break;
        }
    }
    
    // vertical collision
    
    if(Sorts::getSolidBlocks(m_map.getInPosition(x1, y1, z1)) || Sorts::getSolidBlocks(m_map.getInPosition(x2, y1, z1)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x2, y1, z2)) || Sorts::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(Sorts::getSolidBlocks(m_map.getInPosition(x1, y2, z1)) || Sorts::getSolidBlocks(m_map.getInPosition(x2, y2, z1)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x2, y2, z2)) || Sorts::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 = flooring((m_position.x - dx - m_width) / m_block.getBlockSize());
    y3 = flooring((m_position.y - dy - m_bottom) / m_block.getBlockSize());
    z3 = flooring((m_position.z - dz - m_width) / m_block.getBlockSize());
    x4 = flooring((m_position.x - dx + m_width) / m_block.getBlockSize());
    y4 = flooring((m_position.y - dy + (m_top+2)) / m_block.getBlockSize());
    z4 = flooring((m_position.z - dz + m_depth) / m_block.getBlockSize());
    y5 = spherical(y3+(y4-y3)/2); // earlier y place
    
    if(Sorts::getSolidBlocks(m_map.getInPosition(x1, y3, z3)) || Sorts::getSolidBlocks(m_map.getInPosition(x1, y3, z4)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x1, y4, z4)) || Sorts::getSolidBlocks(m_map.getInPosition(x1, y4, z3)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x1, y5, z3)) || Sorts::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(Sorts::getSolidBlocks(m_map.getInPosition(x2, y3, z3)) || Sorts::getSolidBlocks(m_map.getInPosition(x2, y3, z4)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x2, y4, z4)) || Sorts::getSolidBlocks(m_map.getInPosition(x2, y4, z3)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x2, y5, z3)) || Sorts::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(Sorts::getSolidBlocks(m_map.getInPosition(x3, y3, z1)) || Sorts::getSolidBlocks(m_map.getInPosition(x4, y3, z1)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x4, y4, z1)) || Sorts::getSolidBlocks(m_map.getInPosition(x3, y4, z1)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x3, y5, z1)) || Sorts::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(Sorts::getSolidBlocks(m_map.getInPosition(x3, y3, z2)) || Sorts::getSolidBlocks(m_map.getInPosition(x4, y3, z2)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x4, y4, z2)) || Sorts::getSolidBlocks(m_map.getInPosition(x3, y4, z2)) ||
        Sorts::getSolidBlocks(m_map.getInPosition(x3, y5, z2)) || Sorts::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 sort on the earth
and dx, dy, dz are the route of the participant

and here is use the collider:

// participant motion
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

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here