I recently made a Blender (version 2.68a) model of a human male to be imported into JME3 (version 3.0). I used vertex groups connected to bones to allow bone animations. When I imported the file into JME3, it loaded properly. However, when I attempted to run the following code to test if the animations would work, I received a NullPointerException on the line “control.addListener(this);”
Here is the code I am using:
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.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
/** Sample 7 - how to load an OgreXML model and play an animation,
- using channels, a controller, and an AnimEventListener. */
public class Main extends SimpleApplication implements AnimEventListener
{
private AnimChannel channel;
private AnimControl control;
Node player;
public static void main(String[] args)
{
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp()
{
viewPort.setBackgroundColor(ColorRGBA.LightGray);
initKeys();
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal());
rootNode.addLight(dl);
//player = (Node) assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);
player = (Node) assetManager.loadModel(“Models/human_malev4c2a3v10t5/human_malev4c2a3v10t5.j3o”);
player.setLocalScale(0.5f);
rootNode.attachChild(player);
control = player.getControl(AnimControl.class);
control.addListener(this); //NullPointerException here
channel = control.createChannel();
channel.setAnim(“stand”);
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName)
{
if (animName.equals(“Walk”))
{
channel.setAnim(“stand”, 0.50f);
channel.setLoopMode(LoopMode.DontLoop);
channel.setSpeed(1f);
}
}
public void onAnimChange(AnimControl control, AnimChannel channel, String animName)
{
// unused
}
/** Custom Keybinding: Map named actions to inputs. */
private void initKeys() {
inputManager.addMapping(“Walk”, new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(actionListener, “Walk”);
}
private ActionListener actionListener = new ActionListener()
{
public void onAction(String name, boolean keyPressed, float tpf)
{
if (name.equals(“Walk”) && !keyPressed)
{
if (!channel.getAnimationName().equals(“Walk”))
{
channel.setAnim(“Walk”, 0.50f);
channel.setLoopMode(LoopMode.Loop);
}
}
}
};
}
This code is the same as that found in the HelloAnimation tutorial, except with the loaded model changing. By running a few tests, I found out that I am getting the NullPointerException because the line control = player.getControl(AnimControl.class); returned null. I also tried to export as an Ogre file, but this yielded the same result.
I have my animations on one strip in the Blender NLA editor. The model has a root bone properly positioned.
I have searched through various other sources (JME3 documentation, Blender and JME3 tutorials, forum posts, and videos) and I have yet seen any solution to the problem.
So my question is this: How do you set up a model in Blender so that JME3 understands how to retrieve an AnimControl from it?
Thanks!