Is that a bug in PVR vector math library?

This topic contains 3 replies, has 2 voices, and was last updated by  Tobias Hector 4 years, 2 months ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #31423

    Slion
    Member

    Are you guys sure about the following code?
    When multiplying a vector with a matrix using the following function my translation gets lost cause it is stored in 12,13,14
    So to get the expected result I first have to take the transpose of my matrix or fix the following implementation as shown further below.


    PVRTVec4& PVRTVec4::operator*=(const PVRTMat4& rhs)
    {
    VERTTYPE tx = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[1])+VERTTYPEMUL(z,rhs.f[2])+VERTTYPEMUL(w,rhs.f[3]);
    VERTTYPE ty = VERTTYPEMUL(x,rhs.f[4])+VERTTYPEMUL(y,rhs.f[5])+VERTTYPEMUL(z,rhs.f[6])+VERTTYPEMUL(w,rhs.f[7]);
    VERTTYPE tz = VERTTYPEMUL(x,rhs.f[8])+VERTTYPEMUL(y,rhs.f[9])+VERTTYPEMUL(z,rhs.f[10])+VERTTYPEMUL(w,rhs.f[11]);
    w = VERTTYPEMUL(x,rhs.f[12])+VERTTYPEMUL(y,rhs.f[13])+VERTTYPEMUL(z,rhs.f[14])+VERTTYPEMUL(w,rhs.f[15]);
    x = tx;
    y = ty;
    z = tz;
    return *this;
    }

    Possible fix:


    PVRTVec4& PVRTVec4::operator*=(const PVRTMat4& rhs)
    {
    VERTTYPE tx = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[4])+VERTTYPEMUL(z,rhs.f[8])+VERTTYPEMUL(w,rhs.f[12]);
    VERTTYPE ty = VERTTYPEMUL(x,rhs.f[1])+VERTTYPEMUL(y,rhs.f[5])+VERTTYPEMUL(z,rhs.f[9])+VERTTYPEMUL(w,rhs.f[13]);
    VERTTYPE tz = VERTTYPEMUL(x,rhs.f[2])+VERTTYPEMUL(y,rhs.f[6])+VERTTYPEMUL(z,rhs.f[10])+VERTTYPEMUL(w,rhs.f[14]);
    w = VERTTYPEMUL(x,rhs.f[3])+VERTTYPEMUL(y,rhs.f[7])+VERTTYPEMUL(z,rhs.f[11])+VERTTYPEMUL(w,rhs.f[15]);
    x = tx;
    y = ty;
    z = tz;
    return *this;
    }
    #37833

    Slion
    Member

    Ok I think I figured it out.
    I was doing vert*=mat which in fact is short for vert=vert*mat
    But what I really needed was vert=mat*vert which obviously works just fine.
    Still that *= operator is a bit odd. Who actually needs that in OpenGL world?
    Maybe it makes sense for DirectX though…

    #37834

    Hi Slion,

    Actually they should behave as you described. In practice, the result of vert*mat == mat*vert, as the results are the same. The reason for the incorrect calculation is because that calculation is somehow assuming a row-major matrix, when it should in fact be column major. This is a bug and we will fix it for the next release.

    Thanks,
    Tobias

    #37835

    No wait, hang on, I just had to go write a lot of stuff on a whiteboard to figure this out. I was also looking at the wrong function. So the operator functions you mention ARE the correct way round. mat*vec is the correct way of performing a transformation in OpenGL, as you’ve discovered. The reason for having vec*mat and vec*=mat is actually because it’s a shorthand (and more efficient) way of working out “I want to transpose this” without performing an actual transposition. This is useful for say, scaling matrixes, where the inverse == the transpose, so instead of doing “vec = mat / vec”, you can just do “vec = vec * mat” which is equivalent and cheaper to do.

    We do have an incorrect function however, which is the really old “PVRTTransform” which despite having the vector as the first argument is actually doing “mat * vec”. We’ve no intention of fixing this though as it’s technically deprecated and we don’t want to break people’s codebases. A future SDK will remove this function and we’ll verify row vs column major maths in any new code from now on 🙂

    Regards,
    Tobias

Viewing 4 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic.