Ray Sphere Intersections in OpenGL

2019-06-27 04:43发布

问题:

I'm trying to use ray-sphere intersections to perform mouse picking in OpenGL. I found a few formulae online, and the last one I tried was one suggested by a user on Stack Exchange:

Ray-Sphere intersection

From what I've understood of this answer, I'm checking if the quadratic equation has positive roots. I don't really care where the intersection takes place, just if the ray intersects the sphere at all. My code is as follows, but doesn't seem to work.

bool Mesh::useObject(vec3 camera, vec3 direction) {

    // a = (xB-xA)²+(yB-yA)²+(zB-zA)²
    float a = ((direction.v[0] - camera.v[0])*(direction.v[0] - camera.v[0])
        + (direction.v[1] - camera.v[1])*(direction.v[1] - camera.v[1])
        + (direction.v[2] - camera.v[2])*(direction.v[2] - camera.v[2]));

    // b = 2*((xB-xA)(xA-xC)+(yB-yA)(yA-yC)+(zB-zA)(zA-zC))
    float b = 2 * ((direction.v[0] - camera.v[0])*(camera.v[0] - mOrigin.v[0])
        + (direction.v[1] - camera.v[1])*(camera.v[1] - mOrigin.v[1])
        + (direction.v[2] - camera.v[2])*(camera.v[2] - mOrigin.v[2]));

    // c = (xA-xC)²+(yA-yC)²+(zA-zC)²-r²
    float c = ((camera.v[0] - mOrigin.v[0])*(camera.v[0] - mOrigin.v[0])
        + (camera.v[1] - mOrigin.v[1])*(camera.v[1] - mOrigin.v[1])
        + (camera.v[2] - mOrigin.v[2])*(camera.v[2] - mOrigin.v[2])
        - (mRadius)*(mRadius));

    float delta = (b*b) - (4 * a*c);

    if (delta < 0)
        return false;

    else {
        std::cout << "Object " << mMesh << " is at postion (" <<
            mOrigin.v[0] << ", " <<
            mOrigin.v[1] << ", " <<
            mOrigin.v[2] << ")\n" <<
            "Size: " << mRadius << std::endl;
        return true;
    }
}

My C++ skills are pretty rusty, so I apologise if this is a horrible way of doing this. This method takes two vectors of three floats, the position of the camera, and the coordinates of a point in my scene 1 unit in front of the camera (I've called this direction).

I want to get the position of the object and it's radius when I face an object and press a key, but instead I get output only when I'm standing on one of the objects in my scene, or if I stand close to another large object. Clearly there's something wrong with my calculations (or worse, my code) but I cannot figure out what that is. :(

Let me know if you need any more code, or if anything is unclear. This is my first question with SO, so if this question is badly phrased, I'm sorry.

EDIT: I shouldn't have been using mouse coordinates as a point on my ray. Edited my question slightly.