Hello. I’m having the following problem:
When I execute the following code…
var mat = new Matrix4f(
0, 1, 0, 0,
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
System.out.println(mat);
var t = new Transform();
t.fromTransformMatrix(mat);
System.out.println(t.toTransformMatrix());
So all I wanted to do was just swap the x- and y-axis, but Transform won’t allow me to.
The real use-case is much more complex than that of cause. I’ve just broken it down to the essential parts here.
Transform does not support the swapping of axes because it’s internally using a quaternion for rotation. Simplifying rotations with a quaternion necessarily means that assumptions need to be made about axes orientations and handedness. Simplifying rotations with a quaternion comes with a ton of other benefits for a game engine… which is why JME uses that instead of hauling around matrix multiplication everywhere.
Edit: but if you explain what you are actually trying to do then maybe we can provide some alternative approaches.
Thank you for the really fast answer.
It would be helpful if the code would throw me an exception then.
What I’m trying to do is the following:
My graphics card does not support glLineWidth(). glGetFloatv(GL13.GL_LINE_WIDTH_RANGE) gives me float[1.0,1.0].
So I came up with the idea to just draw a small Box around all the lines.
Lines are given by a start and end Vector3f and lineWidth is given as a float.
I successfully computed a transformation matrix that does exactly that. But then I ran into the problem above.
The math probably still worked, it just didn’t produce the results you wanted. Adding specific checks for every odd thing that a caller might send in can really bog down the code after a while.
Are the lines in 2D space or 3D space?
Either way, I feel like you can still do what you want to do without messing with coordinate axes… but I can’t see the code to know why you felt that was necessary in the first place. A box (3D or otherwise) can be projected along a line without swapping axes.
3D space of cause. In 2D, this problem would be way too easy to bother you (or someone else around here).
Yes, I know that that can be done. I just don’t know how.
“Messing” with coordinate axes was the easiest way, because you just have to compute two vectors “a” and “b” from the line vector “v” with a.dot(b) == a.dot(v) == 0 and then you basically have your transformation matrix.
I also tried to use Camera.lookAtDirection and then use the view matrix, but without any luck so far.
But I will try some other workarounds…
Okay, I have a solution. I’m documenting it here just in case someone else has the same problem. Thanks again @pspeed for your help.
Let var box = new Box(lineWidth/2,v.length()/2,lineWidth/2); be the according box and “v” be the line vector.
You can compute the Quaternion for the rotation by using Quaternion.fromAngleAxis() with var angle = Vector3f.UNIT_Y.angleBetween(v.normalize()); and var axis = Vector3f.UNIT_Y.cross(v);.
Of couse, you also have to translate, but that shouldn’t be a problem.
If your box is oriented with Z as the long axis then Quaternion().lookAt() will orient the box correctly if passed the normalized line.end1 - line.end2 vector.
Care needs to be taken if the line is parallel to the up vector supplied.