Author Topic: Patch: fix ship:getAnimationDoneTime() (partially)  (Read 4349 times)

0 Members and 1 Guest are viewing this topic.

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Patch: fix ship:getAnimationDoneTime() (partially)
The underpinnings for the function in modelanim.cpp were utterly broken, so here's a patch which makes it return sensible values. Due to how +acceleration works, which is a completely incomprehensible mess for seemingly no reason at all, it still won't return the correct value for animations which use +acceleration (it'll return a bigger value than it should), but it does for animations which don't use it. Possibly the animation's target angle divided by its velocity needs to equal its time*1000 as well, but I've never understood if there's any use case for doing it otherwise so whatever.

I'm not going to make the patch any fancier and cover the usage of +acceleration, because the design and implementation for that feature is simply so obnoxious that I can't even tell what it's supposed to do exactly, not to mention figuring out how the relevant code works (or rather, doesn't work). No offense to anyone. A comprehensible fix would likely entail a rewrite of those parts of the code and making +acceleration work in an entirely different way entirely.

For now, this patches things up so that getAnimationDoneTime() returns the right value in what I think is the most common use case.

Code: [Select]
Index: modelanim.cpp
===================================================================
--- modelanim.cpp (revision 7992)
+++ modelanim.cpp (working copy)
@@ -107,7 +107,7 @@
  slow_angle.a1d[0], slow_angle.a1d[1], slow_angle.a1d[2]));
 
  has_started = true;
- end_time = q->end_time;
+ end_time = timestamp(model_anim_instance_get_actual_time(q));
 }
 
 void triggered_rotation::set_to_end(queued_animation *q)
