home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / MacCleo / geoface / muscle.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  5.4 KB  |  214 lines

  1. /* ==========================================================================
  2.                                MUSCLE_C
  3. =============================================================================
  4.  
  5.     FUNCTION NAMES
  6.  
  7.     float VecLen     -- calculates a vector length.
  8.     float CosAng     -- compute the cosine angle between two vectors.
  9.     activate_muscle     -- activate a muscle.
  10.     act_muscles     -- activate muscles.
  11.     reset_muscles     -- reset all the muscles.
  12.  
  13.     C SPECIFICATIONS
  14.  
  15.     float VecLen     ( float *v )
  16.     float CosAng     ( float *v1, float *v2 )
  17.     activate_muscle     ( HEAD *face, float *vt, float *vh, 
  18.                           float fstart, float fin, float ang, float val )
  19.     act_muscles     ( HEAD *face ) 
  20.     reset_muscles     ( HEAD *face ) 
  21.  
  22.     DESCRIPTION
  23.     
  24.     This module is where all the muscle action takes place.  This module 
  25.     comes as is with no warranties.  
  26.  
  27.     SIDE EFFECTS
  28.     Unknown.
  29.    
  30.     HISTORY
  31.     Created 16-Dec-94  Keith Waters at DEC's Cambridge Research Lab.
  32.  
  33. ============================================================================ */
  34.  
  35. #include <math.h>
  36. #include <stdio.h>
  37. #include "head.h"
  38.  
  39. #ifdef _WIN32
  40. #pragma warning (disable:4244)    /* Disable bogus conversion warnings. */
  41. #pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
  42. #endif
  43.  
  44. /* Some <math.h> files do not define M_PI... */
  45. #ifndef M_PI
  46. #define M_PI 3.14159265358979323846
  47. #endif
  48. #define DTOR(deg) ((deg)*0.017453292)    /* degrees to radians   */
  49. #define RTOD(rad) ((rad)*57.29577951)   /* radians to degrees   */
  50. #define RADF 180.0 / M_PI 
  51.  
  52.  
  53. /* ======================================================================== */
  54. /* float VecLen ( vec )                                */
  55. /* ======================================================================== */
  56. /*
  57. ** Caculates the length of the vector.
  58. */
  59.  
  60. float VecLen ( float *v )
  61. {
  62.   return (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  63. }
  64.  
  65. /* ======================================================================== */
  66. /* float CosAng ( v1, v2 )                            */
  67. /* ======================================================================== */
  68. /*
  69. ** Rotates the facial muscles 90.0 degrees.
  70. */
  71.  
  72. float CosAng ( float *v1, float *v2 )
  73. {
  74.   float ang, a,b ;
  75.   
  76.   a = VecLen ( v1 ) ;
  77.   b = VecLen ( v2 ) ;
  78.  
  79.   ang = ((v1[0]*v2[0]) + (v1[1]*v2[1] ) + (v1[2]*v2[2])) / (a*b) ;
  80.  
  81.   return ( ang ) ;
  82. }
  83.  
  84. /* ======================================================================== */
  85. /* activate_muscle ( face, vt, vh, fstart, fin, ang, val )            */
  86. /* ======================================================================== */
  87. /*
  88. ** activate the muscle.
  89. */
  90.  
  91. void
  92. activate_muscle (HEAD *face, float *vt, float *vh, float fstart,  float fin,  float ang,  float val)
  93. {
  94.   float newp[3], va[3], vb[3] ;
  95.   int i,j,k,l ;
  96.   float valen, vblen ;
  97.   float cosa, cosv, dif, tot, percent, thet, newv, the, radf ;
  98.   
  99.   radf  = 180.0/ M_PI ;
  100.   the   = ang / radf ; ;
  101.   thet  = cos ( the ) ;
  102.  
  103.   cosa = 0.0 ;
  104.  
  105.   /* find the length of the muscle */
  106.   for (i=0; i<3; i++)
  107.     va[i] = vt[i] - vh[i] ;
  108.   valen = VecLen ( va ) ;
  109.  
  110.   /* loop for all polygons */
  111.   for (i=0; i<face->npolygons; i++) {
  112.  
  113.     /* loop for all vertices */
  114.     for (j=0; j<3; j++) {
  115.  
  116.       /* find the length of the muscle head to the mesh node */
  117.       for (k=0; k<3; k++)
  118.     vb[k] = face->polygon[i]->vertex[j]->xyz[k] - vh[k] ;
  119.       vblen = VecLen ( vb ) ;
  120.  
  121.       if ( valen > 0.0 && vblen > 0.0) {
  122.     cosa = CosAng ( va, vb ) ;
  123.  
  124.     if ( cosa >= thet ) {
  125.       if ( vblen <= fin ) {
  126.         cosv = val * ( 1.0 - (cosa/thet) ) ;
  127.  
  128.         if ( vblen >= fstart && vblen <= fin) {
  129.           dif       = vblen - fstart ;
  130.           tot       = fin - fstart ;
  131.           percent   = dif/tot ;
  132.           newv      = cos ( DTOR(percent*90.0) ) ;
  133.  
  134.           for ( l=0; l<3; l++)
  135.         newp[l] = (vb[l] * cosv) * newv ;
  136.         }
  137.         else {
  138.           for ( l=0; l<3; l++)
  139.         newp[l] = vb[l] * cosv ;
  140.  
  141.         }   /* endif vblen>fin */
  142.  
  143.         for (l=0; l<3; l++)
  144.           face->polygon[i]->vertex[j]->xyz[l] += newp[l] ;
  145.           
  146.       }  /* endif vblen>fin    */
  147.     }   /* endif cosa>thet    */
  148.       }    /* endif mlen&&tlen   */
  149.     }     /* end for j vertices */
  150.   }      /* end for i polygon  */
  151. }
  152.  
  153. /* ======================================================================== */
  154. /* act_muscles ( face )                             */
  155. /* ======================================================================== */
  156. /*
  157. ** activate the muscles
  158. */
  159.  
  160. void
  161. act_muscles ( HEAD *face ) 
  162. {
  163.   int i ;
  164.  
  165.   /* 
  166.    * Loop all the muscles.             
  167.    */ 
  168.   for (i=0; i<face->nmuscles; i++) {
  169.  
  170.     /*
  171.      * Check to see if the muscle is active.                        
  172.     */
  173.     if (face->muscle[i]->active) {
  174.  
  175.       activate_muscle ( face, face->muscle[i]->head,
  176.                       face->muscle[i]->tail,
  177.                       face->muscle[i]->fs,
  178.                       face->muscle[i]->fe,
  179.                       face->muscle[i]->zone,
  180.                        face->muscle[i]->mval ) ;
  181.  
  182.       /* 
  183.       * Reset the muscle activity.     
  184.       */
  185.       face->muscle[i]->active = 1 ;
  186.  
  187.     }
  188.   } 
  189. }
  190.  
  191. /* ======================================================================== */
  192. /* reset_muscles ( face )                             */
  193. /* ======================================================================== */
  194. /*
  195. ** Resets the muscles of the face.  This is achieved by reversing 
  196. ** the muscle contraction.
  197. */
  198.  
  199. void
  200. reset_muscles ( HEAD *face ) 
  201. {
  202.   int i,j,k ;
  203.  
  204.   for ( i=0; i<face->npolygons; i++ ) {
  205.     for ( j=0; j<3; j++ ) {
  206.  
  207.       for ( k=0; k<3; k++ )
  208.     face->polygon[i]->vertex[j]->xyz[k] = 
  209.       face->polygon[i]->vertex[j]->nxyz[k] ;
  210.  
  211.     } /* end for j */
  212.   } /* end for i */
  213.