Advertisement
Guest User

VEX Squad implee

a guest
Feb 25th, 2020
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.21 KB | None | 0 0
  1. #define is_zero(x) abs(x) < 0.0001
  2. #define is_one(x) abs(x) > 0.9999
  3.  
  4. // quaternion dot product (vex version omits last component)
  5. function float qdot(vector4 left; vector4 right)
  6. {
  7.     return left.x * right.x + left.y * right.y
  8.         + left.z * right.z + left.w * right.w;
  9. }
  10.  
  11. // slerp with no invert
  12. function vector4 slerp_non_shortest(vector4 from; vector4 to; float factor)
  13. {
  14.     float dot_product = qdot(from, to);
  15.     if (is_one(dot_product)) return from;
  16.    
  17.     float th = acos(dot_product);
  18.     float sinTh = 1.0 / sin(th);
  19.    
  20.     float t = sin(factor * th) * sinTh;
  21.     float invt = sin((1.0 - factor) * th) * sinTh;
  22.    
  23.     return set(
  24.         invt * from.x + t * to.x,
  25.         invt * from.y + t * to.y,
  26.         invt * from.z + t * to.z,
  27.         invt * from.w + t * to.w
  28.     );
  29. }
  30.  
  31. // logarithmic quaternion
  32. function vector4 qlog(vector4 q)
  33. {
  34.     float a = acos(q.w);
  35.     float s = sin(a);
  36.  
  37.     if (is_zero(s)) return 0;
  38.    
  39.     float f = a / s;
  40.    
  41.     return set(f * q.x, f * q.y, f * q.z, 0);
  42. }
  43.  
  44. // exponential quaternion
  45. function vector4 qexp(vector4 q)
  46. {
  47.     float l = length(vector(q));
  48.     float s = sin(l);
  49.     float c = cos(l);
  50.  
  51.     if (is_zero(l)) return set(0, 0, 0, c);
  52.    
  53.     float t = s / l;
  54.    
  55.     return set(t * q.x, t * q.y, t * q.z, c);
  56. }
  57.  
  58. // get keyframe control point for squad based on previous and next keyframes
  59. function vector4 get_squad_control(vector4 prev; vector4 current; vector4 next)
  60. {
  61.     vector4 qinv = qinvert(current);
  62.     vector4 qprev = qmultiply(qinv, prev);
  63.     vector4 qnext = qmultiply(qinv, next);
  64.     vector4 qlogsum = -0.25 * (qlog(qprev) + qlog(qnext));
  65.     vector4 qe = qexp(qlogsum);
  66.     return qmultiply(current, qe);
  67. }
  68.  
  69. // squad interpolation: from_control and to_control must be calculated beforehand with get_squad_control()
  70. vector4 qsquad(vector4 from; vector4 to; vector4 from_control; vector4 to_control; float factor)
  71. {
  72.     return slerp_non_shortest(
  73.         slerp_non_shortest(from, to, factor),
  74.         slerp_non_shortest(from_control, to_control, factor),
  75.         2.0 * factor * (1 - factor)
  76.     );
  77. }
  78.  
  79. // example for 4 keys
  80.  
  81. vector key1 = chv("key1");
  82. vector key2 = chv("key2");
  83. vector key3 = chv("key3");
  84. vector key4 = chv("key4");
  85.  
  86. vector keys[] = array(key1, key2, key3, key4, key1);
  87. vector4 qkeys[] = array(0, 0, 0, 0, 0);
  88. vector4 qcontrols[] = array(0, 0, 0, 0, 0);
  89.  
  90. for (int i = 0; i < 5; i++)
  91. {
  92.     qkeys[i] = eulertoquaternion(radians(keys[i]), XFORM_XYZ);
  93. }
  94.  
  95. for (int i = 0; i < 5; i++)
  96. {
  97.     int prev_index = i - 1 < 0 ? 3 : i - 1;
  98.     int next_index = i + 1 > 4 ? 1 : i + 1;
  99.     qcontrols[i] = get_squad_control(qkeys[prev_index], qkeys[i], qkeys[next_index]);
  100. }
  101.  
  102. float time_normalized = chf("totaltime");
  103. float time_step = 1.0 / 4.0;
  104.  
  105. int key_index = (int)fit01(time_normalized, 0, 4);
  106. float local_time = time_normalized / time_step - key_index;
  107.  
  108. vector4 current_orientation = qsquad(qkeys[key_index], qkeys[key_index + 1],
  109.     qcontrols[key_index], qcontrols[key_index + 1], local_time);
  110.  
  111. vector angles = quaterniontoeuler(current_orientation, XFORM_XYZ);
  112.  
  113. matrix transform = ident();
  114. rotate(transform, angles, XFORM_XYZ);
  115. setpackedtransform(0, @primnum, transform);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement