我一直在試圖找到一個工作算法,檢測射線(代表從槍的子彈)和敵人周圍的球體之間的交集....我嘗試了幾個發現網,但沒有一個似乎能夠正常工作,也許我做錯了什麼......鼠標到射線 - 球體碰撞檢測
這是我目前使用的一個:
//// 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;
}
如果我用的是敵人的球位置的位置,大致玩家的槍的位置爲射線源,投影的射線方向爲鼠標座標......這是我用來將鼠標座標投影到遠處的OpenGL代碼飛機:
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;
}
這似乎是正確的COS我畫一個線GL與它和它看起來罰款...因此,也許它的交集的代碼,但似乎沒有任何工作....我想這等一個應該返回交叉點距離,但對於任何給定的敵人的位置,但它仍然給了我非常隨機的結果:
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));
他們都被稍微修改,以在我使用的庫相匹配的數學函數...任何人都可以發現他們有什麼問題,或者建議他人嗎?這讓我發瘋......
謝謝!
縮小範圍:交叉碼或OpenGL狀態中的問題是否爲讀取/解釋? – genpfault
這是一個確定的交點,因爲一條線正在繪製,因此它的鼠標座標和投影似乎沒問題! – Alex