具体实现openGL和LWJGL中的局部旋转

问题描述 投票:0回答:1

我也对全局/局部轮换问题感到不安,我不能把手放在上面。我使用openGL和LWJGL使用a lwjgl book实现游戏。我正在将JOML库用于向量和矩阵。

modelview矩阵的构造如下。根据书,这本来是没有本地轮换的,我自己添加了它们。这个想法是每个对象都有一个全局和局部旋转。这些旋转分别进行计算,然后在左侧/右侧乘以模型视图矩阵。

public Matrix4f getModelViewMatrix(Object obj, Matrix4f viewMatrix) {
    Vector3f rotation = obj.getRot();
    Vector3f localRot = obj.getLocalRot();

    Matrix4f localRotMat = new Matrix4f().identity();
    Matrix4f worldRotMat = new Matrix4f().identity();

    localRotMat.rotateLocalX((float)Math.toRadians(localRot.x)).
                rotateLocalY((float)Math.toRadians(localRot.y)).
                rotateLocalZ((float)Math.toRadians(localRot.z));

    worldRotMat.rotateX((float)Math.toRadians(-rotation.x)).
                rotateY((float)Math.toRadians(-rotation.y)).
                rotateZ((float)Math.toRadians(-rotation.z));

    modelViewMatrix.identity().translate(obj.getPos());

    modelViewMatrix.mulLocal(localRotMat);
    modelViewMatrix.mul(worldRotMat);

    modelViewMatrix.scale(obj.getScale());
    Matrix4f viewCurr = new Matrix4f(viewMatrix);
    return viewCurr.mul(modelViewMatrix);
}

这仍然会导致围绕“错误”轴的局部旋转。我已经看过使用四元数的实现,并阅读了有关万向节锁定之类的信息,但对我来说答案要么非常具体,要么太笼统。此外,如果我不需要使用四元数实现,那就太好了,因为我可能必须重构很多代码。

对象类的相关代码:

// Object class
private final Vector3f rot;

private final Vector3f localRot;

public Object() {
    pos = new Vector3f(0, 0, 0);
    scale = 1;
    rot = new Vector3f(0, 0, 0);
    localRot = new Vector3f(0, 0, 0);
}

// getters and setters for above

有人可以解释对模型视图矩阵的旋转计算有什么问题吗?

编辑:我可以像下面那样重写代码,这与@GeestWagen的提示更加一致。但是,我对象的“局部旋转”仍显示为全局,因此确实确实好像对它应用了两次“相同”旋转。但是,现在我被困住了,因为我找不到关于这些功能的更多文档(rotateLocal / rotate)。

modelViewMatrix.identity().translate(obj.getPos()).
                rotateLocalX((float)Math.toRadians(-localRot.x)).
                rotateLocalY((float)Math.toRadians(-localRot.y)).
                rotateLocalZ((float)Math.toRadians(-localRot.z)).
                rotateX((float)Math.toRadians(-rotation.x)).
                rotateY((float)Math.toRadians(-rotation.y)).
                rotateZ((float)Math.toRadians(-rotation.z)).
                scale(obj.getScale());
java opengl rotation local lwjgl
1个回答
0
投票

好的,我终于解决了。这导致我做了更多的研究。我想到的是以下内容:

Vector3f rotation = obj.getRot();
Vector3f localRot = obj.getLocalRot();

Quaternionf rotationQ = new Quaternionf().
        rotateAxis((float)Math.toRadians(-localRot.z), new Vector3f(0f, 0f, 1f)).
        rotateAxis((float)Math.toRadians(-localRot.y), new Vector3f(0f, 1f, 0f)).
        rotateAxis((float)Math.toRadians(-localRot.x), new Vector3f(1f, 0f, 0f)).
    premul(new Quaternionf().
        rotateX((float)Math.toRadians(-rotation.x)).
        rotateY((float)Math.toRadians(-rotation.y)).
        rotateZ((float)Math.toRadians(-rotation.z))
    );

modelViewMatrix.identity().
    translate(obj.getPos()).
    rotate(rotationQ).
    scale(obj.getScale());

[这是受thisthis等启发。令我感到困惑的是,缺乏进行本地[[]]全局轮换的机会。我能找到的大多数东西是any。这将创建一个四元数并将x,y和z轴设置为对象的局部旋转。然后用四元数pre-multiplies将轴设置为对象的整体旋转。然后,将所得的四元数用于modelView矩阵。 因此,要组合局部和全局旋转,四元数似乎是必要的。我以为它是用来确保轴不更改局部旋转(或局部旋转),但在组合两者时也应使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.