anim_object.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /// if arm_anim
  2. type anim_object_t = {
  3. base?: anim_raw_t;
  4. object?: object_t;
  5. oactions?: scene_t[];
  6. oaction?: obj_t;
  7. };
  8. function anim_object_create(object: object_t, oactions: scene_t[]): anim_object_t {
  9. let raw: anim_object_t = {};
  10. raw.base = anim_create();
  11. raw.base.ext = raw;
  12. raw.base.ext_type = "anim_object_t";
  13. raw.object = object;
  14. raw.oactions = oactions;
  15. anim_object_play(raw);
  16. return raw;
  17. }
  18. function anim_object_get_action(raw: anim_object_t, action: string): obj_t {
  19. for (let i: i32 = 0; i < raw.oactions.length; ++i) {
  20. let a: scene_t = raw.oactions[i];
  21. if (a != null && a.objects[0].name == action) {
  22. return a.objects[0];
  23. }
  24. }
  25. return null;
  26. }
  27. function anim_object_update_object_anim(raw: anim_object_t) {
  28. anim_object_update_transform_anim(raw, raw.oaction.anim, raw.object.transform);
  29. transform_build_matrix(raw.object.transform);
  30. }
  31. function anim_object_interpolate_linear(t: f32, t1: f32, t2: f32, v1: f32, v2: f32): f32 {
  32. let s: f32 = (t - t1) / (t2 - t1);
  33. return (1.0 - s) * v1 + s * v2;
  34. }
  35. function anim_object_check_frame_index_t(raw: anim_object_t, frame_values: u32_array_t, t: f32): bool {
  36. return raw.base.speed > 0 ? raw.base.frame_index < frame_values.length - 2 && t > frame_values[raw.base.frame_index + 1] * raw.base.frame_time
  37. : raw.base.frame_index > 1 && t > frame_values[raw.base.frame_index - 1] * raw.base.frame_time;
  38. }
  39. function anim_object_update_transform_anim(raw: anim_object_t, anim: anim_t, transform: transform_t) {
  40. if (anim == null) {
  41. return;
  42. }
  43. let total: i32 = anim.end * raw.base.frame_time - anim.begin * raw.base.frame_time;
  44. if (anim.has_delta) {
  45. let t: transform_t = transform;
  46. if (vec4_isnan(t.dloc)) {
  47. t.dloc = vec4_create();
  48. t.drot = quat_create();
  49. t.dscale = vec4_create();
  50. }
  51. t.dloc = vec4_create(0, 0, 0);
  52. t.dscale = vec4_create(0, 0, 0);
  53. t._deuler_x = t._deuler_y = t._deuler_z = 0.0;
  54. }
  55. for (let i: i32 = 0; i < anim.tracks.length; ++i) {
  56. let track: track_t = anim.tracks[i];
  57. if (raw.base.frame_index == -1) {
  58. anim_rewind(raw.base, track);
  59. }
  60. let sign: i32 = raw.base.speed > 0 ? 1 : -1;
  61. // End of current time range
  62. let t: f32 = raw.base.time + anim.begin * raw.base.frame_time;
  63. while (anim_object_check_frame_index_t(raw, track.frames, t)) {
  64. raw.base.frame_index += sign;
  65. }
  66. // No data for raw track at current time
  67. if (raw.base.frame_index >= track.frames.length) {
  68. continue;
  69. }
  70. // End of track
  71. if (raw.base.time > total) {
  72. if (raw.base.on_complete != null) {
  73. raw.base.on_complete();
  74. }
  75. if (raw.base.loop) {
  76. anim_rewind(raw.base, track);
  77. }
  78. else {
  79. raw.base.frame_index -= sign;
  80. raw.base.paused = true;
  81. }
  82. return;
  83. }
  84. let ti: i32 = raw.base.frame_index;
  85. let t1: f32 = track.frames[ti] * raw.base.frame_time;
  86. let t2: f32 = track.frames[ti + sign] * raw.base.frame_time;
  87. let v1: f32 = track.values[ti];
  88. let v2: f32 = track.values[ti + sign];
  89. let value: f32 = anim_object_interpolate_linear(t, t1, t2, v1, v2);
  90. let target: string = track.target;
  91. if (target == "xloc") {
  92. transform.loc.x = value;
  93. }
  94. else if (target == "yloc") {
  95. transform.loc.y = value;
  96. }
  97. else if (target == "zloc") {
  98. transform.loc.z = value;
  99. }
  100. else if (target == "xrot") {
  101. transform_set_rot(transform, value, transform._euler_y, transform._euler_z);
  102. }
  103. else if (target == "yrot") {
  104. transform_set_rot(transform, transform._euler_x, value, transform._euler_z);
  105. }
  106. else if (target == "zrot") {
  107. transform_set_rot(transform, transform._euler_x, transform._euler_y, value);
  108. }
  109. else if (target == "qwrot") {
  110. transform.rot.w = value;
  111. }
  112. else if (target == "qxrot") {
  113. transform.rot.x = value;
  114. }
  115. else if (target == "qyrot") {
  116. transform.rot.y = value;
  117. }
  118. else if (target == "qzrot") {
  119. transform.rot.z = value;
  120. }
  121. else if (target == "xscl") {
  122. transform.scale.x = value;
  123. }
  124. else if (target == "yscl") {
  125. transform.scale.y = value;
  126. }
  127. else if (target == "zscl") {
  128. transform.scale.z = value;
  129. }
  130. // Delta
  131. else if (target == "dxloc") {
  132. transform.dloc.x = value;
  133. }
  134. else if (target == "dyloc") {
  135. transform.dloc.y = value;
  136. }
  137. else if (target == "dzloc") {
  138. transform.dloc.z = value;
  139. }
  140. else if (target == "dxrot") {
  141. transform._deuler_x = value;
  142. }
  143. else if (target == "dyrot") {
  144. transform._deuler_y = value;
  145. }
  146. else if (target == "dzrot") {
  147. transform._deuler_z = value;
  148. }
  149. else if (target == "dqwrot") {
  150. transform.drot.w = value;
  151. }
  152. else if (target == "dqxrot") {
  153. transform.drot.x = value;
  154. }
  155. else if (target == "dqyrot") {
  156. transform.drot.y = value;
  157. }
  158. else if (target == "dqzrot") {
  159. transform.drot.z = value;
  160. }
  161. else if (target == "dxscl") {
  162. transform.dscale.x = value;
  163. }
  164. else if (target == "dyscl") {
  165. transform.dscale.y = value;
  166. }
  167. else if (target == "dzscl") {
  168. transform.dscale.z = value;
  169. }
  170. }
  171. }
  172. function anim_object_play(raw: anim_object_t, action: string = "", on_complete: () => void = null, blend_time: f32 = 0.0, speed: f32 = 1.0, loop: bool = true) {
  173. anim_play_super(raw.base, action, on_complete, blend_time, speed, loop);
  174. if (raw.base.action == "" && raw.oactions[0] != null) {
  175. raw.base.action = raw.oactions[0].objects[0].name;
  176. }
  177. raw.oaction = anim_object_get_action(raw, raw.base.action);
  178. }
  179. function anim_object_update(raw: anim_object_t, delta: f32) {
  180. if (!raw.object.visible || raw.object.culled || raw.oaction == null) {
  181. return;
  182. }
  183. anim_update_super(raw.base, delta);
  184. if (raw.base.paused) {
  185. return;
  186. }
  187. anim_object_update_object_anim(raw);
  188. }
  189. function anim_object_is_track_end(raw: anim_object_t, track: track_t): bool {
  190. return raw.base.speed > 0 ? raw.base.frame_index >= track.frames.length - 2 : raw.base.frame_index <= 0;
  191. }
  192. function anim_object_total_frames(raw: anim_object_t): i32 {
  193. if (raw.oaction == null || raw.oaction.anim == null) {
  194. return 0;
  195. }
  196. return raw.oaction.anim.end - raw.oaction.anim.begin;
  197. }
  198. /// end