In my simple game i have two boxes, sun and planet. When the user press "u" i want to attach sun to planet, rotate the sun HALF_PI and deattach the planet, maintaining its rotation.
But after the first rotation, the whole thing starts spinning very fast and stops on weird positions. Can anyone help me understand what am i doing wrong?
I think you might have found something interesting here… I managed to make it work, but I think something weird is happening, because the first time you press 'u', the local translation of the planet is not modified by the rotation to the sun (which is what you would expect), but the second time around, IT DOES!!!
So, in order to get around that, after rotating the sun, I just updated the local translation to (-50, 0, 0), and added an updateGeometricState before the endRotation…
public class Test extends SimpleGame {
Node sun = new Node( "Sun" );
Node planet = new Node( "Planet" );
float angle;
float initialAngle;
boolean isRotating;
Yes, it should, but as I said, the system is behaving inconsistently with respect to local rotation on parent affecting local translation on child (it should affect world translation, but not the other one)
This made me realize that there must be something wrong with your references… The only way this would happen is if world AND local translations are REALLY the same object… So use this line at the end of your simpleUpdate method and you will see that they are true after pressing 'u' once!
Sorry about the necroposting, but I have tried his code and after having made the changes I still had to put the planet.setLocalTranslation( -50f, 0f, 0f ); on start rotating for it to work.
I cant understand why could this happened…
I am asking this cause I am also trying to work work with node rotations :S
Doing
planet.setLocalTranslation(planet.getWorldTranslation());
instead of
planet.getLocalTranslation().set(planet.getWorldTranslation());
is probalby one of the most common misstakes you can do when starting with jme.
I did it to in the first jme code I wrote and did my fair share of head banging :)
public class Test extends SimpleGame {
Node sun = new Node( "Sun" );
Node planet = new Node( "Planet" );
float angle;
float initialAngle;
boolean isRotating;
private void startRotation() {
System.out.println("Sun "+sun.getLocalTranslation());
System.out.println("Plnaet "+planet.getLocalTranslation());
rootNode.detachChild(planet);
sun.attachChild(planet);
planet.setLocalRotation( new Quaternion() );
planet.setLocalTranslation( -50f , 0, 0); // <--- if I comment this line it stops woking....
The answer is simple… Whenever a rotation event finishes, it attaches the planet to the root node, so any information about the translation and rotation must be stored in its local coordinate system since the reference from the sun is lost. This is why you have to do the following:
in the endRotation method. Like-wise, when the animation starts, you have to change the local coordinate system to that of the sun. Therefore setting the local translation to the fixed value and no rotation, this will make sure the sun is the one dictating the rotations/translations and no dangling data for when it was attached to the root.
Thanks for the explanation, but isnt there a way to do it without constant values, am I able to get the planet.setLocalTranslation( -50f, 0, 0); from some place instead of using a constant field ?
Well, to begin with, this was a very simple and specific example, IMHO you should always try to take advantage of the Scenegraph structure so you would ideally not have to detach and reattach children unless they truly change their reference point (like a character riding a car).