I have been trying to get a working algorithm that detects intersection between a ray (representing the bullets from a gun) and a sphere around the enemy.... I tried a few found on the net but none seems to work properly, maybe I am doing something wrong...
This is the one I am currently using:
//// Ray-sphere intersection.
// p=(ray origin position - sphere position),
// d=ray direction,
// r=sphere radius,
// Output:
// i1=first intersection distance,
// i2=second intersection distance
// i1<=i2
// i1>=0
// returns true if intersection found,false otherwise.//
bool Player::RaySphereIntersect(const Vector3 &p, const Vector3 &d, double r, double &i1, double &i2){
double det,b;
b = -Vector3::dot(p,d);
det = b*b - Vector3::dot(p,p) + r*r;
if (det<0){
return false;
}
det= sqrt(det);
i1= b - det;
i2= b + det;
// intersecting with ray?
if(i2<0)
return false;
if(i1<0)
i1=0;
return true;
}
Where I use the position of the enemy as sphere position, roughly the position of the player's gun as ray origin and the projected mouse coordinates for ray direction... This is the OpenGL code I am using to project the mouse coords to the the far plane:
Vector3 projectedMouse(float mx, float my){
GLdouble model_view[16];
GLint viewport[4];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble dx, dy, dz, bx, by, bz;
glGetDoublev(GL_MODELVIEW_MATRIX, model_view);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (float)mx;
winY = (float)viewport[3] - (float)my;
glReadPixels ((int)mx, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, 1, model_view, projection, viewport, &dx, &dy, &dz);
projectedAim = Vector3(dx, dy, dz);
return projectedAim;
}
Which seems right cos I am drawing a GL Line with it and it looks fine... So maybe it's the intersection code, but nothing seems to work.... I tried this other one that should return the intersection point distance, but for any given enemy position, it still gives me very random results:
double intersectRaySphere(Vector3 rO, Vector3 rV, Vector3 sO, double sR)
Vector3 Q = sO-rO;
double c = Q.magnitude();
double v = Vector3::dot(Q,rV);
double d = sR*sR - (c*c - v*v);
// If there was no intersection, return -1
if (d < 0.0) return (-1.0f);
// Return the distance to the [first] intersecting point
return (v - sqrt(d));
they have both been slightly modified to match the Math function in the library that I am using.... can anyone spot something wrong with them, or suggest another one? this is driving me crazy....
Thank you!