How does Transform3D().setScale(Vector3f) work?

Hi. A TransGroup (tg) I translate, rotate and scale by using its Transform3D object (t3d), and using these methods on the t3d:
t3d.setTranslation(Vector3f)
t3d.setRotation(Matrix3f)
t3d.setScale(float)
(… and afterwards tg.setTransform(t3d))

According to the (J3d) docu any of these three methods just changes its components of the transform (ie translational, rotational and scale, respectively), and so the order of calling them doesn’t matter, consequently.
For example if I just want to rotate the tg, I just send the setRotation(…) command.

This works fine. As long as I use setScale(float) for the scale part. When I try to scale the three axes differently by using setScale(vector), I get weird results: suddenly the scale and the rotation interferes heavily, and I don’t see the axis being scaled by the three values of the vector…

a) What am I doing wrong?
or
b) is there a bugette (*) ?

Thanks for help.

(*) Bugette being the nickname for a small bug…

For example Andrew Davison writes in his nice Java game book (the online draft, as URLed here in the forum; thanks for it) about Java3d Transform3D():[quote]
The set() method positions the sphere (…) and resets any previous rotations or scalings. set() can also be used to scale and rotate, while reseting the other transformations. The methods setTranslation(), setScale() and setRotation() only affect the given transformation.
[/quote]

From Transform3D.java in the Xith code:


setScale(Vector3f v) {
    matrix.m00 = v.x;
    matrix.m11 = v.y;
    matrix.m22 = v.z;
}

As a transform is represented as 4x4 matrix, using this method does affect the rotation matrix (which is the top-left 3x3 matrix). Someone correct me if I’m wrong though.

I would think that if you used setScale(float), it should affect the matrix in similar way, but since the method is implemented by Matrix4f and its source is hidden inside vecmath I cannot say anything for sure. But it’s possible that it just multiplies the given float by the values already in the diagonal of the matrix, not really disrupting the rotation.

The implementation of setScale(vector) could be slightly changed. I am not really sure, but I think you are better off multiplying transforms instead of setting values like that. Just have something like

Transform3D t = new Transform3D();
t.setScale(vector3f);
t3d.mul(t);

and it should work.

You said bugette, and I thought about a baguette (a word people using here for sandwhiches, not sure if its use’s worldwide though :p). And I’m actually hungry now :stuck_out_tongue:

[quote]For example Andrew Davison writes in his nice Java game book (the online draft, as URLed here in the forum; thanks for it) about Java3d Transform3D():
[/quote]
Have you got that URL at hand? I got curious :wink:
Tried searching for his name in the forum, but only found your post :stuck_out_tongue: I got a bit lazy to google it… so I’ll perfectly understand if you condem by lazyness :slight_smile:

[quote]From Transform3D.java in the Xith code:

setScale(Vector3f v) {
matrix.m00 = v.x;
matrix.m11 = v.y;
matrix.m22 = v.z;
}

As a transform is represented as 4x4 matrix, using this method does affect the rotation matrix (which is the top-left 3x3 matrix). Someone correct me if I’m wrong though.

I would think that if you used setScale(float), it should affect the matrix in similar way, but since the method is implemented by Matrix4f and its source is hidden inside vecmath I cannot say anything for sure. But it’s possible that it just multiplies the given float by the values already in the diagonal of the matrix, not really disrupting the rotation.
[/quote]
I see. Also I’ll have to re-learn Matrix theory. :slight_smile:

What Matrix4f does do on a setScale(float) basically is this (from the the Japanese Opensource version)


...
SVD(null, this);
mulRotationScale(scale);
...
private void mulRotationScale(float scale) 
{
m00 *= scale; m01 *= scale; m02 *= scale;
m10 *= scale; m11 *= scale; m12 *= scale;
m20 *= scale; m21 *= scale; m22 *= scale;
}

Thanks; I’ll try that soon.

Still, how valid is this sentence then: “The methods setTranslation(), setScale() and setRotation() only affect the given transformation.” … when a setScale(vector) actually affects the rotation components of the (T3d) transformation?

Andrew’s book is located on his web page in a draft version. Recently he found a publisher (O’Reilly?) for it!
His announcement can be found in this forum for Java3d and Java2d.

PS: [quote]You said bugette, and I thought about a baguette (a word people using here for sandwhiches, not sure if its use’s worldwide though :p).
[/quote]
Well, living next to France I like baguettes. :slight_smile:
“Bugette” is a wordplay, maybe invented by French programmers. :wink:

I think it’s better (less bug-prone) to have different transforms for each of the affine transformations. Although is not the most compact code you can have, to have different transform for rotation, scale and translation makes life easier.

The sentence is true (assuming you use the vecmath setScale), but that doesn’t mean different components of the matrix do not change. Using setScale() will not rotate the object,but it will change matrix elements that were associated with rotation (which makes it hard --or impossible?-- to retrieve the original scale or rotation values unless you know one of them from a different source).

If you have transforms t3d, Rot, Scl and Move:

t3d.mul(Scl)
t3d.mul(Rot)
t3d.mul(Move)
tg.setTransform(t3d);

Applying t3d to a node in the scenegraph, will scale first, rotate and then move the object. Note that if you were to move first, you rotation would be around the origin, so order is important.

I believe using the methods:

t3d.setTranslation(Vector3f)
t3d.setRotation(Matrix3f)
t3d.setScale(float)
tg.setTransform(t3d)

is quite different. I think the correct usage of transforms really depend on how you store the properties of an object. In my case, all my objects have a AffineTransformGroup object, which is just 3 TransformGroups attached to each other, and if I were to translate an object by [x,y,z], I would set up a transform and multiply it to the corresponding translation transform in my AffineTransformGroup. I could get a vector3f corresponding to the current translation, add to [x,y,z] and then set back to the Transform. But it’s basically the same thing :wink:

I read some where that there is not much loss in performance having a chain of transformsGroups instead of just one, because all these matrices get together are optimized later, but I’m not really sure :stuck_out_tongue:

Yes, that’s right. I now have three Transform3D() objects for my TransformGroup.

[quote]If you have transforms t3d, Rot, Scl and Move:

t3d.mul(Scl)
t3d.mul(Rot)
t3d.mul(Move)
tg.setTransform(t3d);

Applying t3d to a node in the scenegraph, will scale first, rotate and then move the object. Note that if you were to move first, you rotation would be around the origin, so order is important.
[/quote]
Well, it works like a charm now. Many thanks for your help.

Indeed t3d.setScale(vector) affects the matrix’ rotation parameters and the other way round.
The t3d.mul(Move) I can “optimize” to a t3d.setTranslation(Move) because the translation components of the transformation don’t affect the scale and rotation components.

So the Lightwave importer now also scales correctly. :slight_smile:

Cool! Prob. you should ask someone to upload it to the xith webpage, or have it somewhere public so we can have a go with it :wink:

Soon; I’ve still to fix some bugs…
Then I’ll upload a pre^3 alpha test version (source code) for you to play with and then, one day, when it’s usable, I’ll ask William how to upload it to the Xith toolkit page or so. :slight_smile:

I went to what it seemed to be the official unnofficial page of the vecmath library, and I realised that it’s not fully compliant with the javax.vecmath from Java3D. So far, I noticed that it’s missing TexCoord4f :stuck_out_tongue: It’s not really an issue, but I’m curious to know if I’m actually using the newest version of that library.

I got it from: http://objectclub.esm.co.jp/vecmath/index-j.html21

Thanks for that URL; didn’t know it yet.
I get my copy of the Japanese Vecmath from Abies’ page: http://nwn-j3d.sourceforge.net/jogl/vecmath.zip

However I had to add the clone interface (and mini method) to all the classes which I want to be able to clone.
This is another issue with the Japanese version not being fully compliant with the javax.vecmath from Java3D.