fall.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.05 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000  - 2011 OpenFX Development Team
00004 
00005 -- */
00006 
00007 /* FALL.C external animation effect  (Windows NT version)                  */
00008 
00009 #include <math.h>
00010 #include <windows.h>
00011 #include <commctrl.h>
00012 
00013 #include "fall.h"
00014 
00015 #ifndef max
00016 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00017 #endif
00018 
00019 #ifndef PI
00020 #define PI 3.1415926
00021 #endif
00022 
00023 #if __X__MIPS__
00024 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00025 #endif
00026 
00027 static HINSTANCE hDLLinstance=NULL;
00028 
00029 #include "pstruct.h"
00030 
00031 #include "paint.c"
00032 
00033 #if __WATCOMC__
00034 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00035 #else
00036 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00037 #endif
00038   switch (dwReason) {
00039     case DLL_PROCESS_ATTACH:
00040 #if __X__MIPS__
00041       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00042 #endif
00043       hDLLinstance = hDLL;  /* handle to DLL file */
00044       break;
00045     case DLL_PROCESS_DETACH:
00046 #if __X__MIPS__
00047       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00048 #endif
00049       break;
00050   }
00051 return (int)TRUE;
00052 }
00053 
00054 static double CalculatePosition(long n, double zm, double z0,
00055                                 double t,
00056                                 double mu, double a, double d){
00057  int i;
00058  double dfall,ta,dt,h,deltaT;
00059  dfall=z0-(zm-d);   /* must be > 0 */
00060  ta=sqrt(2.0*dfall/a);
00061  if(t < ta)return (z0-a*t*t*0.5);
00062  dt=mu*ta; h=dfall;
00063  if(n > 0)for(i=0;i<3*n;i++){
00064    h=mu*mu*h;
00065    if(t < ta+dt){
00066      deltaT = dt - (t - ta);
00067      return (z0-(dfall-h+a*deltaT*deltaT*0.5));
00068    }
00069    ta += dt;
00070    if(t < ta+dt){
00071      deltaT = (t - ta);
00072      return (z0-(dfall-h+a*deltaT*deltaT*0.5));
00073    }
00074    ta += dt;
00075    dt *= mu;
00076  }
00077  return (z0-dfall);
00078 }
00079 
00080 static void  GetTandA(int nb, double mu, double d, double *t, double *a){
00081  int i;
00082  double t0;
00083  if(nb > 0){
00084    t0=mu;
00085    for(i=0;i<nb-1;i++)t0 = mu*(t0 + 1.0);
00086    t0 *= 2.0;
00087    t0 += 1.0;
00088  }
00089  else t0=1.0;
00090  t0  = 1.0/t0;
00091  *a=2.0*d/(t0*t0);
00092  *t=t0;
00093  return;
00094 }
00095 
00096 long _RenderGlobalEffect
00097 (char *PrmList, sfxinfo *SFXinfo,sfxdata *SFXdata, vertex *Vlist){
00098  long i,nb,v,local,gnd;
00099  double z,zmax=-1.e20,zmin=1.e20,mu,d,t,t0,a;  /* mu is elasticity */
00100  char buffer[128];
00101 #include "pro_key.c"
00102  sscanf(PrmList,"%s %ld %ld %ld %ld %f %f",buffer,&nb,&v,&local,&gnd,&mu,&d);
00103  if(local == 1)return 1;
00104  t=(double)SFXinfo->time;
00105  for(i=0;i<SFXinfo->nvert;i++){
00106    if(Vlist[i].p[2] > zmax)zmax=Vlist[i].p[2];
00107    if(Vlist[i].p[2] < zmin)zmin=Vlist[i].p[2];
00108  }
00109  if(SFXdata->ground && gnd == 1){
00110    if(v == 1 || v == 3)d=zmin-(double)SFXdata->ground_pos[2];
00111    else                d=zmax-(double)SFXdata->ground_pos[2]-10.0;
00112  }
00113  GetTandA(nb,mu,d,&t0,&a);
00114  if(v > 1){ /* final */
00115   v -= 2;
00116   t=1.0;
00117  }
00118  if(v == 1){
00119    z=(double)CalculatePosition(nb,zmax,zmax,t,mu,a,d);
00120    z=zmax-z;
00121    for(i=0;i<SFXinfo->nvert;i++)Vlist[i].p[2] -= z;
00122  }
00123  else{
00124    for(i=0;i<SFXinfo->nvert;i++){
00125      Vlist[i].p[2]=(double)CalculatePosition(nb,zmax,(double)Vlist[i].p[2],
00126                                          t,mu,a,d);
00127    }
00128  }
00129  return 1;
00130 }
00131 
00132 long _RenderExternalEffect
00133 (char *PrmList, sfxinfo *SFXinfo,vertex *Vlist){
00134  long i,nb,v,local,gnd;
00135  double z,zmax=-1.e20,mu,d,t,t0,a;  /* mu is elasticity */
00136  char buffer[128];
00137 #include "pro_key.c"
00138  sscanf(PrmList,"%s %ld %ld %ld %ld %f %f",buffer,&nb,&v,&local,&gnd,&mu,&d);
00139  if(local == 0)return 1;
00140  t=(double)SFXinfo->time;
00141  GetTandA(nb,mu,d,&t0,&a);
00142  for(i=0;i<SFXinfo->nvert;i++)if(Vlist[i].p[2] > zmax)zmax=Vlist[i].p[2];
00143  if(v > 1){ /* final */
00144   v -= 2;
00145   t=1.0;
00146  }
00147  if(v == 1){
00148    z=(double)CalculatePosition(nb,zmax,zmax,t,mu,a,d);
00149    z=zmax-z;
00150    for(i=0;i<SFXinfo->nvert;i++)Vlist[i].p[2] -= z;
00151  }
00152  else{
00153    for(i=0;i<SFXinfo->nvert;i++){
00154      Vlist[i].p[2]=(double)CalculatePosition(nb,zmax,(double)Vlist[i].p[2],
00155                                          t,mu,a,d);
00156    }
00157  }
00158  return 1;
00159 }
00160 
00161 void _PreviewGlobalEffect
00162 (char *PrmList, sfxinfo *SFXinfo,sfxdata *SFXdata, Svertex *Vlist){
00163  long i,nb,v,local,gnd;
00164  double z,zmax=-1.e20,zmin=1.e20,mu,d,t,t0,a;  /* mu is elasticity */
00165  char buffer[128];
00166 #include "pro_key1.c"
00167  sscanf(PrmList,"%s %ld %ld %ld %ld %f %f",buffer,&nb,&v,&local,&gnd,&mu,&d);
00168  if(local == 1)return;
00169  t=(double)SFXinfo->time;
00170  for(i=0;i<SFXinfo->nvert;i++){
00171    if(Vlist[i][2] > zmax)zmax=Vlist[i][2];
00172    if(Vlist[i][2] < zmin)zmin=Vlist[i][2];
00173  }
00174  if(SFXdata->ground && gnd == 1){
00175    if(v == 1 || v == 3)d=zmin-(double)SFXdata->ground_pos[2];
00176    else                d=zmax-(double)SFXdata->ground_pos[2]-10.0;
00177  }
00178  GetTandA(nb,mu,d,&t0,&a);
00179  if(v > 1){ /* final */
00180   v -= 2;
00181   t=1.0;
00182  }
00183  if(v == 1){
00184    z=(double)CalculatePosition(nb,zmax,zmax,t,mu,a,d);
00185    z=zmax-z;
00186    for(i=0;i<SFXinfo->nvert;i++)Vlist[i][2] -= z;
00187  }
00188  else{
00189    for(i=0;i<SFXinfo->nvert;i++){
00190      Vlist[i][2]=(double)CalculatePosition(nb,zmax,(double)Vlist[i][2],
00191                                          t,mu,a,d);
00192    }
00193  }
00194  return;
00195 }
00196 
00197 void _PreviewExternalEffect
00198 (char *PrmList, sfxinfo *SFXinfo,Svertex *Vlist){
00199  long i,nb,v,local,gnd;
00200  double z,zmax=-1.e20,mu,d,t,t0,a;  /* mu is elasticity */
00201  char buffer[128];
00202 #include "pro_key1.c"
00203  sscanf(PrmList,"%s %ld %ld %ld %ld %f %f",buffer,&nb,&v,&local,&gnd,&mu,&d);
00204  if(local == 0)return;
00205  t=(double)SFXinfo->time;
00206  GetTandA(nb,mu,d,&t0,&a);
00207  for(i=0;i<SFXinfo->nvert;i++)if(Vlist[i][2] > zmax)zmax=Vlist[i][2];
00208  if(v > 1){ /* final */
00209   v -= 2;
00210   t=1.0;
00211  }
00212  if(v == 1){
00213    z=(double)CalculatePosition(nb,zmax,zmax,t,mu,a,d);
00214    z=zmax-z;
00215    for(i=0;i<SFXinfo->nvert;i++)Vlist[i][2] -= z;
00216  }
00217  else{
00218    for(i=0;i<SFXinfo->nvert;i++){
00219      Vlist[i][2]=(double)CalculatePosition(nb,zmax,(double)Vlist[i][2],
00220                                          t,mu,a,d);
00221    }
00222  }
00223  return;
00224 }
00225 
00226 BOOL CALLBACK EffectDlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00227 
00228 static long nbounce=2,vvv=0;
00229 static double elasticity=0.4,distance=1.0;
00230 static long local=0,gnd=1;
00231 
00232 char * _SetExternalParameters
00233  (char *Op,                 /* string for the parameters                  */
00234   HWND hWnd,                /* parent window                              */
00235   long ruler,               /* ruler scale value to facilitate scaling    */
00236   char *name,               /* name of DLL file with the effect           */
00237   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00238                                     ){
00239  char buffer[128];
00240  double d1;
00241  if(Op != NULL){  /* parameters exist so read them off the list */
00242    sscanf(Op,"%s %ld %ld %ld %ld %f %f",buffer,&nbounce,&vvv,&local,&gnd,&elasticity,&d1);
00243    distance=d1/(double)ruler;
00244  }
00245  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_EFFECT),hWnd,
00246               (DLGPROC)EffectDlgProc) == FALSE)return Op;
00247    if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00248  d1=distance*(double)ruler;
00249  sprintf(buffer,"%s %ld %ld %ld %ld %f %f",name,nbounce,vvv,local,gnd,elasticity,d1);
00250  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00251    MessageBox(GetFocus(),"Memory",NULL,MB_OK|MB_ICONSTOP);
00252    return NULL;
00253  }
00254  strcpy(Op,buffer);
00255  return Op;
00256 }
00257 
00258 BOOL CALLBACK EffectDlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00259  char str[32];
00260  int err;
00261  switch( msg ) {
00262    case WM_INITDIALOG:
00263      if(vvv >  1){
00264        SendDlgItemMessage(hwnd,DLG_EFFECT_FFF,BM_SETCHECK,TRUE,0);
00265        vvv -= 2;
00266      }
00267      if(vvv == 0)
00268        SendDlgItemMessage(hwnd,DLG_EFFECT_FALL,BM_SETCHECK,TRUE,0);
00269      else
00270        SendDlgItemMessage(hwnd,DLG_EFFECT_DROP,BM_SETCHECK,TRUE,0);
00271      if(local == 1)
00272        SendDlgItemMessage(hwnd,DLG_EFFECT_LOCAL,BM_SETCHECK,TRUE,0);
00273      else
00274        SendDlgItemMessage(hwnd,DLG_EFFECT_GLOBAL,BM_SETCHECK,TRUE,0);
00275      if(gnd == 1)
00276        SendDlgItemMessage(hwnd,DLG_EFFECT_GROUND,BM_SETCHECK,TRUE,0);
00277      SetDlgItemInt(hwnd,DLG_EFFECT_BOUNCE,nbounce,FALSE);
00278      sprintf(str,"%.2f",elasticity);
00279      SetDlgItemText(hwnd,DLG_EFFECT_ELASTICITY,str);
00280      sprintf(str,"%.2f",distance);
00281      SetDlgItemText(hwnd,DLG_EFFECT_DISTANCE,str);
00282      LoadAnimatedClip(hwnd);
00283      CentreDialogOnScreen(hwnd);
00284      return TRUE;
00285    case WM_PAINT:
00286      PaintBackground(hwnd);
00287      break;
00288    case WM_SYSCOMMAND:
00289      switch(LOWORD(wparam & 0xfff0)){
00290        case SC_CLOSE:
00291          EndDialog(hwnd,FALSE);
00292          return(TRUE);
00293        default:
00294          break;
00295      }
00296      break;
00297    case WM_COMMAND:
00298      switch(LOWORD(wparam)){
00299         case IDCANCEL:
00300           EndDialog(hwnd,FALSE);
00301           return(TRUE);
00302         case IDOK:
00303           if(SendDlgItemMessage(hwnd,DLG_EFFECT_DROP,BM_GETCHECK,0,0))
00304                vvv=1;
00305           else vvv=0;
00306           if(SendDlgItemMessage(hwnd,DLG_EFFECT_FFF,BM_GETCHECK,0,0))
00307                vvv += 2;
00308           if(SendDlgItemMessage(hwnd,DLG_EFFECT_LOCAL,BM_GETCHECK,0,0))
00309                local=1;
00310           else local=0;
00311           if(SendDlgItemMessage(hwnd,DLG_EFFECT_GROUND,BM_GETCHECK,0,0))
00312                gnd=1;
00313           else gnd=0;
00314           if(GetDlgItemText(hwnd,DLG_EFFECT_ELASTICITY,str,12) != 0)
00315             elasticity=atof(str);
00316           if(GetDlgItemText(hwnd,DLG_EFFECT_DISTANCE,str,12) != 0)
00317             distance=atof(str);
00318           nbounce=(int)GetDlgItemInt(hwnd,DLG_EFFECT_BOUNCE,&err,TRUE);
00319           EndDialog(hwnd,TRUE);
00320           return(TRUE);
00321         default:
00322           break;
00323       }
00324       break;
00325     default: break;
00326  }
00327  return FALSE;
00328 }
00329 
Generated on Tue Jan 28 06:18:29 2014 for OpenFX by  doxygen 1.6.3