矢量数学库和矩阵运算

vectormath library and matrix operations

我发现这个 copy on github 到 link 但我使用的是从 sourceforge 下载的那个。

我对他们设计矩阵运算的方式的问题对我来说真的很奇怪。

例如,如果我创建一个 4×4 矩阵并设置它的比例。然后我想使用矢量数学矩阵库旋转之前的矩阵似乎将矩阵重置回单位矩阵然后应用旋转,这对于为什么会发生这种情况没有任何意义。

看看这个函数做一个旋转

static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians )
{
    float s, c;
    s = sinf( radians );
    c = cosf( radians );
    vmathV4MakeFromElems( &result->col0, c, 0.0f, -s, 0.0f );
    vmathV4MakeYAxis( &result->col1 );
    vmathV4MakeFromElems( &result->col2, s, 0.0f, c, 0.0f );
    vmathV4MakeWAxis( &result->col3 );
}

这个库是否希望您保留多个矩阵,使用一个来应用旋转然后相乘?

编辑

这是我以前用来旋转矩阵的一些矩阵数学代码,看起来像这样。

mat4_s mat4_rotateX(mat4_s* out, float angle, mat4_s* inMat)
{
    float s = sinf(angle),
            c = cosf(angle),
            a10 = inMat->m[4],
            a11 = inMat->m[5],
            a12 = inMat->m[6],
            a13 = inMat->m[7],
            a20 = inMat->m[8],
            a21 = inMat->m[9],
            a22 = inMat->m[10],
            a23 = inMat->m[11];

    if (!out->m) {
        for(size_t i = 0; i < 16; i++)
        {
            out->m[i] = inMat->m[i];
        }
    } else if (inMat->m != out->m) { // If the source and destination differ, copy the unchanged rows
        out->m[0] = inMat->m[0];
        out->m[1] = inMat->m[1];
        out->m[2] = inMat->m[2];
        out->m[3] = inMat->m[3];

        out->m[12] = inMat->m[12];
        out->m[13] = inMat->m[13];
        out->m[14] = inMat->m[14];
        out->m[15] = inMat->m[15];
    }


    out->m[4] = a10 * c + a20 * s;
    out->m[5] = a11 * c + a21 * s;
    out->m[6] = a12 * c + a22 * s;
    out->m[7] = a13 * c + a23 * s;

    out->m[8] = a10 * -s + a20 * c;
    out->m[9] = a11 * -s + a21 * c;
    out->m[10] = a12 * -s + a22 * c;
    out->m[11] = a13 * -s + a23 * c;
    return *out;
}

这是让矢量数学做同样事情的过程。

mat4* mat4_rotate_y(mat4* out, const float angle){
    mat4 m;
    mat4_identity_v(&m);
    vmathM4MakeRotationY(m, angle);
    mat4_multi(out, out, m);
    return out;
}

乘法代码相当标准,但 vmathM4MakeRotationY 看起来像这样:

static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians )
{
    float s, c;
    s = sinf( radians );
    c = cosf( radians );
    vmathV4MakeFromElems( &result->col0, c, s, 0.0f, 0.0f );
    vmathV4MakeFromElems( &result->col1, -s, c, 0.0f, 0.0f );
    vmathV4MakeZAxis( &result->col2 );
    vmathV4MakeWAxis( &result->col3 );
}

为了完整起见,vmathV4Make_Axis 看起来像这样:

static inline void vmathV4MakeZAxis(VmathVector4 *result) {
    vmathV4MakeFromElems(result, 0.0f, 0.0f, 1.0f, 0.0f);
}

vmathV4MakeFromElms 看起来像这样:

static inline void vmathV4MakeFromElems(VmathVector4 *result, float _x,
                                        float _y, float _z, float _w) {
    result->x = _x;
    result->y = _y;
    result->z = _z;
    result->w = _w;
}

这个函数似乎 "Initialize the matrix to be a rotation transform" 而不是你所期望的 "Add a rotation transform to the current transform"。

就像你说的,你可以通过将旋转存储在一个单独的临时矩阵中然后乘以来解决:

VmathMatrix4 temp;
vmathM4MakeRotationY(&temp, 1.23);
vmathM4Mul(&mytransform, &mytransform, &temp);

这几乎就是假设的 vmathM4ApplyRotationY() 无论如何都必须做的事情。