water.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 /* water.c */
00007 
00008 #include <math.h>
00009 #include <windows.h>
00010 #include <commctrl.h>
00011 
00012 #include "water.h"
00013 
00014 #define UNIT 32767
00015 
00016 #ifndef PI
00017 #define PI 3.1415926
00018 #endif
00019 
00020 static HINSTANCE hDLLinstance=NULL;
00021 
00022 #include "pstruct.h"
00023 
00024 #include "paint.c"
00025 
00026 #if __WATCOMC__
00027 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00028 #else
00029 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00030 #endif
00031  switch (dwReason) {
00032    case DLL_PROCESS_ATTACH:
00033      hDLLinstance = hDLL;  /* handle to DLL file */
00034      break;
00035    case DLL_PROCESS_DETACH:
00036      break;
00037  }
00038  return (int)TRUE;
00039 }
00040 
00041 static void norm(vector v){
00042  float l;
00043  l=1.0/sqrt(v[0]*v[0]+v[1]*v[1]);
00044  v[0]=v[0]*l; v[1]=v[1]*l;
00045 }
00046 
00047 #define NVECTORS 25
00048 
00049 static vector d[NVECTORS];
00050 
00051 static void setup_water(long n){
00052  long i;
00053  float dir;
00054  d[0][0] =  0.0000; d[0][1] =  1.0000; // straight
00055  srand(n);
00056  //d[1][0] =  0.1050; d[1][1] =  0.9490;
00057  //d[2][0] = -0.0552; d[2][1] =  1.0497;
00058  //d[3][0] =  0.5773; d[3][1] =  1.1547; // 60
00059  //d[4][0] = -0.5873; d[4][1] =  1.0547; // -60
00060  if(n > 1)for (i=0;i<n;i++){
00061    //d[i][0]=0.1+(float)rand(); d[i][1]=(float)rand();  
00062    //norm(d[i]);
00063    dir=6.283185*(float)(rand())/((float)RAND_MAX);
00064    d[i][0]=cos(dir); d[i][1]=sin(dir);
00065  } 
00066  return;
00067 }
00068 
00069 
00070 long _RenderGlobalEffect
00071 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, vertex *Vlist){
00072  return 1;
00073 }
00074 
00075 void _PreviewGlobalEffect
00076 (char *PrmList, sfxinfo *SFXinfo, sfxdata *SFXdata, Svertex *Vlist){
00077  return;
00078 }
00079 
00080 long _RenderExternalEffect(char *parameters, sfxinfo *SFXinfo,
00081                                  vertex *v){
00082  char buffer[256];
00083  long i,j;
00084  long ndirections, // number of directional waves
00085       n;           // number of wave cycles
00086  float speed,phi,lambda,A[NVECTORS],Q,theta,arg,height,scale;
00087  lambda=0.0;
00088  for(i=0;i<3;i++){
00089    lambda = max(lambda,SFXinfo->vmax[i]-SFXinfo->vmin[i]);
00090  }
00091  //MessageBox(NULL,parameters,NULL,MB_OK);
00092  sscanf(parameters,"%s %ld %ld %f %f %f",buffer,&n,&ndirections,&height,&speed,&Q);
00093  ndirections=min(NVECTORS,ndirections);
00094  phi=speed*2*PI;
00095  scale=1.0/(double)ndirections;
00096  setup_water(ndirections);
00097  //{char xxx[255]; sprintf(xxx,"%ld %lf",ndirections,scale); MessageBox(NULL,xxx,NULL,MB_OK);}
00098  for(i=0;i<ndirections;i++)A[i]=height*lambda*scale;
00099  for(i=0;i<SFXinfo->nvert;i++){
00100    v[i].p[2]=0.0;
00101    for(j=0;j<ndirections;j++){
00102      theta=(float)n*2.0*PI/lambda*(d[j][0]*v[i].p[0]+d[j][1]*v[i].p[1]);
00103      arg=theta-phi*SFXinfo->time;
00104      v[i].p[2] += A[j]*(1.0 - cos(arg));
00105      v[i].p[0] += Q*(lambda/2.0/PI/(float)n)*d[j][0]*sin(arg)*scale;
00106      v[i].p[1] += Q*(lambda/2.0/PI/(float)n)*d[j][1]*sin(arg)*scale;
00107    }
00108  }
00109  return 1;
00110 }
00111 
00112 void _PreviewExternalEffect(char *parameters, sfxinfo *SFXinfo,
00113                                     Svertex *v){
00114  char buffer[256];
00115  long i,j;
00116  long ndirections, // number of directional waves
00117       n;           // number of wave cycles
00118  float speed,phi,lambda,A[NVECTORS],Q,theta,arg,height,scale;
00119  lambda=0.0;
00120  for(i=0;i<3;i++){
00121    lambda = max(lambda,SFXinfo->vmax[i]-SFXinfo->vmin[i]);
00122  }
00123  sscanf(parameters,"%s %ld %ld %f %f %f",buffer,&n,&ndirections,&height,&speed,&Q);
00124  ndirections=min(NVECTORS,ndirections);
00125  phi=speed*2*PI;
00126  scale=1.0/(double)ndirections;
00127  setup_water(ndirections);
00128  for(i=0;i<ndirections;i++)A[i]=height*lambda*scale;
00129  for(i=0;i<SFXinfo->nvert;i++){
00130    v[i][2]=0.0;
00131    for(j=0;j<ndirections;j++){
00132      theta=(float)n*2.0*PI/lambda*(d[j][0]*v[i][0]+d[j][1]*v[i][1]);
00133      arg=theta-phi*SFXinfo->time;
00134      v[i][2] += A[j]*(1.0 - cos(arg));
00135      v[i][0] += Q*(lambda/2.0/PI/(float)n)*d[j][0]*sin(arg)*scale;
00136      v[i][1] += Q*(lambda/2.0/PI/(float)n)*d[j][1]*sin(arg)*scale;
00137    }
00138  }
00139  return;
00140 }
00141 
00142 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00143 
00144 static int   dlg_n=5,dlg_nwaves=1;
00145 static float dlg_A=0.05,dlg_speed=1.0,dlg_Q=0.8;
00146 
00147 char * _SetExternalParameters(
00148   char *Op,                 /* string for the parameters                  */
00149   HWND hWnd,                /* parent window                              */
00150   long ruler,               /* ruler scale value to facilitate scaling    */
00151   char *name,               /* name of DLL file with the effect           */
00152   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00153   ){
00154  char buffer[256];
00155  if(Op != NULL){  /* parameters exist so read them off the list          */
00156                   /* the name of the DLL file is always the first string */
00157    sscanf(Op,"%s %ld %ld %f %f %f",buffer,&dlg_n,&dlg_nwaves,&dlg_A,&dlg_speed,&dlg_Q);
00158  }
00159  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_WATER),hWnd,
00160               (DLGPROC)DlgProc) == FALSE)return Op;
00161  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00162  sprintf(buffer,"%s %ld %ld %f %f %f",name,dlg_n,dlg_nwaves,dlg_A,dlg_speed,dlg_Q);
00163  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00164   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00165                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00166    return NULL;
00167  }
00168  strcpy(Op,buffer);
00169  //MessageBox(NULL,Op,"End",MB_OK);
00170  return Op;
00171 }
00172 
00173 BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wparam,LPARAM lparam){
00174  char str[16];
00175  float f;
00176  switch( msg ) {
00177    case WM_INITDIALOG:
00178      LoadAnimatedClip(hDlg);
00179      CentreDialogOnScreen(hDlg);
00180      SetDlgItemInt(hDlg,DLG_N,dlg_n,FALSE);
00181      SetDlgItemInt(hDlg,DLG_NWAVES,dlg_nwaves,FALSE);
00182      sprintf(str,"%.0f",dlg_A*2000); SetDlgItemText(hDlg,DLG_A,str);
00183      sprintf(str,"%.0f",dlg_Q*100);  SetDlgItemText(hDlg,DLG_Q,str);
00184      sprintf(str,"%.2f",dlg_speed);  SetDlgItemText(hDlg,DLG_SPEED,str);
00185      return TRUE;
00186    case WM_PAINT:
00187      PaintBackground(hDlg);
00188      break;
00189    case WM_SYSCOMMAND:
00190      switch(LOWORD(wparam & 0xfff0)){
00191        case SC_CLOSE:
00192          EndDialog(hDlg,FALSE);
00193          return(TRUE);
00194        default:
00195          break;
00196      }
00197      break;
00198    case WM_COMMAND:
00199      switch(LOWORD(wparam)){
00200         case IDOK:
00201           if(GetDlgItemText(hDlg,DLG_N,str,12) != 0)sscanf(str,"%ld",&dlg_n);
00202           if(dlg_n < 1)dlg_n=1;
00203           if(GetDlgItemText(hDlg,DLG_NWAVES,str,12) != 0)sscanf(str,"%ld",&dlg_nwaves);
00204           if(dlg_nwaves < 1)dlg_nwaves=1;
00205           if(dlg_nwaves > NVECTORS)dlg_nwaves=NVECTORS;
00206           if(GetDlgItemText(hDlg,DLG_A,str,12) != 0){
00207             sscanf(str,"%f",&f);
00208             dlg_A = f/2000.0;
00209           }
00210           if(GetDlgItemText(hDlg,DLG_Q,str,12) != 0){
00211             sscanf(str,"%f",&f);
00212             dlg_Q = f/100.0;
00213           }
00214           if(GetDlgItemText(hDlg,DLG_SPEED,str,12) != 0){
00215             sscanf(str,"%f",&f);
00216             dlg_speed = f;
00217           }
00218           EndDialog(hDlg,TRUE);
00219           return(TRUE);
00220         case IDCANCEL:
00221           EndDialog(hDlg,FALSE);
00222           return(TRUE);
00223         default:
00224           break;
00225       }
00226       break;
00227     default: break;
00228  }
00229  return FALSE;
00230 }
Generated on Tue Jan 28 06:18:30 2014 for OpenFX by  doxygen 1.6.3