www.jpct.net

Bones - Skeletal and Pose Animations for jPCT/jPCT-AE => Bones => Topic started by: AGP on July 10, 2020, 06:56:38 am

Title: BonesIO Question
Post by: AGP 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?
Title: Re: BonesIO Question
Post by: raft on July 10, 2020, 07:36:31 pm
not sure what's asked here, but loaded SkinClips and SkinClipSequences share the same Skeleton instance.
Title: Re: BonesIO Question
Post by: AGP 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).
Title: Re: BonesIO Question
Post by: AGP 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."
Title: Re: BonesIO Question
Post by: raft 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.

Title: Re: BonesIO Question
Post by: AGP 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.
Title: Re: BonesIO Question
Post by: AGP 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().
Title: Re: BonesIO Question
Post by: raft on July 30, 2020, 10:21:37 am
Difficult to make a comment without knowing how you are actually importing/reading the data.
Title: Re: BonesIO Question
Post by: AGP 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();
}
Title: Re: BonesIO Question
Post by: raft 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)
Title: Re: BonesIO Question
Post by: AGP on August 03, 2020, 11:24:56 pm
No, one compares the values, the other tests if they're the same instance.
Title: Re: BonesIO Question
Post by: AGP 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;
}
Title: Re: BonesIO Question
Post by: raft 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.
Title: Re: BonesIO Question
Post by: AGP 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.

(https://previews.dropbox.com/p/thumb/AA4fm5qwVeyo9H7zC0bEJXv_66bpP-LIabO0t9CjfXgtYeWwI30UrWgGK4eAY9B0L99fndFIJG32o6zPcL-ey0gnu6gYKDvQV5wIbHIfm7xdG4dzZjdJJCm1KZd6iEIwG9BRkx-n4rFjpns-Dc298oymif99PCfy1baq1iSvqof3pi2haHFwXyqDAGYgtQUYNVzx3gCbzG6rX5_uShShLw3EidbXvoCK7Fp0qjV9eD2NLHHuYJ-mG9223o9PITPdlpi_B1fppmVoXzTxpc6vUdLGeV-HWnoEkdpltMFsEhuavbNyXjuCa3V60hOF2eoDcWrurW21QojqmReqGNbY8a20-_jsUO-3fveWVa3cLii1Lw/p.jpeg?fv_content=true&size_mode=5)

(https://previews.dropbox.com/p/thumb/AA4AuwH7ivacLOxG9IZl6tuUVH8E2lcif_c2QrtnwltAdVBqXkdYvc2FSa50w4fidGTHkKg6jOWa4kqgj1CSUx4HRHM9qdgVd8pYqn0S39JBBaWcieZj-fmyADF2DiU0og5xTcFGv9OsclH0Q7jxcNQ5JHUmpib0ny6qpQeoEhG_WujwzH2C2O8U97K98IZOExDvWQb2LcYW5fCBN92kEjjOHT2r_nG_eimGNFBTmjUsmLRixZq2lsxlhT1BwaMaOl12N21fjJdTet3gstWWzgtPZYUfPuSvhEeMbUsg0BqRAPW47KifBUtvYcA5DWfk0GAJah-WEcY4zbz9_l60JGVa8C7_-AlmQkgHnO6w8UAZUQ/p.jpeg?fv_content=true&size_mode=5)
Title: Re: BonesIO Question
Post by: AGP 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)?
Title: Re: BonesIO Question
Post by: raft on September 16, 2020, 08:11:47 pm
that's a weird question AGP! :o

I dont have an IDE ATM either. use grep and look closer at the results.

Code: [Select]
$ grep -rl "Skeleton skeleton"
raft/jpct/bones/Animated3D.java
raft/jpct/bones/AnimatedGroup.java
raft/jpct/bones/BonesImporter.java
raft/jpct/bones/JointChannel.java
raft/jpct/bones/SkeletonDebugger.java
raft/jpct/bones/SkeletonPose.java
raft/jpct/bones/SkinClip.java
raft/jpct/bones/SkinClipSequence.java

$ grep -r "Skeleton skeleton"
raft/jpct/bones/Animated3D.java:        private Skeleton skeleton;
raft/jpct/bones/Animated3D.java://      void replaceSkeleton(Skeleton skeleton) {
raft/jpct/bones/AnimatedGroup.java:             Skeleton skeleton1 = one.objects[0].getSkeleton();
raft/jpct/bones/AnimatedGroup.java:             Skeleton skeleton2 = other.objects[0].getSkeleton();
raft/jpct/bones/AnimatedGroup.java://           Skeleton skeleton = groups[0].get(0).getSkeleton();
raft/jpct/bones/BonesImporter.java:             Skeleton skeleton = convertArdorSkeleton(findUniqueArdorSkeleton(colladaStorage));
raft/jpct/bones/BonesImporter.java:             Skeleton skeleton = null;
raft/jpct/bones/BonesImporter.java:             com.ardor3d.extension.animation.skeletal.Skeleton skeleton = null;
raft/jpct/bones/BonesImporter.java:     private static Skeleton convertArdorSkeleton(com.ardor3d.extension.animation.skeletal.Skeleton skeleton) {
raft/jpct/bones/BonesImporter.java:             Skeleton skeleton = new Skeleton(joints);
raft/jpct/bones/BonesImporter.java:     private static JointChannel convertJMEJointChannel(com.jmex.model.ogrexml.anim.BoneTrack track, Skeleton skeleton, int[] jointOrder) {
raft/jpct/bones/BonesImporter.java:     private static SkinClip convertArdorSkinClip(Skeleton skeleton,
raft/jpct/bones/BonesImporter.java:     private static SkinClip convertJMESkinClip(Skeleton skeleton, com.jmex.model.ogrexml.anim.BoneAnimation boneAnimation, int[] jointOrder) {
raft/jpct/bones/JointChannel.java:      void rotate(Skeleton skeleton, Quaternion rotation) {
raft/jpct/bones/SkeletonDebugger.java:  private final Skeleton skeleton;
raft/jpct/bones/SkeletonPose.java:      final Skeleton skeleton;
raft/jpct/bones/SkeletonPose.java:      public SkeletonPose(Skeleton skeleton) {
raft/jpct/bones/SkinClip.java:  private Skeleton skeleton;
raft/jpct/bones/SkinClip.java:  public SkinClip(Skeleton skeleton, JointChannel... channels) {
raft/jpct/bones/SkinClip.java:  public SkinClip(Skeleton skeleton, List<JointChannel> channels) {
raft/jpct/bones/SkinClip.java:  SkinClip(Skeleton skeleton, SkinClip other) {
raft/jpct/bones/SkinClip.java:  private SkinClip(Skeleton skeleton) {
raft/jpct/bones/SkinClip.java:  void replaceSkeleton(Skeleton skeleton) {
raft/jpct/bones/SkinClipSequence.java:          Skeleton skeleton = sequences[0].getSkeleton();