www.jpct.net

Bones - Skeletal and Pose Animations for jPCT/jPCT-AE => Bones => Topic started by: AGP on August 29, 2017, 10:04:27 pm

Title: Scale Problem?
Post by: AGP on August 29, 2017, 10:04:27 pm
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: [Select]
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;
    }
}

When I print its values as follows, I get perfectly reasonable numbers (values ranging from -30 to +120).

Code: [Select]
System.out.println(newBone.toString() +": "+newBone.index);
But, after creating my AnimatedGroup, as follows, the values range between -Infinity to +Infinity, with NaNs thrown in there for good measure.

Code: [Select]
    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;
    }

These prints produce NaNs, and the infinities:
Code: [Select]
        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();
            }
        }
Title: Re: Scale Problem?
Post by: EgonOlsen on August 30, 2017, 09:05:54 am
Looking at the code, I would expect that one these methods screws it up:

Code: [Select]
scaleBones(bones);
invertBonesCoords(bones);

What are these doing and can you check if your bones are still correct afterwards?
Title: Re: Scale Problem?
Post by: AGP on August 31, 2017, 03:07:27 pm
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: [Select]
    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);
    }

invertBones just multiplies all values by -1. Neither attempts at solutions either help or hurt the problem.
Title: Re: Scale Problem?
Post by: raft on September 01, 2017, 12:07:11 am
hard to say anything without knowing how that MaxBonesImporter creates Bone objects.

in any case, doesnt look like a Bones related problem.
Title: Re: Scale Problem?
Post by: AGP on September 01, 2017, 04:29:31 pm
If this isn't Bones-related, I don't know what is. Especially since the vertex animations all work perfectly.
Title: Re: Scale Problem?
Post by: AGP on September 01, 2017, 10:46:16 pm
Before animateSkin() ever gets called, I get the following bounding box: -0.328329, 0.343511, -0.159473, 0.230658, 0.00242225, 2.12075.

Afterwards, it becomes: -9.9999998E10, 9.9999998E10, -9.9999998E10, 9.9999998E10, -9.9999998E10, 9.9999998E10

The following is the method with which I print the world-space bounding box:

Code: [Select]
    public float[] getWorldSpaceBounds(Object3D obj) {
        float[] objectSpaceBounds = obj.getMesh().getBoundingBox();
       
        SimpleVector mins = new SimpleVector(objectSpaceBounds[0], objectSpaceBounds[2], objectSpaceBounds[4]);
        SimpleVector maxs = new SimpleVector(objectSpaceBounds[1], objectSpaceBounds[3], objectSpaceBounds[5]);

        SimpleVector[] p = new SimpleVector[8];
        p[0] = new SimpleVector(mins.x, mins.y, maxs.z);
        p[1] = new SimpleVector(mins.x, mins.y, mins.z);
        p[2] = new SimpleVector(maxs.x, mins.y, mins.z);
        p[3] = new SimpleVector(maxs.x, mins.y, maxs.z);
        p[4] = new SimpleVector(maxs.x, maxs.y, mins.z);
        p[5] = new SimpleVector(maxs.x, maxs.y, maxs.z);
        p[6] = new SimpleVector(mins.x, maxs.y, mins.z);
        p[7] = new SimpleVector(mins.x, maxs.y, maxs.z);

        float minX = Float.MAX_VALUE;
        float minY = Float.MAX_VALUE;
        float minZ = Float.MAX_VALUE;
        float maxX = -Float.MAX_VALUE;
        float maxY = -Float.MAX_VALUE;
        float maxZ = -Float.MAX_VALUE;

        for (int i = 0; i < 8; i++)  {
            p[i].matMul(obj.getWorldTransformation());

            if (p[i].x < minX) { minX = p[i].x; }
            if (p[i].y < minY) { minY = p[i].y; }
            if (p[i].z < minZ) { minZ = p[i].z; }
            if (p[i].x > maxX) { maxX = p[i].x; }
            if (p[i].y > maxY) { maxY = p[i].y; }
            if (p[i].z > maxZ) { maxZ = p[i].z; }
        }

        float[] worldSpaceBounds = new float[6];
        worldSpaceBounds[0] = minX;
        worldSpaceBounds[1] = maxX;
        worldSpaceBounds[2] = minY;
        worldSpaceBounds[3] = maxY;
        worldSpaceBounds[4] = minZ;
        worldSpaceBounds[5] = maxZ;

        return worldSpaceBounds;
    }
Title: Re: Scale Problem?
Post by: EgonOlsen on September 04, 2017, 08:25:25 am
How does the bounding box look in object space?
Title: Re: Scale Problem?
Post by: AGP on September 05, 2017, 06:41:13 am
Before animateSkin:
Quote
*****Object-space bounds: *****
-0.328329
0.343511
-0.159473
0.230658
0.00242225
2.12075
***** ****** *****
*****World-space bounds: *****
-0.328329
0.343511
-0.159473
0.230658
0.00242225
2.12075
***** ****** *****

After animateSkin:
Quote
*****Object-space bounds: *****
9.9999998E10
-9.9999998E10
9.9999998E10
-9.9999998E10
9.9999998E10
-9.9999998E10
***** ****** *****
*****World-space bounds: *****
-9.9999998E10
9.9999998E10
-9.9999998E10
9.9999998E10
-9.9999998E10
9.9999998E10
***** ****** *****

Any clues?
Title: Re: Scale Problem?
Post by: EgonOlsen on September 15, 2017, 03:25:43 pm
These values look like the initial values of the BB calculation. Which basically means that the object that you are using to calculate the BB on...is empty (i.e. no vertices at all).
Title: Re: Scale Problem?
Post by: AGP on September 19, 2017, 06:02:45 am
I assume you mean that only the post-animateSkin values don't have vertices. Raft, any clue as to how animateSkin could destroy the model's vertices?
Title: Re: Scale Problem?
Post by: raft on September 19, 2017, 11:51:41 am
Raft, any clue as to how animateSkin could destroy the model's vertices?
no idea actually