Some odd matrix math(help needed)
by Benj · in Torque Game Engine · 10/31/2007 (2:15 pm) · 7 replies
Ok so, i made a console method for getting the offset of a point in a scene objects local object space using its inverse matrix.
that works.
now i wanted to make one that does the same with a script transform(position and axis angle).
this i'am having some problems with.
i go in, place a object next to me, i open the console type a line in(ill post it here)
the point version is correct, the transform is way off....
any ideas?
that works.
now i wanted to make one that does the same with a script transform(position and axis angle).
this i'am having some problems with.
ConsoleMethod( SceneObject, transformToObjectSpace, const char*, 3, 3, "Multiplies a given transform by the objects inverse matrix(turning it to local object space)")
{
char *returnBuffer = Con::getReturnBuffer(256);
const MatrixF& imat = object->getWorldTransform();
MatrixF mat;
AngAxisF inputaa(mat);
Point3F inputpos,pos;
dSscanf(argv[2], "%g %g %g %g %g %g %g",
&inputpos.x, &inputpos.y, &inputpos.z, &inputaa.axis.x, &inputaa.axis.y, &inputaa.axis.z, &inputaa.angle);
inputaa.setMatrix(&mat);
mat.setColumn(3,inputpos);
mat.mul(imat);
mat.getColumn(3, &pos);
AngAxisF aa(mat);
dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
return returnBuffer;
}i go in, place a object next to me, i open the console type a line in(ill post it here)
==>echo(1551.transformtoobjectspace(1562.gettransform())); -5.33127 -10.162 32.0896 0.980506 -0.165641 0.10569 0.0914535 ==>echo(1551.pointtoobjectspace(1562.getposition())); 0.18336 3.89822 -0.329147 ==>echo(1551.gettransform()); 450.044 277.742 221.366 0 0 1 0.0900025 ==>echo(1562.gettransform()); 450.577 281.608 221.037 0.669368 -0.0823103 0.738365 0.134901
the point version is correct, the transform is way off....
any ideas?
About the author
#2
M.mul(a) = M * a -> M
M.mul(a, b) = a * b -> M
(see math/mMatrix.h)
Note that Matrix.mul(point) is actually "M * p -> p". The transformer goes first. M.mul(a) should be "M * a -> a" to be consistent with M.mul(p), but it isn't; so you'll want the M.mul(a,b) function instead.
10/31/2007 (11:11 pm)
Matrix multiplication is not communitive. I suspect you're multiplying the matrices in the wrong order. Try:const MatrixF& transMat = object->getWorldTransform(); MatrixF inMat; = input from script MatrixF outMat; outMat.mul(transMat, inMat); // return outMat
M.mul(a) = M * a -> M
M.mul(a, b) = a * b -> M
(see math/mMatrix.h)
Note that Matrix.mul(point) is actually "M * p -> p". The transformer goes first. M.mul(a) should be "M * a -> a" to be consistent with M.mul(p), but it isn't; so you'll want the M.mul(a,b) function instead.
#3
not sure what you meant about the mulp one but, my point version is this.
and it works fine.
i will try the separate matrix thing though.
edit: just tried:
didn't work.
11/01/2007 (7:00 am)
Then why do i get the same off the wall result when i do matrixmul from torquescript with the world transform?not sure what you meant about the mulp one but, my point version is this.
ConsoleMethod( SceneObject, pointToObjectSpace, const char*, 3, 3, "Multiplies a given point by the objects inverse matrix(turning it to local object space)")
{
char *returnBuffer = Con::getReturnBuffer(128);
const MatrixF& mat = object->getWorldTransform();
Point3F p(0.0f, 0.0f, 0.0f);
dSscanf(argv[2], "%g %g %g", &p.x, &p.y, &p.z);
mat.mulP(p);
dSprintf(returnBuffer, 128, "%g %g %g", p.x, p.y, p.z);
return returnBuffer;
}and it works fine.
i will try the separate matrix thing though.
edit: just tried:
outmat.mul(imat,mat);
didn't work.
#4
Probably because you're multiplying the matrices in the wrong order there too. What does your script multiplication look like?
What I mean is that if you compare Matrix::mul(Matrix) with Matrix::mulP(Point), you'll find they are inconsistent in their behavior.
Perhaps you're confusing yourself by not keeping your variable names consistent? in your Point function, let's change it to read:
Now we'll take a direct comparison between your Point and Matrix multiplication functions:
imat.mulP(p) = imat * p
mat.mul(imat) = mat * imat
See the problem? Whereas
outMat.mul(imat, mat) = imat * mat
which is correct.
I tested it briefly to be sure, and found it to work fine. Perhaps you forgot to change the return values?
11/01/2007 (8:40 am)
Quote:Then why do i get the same off the wall result when i do matrixmul from torquescript with the world transform?
Probably because you're multiplying the matrices in the wrong order there too. What does your script multiplication look like?
Quote:not sure what you meant about the mulp one
What I mean is that if you compare Matrix::mul(Matrix) with Matrix::mulP(Point), you'll find they are inconsistent in their behavior.
Perhaps you're confusing yourself by not keeping your variable names consistent? in your Point function, let's change it to read:
ConsoleMethod( SceneObject, pointToObjectSpace, const char*, 3, 3, "Multiplies a given point by the objects inverse matrix(turning it to local object space)")
{
char *returnBuffer = Con::getReturnBuffer(128);
const MatrixF& [b]imat[/b] = object->getWorldTransform();
Point3F p(0.0f, 0.0f, 0.0f);
dSscanf(argv[2], "%g %g %g", &p.x, &p.y, &p.z);
[b]imat[/b].mulP(p);
dSprintf(returnBuffer, 128, "%g %g %g", p.x, p.y, p.z);
return returnBuffer;
}Now we'll take a direct comparison between your Point and Matrix multiplication functions:
imat.mulP(p) = imat * p
mat.mul(imat) = mat * imat
See the problem? Whereas
outMat.mul(imat, mat) = imat * mat
which is correct.
Quote:didn't work.
I tested it briefly to be sure, and found it to work fine. Perhaps you forgot to change the return values?
outmat.mul(imat, mat);
[b]outmat[/b].getColumn(3, &pos);
AngAxisF aa([b]outmat[/b]);
dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
return returnBuffer;
#5
about the multiplication order, whats strange is when i do it on paper it works out as the matrix X the inverse, as when i test the math part in blender threw scripting.
11/01/2007 (10:19 am)
I get what your saying, its still spitting out the wrong values though. with this codeConsoleMethod( SceneObject, transformToWorldSpace, const char*, 3, 3, "Multiplies a given transform(hopefully object space) by the objects matrix(turning it to world space)")
{
char *returnBuffer = Con::getReturnBuffer(256);
const MatrixF& imat = object->getTransform();
MatrixF mat,outmat;
AngAxisF inputaa(mat);
Point3F inputpos,pos;
dSscanf(argv[2], "%g %g %g %g %g %g %g",
&inputpos.x, &inputpos.y, &inputpos.z, &inputaa.axis.x, &inputaa.axis.y, &inputaa.axis.z, &inputaa.angle);
inputaa.setMatrix(&mat);
mat.setColumn(3,inputpos);
outmat.mul(imat,mat);
outmat.getColumn(3, &pos);
AngAxisF aa(outmat);
dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
return returnBuffer;
}about the multiplication order, whats strange is when i do it on paper it works out as the matrix X the inverse, as when i test the math part in blender threw scripting.
#6
11/01/2007 (10:31 am)
O_o When did it become transformToWorldSpace? Are you sure you're working with the correct function?
#7
11/01/2007 (12:44 pm)
Errrrr..... >_>..... pay no attention to the man behind the curtain...... lol whoops, works now, thanks lol
Torque Owner Benj