Author Topic: Scale Problem?  (Read 301 times)

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Scale Problem?
« 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();
            }
        }

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: Scale Problem?
« Reply #1 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?

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Re: Scale Problem?
« Reply #2 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.
« Last Edit: August 31, 2017, 03:09:16 pm by AGP »

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1966
    • View Profile
    • http://www.aptalkarga.com
Re: Scale Problem?
« Reply #3 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.

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Re: Scale Problem?
« Reply #4 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.

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Re: Scale Problem?
« Reply #5 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;
    }

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: Scale Problem?
« Reply #6 on: September 04, 2017, 08:25:25 am »
How does the bounding box look in object space?

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Re: Scale Problem?
« Reply #7 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?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11748
    • View Profile
    • http://www.jpct.net
Re: Scale Problem?
« Reply #8 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).

Offline AGP

  • quad
  • ******
  • Posts: 1518
    • View Profile
Re: Scale Problem?
« Reply #9 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?

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1966
    • View Profile
    • http://www.aptalkarga.com
Re: Scale Problem?
« Reply #10 on: September 19, 2017, 11:51:41 am »
Raft, any clue as to how animateSkin could destroy the model's vertices?
no idea actually