1

私は今、数時間問題に悩まされています。4x4行列(モデル、ビュー、射影)を変換ベクトルを使用して3x3行列に変換する必要があります。私が使用しているAPIには4x4マトリックスクラスとその完全に閉じたソースがないため、これを行う必要があります。

奇妙なことに、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;

...

};
4

1 に答える 1

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. marmalade IwGxGetPerspectiveMatrix()は、オルトグラフィック投影の場合に無効な投影行列を返します(ドキュメントにはその興味深い事実については何も書かれていません)

  4. LookAt()関数は、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
    
于 2013-10-01T16:56:31.177 に答える