home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / 3DSPLIN.TXT < prev    next >
Text File  |  1996-07-31  |  6KB  |  173 lines

  1. How To Calculate KXP Spline Derivatives
  2.  
  3. A Tips & Techniques document for use with the IPAS Toolkit
  4.  
  5. July 13, 1995
  6.  
  7. Introduction:
  8.  
  9. Several IPAS developers have requested information regarding how the
  10. derivatives for 3DS spline interpolation are computed for KXP development.
  11. This document contains a fairly uncommented example that will demonstrate
  12. 3D Studio's implementation of spline interpolation.
  13.  
  14. Example 3D Studio Key Interpolation Code
  15.  
  16. The following is an example of 3D Studio's key interpolation code for KXP
  17. IPAS developers. Note that position keys are handled just like any other
  18. track type except for rotations. Those are handled as detailed in the
  19. CompAB() function below.
  20.  
  21. NOTE: This is unsupported code; use at your own risk.
  22.  
  23. static void CompElementDeriv( float pp, float p, float pn,
  24.                                         float *ds, float *dd,float ksm,
  25.                                         float ksp, float kdm, float kdp )
  26. {
  27.         float delm, delp;
  28.  
  29.         delm = p - pp;
  30.         delp    = pn - p;
  31.         *ds  = ksm*delm + ksp*delp;
  32.         *dd  = kdm*delm + kdp*delp;
  33. }
  34.  
  35. /*-------------------------------------------------------
  36. This computes the derivative at key, as a weighted average of the linear slopes into and out of key, the weights being determined by the tension and continuity
  37.         "ds" is the "source derivative", or "arriving derivative"
  38.         "dd" is the "destination derivative" or "departing derivative"
  39. ----------------------------------------------------------*/
  40. static void CompDeriv( PosKey *keyp, PosKey *key, PosKey *keyn )
  41. {
  42.         int i;
  43.         /* Full TCB computation */
  44.         float tm,cm,cp,bm,bp,tmcm,tmcp,ksm,ksp,kdm,kdp,delm,delp,c;
  45.         float dt,fp,fn;
  46.  
  47.         /* fp,fn apply speed correction when continuity is 0.0 */
  48.         dt = .5 * (float)( keyn->frame - keyp->frame );
  49.         fp = ( (float)( key->frame - keyp->frame ) ) / dt;
  50.         fn = ( (float)( keyn->frame - key->frame ) ) / dt;
  51.         c  = fabs( key->cont );
  52.         fp = fp + c - c * fp;
  53.         fn = fn + c - c * fn;
  54.         cm = 1.0 - key->cont;
  55.         tm = 0.5 * ( 1.0 - key->tens );
  56.         cp = 2.0 - cm;
  57.         bm = 1.0 - key->bias;
  58.         bp = 2.0 - bm;
  59.         tmcm = tm*cm;   tmcp = tm*cp;
  60.         ksm = tmcm*bp*fp;       ksp = tmcp*bm*fp;
  61.         kdm = tmcp*bp*fn;       kdp = tmcm*bm*fn;
  62.  
  63.         for( i = X; i <= Z; i++ ) {
  64.                 CompElementDeriv( keyp->pos[i], key->pos[i], keyn->pos[i],
  65.                              &key->ds[i], &key->dd[i], ksm, ksp, kdm, kdp );
  66.         }
  67.  
  68. }
  69.  
  70. /* -----------------------------------------------------------
  71. Compute the "a" and "b" terms at key "cur", which determine the incoming and outgoing tangents (in quaternion space )
  72.  -----------------------------------------------------------*/
  73. static int CompAB( RotKey *prev, RotKey *cur, RotKey *next )
  74. {
  75.         int i;
  76.         float qprev[4],qnext[4],q[4],qzero[4];
  77.         float qp[4],qm[4],qa[4],qb[4],qae[4],qbe[4];
  78.         float tm,cm,cp,bm,bp,tmcm,tmcp,ksm,ksp,kdm,kdp,c;
  79.         float dt,fp,fn;
  80.  
  81.         if( prev != NULL ) {
  82.                 if( cur->angle > TWOPI-.00001 ) {
  83.                         COPY_POINT3( q, cur->axis );
  84.                         q[3] = 0;
  85.                         qlog( q,qm );
  86.                 } else {
  87.                         qcopy( qprev, prev->quat );
  88.                         if( qdot( qprev, cur->quat ) < 0 ) qnegate( qprev );
  89.                         qlndif( qprev, cur->quat, qm );
  90.                 }
  91.         }
  92.  
  93.         if( next != NULL ) {
  94.                 if( next->angle > TWOPI-.00001 ) {
  95.                         COPY_POINT3( q, next->axis );
  96.                         q[3] = 0;
  97.                         qlog( q, qp );
  98.                 } else {
  99.                         qcopy( qnext, next->quat );
  100.                         if( qdot( qnext, cur->quat ) < 0 ) qnegate( qnext );
  101.                         qlndif( cur->quat, qnext, qp );
  102.                 }
  103.         }
  104.  
  105.         if( prev == NULL ) qcopy( qm, qp );
  106.         if( next == NULL ) qcopy( qp, qm );
  107.  
  108.         fp = fn = 1.0;
  109.         cm = 1.0 - cur->cont;
  110.         if( prev && next ) {
  111.                 dt = 0.5 * (float)(next->frame - prev->frame );
  112.                 fp = ((float)(cur->frame - prev->frame))/dt;
  113.                 fn = ((float)(next->frame - cur->frame))/dt;
  114.                 c = fabs( cur->cont );
  115.                 fp = fp + c - c * fp;
  116.                 fn = fn + c - c * fn;
  117.         }
  118.  
  119.         tm = .5*(1.0 - cur->tens);
  120.         cp = 2.0 - cm;
  121.         bm = 1.0 - cur->bias;
  122.         bp = 2.0 - bm;
  123.         tmcm = tm * cm;
  124.         tmcp = tm * cp;
  125.         ksm  = 1.0 - tmcm * bp * fp;
  126.         ksp  = -tmcp * bm * fp;
  127.         kdm  = tmcp * bp * fn;
  128.         kdp  = tmcm * bm * fn - 1.0;
  129.  
  130.         for( i = 0; i < 4; i++ ) {
  131.                 qa[i] = .5 * ( kdm * qm[i] + kdp * qp[i] );
  132.                 qb[i] = .5 * ( ksm * qm[i] + ksp * qp[i] );
  133.         }
  134.  
  135.         qexp( qa, qae );
  136.         qexp( qb, qbe );
  137.  
  138.         qmul( cur->quat, qae, cur->a );
  139.         qmul( cur->quat, qbe, cur->b );
  140.  
  141.         return TRUE;
  142. }
  143.  
  144. /*
  145. Subject: Re: Question re derivs.c (fwd)
  146. It looks like deriv.c didn't contain the ease function -- just
  147. the geometric derivatives.  In that case, here's the ease function:
  148. */
  149.  
  150. /*  Ease: remap parameter between two keys to apply eases
  151.  
  152. Call this with
  153.    a = easeFrom of key[n],
  154.    b = easeTo of key[n+1], and
  155.  u = (t-t[n]/(t[n+1]-t[n])
  156. -------------------------------------*/
  157.  
  158. local float Ease(float u, float a, float b) {
  159.  float k;
  160.  float s = a+b;
  161.  if (s==0.0) return(u);
  162.  if (s>1.0) {
  163.   a = a/s;
  164.   b = b/s;
  165.   }
  166.  k = 1.0/(2.0-a-b);
  167.  if (u < a) return((k/a)*u*u);
  168.  else if (u<1.0-b) return( k*(2*u - a));
  169.  else {
  170.   u = 1.0-u;
  171.   return(1.0-(k/b)*u*u);
  172.   }
  173.