Search code examples
c++collision-detectioncollision

Sphere-cube collision detection in Opengl?


I am trying to build a game in Opengl. Before I start making better movement mechanics I want to get collision working. I have cube-cube collision working and I have sphere-sphere collision working, but can't figure out cube-sphere collision. Since I want it in 3d I have the pivot at the center of the objects. Anyone have any suggestions?

EDIT: This is the code I currently have:

    bool SphereRectCollision( Sphere& sphere, Rectangle& rect) 
{ 

    //Closest point on collision box
    float cX, cY;

    //Find closest x offset 
    if( sphere.getCenterX() < rect.GetCenterX())//checks if the center of the circle is to the left of the rectangle
        cX = rect.GetCenterX(); 
    else if( sphere.getCenterX() > rect.GetCenterX() + rect.GetWidth()) //checks if the center of the circle is to the right of the rectangle
        cX = rect.GetCenterX() + rect.GetWidth(); 
    else //the circle is inside the rectagle
        cX = sphere.getCenterX(); 

    //Find closest y offset 
    if( sphere.getCenterY() > rect.GetCenterY() + rect.GetHeight() )
        cY = rect.GetCenterY(); 
    else if( sphere.getCenterY() < rect.GetCenterY() - rect.GetHeight() ) 
        cY = rect.GetCenterY() + rect.GetHeight(); 
    else 
        cY = sphere.getCenterY(); 

    //If the closest point is inside the circle 
    if( distanceSquared( sphere.getCenterX(), sphere.getCenterY(), cX, cY ) < sphere.getRadius() * sphere.getRadius() )
    { 
        //This box and the circle have collided 
        return false; 
    }

    //If the shapes have not collided 
    return true; 
}

float distanceSquared( float x1, float y1, float x2, float y2 ) 
{ 
    float deltaX = x2 - x1; 
    float deltaY = y2 - y1; 
    return deltaX*deltaX + deltaY*deltaY; 
}

Solution

  • I found the solution. I had the right idea, but didn't quite know how to execute it:

        bool SphereRectCollision( Sphere& sphere, Rectangle& rect) 
    { 
        float sphereXDistance = abs(sphere.X - rect.X);
        float sphereYDistance = abs(sphere.Y - rect.Y);
        float sphereZDistance = abs(sphere.Z - rect.Z);
    
        if (sphereXDistance >= (rect.Width + sphere.Radius)) { return false; }
        if (sphereYDistance >= (rect.Height + sphere.Radius)) { return false; }
        if (sphereZDistance >= (rect.Depth + sphere.Radius)) { return false; }
    
        if (sphereXDistance < (rect.Width)) { return true; } 
        if (sphereYDistance < (rect.Height)) { return true; }
        if (sphereZDistance < (rect.GetDepth)) { return true; }
    
       float cornerDistance_sq = ((sphereXDistance - rect.Width) * (sphereXDistance - rect.Width)) +
                             ((sphereYDistance - rect.Height) * (sphereYDistance - rect.Height) +
                             ((sphereYDistance - rect.Depth) * (sphereYDistance - rect.Depth)));
    
        return (cornerDistance_sq < (sphere.Radius * sphere.Radius));
    }