2012-11-04 46 views
1

我一直被困在一个问题几个小时了。 我需要将我的4x4矩阵(模型,视图,投影)转换为带有平移向量的3x3矩阵。我需要这样做,因为我使用的API没有4x4矩阵类和完全封闭的源代码。3x3查看矩阵与果酱

奇怪的是他们的LookAt函数声明它根本不影响矩阵的转换部分。在我用来渲染的4x4矩阵中,它(一切呈现100%正确)。

有人可以看看我的转换函数,看看我做错了什么? 感谢

CIwFMat ConvertToMarmaladeFormat(Matrix4& Mat) 
{ 
    CIwFMat M; 

    M.m[0][0] = Mat[0][0]; 
    M.m[0][1] = Mat[0][1]; 
    M.m[0][2] = Mat[0][2]; 

    M.m[1][0] = Mat[1][0]; 
    M.m[1][1] = Mat[1][1]; 
    M.m[1][2] = Mat[1][2]; 

    M.m[2][0] = Mat[2][0]; 
    M.m[2][1] = Mat[2][1]; 
    M.m[2][2] = Mat[2][2]; 

    M.t = CIwFVec3(Mat[3][0], Mat[3][1], Mat[3][2]); 

    return M; 
} 

Matrix4 ConvertFromMarmaladeFormat(CIwFMat& M) 
{ 
    Matrix4 Mat; 
    Mat.identity(); 

    Mat[0][0] = M.m[0][0]; 
    Mat[0][1] = M.m[0][1]; 
    Mat[0][2] = M.m[0][2]; 

    Mat[1][0] = M.m[1][0]; 
    Mat[1][1] = M.m[1][1]; 
    Mat[1][2] = M.m[1][2]; 

    Mat[2][0] = M.m[2][0]; 
    Mat[2][1] = M.m[2][1]; 
    Mat[2][2] = M.m[2][2]; 

    Mat[3][0] = M.t.x; 
    Mat[3][1] = M.t.y; 
    Mat[3][2] = M.t.z; 

    return Mat; 
} 

class Matrix4 
{ 
    friend Vector4 operator*(const Vector4 &lhs, const Matrix4 &rhs); 
    friend Vector3 operator*(const Vector3 &lhs, const Matrix4 &rhs); 
    friend Matrix4 operator*(float scalar, const Matrix4 &rhs); 

public: 
    static const Matrix4 IDENTITY; 
    static Matrix4 createFromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z); 
    static Matrix4 createFromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z); 
    static Matrix4 createFromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees); 
    static Matrix4 createMirror(const Vector3 &planeNormal, const Vector3 &pointOnPlane); 
    static Matrix4 createOrient(const Vector3 &from, const Vector3 &to); 
    static Matrix4 createRotate(const Vector3 &axis, float degrees); 
    static Matrix4 createScale(float sx, float sy, float sz); 
    static Matrix4 createTranslate(float tx, float ty, float tz); 

    Matrix4() {} 
    Matrix4(float m11, float m12, float m13, float m14, 
      float m21, float m22, float m23, float m24, 
      float m31, float m32, float m33, float m34, 
      float m41, float m42, float m43, float m44); 
    ~Matrix4() {} 

    float *operator[](int row); 
    const float *operator[](int row) const; 

    bool operator==(const Matrix4 &rhs) const; 
    bool operator!=(const Matrix4 &rhs) const; 

    Matrix4 &operator+=(const Matrix4 &rhs); 
    Matrix4 &operator-=(const Matrix4 &rhs); 
    Matrix4 &operator*=(const Matrix4 &rhs); 
    Matrix4 &operator*=(float scalar); 
    Matrix4 &operator/=(float scalar); 

    Matrix4 operator+(const Matrix4 &rhs) const; 
    Matrix4 operator-(const Matrix4 &rhs) const; 
    Matrix4 operator*(const Matrix4 &rhs) const; 
    Matrix4 operator*(float scalar) const; 
    Matrix4 operator/(float scalar) const; 

    float determinant() const; 
    void fromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z); 
    void fromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z); 
    void fromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees); 
    void identity(); 
    Matrix4 inverse() const; 
    void orient(const Vector3 &from, const Vector3 &to); 
    void rotate(const Vector3 &axis, float degrees); 
    void scale(float sx, float sy, float sz); 
    void toAxes(Vector3 &x, Vector3 &y, Vector3 &z) const; 
    void toAxesTransposed(Vector3 &x, Vector3 &y, Vector3 &z) const; 
    void toHeadPitchRoll(float &headDegrees, float &pitchDegrees, float &rollDegrees) const; 
    void translate(float tx, float ty, float tz); 
    Matrix4 transpose() const; 

private: 
    float mtx[4][4]; 
}; 

class CIwFMat 
{ 
public: 
/** 
* 3x3 rotation matrix. 
*/ 
    float m[3][3]; 
/** 
* Trans vector. 
*/ 
    CIwFVec3 t; 

... 

}; 
+1

明确设置你假设两个矩阵存储为[专栏] [行]。实际上是这样吗?如果其中任何一个是[行] [列],那么您的转换将失败。但如果两者都是[col] [row],那么代码看起来就OK。转换失败还是只有一个? – ChrisF

+0

究竟发生了什么问题?你的代码看起来很好...... – Goz

+0

好东西只是无法正确渲染。令我惊讶的是,橘子果酱正在使用3x3矩阵,而不支持任何4x4矩阵。我读到投影矩阵不能小于4x4:( – Kachinsky

回答

1

您的转换看起来不错,但检查:

  1. 果酱采用行列矩阵符号,和右手轴系统(与你的转换忍受记)

  2. 橘子果酱“视图”矩阵实际上并不是一个视图矩阵,它是相机的位置和方向矩阵。要获得实际的视图矩阵一个应该做的水木清华这样的:

    CIwFMat MarmaladeView = IwGxGetViewMatrix(); 
    CIwFMat view = (CIwFMat(CIwFMat::g_Identity, -MarmaladeView.GetTrans()) * MarmaladeView.GetTranspose()); // actually it's simple matrix inversion, but CIwFMat doesn't have Inverse() method 
    // in some cases your should add axis-flip transform 
    
  3. 果酱IwGxGetPerspectiveMatrix()在Ortographic投影的情况下返回无效的投影矩阵(文件说,有关有趣的事实没有)

  4. 注视()功能简单地设置矩阵的旋转部分匹配2点之间的方向,所以做翻译手动

  5. 检查您的远/近平面

  6. 所有MVP矩阵应该由

    IwGxSetViewMatrix(); // sets view matrix view - camera position 
    IwGxSetModelMatrix(); // sets model matrix 
    IwGxSetPerspMul(); // sets perspective projection in terms of distance to view plane 
    IwGxSetFarZNearZ(); // sets clipping planes