我正在尝试使用射线球交叉点在 OpenGL 中执行鼠标拾取。我在网上找到了一些公式,我尝试的最后一个是 Stack Exchange 上的用户建议的一个:
根据我对这个答案的理解,我正在检查二次方程是否有正根。我真的不在乎相交发生在哪里,只要光线与球体相交即可。我的代码如下,但似乎不起作用。
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;
}
}
我的 C++ 技能相当生疏,所以如果这是一种可怕的做法,我深表歉意。此方法采用三个浮点数的两个向量、相机的位置以及我的场景 1 单元中相机前面的一个点的坐标(我称之为这个方向)。
当我面对一个对象并按下一个键时,我想获取对象的位置和它的半径,但是只有当我站在场景中的一个对象上,或者我站在靠近另一个大型对象时,我才会得到输出目的。很明显我的计算有问题(或者更糟糕的是,我的代码),但我无法弄清楚那是什么。:(
如果您需要更多代码,或者有任何不清楚的地方,请告诉我。这是我对 SO 的第一个问题,所以如果这个问题措辞不当,我很抱歉。
编辑:我不应该使用鼠标坐标作为我的射线上的一个点。稍微编辑了我的问题。