Tagged: vector math library

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

- AuthorPosts
- July 30, 2013 at 1:39 pm #31423
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;

}

July 30, 2013 at 2:34 pm #37833Ok 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…July 31, 2013 at 10:46 am #37834Hi 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,

TobiasJuly 31, 2013 at 11:30 am #37835No 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