[SOLVED] How to implemet animation for any Moving Spatial or Object

Hello,
I have implemented Animation Channel with one AnimControl
Now , when i run my program i get a NullPointerException as if i havenot initialized the Object Anim Channel or Anim Control… Any Suggestions ?
Thank you,

Code:

AnimControl control = spaceship.getControl(AnimControl.class);
              System.out.println(control);//it gives me null in stackTrace
                 channel = control.createChannel();

in simpleInitApp();

&

 if (KeysListener.up) {
                    channel.setLoopMode(LoopMode.DontLoop);
                    channel.setAnim("Up", 1.3f);
                    walkDirection.addLocal(cam.getDirection().multLocal(0.1f));
                    rotateShip(spaceship, walkDirection, new Vector3f(0f,cam.getRotation().getY(),0f));
                    System.out.println(walkDirection);
        }

in simpleUpdate(float tpf);

If control is null then spaceship doesn’t have an AnimControl.

1 Like
1 Like

Or it’s on a child… or…

Could be three or four things. Need more information to know what.

1 Like

Actually , yes it doesnot have ,but i didnot find how to create one for a spatial or node in JmE wiki

It’s hard to answer questions unasked, unfortunately. Then we play 20 questions.

What are you actually trying to do?
What have your tried?
…etc…

1 Like

I have tried snippets of what i have sent here which is the same as JME wiki, but they seem they are not complete code because i cannot find resource …i have read examples & wiki

What are you actually trying to do?

As in, what do you want to accomplish? What are you starting with? Where does spaceship come from?

Actually… I’m out. I’ll let other people play the game. I will say that not once in the entire history of JME questions has anyone ever complained that OP provided too much information. So if you are going to err in one direction or another: provide way more information than you right now think is required.

I just want to assign an AnimControl to a spatial or Node

That’s easy.
mySpatial.addControl(new AnimControl());

…but probably, and I’m just going out on a limb here… you actually want to DO something with it.

Because just adding an anim control to a node or spatial is going to have an empty anim control, no skeleton, etc…

And now we are right back to what are you ACTUALLY trying to do? “Having a control on the spatial” is not your end goal. Else you can do that in one line above and be done.

all i understand is that you get NullPointer about something animation related(i noticed now you have it on control variable), but you didnt provide full stacktrace.

i can only guess your issue now.

you probably have AnimComposer instead of AnimControl classes due to 3.3 changes.

or you have no animations exported with model.

Still, like people said above, it lack information to help u.

informations that could help help u.:

  • how do you export spaceship(where it get from like pspeed already asked)
    its important, because this control is get from export usually.

  • are you sure model have animations in source in it?

  • what JME version model was exported/created and what JME version you use to load it.

1 Like

Okay , i solved my problem , created code manually with one TransformTrack as a single keyFrame :smile:

Code :

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package JPlutoAnimation;

import com.jme3.anim.AnimClip;
import com.jme3.anim.AnimComposer;
import com.jme3.anim.AnimTrack;
import com.jme3.anim.TransformTrack;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;

/**
 *
 * @author twisted aka Pavly G.
 */
public class ModelAnimator {
    private final AnimComposer anim=new AnimComposer();
    private final AnimClip clip;
    private final Node spatial;
    private final String Animclipname;
    private Quaternion[] rotations;
    private Vector3f[] scales;
    private Vector3f[] translations;
    private AnimTrack[] tracks=new AnimTrack[3];
    private int num=0;
    /**
     * Create a simple animation Thread for a Particular mesh composed of one TransFormTrack 
     * @param spatial model to add the animation to .
     * @param Animclipname name of animation thread .
     */
    public ModelAnimator(Node spatial,String Animclipname){
        /**
         * Create new AnimClip 
         * Add the animClip to new AnimControl System(AnimComposer)
         */
        clip=new AnimClip(Animclipname);
        anim.addAnimClip(clip);
        /**
         * Assign the Control to a particular Spatial
         */
        spatial.addControl(anim);
        
        this.spatial=spatial;
        this.Animclipname=Animclipname;
        
    }
    /**
     * Add translations for the TransformTrack thread 
     * @param translations set of translations to be played as animation
     * @return Vector3f[] representing set of translations to be played as animation
     */
    public Vector3f[] addTranslations(Vector3f[] translations){
        this.translations=translations;
        return translations;
    }
    /**
     * Add scales for the TransformTrack thread
     * @param scales set of scales to be played 
     * @return Vector3f[] representing set of scales to be played as animation
     */
    public Vector3f[] addScales(Vector3f[] scales){
        this.scales=scales;
        return scales;
    }
    /**
     * Add rotations for the TransformTrack thread
     * @param rotations set of quaternions to be played
     * @return Vector3f[] representing set of rotations to be played as animation
     */
    public Quaternion[] addRotations(Quaternion[] rotations){
        this.rotations=rotations;
        return rotations;
    }
    /**
     * Create a new TransformTrack holding the addTranslations(Vector3f[] translations),addScales(Vector3f[] scales),addRotations(Quaternion[] rotations)
     * @param frameClock time of the frame holding addTranslations(Vector3f[] translations),addScales(Vector3f[] scales),addRotations(Quaternion[] rotations)
     *                      that you have assigned previously
     */
    public void applyTracks(float[] frameClock){
          /**
           * Add a transformation track
           */
          TransformTrack track=new TransformTrack(spatial, frameClock, addTranslations(translations), addRotations(rotations)
                , addScales(scales));
          /**
           * set Animation Clip Tracks(Motion Path for Bones)
           */
   
          clip.setTracks(new AnimTrack[]{track});
          /**
           * start the animation
           */
          spatial.getControl(AnimComposer.class).setCurrentAction(Animclipname);
          /**
           * freezes the animation till you press start
           */
          anim.setEnabled(false);

    }
    
    /**
     * starts the animation state
     * @return true if succeeded
     */
    public boolean start(){
           /**
           * Run the animation Control Tracks
           */
           if(!anim.isEnabled()){
               anim.setEnabled(true);
                return true;

           }else{
            return false;
           }
    }
    
    /**
     *Stops the animation state
     * @return true if it stops
     */
    public boolean stop(){
        /**
           * Run the animation Control Tracks
           */
           if(anim.isEnabled()){
               anim.setEnabled(false);
                         return true;

           }else{
            return false;
           }
    }
    
}

added to a Trophy for physicsListener :
(Node)((Node)rootNode.getChild("Trophy")).getChild("openTrophy")

Runs onCollision :

 new CollisionerCondition(pce, "Mars Rover", "Trophy") {
            @Override
            public void execute() {
                    animTrophy=new ModelAnimator((Node)((Node)rootNode.getChild("Trophy")).getChild("openTrophy"), "trophyAnim");
                    animTrophy.addScales(new Vector3f[]{new Vector3f(20f,20f,25f),new Vector3f(20f,20f,30f),new Vector3f(20f,20f,40f)});
                    animTrophy.applyTracks(new float[]{0.4f,0.8f,1.16f});
                    animTrophy.start();   
            }
        };

Look at the red trophy :

1 Like