MD5 animation controller

I have 20 MD5 animation (.md5anim) and 1 MD5 mesh (.md5mesh)



How can I make a MD5 animation controller to load 1 out of the 20 animation?



The following code has 2 animation, but if I have 20 animation, the code will repeat alot as # of animation increase.



What's a good way to modify the following code to deal with alot animation files?



import com.jme.app.SimpleGame;

import com.jme.bounding.BoundingBox;

import com.jme.light.PointLight;

import com.jme.math.Quaternion;
import com.jme.math.Vector3f;

import com.jme.renderer.ColorRGBA;

import com.jme.scene.Node;

import md5reader.MD5AnimReader;
import md5reader.MD5MeshReader;

import model.Model;
import model.SkeletalModelInstance;

import model.animation.*;
import model.animation.Animation;
import model.animation.AnimationAnimator;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import com.jme.input.*;

public class Player extends SimpleGame {
    private static final String BODYMODEL = "models/aaa.md5mesh";
    private static final String RUNNINGANIM = "models/aaa-right.md5anim";
    private static final String STANDINGANIM = "models/aaa.md5anim";
    public Node playerNode;
    private Model bodyModel;
    private Animation runningAnimation;
    private Animation standingAnimation;
    private SkeletalAnimationController bodyAnimationController;
    private SkeletalModelInstance bodyInstance;
    AnimationAnimator runningAnimator;
    AnimationAnimator standingAnimator;
   
    int counter = 0;

    public Player() {
        playerNode = new Node();

        buildPlayer();
    }

    private void buildPlayer() {
        try {
            bodyModel = loadModel(BODYMODEL);
            runningAnimation = loadAnimation(RUNNINGANIM);
            standingAnimation = loadAnimation(STANDINGANIM);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    protected void simpleInitGame() {
        lightState.get(0).setAmbient(new ColorRGBA(1.5f, 1.5f, 1.5f, 1.0f));

        lightState.detachAll();

        cam.setLocation(new Vector3f(0f, 50f, 100f));
        cam.update();

        bodyInstance = new SkeletalModelInstance(bodyModel);
        bodyAnimationController = (SkeletalAnimationController) bodyInstance.addAnimationController();
        runningAnimator = bodyAnimationController.addAnimation(runningAnimation);
        standingAnimator = bodyAnimationController.addAnimation(standingAnimation);

        standingAnimator.fadeTo(0, 1);

        runningAnimator.fadeIn(1);
        runningAnimator.setSpeed(.9f);

        // bodyInstance.getLocalRotation().fromAngleAxis(FastMath.PI,Vector3f.UNIT_Y);
        bodyInstance.getLocalTranslation().set(-50, 50, 0);
        //bodyInstance.setNormalsMode(SceneElement.NM_GL_NORMALIZE_PROVIDED);
       
        Quaternion rotate3 = new Quaternion();
        // angle in radian no degree
        rotate3.fromAngleAxis(1.57f, new Vector3f(1, 0, 0));
        bodyInstance.setLocalRotation(rotate3);
       
       
        bodyInstance.setLocalScale(.28f);
        bodyInstance.updateGeometricState(0, false);
        bodyInstance.setModelBound(new BoundingBox());
        bodyInstance.updateModelBound();

        playerNode.attachChild(bodyInstance);
        //          playerNode.setModelBound(new BoundingBox());
        //          playerNode.updateModelBound();
        playerNode.getLocalTranslation().set(0, 1, 0);
        playerNode.updateGeometricState(0, false);
        playerNode.updateRenderState();
        rootNode.attachChild(playerNode);

        PointLight pl = new PointLight();
        pl.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1));
        pl.setDiffuse(new ColorRGBA(1, 1, 1, 1));
        pl.setLocation(new Vector3f(100, 100, 0));
        pl.setEnabled(true);
        lightState.attach(pl);
        setStandingAnimator();
       
    }

    protected void simpleUpdate() {
       
        if (KeyInput.get().isKeyDown(KeyInput.KEY_H)) {
           setRunningAnimator();
      } else {
         setStandingAnimator();
         
      }
       
  
    }

    public void setStandingAnimator() {
        runningAnimator.fadeOut(.1f, false);
        standingAnimator.fadeIn(.5f);
    }

    public void setRunningAnimator() {
        standingAnimator.fadeOut(.2f, false);
        runningAnimator.fadeIn(.5f);
    }

    private Model loadModel(String path) throws IOException {
        InputStream in = getClass().getResourceAsStream("/" + path);

        if (in == null) {
            throw new FileNotFoundException("Cannot find " + path);
        }

        MD5MeshReader reader = new MD5MeshReader();

        reader.setProperty(MD5MeshReader.CLASSLOADER, getClass().getClassLoader());

        return reader.readModel(in);
    }

    private Animation loadAnimation(String path) throws IOException {
        InputStream in = getClass().getResourceAsStream("/" + path);

        if (in == null) {
            throw new FileNotFoundException("Cannot find " + path);
        }

        MD5AnimReader animReader = new MD5AnimReader();

        Animation animation = animReader.readAnimation(in);

        return animation;
    }

    public Node getPlayer() {
        return playerNode;
    }

    public static void main(String[] args) throws IOException {
        final Player app = new Player();

        app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);

        // Turn the logger off so we can see the XML later on
        app.start();
    }
}

Instead of having variables for each animation, why not have a TreeMap or something similar of names (as the keys) and animations (as the values).



So you could do something like having a method:


public void callAnimation(String animName)
{
  myAnimMap.get(animName).fadeIn();
}



Something like that.  I have my own custom Controller where I do something similar.  Hope this gives you some ideas.

Are you meaning



TreeMap

Key = String (TYPE)

Value = AnimationAnimator (TYPE)



AnimationAnimator leftAnimator;

AnimationAnimator standingAnimator;

AnimationAnimator rightAnimator;

AnimationAnimator forwardAnimator;

AnimationAnimator backwardAnimator;

… etc



all above AnimationAnimator Objects added to a TreeMap



How can I fadeout all the current animation?



currently I use the method that fadeOut all animation no mater they are running or not like



    public void setForwardAnimator() {
        standingAnimator.fadeOut(.2f, false);
        leftAnimator.fadeOut(.2f, false);
        backwardAnimator.fadeOut(.2f, false);
        rightAnimator.fadeOut(.2f, false);
        forwardAnimator.fadeIn(.5f);
    }

How can I fadeout all the current animation?



currently I manually fadeOut animation one by one no mater they are running or not like



    public void setForwardAnimator() {
        standingAnimator.fadeOut(.2f, false);
        leftAnimator.fadeOut(.2f, false);
        backwardAnimator.fadeOut(.2f, false);
        rightAnimator.fadeOut(.2f, false);
        forwardAnimator.fadeIn(.5f);
    }