它所做的基本上是检查与三角形阵列的碰撞,并根据碰撞到的三角形的颜色绘制图像。我认为我的问题在于碰撞检测。此处编码:
for (int i = 0; i < triangles.size(); i++){
vec3 v0 = triangles[i].v0;
vec3 v1 = triangles[i].v1;
vec3 v2 = triangles[i].v2;
vec3 e1 = v1 - v0;
vec3 e2 = v2 - v0;
vec3 b = start - v0;
mat3 A(-dir, e1, e2);
vec3 x = glm::inverse(A) * b;
if (x.x > 0 && x.y > 0 && (x.x + x.y < 1) && (x.z - start.z>= 0)){
return true;
}
}
其中">dir"是来自摄影机的光线方向,计算为">x-SCREEN_WIDTH/2,y-SCREEN_HIGHT/2,focalLengthSCREEN_WIDTH、SCREEN_HEIGHT和焦距是常数开始是摄影机的位置,设置为0,0,0。
我不确定的是x到底是什么,以及在返回true之前应该检查什么。">x.x>0&&x.y>0&aamp;&(x.x+x.y<1)"应该检查光线是否不仅在同一平面上,而且实际上在三角形内部,以及最后一部分(">x.z-start.z>=0,我最不确定的一个),如果碰撞发生在相机前面。
我得到了图像,但无论我怎么尝试,它永远不会是正确的。它应该是一个房间的经典TestModel,里面有不同颜色的墙和两个形状。我想我最接近的一次是把五堵墙中的四堵弄对了,缺了最远的一堵,另一边有一个形状的一部分。
我不熟悉三角形相交的矩阵公式——它听起来相当昂贵。
我自己的代码如下,其中我的e1
和e2
与您的等价,即它们分别表示从v0
到v1
和v2
的边缘向量:
// NB: triangles are assumed to be in world space
vector3 pvec = vector3::cross(ray.direction(), e2);
double det = e1.dot(pvec);
if (::fabs(det) < math::epsilon) return 0;
double invDet = 1.0 / det;
vector3 tvec(p0, ray.origin());
double u = tvec.dot(pvec) * invDet;
if (u < 0 || u > 1) return 0;
vector3 qvec = vector3::cross(tvec, e1);
double v = ray.direction().dot(qvec) * invDet;
if (v < 0 || u + v > 1) return 0;
double t = e2.dot(qvec) * invDet;
if (t > math::epsilon) { // avoid self intersection
// hit found at distance "t"
}
我怀疑问题出在你对射线矢量的计算上,它应该被归一化。