我正在将图块贴图渲染到fbo,然后将结果缓冲区移动到纹理并将其渲染到FSQ上。然后从鼠标单击事件中,我得到了屏幕坐标并将其移至剪辑空间[-1,1]:
glm::vec2 posMouseClipSpace((2.0f * myCursorPos.x) / myDeviceWidth -
1.0f, 1.0f - (2.0f * myCursorPos.y) / myDeviceHeight);
我的程序中有逻辑,基于这些坐标,它将在纹理上选择特定的图块。
现在,转到3D,我将使用在上一步中使用的FBO为半圆柱体构造纹理:
在这种情况下,我使用的射线三角形交点以半径r和高度h击中圆柱体。想法是将此交点移动到空间[-1,1],因此我可以将逻辑保留在程序中以选择图块
我使用Möller-Trumbore算法来检查射线照射到圆柱体上的点。假设相交的点是(x,y)(不确定该点是在三角形,物体还是世界空间中。显然是世界空间)。 我想将该点转换为空间x:[-1,1],y [-1,1]。
我知道我的圆柱体的高度,它是圆柱体弧长的四分之一:
cylinderHeight = myRadius *(PI / 2);
因此可以在[-1,1]空间中设置Y轴上的点:
vec2.y = (2.f * (intersectedPoint.y - myCylinder->position().y) ) /
(myCylinder->height()) - 1.f
那很好用。
但是,如何计算取决于2个变量x和z的水平轴?
当前,我的圆柱体的半径为1,因此巧合的是,原点设置的半圆柱体将从X轴上的(-1,1)开始,这使我认为它是[-1,1]空间,但是事实并非如此。 我的下一个方法是使用半圆的弧长 s = r * PI ,然后将该值插入方程式:
vec2.x = (2.f * (intersectedPoint.x - myCylinder->position().x) ) /
(myCylinder->arcLength()) - 1.f
但很明显,它在负方向上偏离了1个单位。
感谢您的帮助。
答案 0 :(得分:1)
根据您的描述,您似乎想将世界空间相交坐标转换为其对应的归一化纹理坐标。
为此,您还需要Z坐标,因为必须有两个“水平”坐标。但是,不需要需要弧长。
使用intersectedPoint
的相对X和Z坐标,使用atan2
计算极角,然后除以PI
(半圆弧的角度范围):>
vec2.x = atan2(intersectedPoint.z - myCylinder->position().z,
myCylinder->position().x - intersectedPoint.x) / PI;