back2music 100 Report post Posted April 24, 2010 Hi I seemed to have an error in and old code i digged up. The error was related to the matrix class operator* and some confusion in which order the operators argument comes into the function. Soo please validate what is the correct order of arguments to a operator when doing matrix multiplication. for example consider a*b; Is "this" the left-side (a), and m the right-side (b) according to the function? In my previous code I had to reverse the order in MatrixMultiply, that is exchange arguments this.ref() and m.ref(). So either I didn't understand which arguments was left-/right-side in the operator or the multiply function was wrong. If this function below is correct, then the multiply was originally wrong. Matrix Matrix::operator*(Matrix &m) { Matrix tmp; MatrixMultiply(tmp.ref(), this->ref(), m.ref()); return tmp; } 0 Share this post Link to post Share on other sites
L. Spiro 25641 Report post Posted April 24, 2010 Row-major matrices used by DirectX produces results equal to the left operand followed by the right operand.Column-major matrices used by OpenGL produce results equal to the right operand followed by the left operand.There is no right or wrong answer. You have mixed up the major-ness of your matrices. Pick one and stick with it.L. Spiro 0 Share this post Link to post Share on other sites
haegarr 7374 Report post Posted April 24, 2010 The result of a matrix multiplication A * B is mathematically defined in explicit terms. You should ever implement the operator w.r.t. that definition, or else confusion will emerge! You should further implement it as non-member function.Because matrix multiplication isn't commutative, you'll probably come to cases where you don't want to distinct "on the left" or "on the right" (what would simply be possible with operator*) but "on the local side" or "on the global side". Now, here comes the problem of column vs. row vectors into play EDIT, as already mentioned by YogurtEmperor/EDIT. To avoid any confusion, it would IMHO be best to implement 2 non-member functions that explicitely express their behaviour in their names, e.g.inline Matrix mulWithLocal( Matrix const& matrix, Matrix const& local );inline Matrix mulWithGlobal( Matrix const& matrix, Matrix const& global );(Made them inlined to avoid performance penalties.) Then implement the both helper routines w.r.t. the vector convention of your choice utilizing the operator*.The only issue with the solution above is IMHO that it needs more typing than a simple *.Just my 2 €-Cent.[Edited by - haegarr on April 24, 2010 10:43:24 AM] 0 Share this post Link to post Share on other sites
jyk 2094 Report post Posted April 24, 2010 Quote:Original post by haegarrNow, here comes the problem of column vs. row vectors into play, as already mentioned by YogurtEmperor.YogurtEmperor was actually referring to matrix majorness (a different issue).Quote:Original post by YogurtEmperorRow-major matrices used by DirectX produces results equal to the left operand followed by the right operand.Column-major matrices used by OpenGL produce results equal to the right operand followed by the left operand.It sounds like you might be confusing matrix 'majorness' with vector notation convention. When you say (e.g.) 'equal to the left operand followed by the right operand', I assume you mean that the resulting transform is equal to the transform represented by the matrix on the left, followed by the transform represented by the matrix on the right (as would be the case in DirectX). However, this doesn't have anything to do with matrix majorness; rather, it has to do with whether row vectors or column vectors are being used.In any case, this shouldn't have any impact on how the '*' operator is implemented for matrices; matrix multiplication is defined the same way (and should be implemented the same way) regardless of what vector notation convention is being used. 0 Share this post Link to post Share on other sites
haegarr 7374 Report post Posted April 24, 2010 Quote:Original post by jykQuote:Original post by haegarrNow, here comes the problem of column vs. row vectors into play, as already mentioned by YogurtEmperor.YogurtEmperor was actually referring to matrix majorness (a different issue).Uhh, I've read it in a hurry. You're right, of course. However,Quote:Original post by jykIn any case, this shouldn't have any impact on how the '*' operator is implemented for matrices; matrix multiplication is defined the same way (and should be implemented the same way) regardless of what vector notation convention is being used.is nevertheless exactly what I meant :) 0 Share this post Link to post Share on other sites
Ariste 296 Report post Posted April 24, 2010 A good way to keep track of this is to wrap your multiplication routine in another named member function, such as Concatenate. Let this function take care of the funny business of matrix multiplication order. This way client code need only worry about which transform should be concatenated, and not the (somewhat arbitrary) way in which this is accomplished. 0 Share this post Link to post Share on other sites
taz0010 277 Report post Posted April 24, 2010 Quote:for example consider a*b;Is "this" the left-side (a), and m the right-side (b)according to the function?Yes for all operators. a * b is the equivalent of a.operator*(b), so "this" is the left hand side, and the parameter is the right hand side. 0 Share this post Link to post Share on other sites
back2music 100 Report post Posted April 25, 2010 Quote:Original post by taz0010Quote:for example consider a*b;Is "this" the left-side (a), and m the right-side (b)according to the function?Yes for all operators. a * b is the equivalent of a.operator*(b), so "this" is the left hand side, and the parameter is the right hand side.As I suspected, I just forgot the logic around the operators and became unsure whatever was right soo thank you all!It's been 10 years since I worked with software development before I completely quit coding soo these little things are easy to forget.My old library routine for matrix multiplication was indeed in the incorrect order, it calculated B*A when it should have calculated A*B (I never tested them when I wrote them a long time ago since I used a sdk at the time).Once again, thank you all for your help! 0 Share this post Link to post Share on other sites