【问题标题】:Orient object along surface normal沿曲面法线定向对象
【发布时间】:2017-03-27 23:26:06
【问题描述】:

当用户点击一个表面时,我想在这个位置放置一个对象并使其垂直于表面法线。

用户执行点击后,我从缓冲区读取三个相邻像素的深度,将像素从屏幕坐标解投影到对象空间,然后从对象空间中的这些点计算表面法线:

glReadPixels(mouseX, mouseY, ..., &depthCenter);
pointCenter = gluUnProject(mouseX, mouseY, depthCenter, ...);

glReadPixels(mouseX, mouseY - 1, ..., &depthUp);
pointUp = gluUnProject(mouseX, mouseY - 1, depthUp, ...);

glReadPixels(mouseX - 1, mouseY, ..., &depthLeft);
pointLeft = gluUnProject(mouseX - 1, mouseY, depthLeft, ...);

centerUpVec = norm( pointCenter - pointUp );
centerLeftVec = norm( pointCenter - pointLeft );
normalVec = norm( centerUpVec.cross(centerLeftVec) );

我知道仅从三个像素计算法线是有问题的(例如,在边缘处或如果三个点的深度差异很大),但对于我在平坦表面上的初始测试,这必须足够了。

最后,为了使对象沿着计算出的法线向量定向,我从法线向量和向上向量创建了一个旋转矩阵:

upVec = vec(0.0f, 1.0f, 0.0f);
xAxis = norm( upVec.cross(normalVec) );
yAxis = norm( normalVec.cross(xAxis) );

// set orientation of model matrix
modelMat(0,0) = xAxis(0);
modelMat(1,0) = yAxis(0);
modelMat(2,0) = normalVec(0);

modelMat(0,1) = xAxis(1);
modelMat(1,1) = yAxis(1);
modelMat(2,1) = normalVec(1);

modelMat(0,2) = xAxis(2);
modelMat(1,2) = yAxis(2);
modelMat(2,2) = normalVec(2);

// set position of model matrix by using the previously computed center-point
modelMat(0,3) = pointCenter(0);
modelMat(1,3) = pointCenter(1);
modelMat(2,3) = pointCenter(2);

出于测试目的,我在每次单击后将对象放置在平坦的表面上。在大多数情况下,当我的相机朝上矢量向下时,这很有效。

但是,一旦我旋转我的相机,放置的对象就会任意定向,我不知道为什么!

【问题讨论】:

  • 您的xAxisyAxis 是相等的。您应该使用xAxis 来计算yAxis。喜欢这个yAxis = norm( upVec.cross(xAxis) );。此外,如果normalVecupVec 共线(如果可能的话),最好使用另一个upVec
  • 而不是使用 3 个像素来计算法线,只需确定单击了哪个面/多边形(使用 glSelectBuffer 等),并使用该面的法线。
  • @MichaelNastenko 这只是一个错字,谢谢指出!
  • @1201ProgramAlarm 如前所述,我知道有更好的方法来计算法线,但这应该足以在平面上进行测试,直到一切正常......

标签: opengl rotation orientation transformation normals


【解决方案1】:

好的,我刚刚在我的代码中发现了一个与实际问题无关的小错误。因此,上述问题中所述的方法工作正常。

为了避免一些陷阱,当然可以只使用数学库,例如 Eigen,来计算上向量和表面法线之间的旋转:

upVec = Eigen::Vector3f(0.0f, 1.0f, 0.0f);
Eigen::Quaternion<float> rotationQuat;
rotationQuat.setFromTwoVectors(upVec, normalVec);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 2016-03-16
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    相关资源
    最近更新 更多