Hello animation null pointer exception may have been solved at last

playerModel = (Node)assetManager.loadModel("/Models/character.glb");

This is ok for testing but not for in game.

If you read the links from @Ali_RS you will see you need to convert the model to j3o using the binary exporter or SDK. Using 3.2.4 or earlier versions. This will add the AnimControl to the model.

This is a .glb file and you are loading it without converting so it is loaded with AnimComposer control. You can change your code to use the new system, or convert the model and use the old system.

Your control is under the playerModel node somewhere,

playerModel = (Node)assetManager.loadModel("/Models/character.glb");

You can also traverse this Node using a SceneGraphVisitorAdapter, edit for your use case,

        spatial.depthFirstTraversal(new SceneGraphVisitorAdapter() {
            @Override
            public void visit(Node node) {
                if (node.getControl(AnimControl.class) != null) {
                    animControl = node.getControl(AnimControl.class);
                    animControl.addListener(new AnimationEventListener());
                    animChannel = animControl.createChannel();
                }
            }
        });

The wiki will be updated on its v3.3.0 release. The current wiki is 3.2.4.

Thanks.

My old video

j3o → armature → object : control

 playerModel.depthFirstTraversal(new SceneGraphVisitorAdapter() {
            @Override
            public void visit(Node node) {
                if (node.getControl(AnimControl.class) != null) {
                    animControl = node.getControl(AnimControl.class);
                    animControl.addListener(new AnimationEventListener());
                    animChannel = animControl.createChannel();
                }
            }
        });
    
     animChannel.setAnim("run");  

 animChannel.setAnim("run");  

returns null

  playerModel = (Node)assetManager.loadModel("/Models/character.glb");
    sceneModel.setLocalScale(0.2f);
    rootNode.attachChild(playerModel);
    
    playerModel.move(0, 0, 7f);
    

  //playerControl.addListener( this);
  /**
     * ANIMATION
     */
 
        animControl = playerModel.getChild("test.001").getControl(AnimControl.class);
         animControl.addListener((AnimEventListener) this);
         animChannel = animControl.createChannel();

null

As @Ali_RS said it’s AnimComposer not AnimControl.

You are full of energy to code but must slow down to read. Relax. Slow down.

1 Like

My character model → to j3o
don’t have aramature and anim control

how to fix it?

export bug? where anim control?

image
image
image
image
image

i can create animControl from this 3d model?

or get AnimControl from animComposer?

You need to read the messages already posted. Like ACTUALLY READ them.

   animComposer = playerModel.getControl(AnimComposer.class);
        /// animControl.addListener((AnimEventListener) this);
        // animChannel = animControl.createChannel();

now i have animComposer class

but animControl and anim chanel not work

That’s it… I’ll let others try to take over helping now.

Download that and convert the model to j3o.

You are using SDK 3.3.0.
AnimComposer is different. See Ali post. It even has both systems in it.

problem is that you are thinking wrong.

AnimComposer is NOT AnimControl related.

This are 2 different controls.

AnimControl is for JME 3.2
AnimComposer is for JME 3.3

if you export model using 3.2 you get AnimControl control.
if you export model using 3.3 you get AnimComposer control.

you can make AnimComposer from AnimControl using utility, but you cant do otherwise.

Overall knowledge you are missing is that JME 3.3 use Different animation system (old one is deprecated there)

1 Like

Okay
i install jmonkeyengine 3.2

package mygame;


import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.SceneGraphVisitor;
import com.jme3.scene.SceneGraphVisitorAdapter;
import com.jme3.scene.Spatial;
import java.util.ArrayList;
/**
 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 * @author normenhansen
 */



public class Main extends SimpleApplication  implements ActionListener, AnimEventListener {
  private Spatial sceneModel;
  private Node playerModel;
  private float rotationYOld;
  
  private BulletAppState bulletAppState;
  private RigidBodyControl landscape;
  private CharacterControl player;
  private Vector3f walkDirection = new Vector3f();
  private boolean left = false, right = false, up = false, down = false;

