www.jpct.net

Bones - Skeletal and Pose Animations for jPCT/jPCT-AE => Bones => Topic started by: AGP on May 04, 2018, 10:51:28 pm

Title: Parsing SkinClipSequence
Post by: AGP on May 04, 2018, 10:51:28 pm
Since EasyOgreExporter exports all clips into a single animation, I'm forced to write a parser. How, then, might I split a SkinClipSequence of one SkinClip into a SkinClipSequence of two or more?
Title: Re: Parsing SkinClipSequence
Post by: raft on May 04, 2018, 11:01:04 pm
get clips from sequence, create new sequences, add clips into new sequences
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 04, 2018, 11:21:14 pm
No, because I need to say that a single clip is actually two or three. It's not about adding, it's about parsing or splitting.
Title: Re: Parsing SkinClipSequence
Post by: raft on May 04, 2018, 11:27:03 pm
ah okay. well, still the same method in other scale, get JointChannel's from SkinClip, create new clips, add channels into new clips
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 05, 2018, 09:55:14 pm
OK, I got this far:

Code: [Select]
     private void addSequence() {
java.util.List<JointChannel> jointChannels = (java.util.List)sequence.getClip(0).iterator();
SkinClip clip = new SkinClip(sequence.getSkeleton(), jointChannels);
clip.setName("1");
java.util.ArrayList<SkinClip> clipList = new java.util.ArrayList<SkinClip>();
clipList.add(clip);
clip = new SkinClip(sequence.getSkeleton(), jointChannels);
clip.setName("2");
clipList.add(clip);
newSequence = new SkinClipSequence(clipList);
newSequence.addClip(clip);
     }

But I still haven't given the clips proper information. Is it as simple as passing each half of the JointChannels?
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 05, 2018, 10:36:06 pm
I tried this:
Code: [Select]
     private void addSequence() {
java.util.Iterator<JointChannel> jCs = sequence.getClip(0).iterator();
ArrayList<JointChannel> jointChannels = new ArrayList<JointChannel>();
while (jCs.hasNext())
     jointChannels.add(jCs.next());
System.out.println("jointChannels Length: "+jointChannels.size() +" Is jointChannels[0] null? "+(jointChannels.get(0)==null));
ArrayList<JointChannel> half1 = new ArrayList<JointChannel>(jointChannels.size()/2);
for (int i = 0; i < jointChannels.size()/2; i++)
     half1.add(jointChannels.get(i));
ArrayList<JointChannel> half2 = new ArrayList<JointChannel>(jointChannels.size()/2);
for (int i = jointChannels.size()/2; i < jointChannels.size(); i++)
     half2.add(jointChannels.get(i));
SkinClip clip = new SkinClip(sequence.getSkeleton(), half1);
clip.setName("1");
java.util.ArrayList<SkinClip> clipList = new java.util.ArrayList<SkinClip>();
clipList.add(clip);
clip = new SkinClip(sequence.getSkeleton(), half2);
clip.setName("2");
clipList.add(clip);
newSequence = new SkinClipSequence(clipList);
newSequence.addClip(clip);
     }

But the printout tells me that jointChannnels.get(0) is null. So what am I doing wrong?
Title: Re: Parsing SkinClipSequence
Post by: raft on May 07, 2018, 01:48:39 pm
Code: [Select]
/** <p>Returns an iterator of channels. Note some channels may be null.</p> */
public Iterator<JointChannel> iterator() {
return Arrays.asList(channels).iterator();
}
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 07, 2018, 08:11:00 pm
Raft, do you mind being a little more helpful? Is this even the way to go? Because currently I'm only getting NullPointerExceptions.
Title: Re: Parsing SkinClipSequence
Post by: raft on May 07, 2018, 08:14:01 pm
well, as the Javadoc says, SkinClip.iterator() may return null values, just skip null ones in your code
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 07, 2018, 08:18:23 pm
OK, so filling two sets of JointChannels with non-null entries will definitely produce two sets of animations?
Title: Re: Parsing SkinClipSequence
Post by: raft on May 07, 2018, 08:19:33 pm
yup, supposed to be
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 07, 2018, 08:22:13 pm
Thanks.
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 07, 2018, 08:35:07 pm
It worked, but it did not parse the animations: it parsed the movements instead. Now I have an animation that only moves my character's fingers.
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 08, 2018, 01:36:21 am
Isn't SkinClipSequence supposed to be analog to Animation? Because Animation gives us access to KeyFrames, so why can't I find something similar in SkinClipSequence?
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 08, 2018, 07:32:15 am
From what I gather, it's the JointChannels themselves, rather than their number, that I need to split here. But Bones doesn't give me access to that. Would you be willing to change that?
Title: Re: Parsing SkinClipSequence
Post by: raft on May 08, 2018, 05:44:50 pm
SkinClip is the analogue of sub sequence in jPCT's Animation class. It's for whole skeleton, JointChannel is only for a joint in skeleton.

I can expose the internal data in JointChannel, but may not be trivial to split a channel's animation into shorter ones.

It's a bit weird EasyOgreExporter doesnt support multiple animations, it's written 'multiple Skeleton Animations' in their web page. Anyway, if that is the case, I would suggest, export each animation into a different file, and merge them with Bones, so you will end up with separate animations. merging can be done either with scripts (multiple input files) or programatically with AnimatedGroup.mergeAnimations(..) method.
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 08, 2018, 06:26:02 pm
They just implemented multiple animations and I just learned a trick to split them. But I still have a problem with the last (occasionally first) frame, which breaks an otherwise perfect loop. Control over the SkinClips would serve all kinds of purpose, and the ability to fix this would be one of them.
Title: Re: Parsing SkinClipSequence
Post by: raft on May 08, 2018, 07:51:07 pm
okay, exposed a copy of internal data structures in JointChannel. please re-download.

hope this helps
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 08, 2018, 08:38:19 pm
Thanks a lot.
Title: Re: Parsing SkinClipSequence
Post by: AGP on May 08, 2018, 10:18:15 pm
I feel like this could be a sticky. It's working, and it will prove very helpful. The ArrayList is there because I was originally testing for nulls before adding to it, but it may as well be removed for performance (although this is the kind of performance that doesn't really matter because you only run this code once before creating your .bones file.

Code: [Select]
     private void firstFrameToLast() {
SkinClipSequence sequence = animatedGroup.getSkinClipSequence();
for (int i = 0; i < sequence.getSize(); i++) {
     SkinClip clip = sequence.getClip(i);
     java.util.Iterator<JointChannel> jCs = clip.iterator();
     ArrayList<JointChannel> jointChannels = new ArrayList<JointChannel>();
     while (jCs.hasNext()) {
JointChannel jC = jCs.next();
     jointChannels.add(jC);
JointChannel channel = jC;
int index = channel.getJointIndex();
float[] times = channel.getTimes();
SimpleVector[] translations = channel.getTranslations();
Quaternion[] rotations = channel.getRotations();
SimpleVector[] scales = channel.getScales();
translations[translations.length-1] = translations[0];
rotations[rotations.length-1] = rotations[0];
scales[scales.length-1] = scales[0];
channel = new JointChannel(index, times, translations, rotations, scales);
clip.removeChannel(jC);
clip.addChannel(channel);
     }
}
saveToBones(objectFileName.substring(0, objectFileName.lastIndexOf("."))+".bones");
System.out.println("Last Frame Replaced With First");
Toolkit.getDefaultToolkit().beep();
     }