Author Topic: BonesIO Question  (Read 759 times)

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
BonesIO Question
« on: July 10, 2020, 06:56:38 am »
How is it that when you load your SkinClipSequences from a bones file instead of each SkinClip having identical Skeletons they each share the same instance of a Skeleton?

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
Re: BonesIO Question
« Reply #1 on: July 10, 2020, 07:36:31 pm »
not sure what's asked here, but loaded SkinClips and SkinClipSequences share the same Skeleton instance.

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #2 on: July 10, 2020, 08:36:30 pm »
That's right. The question was: how? When I'm doing the same thing with JSON, I'm getting identical copies of the skeleton (the model loads but no animation will work).

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #3 on: July 11, 2020, 12:19:21 am »
This is not that old, much more ambitious project, by the way. I came very close to exporting a fully-ready, animated and textured, JSON-serialized model right out of both Max and Blender. This is just so I can get Bones out of Java. But I suspect that if you answer at all it will be with, "I don't know."

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
Re: BonesIO Question
« Reply #4 on: July 16, 2020, 06:56:49 pm »
sorry for the late answer, somehow I didnt receive the notification email.

BonesIO class reads and writes using Java serialization. Java serialization preserves objects references.

So, as long as SkinClips and SkinClipSequences share the same Skeleton instance when they are written by BonesIO, they will share the same Skeleton instance when read by BonesIO.


Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #5 on: July 17, 2020, 08:34:02 am »
Thanks for replying. My problem is Gson's fault. Clean, near-identical to yours, code produced a perfect model, loaded quickly, but with many copies of the same Skeleton. It turns out that Gson doesn't do instances very well. I'm working on a registerTypeAdapterFactory solution which is producing NullPointerExceptions for SkinClipSequences (but for no other class, including Skeleton and SkeletonPose). I also tried Jackson with no success, so I returned to Gson. I expect to succeed soon, and I will post the sources for BonesIO, AnimatedGroup and Animated3D here.

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #6 on: July 29, 2020, 10:31:48 pm »
I'm stuck, now, at an Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: there is already a channel for joint 84. But I'm serializing the data as-is. I wonder if it's related to the potentially null instances of JointChannel in SkinClip.iterator().

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
Re: BonesIO Question
« Reply #7 on: July 30, 2020, 10:21:37 am »
Difficult to make a comment without knowing how you are actually importing/reading the data.

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #8 on: August 01, 2020, 08:36:32 am »
I made the SkinClips work (in the sense that they're filled properly) by making a custom serializer and deserializer for them. But now I'm getting the same instancing issue with Skeletons. So I wrote the hacky method below and called it at the very end of the appropriate AnimatedGroup constructor. Now when I comment out the if (skeleton != pose.skeleton) test in SkinClip.applyTo(...), my model gets all bunched-up once, then doesn't animated at all (but doesn't crash, either) again.

Code: [Select]
private void attemptSkeletonInstanceFix() {//Gson Skeleton instance crap
     SkinClip lastClip = skinClipSequence.getClip(0);
     if (lastClip.getSkeleton().equals(objects[0].getSkeleton()) && lastClip.getSkeleton() != objects[0].getSkeleton()) {
lastClip.skeleton = objects[0].getSkeleton();
     }
     for (int i = 1; i < skinClipSequence.getSize(); i++) {
if (lastClip.getSkeleton().equals(skinClipSequence.getClip(i).getSkeleton()) && lastClip.getSkeleton() != skinClipSequence.getClip(i).getSkeleton())
     skinClipSequence.getClip(i).skeleton = lastClip.getSkeleton();
lastClip = skinClipSequence.getClip(i);
     }
     for (Animated3D object : objects)
object.currentPose.skeleton = objects[0].getSkeleton();
}

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
Re: BonesIO Question
« Reply #9 on: August 03, 2020, 02:12:19 pm »
isnt this always returning false?
Code: [Select]
if (lastClip.getSkeleton().equals(objects[0].getSkeleton()) && lastClip.getSkeleton() != objects[0].getSkeleton())
like
Code: [Select]
if (a.equals(b) && a != b)

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #10 on: August 03, 2020, 11:24:56 pm »
No, one compares the values, the other tests if they're the same instance.

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #11 on: August 17, 2020, 07:25:13 am »
Single-part objects are working! Now for the ones that have more than one part, could the following method be breaking something (currently one of the parts of the model animates properly while the rest stays still)? From what I understand, to be in an AnimatedGroup every Animated3D must share the same skeleton, so this method shouldn't break anything. Right?

Code: [Select]
private void attemptSkeletonInstanceFix() {//Gson Skeleton instance crap
     Skeleton skel = objects[0].getSkeleton();
     for (int i = 0; i < skinClipSequence.getSize(); i++) {
if (skinClipSequence.getClip(i).getSkeleton() != skel)
     skinClipSequence.getClip(i).skeleton = skel;
     }
     for (Animated3D object : objects)
object.currentPose.skeleton = skel;
}
« Last Edit: August 17, 2020, 07:26:52 am by AGP »

Offline raft

  • Moderator
  • quad
  • *****
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
Re: BonesIO Question
« Reply #12 on: August 17, 2020, 10:12:02 am »
that's correct, every Animated3D must share the same skeleton to be in the same AnimatedGroup.

I cant see anything breaking the animation in that method.

Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #13 on: September 04, 2020, 09:17:38 am »
After a lot of trial-and-error and writing and re-writing my loader on C#, I loaded the model and filled its SkinClips. Alas, the problem is now very similar to the one I had on that older project. The first screenshot shows the simple model properly loaded and not yet animated. The second shows it the second I call animateSkin(...). I have multiple frames for every animation (it's not that bunching-up-once-and-never-moving-again error), but the frames all destroy the model in similar ways.




Offline AGP

  • quad
  • ******
  • Posts: 1652
    • View Profile
Re: BonesIO Question
« Reply #14 on: September 16, 2020, 05:34:33 am »
It's working for one-part models in C# as well, and I get the same problem with multi-part models as I did in Java.

Here's a question so that I may solve the multiple Skeleton references once and for all: which are all the classes that hold an instance to Skeleton (I don't use IDEs and Windows is surprisingly not helpful even with the searches reading inside the files)?