Preventing a box rotating when its node rotates?

The subject says it all really - I have a box attached to a node, and would like its rotation to remaing fixed even if the node rotates.  I thought it might be simple with something like this:-



box.setLocalRotation(box.getParent().getLocaRotation().mult(-1))



…but that doesn't seem to work.

lock transforms on the box should do it…

ncomp said:

lock transforms on the box should do it....


Without having actually experimented with this, I think that this solution would also prevent the box from moving within the node. This could be a problem, if the functionality you want includes being able to move the box, but not rotate it.

If this is the case, I suggest running your game and printing the rotation during start-up (i.e. the rotation you'll want the box to maintain). Then, in your update method, do something like this:


//during initGame()
cuberot = myCube.getLocalRotation().clone(); //cuberot is a global Quaternion object

//during update()
if(!myCube.getLocalRotation().equals(cuberot))
     myCube.setLocalRotation(cubeRot.clone());



Which would be an effective solution for locking only rotations.

But fixing the local rotation won't stop the world rotation changing when the parent rotates.



I'm curious as to how the original solution doesn't work.



Here's a SimpleGame test I modified to try it, I used inverse() instead of multiplying by -1.:



public class RotationEx extends SimpleGame {

   Quaternion q = null;
   Box b2 = null;
   Box b = null;
   Node n = null;
   
   @Override
   protected void simpleInitGame() {
   
      b = new Box("Box", new Vector3f( 0, -1.0f, -0.5f), new Vector3f( 5.0f, 1.0f, 0.5f));
      b.setLocalTranslation( 0, 0, 0);
      b2 = new Box("Box", new Vector3f( -2.5f, -2.5f, -2.5f), new Vector3f( 2.5f, 2.5f, 2.5f));
      b2.setLocalTranslation(5.0f, 0, 0);
      
      q = new Quaternion();
      
      n = new Node ("centreOfRotation");
      n.attachChild(b);
      n.attachChild(b2);
      
      rootNode.attachChild(n);
      wireState.setEnabled(true);
   }
   
   protected void simpleUpdate() {
      q.fromAngleNormalAxis(1.0f * tpf, new Vector3f(0,1.0f,0) );
      n.getLocalRotation().multLocal(q);

      b2.setLocalRotation( b2.getParent().getLocalRotation().inverse() );
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      RotationEx demo = new RotationEx();
      demo.setConfigShowMode(ConfigShowMode.AlwaysShow);
      demo.start();
   }

}



EDIT: Made it JME2 ;p

my bad…i thought you wanted the box's transform to stay fixed at all time…

apologies…

Alric, that does it perfectly!  Thanks a lot.  Looking at the JME sourcecode, inverse() does a lot more than just multiplies it by -1, and it does the trick.


Isn't this pretty much what a billboard node does ?

Not exactly - a billboard doesn't rotate relative to the camera, but it is actively rotated in the world, to face the camera.