Node 'moving' when I add AnimControl to it, and somehow "null"

Hi everyone!

I am trying to add an animation to a Node. The animation simply changes the rotation of the node over time. (The node is used to control a weapon, like a turret).

My problem is, everything works fine until you add the animation for the first time. At that point, the weapon node jumps from its correct position (0,6,0), to (0,0,0), seemingly without being told.

Further, when I am debugging it through the use of Print statements, the Node is printed out as “null (Node)”, But I am confident it is not null, and no exceptions are raised.

I really have no clue what is happening! I’m sure it shouldn’t be null, as there are methods being applied to this ‘null’ Node, and I really don’t see why it would change location regardless. Any help would be appreciated!

An excerpt from the Print-out is shown below, starting from the first instance where the animation is applied

RECEIVED: $$WEAPROT:1|192.168.1.8|8889|-0.18309613, 0.6810445, 0.18292011, 0.68497765|1 Shooting! Player null (Node) Node location: (0.0, 6.0, 0.0) Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0) Shooting = true Shooting value = 1 New Player null (Node) Node location: (0.0, 0.0, 0.0) New Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0) RECEIVED: $$WEAPROT:1|192.168.1.8|8889|-0.18301918, 0.6813391, 0.18299787, 0.68468446|1 Shooting! Player null (Node) Node location: (0.0, 0.0, 0.0) Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0) Shooting = true Shooting value = 1 New Player null (Node) Node location: (0.0, 0.0, 0.0) New Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0) RECEIVED: $$WEAPROT:1|192.168.1.8|8889|-0.18295474, 0.68163043, 0.18306322, 0.6843941|1 Shooting! Player null (Node) Node location: (0.0, 0.0, 0.0) Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0) Shooting = true Shooting value = 1 New Player null (Node) Node location: (0.0, 0.0, 0.0) New Player TurbineCannon-geom-0 (Geometry) location: (0.0, 1.0, 0.0)

The code controlling the animation is here:

   public void updatePeerWeapon(Quaternion weapRot, Boolean shooting, float delay)
    {
        final Quaternion newWeapRot = weapRot;
        Quaternion curWeapRot = playerVehicle.getPlayerWeaponNode().getLocalRotation();
        
        System.out.println("Player "+ playerVehicle.getPlayerWeaponNode()+" Node location: "+playerVehicle.getPlayerWeaponNode().getLocalTranslation());
        System.out.println("Player "+ playerVehicle.getPlayerWeapon().getWeapon().toString() +" location: "+playerVehicle.getPlayerWeapon().getWeapon().getLocalTranslation());
        
        if(shooting == true){playerVehicle.startShooting();}else{playerVehicle.stopShooting();}
        
        AnimationFactory factory = new AnimationFactory(delay, "weapRot");
        factory.addTimeRotation(0, curWeapRot);
        factory.addTimeRotation(delay, newWeapRot);

        final AnimControl rotAnimControl = new AnimControl();
        rotAnimControl.addAnim(factory.buildAnimation());
        playerVehicle.getPlayerWeaponNode().addControl(rotAnimControl);
        rotAnimControl.createChannel().setAnim("weapRot");
        rotAnimControl.getChannel(0).setLoopMode(LoopMode.DontLoop);
        
        rotAnimControl.addListener(new AnimEventListener(){

            public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
                playerVehicle.getPlayerWeaponNode().removeControl(rotAnimControl);
                playerVehicle.getPlayerWeaponNode().setLocalRotation(newWeapRot);
                System.out.println("New Player "+ playerVehicle.getPlayerWeaponNode() +" Node location: "+playerVehicle.getPlayerWeaponNode().getLocalTranslation());
                System.out.println("New Player "+ playerVehicle.getPlayerWeapon().getWeapon().toString() +" location: "+playerVehicle.getPlayerWeapon().getWeapon().getLocalTranslation());
                //playerVehicle.setShooting(false);
            }

            public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
                
            }
        });
        
        
        
    }

If I perform a ‘proper’ test, to compare the node to null, my print statement below never gets fired, so it’s clearly a naming issue…

       if(playerVehicle.getPlayerWeaponNode() == null)
        {
            System.out.println("The Weapon Node, "+playerVehicle.getPlayerWeaponNode()+" IS NULL.");
        }

But still, if I add an AnimControl to the node, it immediately defaults back to its ORIGINAL position (0,0,0).
I also noticed, if I apply the AnimControl to the Spatial which is attached to the Node, that spatial too will default to its original position, and scale. (resulting in an object which is too big).

…Still stuck though!

Further, when I am debugging it through the use of Print statements, the Node is printed out as “null (Node)”, But I am confident it is not null, and no exceptions are raised.

Of course it’s not null because it printed something. It didn’t print “null”. It printed “null (Node)”… ergo it cannot possibly be null. The ‘null’ part is the name of the node which just wasn’t set. So you were fine to be confident and moreover all of the information was right there.

Note: the source code is only two clicks away if you ever want to look at something like that and have 10 extra seconds. It’s a great learning experience. Take a look at Spatial.toString

…you could probably even sort out your real issue that way, too. Poke around in AnimationFactory.

Hello pspeed, thanks for you help.

A little bit before you posted this response, I was able to sort out the issue. It turns out that I was wrong to assume that because there were no changes to the translation of the Node in the AnimFactory, that the original translation would be kept. This is however incorrect.

I need to explicitly tell the AnimFactory that it should retain the original location:

        AnimationFactory factory = new AnimationFactory(delay, "weapRot");
        factory.addTimeRotation(0, curWeapRot);
        factory.addTimeRotation(delay, newWeapRot);
        factory.addTimeTranslation(0, oldTranslation);  //<- This line is the solution

Thanks for your help, I am glad to have solved this!