Bones - Skeletal and Pose Animations for jPCT/jPCT-AE > Bones

Scale Problem?

(1/3) > >>

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