twist.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 -- */
00005 
00006 /* TWIST.C external animation effect  (Windows NT version)                 */
00007 /*                                                                         */
00008 /* This effect twists the model about an axis in either the up/down  left/ */
00009 /* right or up/down directions. The angle of the twist is specifed by the  */
00010 /* user. The twist at the most negative co-ordinate of the model in the    */
00011 /* axis direction is zero and reaches its maximum at the most positive     */
00012 /* co-ordinate of the axis direction. The twist is zero at the first frame */
00013 /* of the channel(time-line) and maximum in the last. Using a +ve twist    */
00014 /* for one channel eg. frames 1-10 and a -ve  twist for a subsequent       */
00015 /* channel eg. frames 11-20 will give the impression of the model twisting */
00016 /* round and back.                                                         */
00017 /*                                                                         */
00018 
00019 #include <math.h>
00020 #include <windows.h>
00021 #include <commctrl.h>
00022 
00023 #include "twist.h"
00024 
00025 #if __ZTC__ || __SC__
00026 #ifndef max
00027 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00028 #endif
00029 #endif
00030 
00031 #ifndef PI
00032 #define PI 3.1415926
00033 #endif
00034 
00035 #if __X__MIPS__
00036 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00037 #endif
00038 
00039 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL   */
00040 
00041 
00042 /**************  Structures that may be addressed externally ********/
00043 
00044 #include "pstruct.h"
00045 
00046 /************************** Local Utility Functions ***********************/
00047 
00048 #include "paint.c"
00049 
00050 #if __WATCOMC__
00051 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00052 #else
00053 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00054 #endif
00055   switch (dwReason) {
00056     case DLL_PROCESS_ATTACH:
00057 #if __X__MIPS__
00058       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00059 #endif
00060       hDLLinstance = hDLL;  /* handle to DLL file */
00061       break;
00062     case DLL_PROCESS_DETACH:
00063 #if __X__MIPS__
00064       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00065 #endif
00066       break;
00067   }
00068 return (int)TRUE;
00069 }
00070 
00071 #if __SC__
00072 #pragma startaddress(LibMain)
00073 #endif
00074 
00075 /*******************************************************************\
00076 |                Code that define the effects                       |
00077 \*******************************************************************/
00078 
00079 
00080 long _RenderGlobalEffect
00081 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, vertex *Vlist){
00082  return 1;
00083 }
00084 
00085 void _PreviewGlobalEffect
00086 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, Svertex *Vlist){
00087  return;
00088 }
00089 
00090 long _RenderExternalEffect(char *PrmList, sfxinfo *SFXinfo,
00091                                  vertex *Vlist){
00092  double h,d,t,x,y;
00093  long i;
00094  int val;
00095  double PRMangle=60, angle, ang;
00096  char buffer[128];
00097  int PRMaxis, axis, paxis, paxis2, type;
00098  sscanf(PrmList,"%s %d %d %d",buffer,&PRMaxis,&type,&val);
00099  PRMangle=(double)val;  /* extract the maximum twist angle       */
00100  t=SFXinfo->time;       /* extract the percentage of the effect  */
00101  if     (PRMaxis == 3) axis=1;    /* F / B */
00102  else if(PRMaxis == 1) axis=2;    /* U / D */
00103  else if(PRMaxis == 2) axis=0;    /* L / R */
00104  if     (axis == 0){ paxis = 1; paxis2 = 2; }
00105  else if(axis == 2){ paxis = 1; paxis2 = 0; }
00106  else if(axis == 1){ paxis = 0; paxis2 = 2; }
00107  /* The axis of twist is known paxis and paxis2 are the axes perpendicular */
00108  /* to the axis about which the twist is occuring                          */
00109  if(type == 2) t = 1.00 - t;    /* Is it Un-Twist, Untwist starts with max */
00110                                 /* twist at first frame of channed         */
00111  t = -1.00 * (t*t) + 2.00 * t;  /* Non-linear twist, apparent acceleration */
00112  angle=(PRMangle * PI/180) * t; /* maximum angle of twist at this frame    */
00113  for(i=0L; i < SFXinfo->nvert; i++){ /* for all vertices in model          */
00114   /* For each vertex get its distance from the minimum co-ordinate of the  */
00115   /* twist axis. Scale twist angle so that it is zero at the base.         */
00116   h=(double)(Vlist[i].p[axis] - SFXinfo->vmin[axis]) /
00117     (double)(SFXinfo->vmax[axis] - SFXinfo->vmin[axis]);
00118   ang=angle * h;
00119   /* Apply the twist to the co-ord axes perpendicular to twist axis        */
00120   x=Vlist[i].p[paxis]; y=Vlist[i].p[paxis2];
00121   Vlist[i].p[paxis]=(double)x*(double)cos(ang)-(double)y*(double)sin(ang);
00122   Vlist[i].p[paxis2]=(double)y*(double)cos(ang)+(double)x*(double)sin(ang);
00123  }
00124  return 1;
00125 }
00126 
00127 /********* Functions used to preview external effect                    ****/
00128 /********* Return immediatly if no preview possible else do best approx ****/
00129 /********* Note different data structures from Renderers requirement    ****/
00130 
00131 void _PreviewExternalEffect(char *PrmList, sfxinfo *SFXinfo,
00132                                     Svertex *Vlist){
00133  /* For this effect the preview is a duplicate copy  of the effect itself. */
00134  /* The only difference is in the addressing of the Vertices.              */
00135  double h,d,t,x,y;
00136  long i;
00137  int val;
00138  double PRMangle=60, angle, ang;
00139  char buffer[128];
00140  int PRMaxis, axis, paxis, paxis2, type;
00141  sscanf(PrmList,"%s %d %d %d",buffer,&PRMaxis,&type,&val);
00142  PRMangle=(double)val;
00143  t=SFXinfo->time;
00144  if(PRMaxis == 3) axis=1;         /* F / B */
00145  else if(PRMaxis == 1) axis=2;    /* U / D */
00146  else if(PRMaxis == 2) axis=0;    /* L / R */
00147  if(axis == 0){      paxis = 1; paxis2 = 2; }
00148  else if(axis == 2){ paxis = 1; paxis2 = 0; }
00149  else if(axis == 1){ paxis = 0; paxis2 = 2; }
00150  if(type == 2) t = 1.00 - t;
00151  t = -1.00 * (t*t) + 2.00 * t;
00152  angle=(PRMangle * PI/180) * t;
00153  for(i=0L; i < SFXinfo->nvert; i++){
00154   h=(double)(Vlist[i][axis] - SFXinfo->vmin[axis]) /
00155     (double)(SFXinfo->vmax[axis] - SFXinfo->vmin[axis]);
00156   ang=angle * h;
00157   x=Vlist[i][paxis]; y=Vlist[i][paxis2];
00158   Vlist[i][paxis]=(double)x*(double)cos(ang)-(double)y*(double)sin(ang);
00159   Vlist[i][paxis2]=(double)y*(double)cos(ang)+(double)x*(double)sin(ang);
00160  }
00161  return;
00162 }
00163 
00164 /*************** Functions used to set up effect ***************/
00165 
00166 /* Dialog box callback  */
00167 BOOL CALLBACK TwistDlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00168 
00169 
00170 /* Set defaults for the parameter variables, declare them as static so that
00171    they are available to the dialog function. They are here only for the
00172    function that edits the parameter list and must not be used in the
00173    code that is called from the renderer to execute the effect            */
00174 
00175 static long type=1,PRMaxis=1,PRMangle=60;
00176 
00177 
00178 /************ Functions called by the animator to set up effect *************/
00179 
00180 char * _SetExternalParameters(
00181   char *Op,                 /* string for the parameters                  */
00182   HWND hWnd,                /* parent window                              */
00183   long ruler,               /* ruler scale value to facilitate scaling    */
00184   char *name,               /* name of DLL file with the effect           */
00185   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00186                                     ){
00187 /* output name and buffer should be as long as necessary to hold full string */
00188  char buffer[128];
00189  if(Op != NULL){  /* parameters exist so read them off the list */
00190    sscanf(Op,"%s %ld %ld %ld",buffer,&PRMaxis,&type,&PRMangle);
00191  }
00192 /*   Do the user interface as required to set up the effect, may use a     */
00193 /*   dialog box etc. Return old string if effect is cancelled (no change)  */
00194 
00195  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_TWIST),hWnd,
00196               (DLGPROC)TwistDlgProc) == FALSE)return Op;
00197 
00198 /* Free space occupied by old parameter string */
00199    if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00200 /* print the parameters into the buffer */
00201  sprintf(buffer,"%s %ld %ld %ld",name,PRMaxis,type,PRMangle);
00202 /* Prepare the output buffer to take copy of parameter list */
00203  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00204   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00205                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00206    return NULL;
00207  }
00208  /* Copy the parameter string to the output buffer */
00209  strcpy(Op,buffer);
00210 //MessageBox(NULL,Op,"Output",MB_OK);
00211  return Op;
00212 }
00213 
00214 BOOL CALLBACK TwistDlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00215  int n,err,axisID[3]={DLG_TWIST_UD,DLG_TWIST_LR,DLG_TWIST_FB};
00216  char str[16];
00217  switch( msg ) {
00218    case WM_INITDIALOG:
00219      if(type == 2)SendDlgItemMessage(hwnd,DLG_TWIST_UNTWIST,BM_SETCHECK,1,0);
00220      else         SendDlgItemMessage(hwnd,DLG_TWIST_TWIST,BM_SETCHECK,1,0);
00221      SendDlgItemMessage(hwnd,axisID[PRMaxis-1],BM_SETCHECK,1,0);
00222      SetDlgItemInt(hwnd,DLG_TWIST_ANGLE,PRMangle,TRUE);
00223      LoadAnimatedClip(hwnd);
00224      CentreDialogOnScreen(hwnd);
00225      return TRUE;
00226    case WM_PAINT:
00227      PaintBackground(hwnd);
00228      break;
00229    case WM_SYSCOMMAND:
00230      switch(LOWORD(wparam & 0xfff0)){
00231        case SC_CLOSE:
00232          EndDialog(hwnd,FALSE);
00233          return(TRUE);
00234        default:
00235          break;
00236      }
00237      break;
00238    case WM_COMMAND:
00239      switch(LOWORD(wparam)){
00240         case DLG_TWIST_TWIST:           type=1;          break;
00241         case DLG_TWIST_UNTWIST:         type=2;          break;
00242         case DLG_TWIST_UD:              PRMaxis=1;       break;
00243         case DLG_TWIST_LR:              PRMaxis=2;       break;
00244         case DLG_TWIST_FB:              PRMaxis=3;       break;
00245         case DLG_TWIST_CANCEL:
00246           EndDialog(hwnd,FALSE);
00247           return(TRUE);
00248         case DLG_TWIST_OK:
00249           n=(int)GetDlgItemInt(hwnd,DLG_TWIST_ANGLE,&err,TRUE);
00250           if(!err){
00251             MessageBox (GetFocus(),"External effect: Error in angle setting",
00252                "Error",MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00253             break;
00254           }
00255           else PRMangle=n;
00256           EndDialog(hwnd,TRUE);
00257           return(TRUE);
00258         default:
00259           break;
00260       }
00261       break;
00262     default: break;
00263  }
00264  return FALSE;
00265 }
00266 

Generated on Sun Apr 27 14:20:12 2014 for OpenFX by  doxygen 1.5.6