我的矩阵计算中无法识别错误?

时间:2014-07-07 22:45:04

标签: opengl matrix rotation quaternions opentk

所以,我尝试在OpenTK中使用矩阵,我的"转换" class有一个Rotation(四元数)和一个Vector3作为位置。它提供了以下的领域:

    public virtual Vector3 Right
    {
        get
        {

            return Vector3.Transform(Vector3.UnitX, Rotation);
        }
    }
    public virtual Vector3 Forward
    {
        get 
        {
            return Vector3.Transform(-Vector3.UnitZ, Rotation);
        }
    }
    public virtual Vector3 Up
    {
        get
        {
            return Vector3.Transform(Vector3.UnitY, Rotation);
        }
    }

这是视图和模型矩阵的创建方式:

    public virtual Matrix4 GetMatrix()
    {
        Matrix4 translation = Matrix4.CreateTranslation(Position);
        Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
        return translation * rotation;
    }

投影:

    private void SetupProjection()
    {
        if(GameObject != null)
        {
            AspectRatio = GameObject.App.Window.Width / (float)GameObject.App.Window.Height;
            projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov) / 180), AspectRatio, ZNear, ZFar);

        }
    }

矩阵乘法:

    public Matrix4 GetModelViewProjectionMatrix(Transform model)
    {
        return  model.GetMatrix()* Transform.GetMatrix() * projectionMatrix;
    }

着色器:

[Shader vertex]
#version 150 core

in vec3 pos;
in vec4 color;
uniform float _time;
uniform mat4 _modelViewProjection;

out vec4 vColor;

void main() {
    gl_Position = _modelViewProjection * vec4(pos, 1);
    vColor = color;
}

OpenTK矩阵是转置的,因此是乘法顺序。

此设置的问题是,所有轴和方向向量以及对象位置都是混合,镜像和颠倒。

经过大量的摆弄,我设法得到了有用的转变,最终得到了以下结论:

我必须将四元数反转为方向:

    public virtual Vector3 Right
    {
        get
        {

            return Vector3.Transform(Vector3.UnitX, Rotation.Inverted());
        }
    }
    public virtual Vector3 Forward
    {
        get
        {
            return Vector3.Transform(-Vector3.UnitZ, Rotation.Inverted());
        }
    }
    public virtual Vector3 Up
    {
        get
        {
            return Vector3.Transform(Vector3.UnitY, Rotation.Inverted());
        }
    }

我必须像这样修改视图矩阵结构:

    public virtual Matrix4 GetMatrixView()
    {
        Matrix4 translation = Matrix4.CreateTranslation(Position*2).Inverted();
        Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
        return translation * rotation;
    }

如您所见,我不得不反转平移矩阵并将位置乘以2,以使相机空间与世界空间相匹配。什么F?

编辑:看看这个。使用默认/直觉设置,我得到了:

  

[日志] :( 0; 0; 10) - >

     

[LOG]:FW(0; 0; -1)

     

[LOG]:R(-1; 0; 0)

     

[LOG]:UP(0; 1; 0)

好的,我在Z 10,看着0,0,0。正如预期的那样,前进是x -1。 Up是Y 1,也没关系。但水平轴是否为LEFT?这是一种什么样的坐标系?

1 个答案:

答案 0 :(得分:2)

你提到矩阵是转置的,因此乘法顺序颠倒了。例如,你的MVP计算是:

model.GetMatrix()* Transform.GetMatrix() * projectionMatrix;

但是你的翻译*轮换连接顺序错误:

Matrix4 translation = Matrix4.CreateTranslation(Position);
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return translation * rotation;

对于非转置矩阵,正确的乘法顺序为:

translation * rotation * scale

因此,对于您的转置矩阵,它应该反转为:

scale * rotation * translation

所以你的代码应该是:

Matrix4 translation = Matrix4.CreateTranslation(Position);
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return rotation * translation;