  private AnimChannel animChannel;
    private AnimControl animControl;

  
  //Temporary vectors used on each frame.
  //They here to avoid instanciating new vectors on each frame
  private Vector3f camDir = new Vector3f();
  private Vector3f camLeft = new Vector3f();
  

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    public void simpleInitApp() {
    /** Set up Physics */
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    //bulletAppState.setDebugEnabled(true);

    // We re-use the flyby camera for rotation, while positioning is handled by physics
    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
    flyCam.setMoveSpeed(100);
    setUpKeys();
    setUpLight();

    // We load the scene from the zip file and adjust its size.
    //assetManager.registerLocator("new-scene.zip", ZipLocator.class);
    sceneModel = assetManager.loadModel("/Models/untitled.glb");
    sceneModel.setLocalScale(2f);
    
    playerModel = (Node)assetManager.loadModel("/Models/character.glb");
    sceneModel.setLocalScale(0.2f);
    rootNode.attachChild(playerModel);
    
    playerModel.move(0, 0, 7f);
    

  //playerControl.addListener( this);
  /**
     * ANIMATION
     */
  
         animControl = playerModel.getChild("test.001").getControl(AnimControl.class);
 
         animControl.addListener((AnimEventListener) this);
         animChannel = animControl.createChannel();
  
     
    //playerModel = assetManager.loadModel("Models/character.glb");
    
    // We set up collision detection for the scene by creating a
    // compound collision shape and a static RigidBodyControl with mass zero.
    CollisionShape sceneShape =
            CollisionShapeFactory.createMeshShape(sceneModel);
    landscape = new RigidBodyControl(sceneShape, 0);
    sceneModel.addControl(landscape);
    
    /**
     * We set up collision detection for the player by creating
     * a capsule collision shape and a CharacterControl.
     * The CharacterControl offers extra settings for
     * size, stepheight, jumping, falling, and gravity.
     * We also put the player in its starting position.
     */
    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 3f, 1);
    player = new CharacterControl(capsuleShape, 0.05f);
    player.setJumpSpeed(50);
    player.setFallSpeed(50);

    
    // We attach the scene and the player to the rootnode and the physics space,
    // to make them appear in the game world.
    rootNode.attachChild(sceneModel);

    
    player.setSpatial(playerModel);

    bulletAppState.getPhysicsSpace().add(landscape);
    bulletAppState.getPhysicsSpace().add(player);

    // You can change the gravity of individual physics objects before or after
    //they are added to the PhysicsSpace, but it must be set before MOVING the
    //physics location.
    player.setGravity(new Vector3f(0,-30f,0));
    player.setPhysicsLocation(new Vector3f(4, 12, 4));
    
    
  }
    
        private void setUpLight() {
       // We add light so we see the scene
       AmbientLight al = new AmbientLight();
       al.setColor(ColorRGBA.White.mult(0.5f));
       rootNode.addLight(al);

       DirectionalLight dl = new DirectionalLight();
       dl.setColor(ColorRGBA.White);
       dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
       rootNode.addLight(dl);
  }
     
     private void setUpKeys() {
    inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
   // inputManager.addListener(actionListener, "Walk");
    
    
    
    
    inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addListener(this, "Left");
    inputManager.addListener(this, "Right");
    inputManager.addListener(this, "Up");
    inputManager.addListener(this, "Down");
    inputManager.addListener(this, "Jump");
  }
     
  
  
  
  
       /** These are our custom actions triggered by key presses.
   * We do not walk yet, we just keep track of the direction the user pressed. */
  public void onAction(String binding, boolean isPressed, float tpf) {
    if (binding.equals("Left")) {
      left = isPressed;
    } else if (binding.equals("Right")) {
      right= isPressed;
    } else if (binding.equals("Up")) {
      up = isPressed;
    } else if (binding.equals("Down")) {
      down = isPressed;
    } else if (binding.equals("Jump")) {
      if (isPressed) { player.jump(new Vector3f(0,20f,0));}
    }
  }

    @Override
    public void simpleUpdate(float tpf) {
        camDir.set(cam.getDirection()).multLocal(0.6f);
        camLeft.set(cam.getLeft()).multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());
        
        //Quaternion  playerRotation =  new Quaternion(walkDirection.x,walkDirection.y,walkDirection.z,0);
        //playerModel.setLocalRotation(playerRotation);
       
       //player.setPhysicsLocation(player.getPhysicsLocation());
        playerModel.setLocalTranslation (player.getPhysicsLocation().x , player.getPhysicsLocation().y, player.getPhysicsLocation().z);
        
        
        /**
         * Rotation camera with chacarter
         */
        float[] angles = new float[3];
        cam.getRotation().toAngles(angles); // we get the cam angles here
        angles[0] = 0; // you don't want to rotate along the x-axis, so we set it to 0
        angles[2] = 0; // you don't want to rotate along the z-axis, so we set it to 0
        playerModel.setLocalRotation(playerModel.getLocalRotation().fromAngles(angles));

        //playerModel.setLocalRotation(q);
    }

    @Override
    public void onAnimCycleDone(AnimControl ac, AnimChannel ac1, String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void onAnimChange(AnimControl ac, AnimChannel ac1, String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }




    
    
    
}

jmonkey engine 3.2.4

null poiner exception at line

animControl.addListener((AnimEventListener) this);

You don’t read… You need to import the model using jme 3.2

1 Like

https://wiki.jmonkeyengine.org/docs/jme3/intermediate/multi-media_asset_pipeline.html#convert-3d-models-to-j3o-format

You are almost there. :crossed_fingers:

Hello i listen
Try conver models from jmonkey 3.2 and move to jmonkey 3.3

try all versions jmonkey
jmonkey is better 3d sdk i think,
but i start code 3d engine based “Java 3d open gl”

  • loader 3d
  • animations
  • collisions

Tutorial not work
https://wiki.jmonkeyengine.org/docs/jme3/beginner/hello_animation.html