It’s me again! I actually got the animation running. But it’s not working correctly. All the changes that I did.
The MeshLoader class
[java]
public class MeshLoader extends DefaultHandler implements AssetLoader {
private ArrayList poses;
private String poseName = "";
private ArrayList animation;
private int keyIndex = 0;
private float[] times;
private int poseRefIndex = 0;
private Pose[] poseRef;
private float[] weights;
private PoseTrack.PoseFrame[] frame;
private String animname;
private float animlength;
private int trackIndex = 0;
private boolean poseFlag = false;
ArrayList poseVecHelp;
ArrayList indiciesHelp;
public void startElement(String uri, String localName, String qName,
Attributes attribs) throws SAXException {
if(){
…
} else if (qName.equals("poses")) {
poses = new ArrayList();
} else if (qName.equals("pose")) {
poseName = attribs.getValue("name");
poseVecHelp = new ArrayList();
indiciesHelp = new ArrayList();
} else if (qName.equals("poseoffset")) {
int index = Integer.parseInt(attribs.getValue("index"));
float x = Float.parseFloat(attribs.getValue("x"));
float y = Float.parseFloat(attribs.getValue("y"));
float z = Float.parseFloat(attribs.getValue("z"));
if (x == 0f && y == 0f && z == 0f) {
} else {
poseVecHelp.add(new Vector3f(x,y,z));
indiciesHelp.add(index);
}
} else if (qName.equals("animations")) {
animation = new ArrayList();
} else if (qName.equals("animation")) {
animlength = Float.parseFloat(attribs.getValue("length"));
animname = String.valueOf(attribs.getValue("name"));
int frameCount = (int) Math
.round((animlength / 0.041666666667f) + 1f);
times = new float[frameCount];
keyIndex = 0;
} else if (qName.equals("tracks")) {
trackIndex = 0;
} else if (qName.equals("track")) {
// ok
} else if (qName.equals("keyframes")) {
// ok
frame = new PoseTrack.PoseFrame[times.length];
} else if (qName.equals("keyframe")) {
times[keyIndex] = Float.parseFloat(attribs.getValue("time"));
poseRefIndex = 0;
weights = new float[poses.size()];
poseRef = new Pose[poses.size()];
} else if (qName.equals("poseref")) {
int poseInd = Integer.parseInt(attribs.getValue("poseindex"));
Pose actPose = poses.get(poseInd);
poseRef[poseRefIndex] = actPose;
weights[poseRefIndex] = Float.parseFloat(attribs
.getValue("influence"));
poseRefIndex++;
} else{
....
}
…
}
[/java]
[java]
public void endElement(String uri, String name, String qName) {
if(){
…
}else if (qName.equals(“pose”)) {
Vector3f[] poseVec = new Vector3f[poseVecHelp.size()];
int[] indicies = new int[indiciesHelp.size()];
for (int o = 0; o < poseVecHelp.size(); o++){
poseVec[o] = poseVecHelp.get(o);
indicies[o] = indiciesHelp.get(o);
}
Pose pose = new Pose(poseName, meshIndex, poseVec, indicies);
poses.add(pose);
} else if (qName.equals(“keyframe”)) {
setUpPoseAnim();
} else if (qName.equals(“track”)) {
trackIndex++;
} else if (qName.equals(“tracks”)) {
endPoseAnim();
} else if (qName.equals("animation")) {
poseFlag = true;
}
}
}
// Sets up the PoseFrame
private void setUpPoseAnim() {
PoseFrame helpFrame = new PoseFrame(poseRef, weights);
frame[keyIndex] = helpFrame;
keyIndex++;
}
// Sets up the PoseTrack
private void endPoseAnim() {
PoseTrack[] track = new PoseTrack[trackIndex];
for (int i = 0; i < track.length; i++) {
track[i] = new PoseTrack(meshIndex, times, frame);
Animation a = new Animation(animname, animlength);
a.setTracks(track);
animation.add(a);
}
}
[/java]
[java]
private Node compileModel() {
Node model = new Node(meshName + "-ogremesh");
for (int i = 0; i < geoms.size(); i++) {
Geometry g = geoms.get(i);
Mesh m = g.getMesh();
// New code for buffer extract
if (sharedMesh != null && usesSharedMesh.get(i)) {
m.extractVertexData(sharedMesh);
}
// Old code for buffer sharer
// if (sharedMesh != null && isUsingSharedVerts(g)) {
// m.setBound(sharedMesh.getBound().clone());
// }
model.attachChild(geoms.get(i));
}
// Do not attach shared geometry to the node!
// if (animData != null) {
// This model uses animation
// Old code for buffer sharer
// generate bind pose for mesh
// ONLY if not using shared geometry
// This includes the shared geoemtry itself actually
// if (sharedMesh != null) {
// sharedMesh.generateBindPose(!HARDWARE_SKINNING);
// }
for (int i = 0; i < geoms.size(); i++) {
Geometry g = geoms.get(i);
Mesh m = geoms.get(i).getMesh();
m.generateBindPose(!HARDWARE_SKINNING);
// Old code for buffer sharer
// boolean useShared = isUsingSharedVerts(g);
// if (!useShared) {
// create bind pose
// m.generateBindPose(!HARDWARE_SKINNING);
// }
}
// Put the animations in the AnimControl
HashMap anims = new HashMap();
ArrayList animList = new ArrayList();
if (poseFlag == true) {
animList = animation;
} else {
animList = animData.anims;
}
for (int i = 0; i < animList.size(); i++) {
Animation anim = animList.get(i);
anims.put(anim.getName(), anim);
}
if (poseFlag == true) {
AnimControl ctrl = new AnimControl();
ctrl.setAnimations(anims);
model.addControl(ctrl);
} else {
AnimControl ctrl = new AnimControl(animData.skeleton);
ctrl.setAnimations(anims);
model.addControl(ctrl);
// Put the skeleton in the skeleton control
SkeletonControl skeletonControl = new SkeletonControl(
animData.skeleton);
// This will acquire the targets from the node
model.addControl(skeletonControl);
}
return model;
}
}
[/java]
In PoseTrack I only changed this part
[java]
target = targets[targetMeshIndex];
[/java]
into this
[java]
Spatial spat = control.getSpatial();
Geometry geom = findGeom(spat);
Mesh target = geom.getMesh();
[/java]
the findGeom()
[java]
public Geometry findGeom(Spatial spatial) {
if (spatial instanceof Node) {
Node findingnode = (Node) spatial;
for (int i = 0; i < findingnode.getQuantity(); i++) {
Spatial child = findingnode.getChild(i);
Geometry result = findGeom(child);
if (result != null) {
return result;
}
}
} else if (spatial instanceof Geometry) {
return (Geometry) spatial;
}
return null;
}
[/java]
It kind of works…But the animation is different from the animation in Blender. It looks like it is scaled bigger. For example, if a point should move 2 blenderUnits along the x axis in the animation it looks like 20(or even more) blenderUnits. Any ideas where this could happen?