我正在将一个平铺贴图渲染到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);
所以Y轴上的点可以在[-1,1]空间中设置:
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个单位消失。
我很感激帮助。
根据您的描述,您似乎希望将世界空间交点坐标转换为其对应的标准化纹理坐标。
为此,您还需要Z坐标,因为必须有两个“水平”坐标。但是,您不需要弧长。
使用intersectedPoint
的相对X和Z坐标,使用atan2
计算极角,并除以PI
(半圆弧的角度范围):
vec2.x = atan2(intersectedPoint.z - myCylinder->position().z,
myCylinder->position().x - intersectedPoint.x) / PI;