Possible bug in KeyFrameController

Hi all,

When calling this piece of code everyframe, it works fine:



gangsterC.setRepeatType(Controller.RT_CYCLE);
weaponC.setRepeatType(Controller.RT_CYCLE);
gangsterC.setMinTime(172f);
gangsterC.setMaxTime(177f);
weaponC.setMinTime(0f);
weaponC.setMaxTime(0f);



However, if I change cycle to clamp, the animation freezes at minTime. Even if I added a mechanism whereby the setRepeatType is only called once, the freezing action still occurs.

so the code for clamp is:


gangsterC.setRepeatType(Controller.RT_CLAMP);
weaponC.setRepeatType(Controller.RT_CLAMP);
gangsterC.setMinTime(172f);
gangsterC.setMaxTime(177f);
weaponC.setMinTime(0f);
weaponC.setMaxTime(0f);



the animation freezes on minTime. Is this intended or is it a bug?

DP

gangsterC.setRepeatType(Controller.RT_CLAMP);
weaponC.setRepeatType(Controller.RT_CLAMP);
gangsterC.setMinTime(172f);
gangsterC.setMaxTime(177f);
weaponC.setMinTime(0f);
weaponC.setMaxTime(0f);



What that should do is animate gangster from 172 to 177 and then freeze him at 177. Then it should animate weapon from 0 to 0, hit 0, then stop. You're saying it goes from 172 to 177 then back to 172 and freezes, or does it simply not animate at all? Is it active before you set this?

what im saying is that it just doesn’t animate at all. And yes, its active.



DP

try



gangsterC.setNewAnimationTimes(172,177)

weaponC.setNewAnimationTimes(0,0)



Depending upon how your state is at the time, your movingForward flag could be conflicted. There is also a posibility that the “curTime” of KeyframeController isn’t in your new bounds. That’s why I added setNewAnimationTimes(float,float). Also you say you call it every frame. You should only change animation times when they need to be changed. It should work fine with setNewAnimationTimes(). The function is somewhat smart. If the two times are the same, it sets to that time and turns the animation off automatically. If not, it turns it on automactially. If the start time is greater than the end time, it sets up a reverse animation.

ok, the setNewAnimationTimes work with CLAMP. However, they cannot be called everyframe. Which makes life harder.



BTW, if you were to convert Md2 to jME and compare the animation smoothness between teh md2 and the jme, youd find that the Md2 wraps better than the jme, not jumps between the maxTime and the minTime when it changes back.



I have a md2viewer and it tells me when a certain animation starts and ends, so im using that as my guide.



Cep, if were to add those lines at the bottom of simpleUpdate in TestMd2JmeWrite, you’l know what I mean:



kc.setRepeatType(Controller.RT_WRAP);
kc.setMinTime(0);
kc.setMaxTime(39);



That is basically the first animation looping over and over.

Comparing it with TestMd2, select the first animation using F1, you'l see that it doesn't jump when going back to frame 0.

Any thoughts about this?

Use a boolean flag to tell you when to change animation types. It should be faster that way, than making some unneeded function calls every single frame.



Animation times are 0 indexed with md2. Try using


kc.setNewAnimationTimes(0,38);



and you won't see the jump. The jump is it actually trying to goto the next animation set. if you're talking about the jump from 38 back to 0, I agree it does jump, but that's suppose to happen. I mean, how do I define an animation from time t=38 to time t=0?? How long should it take to animate between the two? If you're cleaver, you could insert an animate at time t=39 that looks like t=0 and loop from 0-39. Another way, would be to set your repeat type to CLAMP and animate from 0-38 to start and do this.

if (kc.isActive()==false){
kc.setActive(true)
kc.setSmoothTranslation(0,1,0,38);
// Translate back to 0.  Take 1 second to do it. Then reactivate animation
//    from 0 to 38
}



It takes advantage of the fact that CLAMP turns the animation off when it's done.

I have indexed the animations to start at 0, it was from 1 - 40, i changed it from 0 - 39.



I can see your point cep, but VertexKeyframeController doesn’t have this problem. And setting an animation at frame 40 that looks like 0 and the smooth transitions just look like a work around to me cep, they dont solve the actual problem.



Perhaps you could make a special case for md2 models?



DP

I have just had a look at the animation part of the XML document generated. And I think I have found the problem.



I dont know the solution, but I know ( i think ) whats causing the problem. When wrapping from say 39 back to 0, the animation is at frame 38, on the next frame, 39 should be rendered, but because of the wrap, at the end of the update, its bought back to 0 before 39 had a chance to be rendered. So frame 39 isn’t being rendered and the jump is from 38 - 0 not from 39 - 0.



But this is based on observation rather than looking at the code, so I could be way of base.



DP

Frame 39 isn’t suppost to be rendered. It’s just rendering frame 38.99999 which is basicly the same as 39.



It’s working the way I entented but you’re saying you want a smooth transformation from the last frame to the begining frame? I’ll look into it when I get back home

cep, any progress on this yet?



DP

It had taken a back seat for the documentation, and I had forgot. I’ll crack it open tonight.

cep, its been like a month now, and youve taken a completely new task and forgot about this.



I just want to know if this will be done or not? Its ok if you dont do it, il guess im going to have to go through all your code and figure out how to implement this.



DP

I did look at it. It was a bit more difficult than I thought it would be so I stopped for a bit and forgot again :? You can fix it yourself if you want. Here’s what update() tries to do.



The function findFrame() tries to set curFrame to the correct value. In your case, curFrame will be the last one the user wants to use.



Then you have oldShape (which is what the shape is morphing “away” from) and you have newShape (which is what the shape is morphing “towards”). This is usually the shapes between the curTime. But in your case, you are going away from the last frame and towards the first frame. The amount of change between oldShape and newShape is delta, which is a float percent between .00 and 1.00. You’ll need a special case that detects that the KeyframeController is at the end (or begining) of an animation and morphs from the last TriMesh users want, towards the first TriMesh the users want, by some growning delta across time.



If you run into any problems, PM me. Sorry about the delay.