Bones - Skeletal and Pose Animations for jPCT/jPCT-AE > Bones
Scale Problem?
AGP:
I have a class called Bone, as defined in the following code. It's used as a bridge between the JSON-serialized format I created and Bones.
--- Code: ---class Bone {
protected String name;
protected SimpleVector position;
protected Matrix transform;
protected int index, parentIndex;
public Bone(String name, SimpleVector position, Matrix transform, int index, int parentIndex) {
this.name = name;
this.position = position;
this.transform = transform;
this.index = index;
this.parentIndex = parentIndex;
}
public boolean hasParent () {
return this.parentIndex >= 0;
}
public String toString () {
return this.name + ": " + this.position;
}
}
--- End code ---
When I print its values as follows, I get perfectly reasonable numbers (values ranging from -30 to +120).
--- Code: ---System.out.println(newBone.toString() +": "+newBone.index);
--- End code ---
But, after creating my AnimatedGroup, as follows, the values range between -Infinity to +Infinity, with NaNs thrown in there for good measure.
--- Code: --- public static AnimatedGroup loadGroup(JsonLoader jsonLoader) {
MaxBonesClip[] clips = Importer.getMaxBonesClips(jsonLoader);
MaxBonesImporter jImporter = new MaxBonesImporter(jsonLoader, clips);
ArrayList<ArrayList> objects = jImporter.getList();
ArrayList<Bone> bones = jImporter.getBones();
ArrayList<ArrayList> objectsBonesReferences = jImporter.getBonesReferences(); // for all objects, respects the same order of objects
Animated3D anObject = null;
SimpleVector center = null;
scaleBones(bones);
invertBonesCoords(bones);
Skeleton skeleton = Importer.makeSkeleton(bones);
SkeletonPose pose = new SkeletonPose(skeleton);
pose.updateTransforms();
Animated3D[] list = new Animated3D[objects.size()];
for (int i = 0; i < objects.size(); i++) {
ArrayList<ArrayList> theObject = objects.get(i);
if (bones == null || bones.size() <= 0) {
Logger.log("Problem: no bones. Try loadObject(String) instead.");
java.awt.Toolkit.getDefaultToolkit().beep();
return null;
}
anObject = makeAnimated3D(pose, objectsBonesReferences.get(i), theObject, new File(jsonLoader.getMainFileName()).getParent());
anObject.build();
list[i] = anObject;
}
System.out.println("To test: "+bones.get(JSONFrame.BONE_INDEX_TO_TEST));
AnimatedGroup asGroup = new AnimatedGroup(list);
asGroup.setSkinClipSequence(getSkinClipSequence(jImporter, anObject.getSkeleton()));
return asGroup;
}
private static Animated3D makeAnimated3D(SkeletonPose pose, ArrayList<BoneReference> boneRefs, ArrayList<ArrayList> theImportedObject, String absolutePath) {
ArrayList<ArrayList> vertices = theImportedObject.get(0);
ArrayList<String> diffuseAndNormal = theImportedObject.get(3);
int verticesCount = vertices.size();
//skeletonDebugger = new SkeletonDebugger(pose, 0f, 1f);
float[][] weights = new float[verticesCount][Importer.MAX_JOINTS_PER_VERTEX];
short[][] jointIndices = new short[verticesCount][Importer.MAX_JOINTS_PER_VERTEX];
int[] verticesCounters = new int[verticesCount];
for (int i = 0; i < verticesCount; i++) verticesCounters[i] = 0;
for (BoneReference aBoneRef: boneRefs) {
int vertexRef = aBoneRef.vertexIndexReference;
int verticesCounter = verticesCounters[vertexRef];
if (verticesCounter < Importer.MAX_JOINTS_PER_VERTEX) {
weights[vertexRef][verticesCounter] = aBoneRef.vertexWeight;
jointIndices[vertexRef][verticesCounter] = aBoneRef.boneIndexReference;
verticesCounters[vertexRef]++;
}
}
SkinData skin = new SkinData(weights, jointIndices);
if (!TextureManager.getInstance().containsTexture(diffuseAndNormal.get(0)))
TextureManager.getInstance().addTexture(diffuseAndNormal.get(0), new Texture(absolutePath +File.separator+diffuseAndNormal.get(0)));
MeshData meshData = makeMeshData(theImportedObject);
Animated3D anAnimated = new Animated3D(meshData, skin, pose);
anAnimated.setTexture(diffuseAndNormal.get(0));
return anAnimated;
}
--- End code ---
These prints produce NaNs, and the infinities:
--- Code: --- for (int h = 0; h < asGroup.getSize(); h++) {
Animated3D temp = asGroup.get(h);
Skeleton s = asGroup.get(h).getSkeletonPose().getSkeleton();
for (int i = 0; i < s.getNumberOfJoints(); i++) {
System.out.println(temp.getSkinClipSequence().getClip(0).getSkeleton().getJoint(i).getBindPose().toString());
//temp.applySkeletonPose();
//temp.animateSkin(frame, sequence);
//temp.applyAnimation();
}
}
--- End code ---
EgonOlsen:
Looking at the code, I would expect that one these methods screws it up:
--- Code: ---scaleBones(bones);
invertBonesCoords(bones);
--- End code ---
What are these doing and can you check if your bones are still correct afterwards?
AGP:
Sorry, I hadn't realized that you replied.
No, they were both attempts to fix the incomprehensible problem. scaleBones looks like this (where SCALE is currently set to 1.00f):
--- Code: --- private static void scaleBones(ArrayList<Bone> bones) {
for (int i = 0; i < bones.size(); i++) {
Bone aBone = bones.get(i);
scaleBonePosition(aBone);
scaleBoneMatrix(aBone);
}
}
private static void scaleBonePosition(Bone aBone) {
aBone.position.x *= SCALE;
aBone.position.y *= SCALE;
aBone.position.z *= SCALE;
}
private static void scaleBoneMatrix(Bone aBone) {
aBone.transform.scalarMul(SCALE);
}
--- End code ---
invertBones just multiplies all values by -1. Neither attempts at solutions either help or hurt the problem.
raft:
hard to say anything without knowing how that MaxBonesImporter creates Bone objects.
in any case, doesnt look like a Bones related problem.
AGP:
If this isn't Bones-related, I don't know what is. Especially since the vertex animations all work perfectly.
Navigation
[0] Message Index
[#] Next page
Go to full version