面向相机的广告牌在180度附近旋转错误

时间:2015-05-17 12:48:51

标签: java opengl matrix lwjgl particles

我实施了一个粒子系统。我在广告牌上绘制纹理,应该朝着相机旋转。

除了粒子 - >相机和法线之间的角度接近180度的情况外,这种方法很好。然后粒子开始绕自身旋转很多次。

使用cos(角度)=点(a,b)/(长度(a)*长度(b)计算角度,长度均为1,因为向量被归一化。 使用这两个向量的叉积计算轴。

    glDisable(GL_CULL_FACE);

    //calculate rotation
    Vector3f normal = new Vector3f(0, 0, 1);
    Vector3f dir = Vector3f.sub(new Vector3f(GraphicsData.camera.x, GraphicsData.camera.y, GraphicsData.camera.z), new Vector3f(x, y, z), null);
    if(dir.length() == 0)
    {
        glEnable(GL_CULL_FACE);
        return;
    }
    dir = (Vector3f) dir.normalise();
    float angle = (float) Math.toDegrees(Math.acos(Vector3f.dot(normal, dir)));
    Vector3f rotationAxis = Vector3f.cross(normal, dir, null);
    rotationAxis = (Vector3f) rotationAxis.normalise();
    System.out.println("Angle: + " + angle + "    Axis: " + rotationAxis);


    glBindTexture(GL_TEXTURE_2D, ParticleEngine.particleTextures.get(typeId).texture.getTextureID());


    glColor4f(1f,1f,1f, time >= lifeTime - decayTime ? ((float)lifeTime - (float)time) / ((float)lifeTime - (float)decayTime) : 1f);
    shaderEngine.createModelMatrix(new Vector3f(x, y, z), new Vector3f(angle * rotationAxis.x, angle * rotationAxis.y, angle * rotationAxis.z), new Vector3f(sx, sy, sz));
    shaderEngine.loadModelMatrix(shaderEngine.particle);
    glCallList(ParticleEngine.particleTextures.get(typeId).displayListId + textureIndex);

    glEnable(GL_CULL_FACE);

我在计算旋转时做错了什么?

public static void createModelMatrix(Vector3f pos, Vector3f rot, Vector3f scale)
{
    GraphicsData.camera.modelMatrix = new Matrix4f();
    GraphicsData.camera.modelMatrix.setIdentity();
    GraphicsData.camera.modelMatrix.translate(pos);
    GraphicsData.camera.modelMatrix.rotate((float) Math.toRadians(rot.x), new Vector3f(1,0,0));
    GraphicsData.camera.modelMatrix.rotate((float) Math.toRadians(rot.y), new Vector3f(0,1,0));
    GraphicsData.camera.modelMatrix.rotate((float) Math.toRadians(rot.z), new Vector3f(0,0,1));
    GraphicsData.camera.modelMatrix.scale(scale);
}

1 个答案:

答案 0 :(得分:0)

更长时间的评论或可能是问题的部分答案:

如果您正在计算跨产品,请使用

norm( a × b ) = sin(angle) * norm(a)*norm(b)
dot(a,b)      = cos(angle) * norm(a)*norm(b)

确定

angle = atan2( norm(a×b), dot(a,b) )