transform.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. type transform_t = {
  2. world?: mat4_t;
  3. local_only?: bool;
  4. local?: mat4_t;
  5. loc?: vec4_t;
  6. rot?: quat_t;
  7. scale?: vec4_t;
  8. scale_world?: f32;
  9. world_unpack?: mat4_t;
  10. dirty?: bool;
  11. object?: object_t;
  12. dim?: vec4_t;
  13. radius?: f32;
  14. /// if arm_anim
  15. // Wrong order returned from get_euler(), store last state for animation
  16. _euler_x?: f32;
  17. _euler_y?: f32;
  18. _euler_z?: f32;
  19. // Animated delta transform
  20. dloc?: vec4_t;
  21. drot?: quat_t;
  22. dscale?: vec4_t;
  23. _deuler_x?: f32;
  24. _deuler_y?: f32;
  25. _deuler_z?: f32;
  26. /// end
  27. };
  28. function transform_create(object: object_t): transform_t {
  29. let raw: transform_t = {};
  30. raw.local_only = false;
  31. raw.scale_world = 1.0;
  32. raw.object = object;
  33. transform_reset(raw);
  34. return raw;
  35. }
  36. function transform_reset(raw: transform_t) {
  37. raw.world = mat4_identity();
  38. raw.world_unpack = mat4_identity();
  39. raw.local = mat4_identity();
  40. raw.loc = vec4_create();
  41. raw.rot = quat_create();
  42. raw.scale = vec4_create(1.0, 1.0, 1.0);
  43. raw.dim = vec4_create(2.0, 2.0, 2.0);
  44. raw.radius = 1.0;
  45. raw.dirty = true;
  46. }
  47. function transform_update(raw: transform_t) {
  48. if (raw.dirty) {
  49. transform_build_matrix(raw);
  50. }
  51. }
  52. /// if arm_anim
  53. function transform_compose_delta(raw: transform_t) {
  54. // Delta transform
  55. raw.dloc = vec4_add(raw.loc, raw.dloc);
  56. raw.dscale = vec4_add(raw.dscale, raw.scale);
  57. raw.drot = quat_from_euler(raw._deuler_x, raw._deuler_y, raw._deuler_z);
  58. raw.drot = quat_mult(raw.rot, raw.drot);
  59. raw.local = mat4_compose(raw.dloc, raw.drot, raw.dscale);
  60. }
  61. /// end
  62. function transform_build_matrix(raw: transform_t) {
  63. // if (vec4_isnan(raw.dloc)) {
  64. raw.local = mat4_compose(raw.loc, raw.rot, raw.scale);
  65. // }
  66. // else {
  67. // transform_compose_delta(raw);
  68. // }
  69. if (raw.object.parent != null && !raw.local_only) {
  70. raw.world = mat4_mult_mat3x4(raw.local, raw.object.parent.transform.world);
  71. }
  72. else {
  73. raw.world = mat4_clone(raw.local);
  74. }
  75. raw.world_unpack = mat4_clone(raw.world);
  76. if (raw.scale_world != 1.0) {
  77. raw.world_unpack.m00 *= raw.scale_world;
  78. raw.world_unpack.m01 *= raw.scale_world;
  79. raw.world_unpack.m02 *= raw.scale_world;
  80. raw.world_unpack.m03 *= raw.scale_world;
  81. raw.world_unpack.m10 *= raw.scale_world;
  82. raw.world_unpack.m11 *= raw.scale_world;
  83. raw.world_unpack.m12 *= raw.scale_world;
  84. raw.world_unpack.m13 *= raw.scale_world;
  85. raw.world_unpack.m20 *= raw.scale_world;
  86. raw.world_unpack.m21 *= raw.scale_world;
  87. raw.world_unpack.m22 *= raw.scale_world;
  88. raw.world_unpack.m23 *= raw.scale_world;
  89. }
  90. transform_compute_dim(raw);
  91. // Update children
  92. for (let i: i32 = 0; i < raw.object.children.length; ++i) {
  93. let n: object_t = raw.object.children[i];
  94. transform_build_matrix(n.transform);
  95. }
  96. raw.dirty = false;
  97. }
  98. function transform_translate(raw: transform_t, x: f32, y: f32, z: f32) {
  99. raw.loc.x += x;
  100. raw.loc.y += y;
  101. raw.loc.z += z;
  102. transform_build_matrix(raw);
  103. }
  104. function transform_set_matrix(raw: transform_t, mat: mat4_t) {
  105. raw.local = mat4_clone(mat);
  106. transform_decompose(raw);
  107. transform_build_matrix(raw);
  108. }
  109. function transform_mult_matrix(raw: transform_t, mat: mat4_t) {
  110. raw.local = mat4_mult_mat(raw.local, mat);
  111. transform_decompose(raw);
  112. transform_build_matrix(raw);
  113. }
  114. function transform_decompose(raw: transform_t) {
  115. let dec: mat4_decomposed_t = mat4_decompose(raw.local);
  116. raw.loc = dec.loc;
  117. raw.rot = dec.rot;
  118. raw.scale = dec.scl;
  119. }
  120. function transform_rotate(raw: transform_t, axis: vec4_t, f: f32) {
  121. let q: quat_t = quat_from_axis_angle(axis, f);
  122. raw.rot = quat_mult(q, raw.rot);
  123. transform_build_matrix(raw);
  124. }
  125. function transform_move(raw: transform_t, axis: vec4_t, f: f32 = 1.0) {
  126. raw.loc = vec4_fadd(raw.loc, axis.x * f, axis.y * f, axis.z * f);
  127. transform_build_matrix(raw);
  128. }
  129. function transform_set_rot(raw: transform_t, x: f32, y: f32, z: f32) {
  130. raw.rot = quat_from_euler(x, y, z);
  131. /// if arm_anim
  132. raw._euler_x = x;
  133. raw._euler_y = y;
  134. raw._euler_z = z;
  135. /// end
  136. raw.dirty = true;
  137. }
  138. function transform_compute_radius(raw: transform_t) {
  139. raw.radius = math_sqrt(raw.dim.x * raw.dim.x + raw.dim.y * raw.dim.y + raw.dim.z * raw.dim.z);
  140. }
  141. function transform_compute_dim(raw: transform_t) {
  142. if (raw.object.raw == null && raw.object.ext_type == "mesh_object_t") {
  143. let mo: mesh_object_t = raw.object.ext;
  144. let aabb: vec4_t = mesh_data_calculate_aabb(mo.data);
  145. let o: object_t = raw.object;
  146. o.raw = {};
  147. o.raw.dimensions = f32_array_create_xyz(aabb.x, aabb.y, aabb.z);
  148. }
  149. if (raw.object.raw == null || raw.object.raw.dimensions == null) {
  150. raw.dim = vec4_create(2 * raw.scale.x, 2 * raw.scale.y, 2 * raw.scale.z);
  151. }
  152. else {
  153. let d: f32_array_t = raw.object.raw.dimensions;
  154. raw.dim = vec4_create(d[0] * raw.scale.x, d[1] * raw.scale.y, d[2] * raw.scale.z);
  155. }
  156. transform_compute_radius(raw);
  157. }
  158. function transform_apply_parent_inv(raw: transform_t) {
  159. let pt: transform_t = raw.object.parent.transform;
  160. transform_build_matrix(pt);
  161. let pinv: mat4_t = mat4_inv(pt.world);
  162. raw.local = mat4_mult_mat(raw.local, pinv);
  163. transform_decompose(raw);
  164. transform_build_matrix(raw);
  165. }
  166. function transform_apply_parent(raw: transform_t) {
  167. let pt: transform_t = raw.object.parent.transform;
  168. transform_build_matrix(pt);
  169. raw.local = mat4_mult_mat(raw.local, pt.world);
  170. transform_decompose(raw);
  171. transform_build_matrix(raw);
  172. }
  173. function transform_look(raw: transform_t): vec4_t {
  174. return mat4_look(raw.world);
  175. }
  176. function transform_right(raw: transform_t): vec4_t {
  177. return mat4_right(raw.world);
  178. }
  179. function transform_up(raw: transform_t): vec4_t {
  180. return mat4_up(raw.world);
  181. }
  182. function transform_world_x(raw: transform_t): f32 {
  183. return raw.world.m30;
  184. }
  185. function transform_world_y(raw: transform_t): f32 {
  186. return raw.world.m31;
  187. }
  188. function transform_world_z(raw: transform_t): f32 {
  189. return raw.world.m32;
  190. }