@@ -175,7 +175,7 @@
 
  if (new_queue.start == 0) {
  new_queue.start_time = timestamp();
- new_queue.end_time = timestamp( new_queue.end );
+ new_queue.end_time = timestamp( model_anim_instance_get_actual_time(&new_queue) );
 
  // if there is no delay don't bother with the queue, just start the thing
  start( &new_queue );
@@ -193,7 +193,7 @@
  // so this means that there is some sort of delay that's getting fubared becase of other queue items getting removed due to reversal
  // this animation needs to be started now!
  new_queue.start_time = timestamp();
- new_queue.end_time = timestamp( new_queue.end );
+ new_queue.end_time = timestamp( model_anim_instance_get_actual_time(&new_queue) );
 
  // if there is no delay don't bother with the queue, just start the thing
  start( &new_queue );
@@ -515,9 +515,13 @@
  int temp = 0;
 
  for (int a = 0; a < 3; a++) {
- temp = fl2i( ((3.0f * properties->vel.a1d[a] * properties->vel.a1d[a]) + (2.0f * properties->accel.a1d[a] * fabs(properties->angle.a1d[a])))
+ if (properties->accel.a1d[a] > 0.0f) {
+ temp = fl2i( ((3.0f * properties->vel.a1d[a] * properties->vel.a1d[a]) + (2.0f * properties->accel.a1d[a] * fabs(properties->angle.a1d[a])))
  / (2.0f * properties->accel.a1d[a] * properties->vel.a1d[a]) * 1000.0f )
  + properties->start;
+ } else {
+ temp = properties->end;
+ }
 
  if (temp > ret)
  ret = temp;
@@ -643,16 +647,24 @@
 
  for (int a = 0; a < 3; a++) {
  triggered_rotation tr = pss->trigger;
- float end_angle = (tr.current_ang.a1d[a]  + (((tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a]) - (tr.current_vel.a1d[a]*tr.current_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])));
 
- if (end_angle > tr.slow_angle.a1d[a]) {
- //T(total) =  (2V(maximum) - V(initial))/a + (S(turnpoint) - S(initial) + (V(initial)^2 - V(maximum)^2)/2a) / V(maximum)
- a_time = fl2i(((((2*tr.rot_vel.a1d[a]) - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) + tr.slow_angle.a1d[a] - tr.current_ang.a1d[a] + (((tr.current_vel.a1d[a]*tr.current_vel.a1d[a]) - (tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])))*1000.0f);
- if (ani_time < a_time)
- ani_time = a_time;
+ if (tr.rot_accel.a1d[a] > 0.0f) {
+ float end_angle = (tr.current_ang.a1d[a]  + (((tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a]) - (tr.current_vel.a1d[a]*tr.current_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])));
+
+ if (end_angle > tr.slow_angle.a1d[a]) {
+ //T(total) =  (2V(maximum) - V(initial))/a + (S(turnpoint) - S(initial) + (V(initial)^2 - V(maximum)^2)/2a) / V(maximum)
+ a_time = fl2i(((((2*tr.rot_vel.a1d[a]) - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) + tr.slow_angle.a1d[a] - tr.current_ang.a1d[a] + (((tr.current_vel.a1d[a]*tr.current_vel.a1d[a]) - (tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])))*1000.0f);
+ if (ani_time < a_time)
+ ani_time = a_time;
+ } else {
+ //T(total)  = 2 * sqrt((S(final) - S(initial))/a - ( (V(initial)/a)^2 ) / 2 ) - V(initial)/a
+ a_time = fl2i((2 * fl_sqrt(((tr.end_angle.a1d[a] - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) - ((tr.current_vel.a1d[a] * tr.current_vel.a1d[a]) / (tr.rot_accel.a1d[a] * tr.rot_accel.a1d[a])) / 2) - (tr.current_vel.a1d[a] / tr.rot_accel.a1d[a]))*1000.0f);
+ if (ani_time < a_time)
+ ani_time = a_time;
+ }
  } else {
- //T(total)  = 2 * sqrt((S(final) - S(initial))/a - ( (V(initial)/a)^2 ) / 2 ) - V(initial)/a
- a_time = fl2i((2 * fl_sqrt(((tr.end_angle.a1d[a] - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) - ((tr.current_vel.a1d[a] * tr.current_vel.a1d[a]) / (tr.rot_accel.a1d[a] * tr.rot_accel.a1d[a])) / 2) - (tr.current_vel.a1d[a] / tr.rot_accel.a1d[a]))*1000.0f);
+ a_time = tr.end_time - timestamp();
+
  if (ani_time < a_time)
  ani_time = a_time;
  }
@@ -663,7 +675,7 @@
  } else {
  // if it isn't moving then it's trivial.
  // no currently playing animation
- ani_time = psub->triggers[i].end + psub->triggers[i].start;
+ ani_time = 0;
  }
 
  if (ret < ani_time)
Index: modelanim.h
===================================================================
--- modelanim.h (revision 7992)
+++ modelanim.h (working copy)
@@ -145,6 +145,7 @@
 bool model_anim_start_type(ship *shipp, int animation_type, int subtype, int direction); // for all valid subsystems
 
 // how long until the animation is done
+int model_anim_instance_get_actual_time(queued_animation *properties);
 int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype); // for a specific subsystem
 int model_anim_get_time_type(ship *shipp, int animation_type, int subtype); // for all valid subsystems
 

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Patch: fix ship:getAnimationDoneTime() (partially)
I'm not going to make the patch any fancier and cover the usage of +acceleration, because the design and implementation for that feature is simply so obnoxious that I can't even tell what it's supposed to do exactly, not to mention figuring out how the relevant code works (or rather, doesn't work). No offense to anyone. A comprehensible fix would likely entail a rewrite of those parts of the code and making +acceleration work in an entirely different way entirely.
My feelings exactly.  I was frustrated enough trying to solve some animation issues involved in adding an animation trigger, let alone understanding the animation code itself.

I've PMmed Vasudan Admiral for a second person to test this patch.  If he's happy too, I'll commit it.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Patch: fix ship:getAnimationDoneTime() (partially)
i tend to prefer scripting for animation, it just does more, does it better, and isnt a convoluted mess. just interpolate between 2 matrices using a 0-1 float for input. you have everything you need to implement a keyaframe animation and even ik if one was so inclined. the "animation code" system has never been reliable, it works in some builds and doesnt in others, very few modders know how to use it. most importently the feature was never completed. no variable linked animation and very few events are supported.
« Last Edit: February 09, 2012, 11:48:14 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Dragon

  • Citation needed
  • 212
  • The sky is the limit.
Re: Patch: fix ship:getAnimationDoneTime() (partially)
IMO, somebody should give the animation system an overhaul. It's possible to do a lot of amazing things using it, but translation requires an ugly model hack and bay doors can't be opened by SEXPs, not to mention other limitations. There are also issues with rapid weapon cycling (sometimes, if you don't allow the animation to cycle before switching to the next bank, it might get stuck).

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Patch: fix ship:getAnimationDoneTime() (partially)
Well, I recently added a sexp to trigger submodel animation.  But I agree, the actual rotation code needs to be rewritten.

 

Offline Spoon

  • 212
  • ヾ(´︶`♡)ノ
Re: Patch: fix ship:getAnimationDoneTime() (partially)
Isn't it common knowledge that the animation code is a incomplete, poorly done mess?  :p
Urutorahappī!!

[02:42] <@Axem> spoon somethings wrong
[02:42] <@Axem> critically wrong
[02:42] <@Axem> im happy with these missions now
[02:44] <@Axem> well
[02:44] <@Axem> with 2 of them

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Patch: fix ship:getAnimationDoneTime() (partially)
i could replace the thing with scripting in an hour, if it were to be depricated, i already have a a prtial linked animation system in my cockpit script.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Valathil

  • ...And I would have had a custom title if it wasn't for you meddling kids!
  • 29
  • Custom Title? Wizards need no Custom Title!
Re: Patch: fix ship:getAnimationDoneTime() (partially)
Light a fire under Swifty's ass. NEED SKELETAL ANIMATION CODE NAU
┏┓╋┏┓╋╋╋╋╋╋╋╋╋┏┓
┃┃╋┃┃╋╋╋╋╋╋╋╋╋┃┃
┃┃┏┫┃┏┳━━┓┏━━┓┃┗━┳━━┳━━┳━━┓
┃┃┣┫┗┛┫┃━┫┃┏┓┃┃┏┓┃┏┓┃━━┫━━┫
┃┗┫┃┏┓┫┃━┫┃┏┓┃┃┗┛┃┗┛┣━━┣━━┃
┗━┻┻┛┗┻━━┛┗┛┗┛┗━━┻━━┻━━┻━━┛

 

Offline Ace

  • Truth of Babel
  • 212
    • http://www.lordofrigel.com
Re: Patch: fix ship:getAnimationDoneTime() (partially)
I thought that was speeeled NAOI!!!!111

Anyway proper translation code would be good to have, for obvious 2km in size reasons....
Ace
Self-plagiarism is style.
-Alfred Hitchcock

 

Offline Bobboau

  • Just a MODern kinda guy
    Just MODerately cool
    And MODest too
  • 213
Re: Patch: fix ship:getAnimationDoneTime() (partially)
acceleration (and speed for that matter) run on a simplified physics simulation, it's purpose is to allow smooth animations, so that things start and end stopped, but can move quite fast in the middle. you need a little calculus to get things working right.
Bobboau, bringing you products that work... in theory
learn to use PCS
creator of the ProXimus Procedural Texture and Effect Generator
My latest build of PCS2, get it while it's hot!
PCS 2.0.3


DEUTERONOMY 22:11
Thou shalt not wear a garment of diverse sorts, [as] of woollen and linen together

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Patch: fix ship:getAnimationDoneTime() (partially)
id just use interpolation to get an intermediate matrix from start and end matrices, and animate the 0..1 intepolation value as a function of time (ramping and unramping effects could also be done). id like to see better animation though, keyframe animation, iterative ik, etc. really we cant do much with animation with the way our subobjects work. if we cant even lod subobjects separate from the ship, and we can only rotate them, and even then bounding boxes give us collision hell. some time ago i suggested having another object class derivative to the game so that you could use separate models for things like turrets, and physical subsystems, which would be more animation friendly and could be lod-ed by actual distance rather than by parent distance.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Aardwolf

  • 211
  • Posts: 16,384
    • Minecraft
Re: Patch: fix ship:getAnimationDoneTime() (partially)
I would suggest using quaternions instead. That way you can do SLERP (spherical linear interpolation)... linearly interpolating matrices can yield some pretty freaky results... e.g. the way the camera code used to do ridiculous zooms as the camera rotated.

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Patch: fix ship:getAnimationDoneTime() (partially)
Ugh.  Are we going to have to sic CP5670 on this?

 

Offline Bobboau

  • Just a MODern kinda guy
    Just MODerately cool
    And MODest too
  • 213
Re: Patch: fix ship:getAnimationDoneTime() (partially)
Nuke, Aardwolf, you suggest completely abandoning the existing animation system and rewriting it from scratch. Just wanted to make sure you were aware of what you were proposing.
Bobboau, bringing you products that work... in theory
learn to use PCS
creator of the ProXimus Procedural Texture and Effect Generator
My latest build of PCS2, get it while it's hot!
PCS 2.0.3


DEUTERONOMY 22:11
Thou shalt not wear a garment of diverse sorts, [as] of woollen and linen together

  

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Patch: fix ship:getAnimationDoneTime() (partially)
really its a matter of what is easier. to upgrade and maintain the existing system, or to replace it with something of superior design. the main issues are, that the system is hard to set up, breaks down often (its been broke and patched more times than i can count), and few of the coders really understand how it works (which results in "breaks down often"). if those issues can be resolved then i dont see any reason to deprecate. a new system also wont really bring anything new to the table. you will be able to do the same kind of animations. the major limits (no translations, bounding box issues, etc) have nothing to do with the system at all, and are general engine limitations. i wouldn't replace it with a new system from scratch unless it can do something the existing system cant, and for me scripting is a viable alternative.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN