Per joint jointcontroller

i modified the jointcontroller to control every joint independently from the others:

-> http://www.vegan-empire.de/randomstuff/JointController.java



i'm not sure, but i think i also fixed some bugs. :stuck_out_tongue:



the jointcontroller supports accessing joint by their names which is rather slow compared to alljoints[index], but if you want to use it, you need to modify the milktojme converter:

 private boolean readJoints() throws IOException {
    float fAnimationFPS = inFile.readFloat();
    float curTime = inFile.readFloat();     // Ignore currentTime
    int iTotalFrames = inFile.readInt();      // Ignore total Frames
    int nNumJoints = inFile.readUnsignedShort();
    if (nNumJoints == 0) {
      return false;
    }
    String[] jointNames = new String[nNumJoints];
    String[] parentNames = new String[nNumJoints];
    JointController jc = new JointController(nNumJoints);
    jc.FPS = fAnimationFPS;

    for (int i = 0; i < nNumJoints; i++) {
      inFile.readByte();  // Ignore flags
      inFile.readFully(tempChar, 0, 32);
      jointNames[i] = cutAtNull(tempChar);
      inFile.readFully(tempChar, 0, 32);
      parentNames[i] = cutAtNull(tempChar);
      jc.localRefMatrix[i].setEulerRot(inFile.readFloat(), inFile.readFloat(), inFile.readFloat());
      jc.localRefMatrix[i].setTranslation(inFile.readFloat(), inFile.readFloat(), inFile.readFloat());
      int numKeyFramesRot = inFile.readUnsignedShort();
      int numKeyFramesTrans = inFile.readUnsignedShort();
      for (int j = 0; j < numKeyFramesRot; j++) {
        jc.setRotation(i, inFile.readFloat(), inFile.readFloat(), inFile.readFloat(), inFile.readFloat());
      }
      for (int j = 0; j < numKeyFramesTrans; j++) {
        jc.setTranslation(i, inFile.readFloat(), inFile.readFloat(), inFile.readFloat(), inFile.readFloat());
      }
      jc.setJointName(jointNames[i], i);//THIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEWTHIS IS NEW
    }
    for (int i = 0; i < nNumJoints; i++) {
      jc.parentIndex[i] = -1;
      for (int j = 0; j < nNumJoints; j++) {
        if (parentNames[i].equals(jointNames[j])) {
          jc.parentIndex[i] = j;
        }
      }
    }
    jc.setRepeatType(Controller.RT_WRAP);
    finalNode.addController(jc);
    addJointMeshes(finalNode, jc);
    return true;
  }

missing files:

/* Copyright H-Star Development 2007 */
package hstar.commons.various;

/**
 * Developed with pleasure :)<br>
 *
 * @author HamsterofDeath Created 11.02.2007 @ 12:27:36
 */
public class VFloat {

  //~ Instance fields



  public float f;

  public VFloat() {
    super();
  }

  public VFloat(final float p_value) {
    super();
    f = p_value;
  }

  public float getValue() {
    return f;
  }


  public String toString() {
    return "VFloat{" +
       "f=" + f +
       '}';
  }

  public VFloat set(final float p_v) {
    f = p_v;
    return this;
  }
}



and

/* Copyright H-Star Development 2007 */
package hstar.commons.various;

/**
 * Developed with pleasure :)<br>
 *
 * @author HamsterofDeath
 *         Created 16.11.2007 @ 19:44:31
 */
public class VInt {
  public int i;

  public VInt set(final int p_value) {
    i = p_value;
    return this;
  }


  public String toString() {
    return "VInt{" +
       "i=" + i +
       '}';
  }
}



/* Copyright H-Star Development 2007 */
package com.jme.animation;

import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.Savable;

import java.io.IOException;

/**
 * Developed with pleasure :)<br>
 *
 * @author HamsterofDeath
 *         Created 17.11.2007 @ 01:32:43
 */
public class VBool implements Savable {
  public boolean b;

  public VBool set(final boolean p_b) {
    this.b = p_b;
    return this;
  }

  public void write(final JMEExporter ex) throws IOException {
    ex.getCapsule(this).write(b, "b", false);
  }

  public void read(final JMEImporter im) throws IOException {
    b = im.getCapsule(this).readBoolean("b", false);
  }

  public Class getClassTag() {
    return getClass();
  }
}



/* Copyright H-Star Development 2007 */
package hstar.commons.various;

/**
 * Developed with pleasure :)<br>
 *
 * @author HamsterofDeath
 *         Created 16.11.2007 @ 19:44:31
 */
public class VInt {
  public int i;

  public VInt set(final int p_value) {
    i = p_value;
    return this;
  }


  public String toString() {
    return "VInt{" +
       "i=" + i +
       '}';
  }
}

Just wondering why not use Integer/Float auto-wrapping function of the java 1.5 compiler? Something like this would do:


ArrayList<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add( new Integer(4) );
list.add( list.get(0) + list.get(1) );
int seven = list.get(2);

because the jdk number classes are immutable -> garbage created per frame (except for integers >=-128 && <=127) -> bad

I believe one (minor) reason the Number classes are immutable is to allow for optimizations in order to avoid excessive garbage creation. Do you have a reference or something to read about them being gc intensive?

(Not to question your knowledge, but rather to learn something new for myself!)



EDIT: sorry I just realized that this is thread hijacking. HamsterOfDeath, please fork a new thread for your answer if you'd rather not have this discussed here!

vint and vbool added. sorry for using confusing packages.


Do you have a reference or something to read about them being gc intensive?



(no idea how to fork a thread, so ->)
no i haven't read about it. i tried.
a main method containing a simple loop like this:

public static void main(String[] args) {
    Integer x = 0;
    for (int i = 0;i<999999999;i++)
    {
                  x++;
    }
    System.out.println(x);

  }


leads to ~27k minor collections with exactly these values (time varies a bit) on a 1.5.0_10 vm:
[GC 681K->169K(1984K), 0.0000388 secs]
which tells us that about 13.1 GB of garbage have been created and collected.
the result for a 1.6.0 vm is similar.

But it might be using exactly the same memory each time… performance is what would be important, maybe if you compared it vs your VInt implementation (which will be faster, but by how much?)



Now I am curious… So I coded it up myself…


public class Test2 {
  static class VInt {
    private int v = 0;
    public int get() {return v;}
    public void set(int i) {v=i;}
  }
  public static void main(String[] args)
  {
    VInt x = new VInt();
    for (int i = 0;i<999999999;i++)
       x.set( x.get()+1 );
    System.out.println(x);
  }
}



$ time java Test2
Test2$VInt@10d448

real    0m6.005s
user    0m4.399s
sys    0m0.163s

For your code (using Integer), however...

$ time java Test
999999999

real    2m22.495s
user    1m2.073s
sys    0m6.424s

Over 2 minutes!  :-o

On a PPC Mac OSX... Now I am disappointed... I though the Java runner would be better at optimizing it out.

btw, using a public member is faster than using simple set & get-methods (at least the last time i checked it was)

Right, but I thought you had that getter/setter structure in your code and I wanted to be fair… My bad!

Thanks for the speed code tips, think I have the dreaded boxed Integer in my own code that I will need to check.



the JointController Code, does this need to be added to the jme core ??