6

我正在创建一个 3D 图形引擎,其中一个要求是绳索的行为类似于 Valve 的源引擎。

所以在源引擎中,一段绳索是一个四边形,它沿着它的方向轴旋转以面对相机,所以如果绳索段在 +Z 方向上,它将沿着 Z 轴旋转,所以它的面朝向相机的中心位置。

目前,我已经定义了绳索的部分,所以我可以有一个很好的弯曲绳索,但现在我正在尝试构建一个矩阵,它将沿着它的方向向量旋转它。

我已经有一个基于这种广告牌技术渲染广告牌精灵的矩阵: 构建广告牌矩阵 目前我一直在尝试对其进行重组,以使右、上、前向量与绳索段的方向向量相匹配。

我的绳子是由多个部分组成的,每个部分是一个由两个三角形组成的矩形,正如我上面所说的,我可以将位置和部分完美地获得,正是面对相机的旋转给我带来了很多问题。

这是在 OpenGL ES2 中并用 C 编写的。

我在 Model_beam.cpp 中研究了 Doom 3 的光束渲染代码,那里使用的方法是基于法线而不是使用矩阵来计算偏移量,所以我在我的 C 代码中创建了一个类似的技术,它有点工作,至少它,我现在需要的就可以了。

因此,对于那些也想弄清楚这一点的人,使用绳索中点与相机位置的叉积,对其进行归一化,然后将其乘以您希望绳索的宽度,然后在构建时顶点,在结果向量的 + 或 - 方向上偏移每个顶点。

尽管这并不完美,但进一步的帮助会很棒!

谢谢

4

1 回答 1

1

在 OpenGL 的广告牌上查看这个相关的 stackoverflow 帖子 它引用了一个很不错的lighthouse3d教程。以下是该技术的要点:

void billboardCylindricalBegin(
                float camX, float camY, float camZ,
                float objPosX, float objPosY, float objPosZ) {

        float lookAt[3],objToCamProj[3],upAux[3];
        float modelview[16],angleCosine;

        glPushMatrix();

    // objToCamProj is the vector in world coordinates from the 
    // local origin to the camera projected in the XZ plane
        objToCamProj[0] = camX - objPosX ;
        objToCamProj[1] = 0;
        objToCamProj[2] = camZ - objPosZ ;

    // This is the original lookAt vector for the object 
    // in world coordinates
        lookAt[0] = 0;
        lookAt[1] = 0;
        lookAt[2] = 1;


    // normalize both vectors to get the cosine directly afterwards
        mathsNormalize(objToCamProj);

    // easy fix to determine wether the angle is negative or positive
    // for positive angles upAux will be a vector pointing in the 
    // positive y direction, otherwise upAux will point downwards
    // effectively reversing the rotation.

        mathsCrossProduct(upAux,lookAt,objToCamProj);

    // compute the angle
        angleCosine = mathsInnerProduct(lookAt,objToCamProj);

    // perform the rotation. The if statement is used for stability reasons
    // if the lookAt and objToCamProj vectors are too close together then 
    // |angleCosine| could be bigger than 1 due to lack of precision
       if ((angleCosine < 0.99990) && (angleCosine > -0.9999))
          glRotatef(acos(angleCosine)*180/3.14,upAux[0], upAux[1], upAux[2]);   
    }
于 2013-10-07T23:21:14.330 回答