carved.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 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 // carved.c
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <float.h>
00030 #include <windows.h>
00031 #include <gl/gl.h>
00032 
00033 #if __ZTC__ || __SC__
00034 #ifndef max
00035 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00036 #endif
00037 #endif
00038 
00039 #if __WATCOMC__
00040 #define PI 3.1415926
00041 #endif
00042 
00043 #if __X__MIPS__
00044 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00045 #endif
00046 
00047 static HINSTANCE hDLLinstance=NULL;
00048 
00049 #include "..\animate\memory.h" /* for memory definition */
00050 #include "..\animate\memdef.h" /* local names           */
00051 #include "defines.h"
00052 #include "rstruct.h"
00053 #include "carved.h"
00054 
00055 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00056 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00057 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00058 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00059 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00060 
00061 #define IMOD(z,a) ((z) - ((z)/(a))*(a))
00062 #define PATTERN(x,y,z)   ( ((z)+16384L)*64536L +  \
00063                            ((y)+16384L)*32768L +  \
00064                            ((x)+16384L))
00065 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00066 #define FMOD(x,a) ((x) >= 0.0 ? fmod(x,a) :(a - fmod(-(x),a)))
00067 
00068 #include "randno.c"
00069 
00070 static long ip[27][3]={
00071    { 0, 0, 0},
00072    { 1, 0, 0},
00073    { 1, 1, 0},
00074    { 0, 1, 0},
00075    {-1, 1, 0},
00076    {-1, 0, 0},
00077    {-1,-1, 0},
00078    { 0,-1, 0},
00079    { 1,-1, 0},
00080    { 0, 0,-1},
00081    { 1, 0,-1},
00082    { 1, 1,-1},
00083    { 0, 1,-1},
00084    {-1, 1,-1},
00085    {-1, 0,-1},
00086    {-1,-1,-1},
00087    { 0,-1,-1},
00088    { 1,-1,-1},
00089    { 0, 0, 1},
00090    { 1, 0, 1},
00091    { 1, 1, 1},
00092    { 0, 1, 1},
00093    {-1, 1, 1},
00094    {-1, 0, 1},
00095    {-1,-1, 1},
00096    { 0,-1, 1},
00097    { 1,-1, 1}
00098  };
00099 
00100 #if __WATCOMC__
00101 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00102 #else
00103 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00104 #endif
00105   HANDLE ghMod;
00106   switch (dwReason) {
00107     case DLL_PROCESS_ATTACH:
00108 #if __X__MIPS__
00109       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00110 #endif
00111       hDLLinstance = hDLL;  /* handle to DLL file */
00112       break;
00113     case DLL_PROCESS_DETACH:
00114 #if __X__MIPS__
00115       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00116 #endif
00117       break;
00118   }
00119   return (int)TRUE;
00120 }
00121 
00122 #if __SC__
00123 #pragma startaddress(DllMain)
00124 #endif
00125 
00126 static double x=1.0,y=1.0,z=1.0;
00127 
00128 #if 0
00129 long CALLBACK ExternalTextureStartup(
00130 #else
00131 long _ExternalTextureStartup(
00132 #endif
00133   long frame,long nframes,char *parameter_list, X__SHADER *lpEVI){
00134  if(parameter_list[0] != '#'){
00135    MessageBox ( GetFocus(),
00136                 (LPCTSTR) "External texture: Startup",
00137                 (LPCTSTR) "Parameter list missing",
00138                 MB_OK | MB_SYSTEMMODAL );
00139  }
00140  else {
00141   parameter_list++;
00142   sscanf(parameter_list,"%f %f %f",
00143          &x,&y,&z);
00144  }
00145  return LoadAndCompileShader("carved");
00146 }
00147 
00148 #if 0
00149 long CALLBACK ExternalTextureMorph(
00150 #else
00151 long _ExternalTextureMorph(
00152 #endif
00153  char *parameter_list, double mr){
00154  double x_m,y_m,z_m;
00155  parameter_list++;
00156  sscanf(parameter_list,"%f %f %f",
00157         &x_m,&y_m,&z_m);
00158  x=x_m+(x-x_m)*mr;
00159  y=y_m+(y-y_m)*mr;
00160  z=z_m+(z-z_m)*mr;
00161  return 1;
00162 }
00163 
00164 #if 0
00165 long CALLBACK ExternalTextureProcedure(
00166 #else
00167 long _ExternalTextureProcedure(
00168 #endif
00169   long coord_type,  vector p, vector n,
00170   double alpha, double beta, double gamma,
00171   double bump,  double map_x,  double map_y,
00172   double *alpha_channel, unsigned char sc[3], double colour[3],
00173   double *reflectivity, double *transparency,
00174   X__SHADER *lpEVI
00175 ){
00176  static long N=1;
00177  static double bradius=1.0,lradius=0.0;
00178  double a;
00179  vector u,v;
00180  double xx,yy,zz;
00181  double  dpoint[27];
00182  double dradius[27];
00183  vector pp[27];
00184  double dx,dy,dz,cx,cy,cz,zb,ccc,dc,zbb,radius;
00185  long i,ix,iy,iz;
00186  BOOL ins;
00187  long k,j,jid,id,pattern,patterni;
00188  double len,rad;
00189  vector ppc;
00190 
00191  xx=alpha / x;
00192  yy=beta  / y;
00193  zz=gamma / z;
00194 
00195  xx *= 4.0;
00196  yy *= 4.0;
00197  zz *= 4.0;
00198 // for(k=0;k<5;k++){ // rough
00199  for(k=0;k<2;k++){ // carved
00200 // for(k=0;k<1;k++){ // (3)
00201  id=0;
00202  ix=FLOOR(xx);
00203  iy=FLOOR(yy);
00204  iz=FLOOR(zz);
00205  cx=xx-(double)ix;
00206  cy=yy-(double)iy;
00207  cz=zz-(double)iz;
00208  zb=-10.0;
00209  ins=TRUE;
00210  id = -1;
00211  len=sqrt(tAxis_u[0]*tAxis_u[0]+
00212           tAxis_u[1]*tAxis_u[1]+
00213           tAxis_u[2]*tAxis_u[2]);
00214  VECCOPY(-tAxis_n,u)
00215  VECSCALE(len,u,u)         // third axis
00216  VECCOPY(tAxis_o,v)
00217  VECSUM(v,cx*tAxis_u,v)
00218  VECSUM(v,cy*tAxis_v,v)
00219  VECSUM(v,cz*u,v)         // coord of point on surface
00220  for(j=0;j<27;j++){
00221  pattern=PATTERN(ix+ip[j][0],iy+ip[j][1],iz+ip[j][2]);
00222  pattern=IMOD(N*pattern,1900);
00223  for(i=0;i<N;i++){
00224    jid=j*N+i;
00225    patterni=pattern+i;
00226    VECSUM((double)ip[j],rand_v[patterni],ppc)
00227    VECSUM(tAxis_o,ppc[0]*tAxis_u,pp[jid])
00228    VECSUM(pp[jid],ppc[1]*tAxis_v,pp[jid])
00229    VECSUM(pp[jid],ppc[2]*u,      pp[jid])
00230 
00231    radius=(bradius+lradius*(rand_v[patterni][1]-0.5))*len;
00232    dradius[jid]=radius;
00233    dpoint[jid] = -1.0;
00234    dx=(v[0]-pp[jid][0]);
00235    dy=(v[1]-pp[jid][1]);
00236    dz=(v[2]-pp[jid][2]);
00237    if(fabs(dx) > radius)continue;
00238    if(fabs(dy) > radius)continue;
00239    if(fabs(dz) > radius)continue;
00240    if((a=sqrt(dx*dx+dy*dy+dz*dz)) < radius){
00241      dpoint[jid]=a;
00242      dc=(radius-a);
00243      if(dc > zb){
00244        id=jid;
00245        zb=dc;
00246      }
00247    }
00248  }
00249  }
00250  if(id >= 0 && ins){
00251    {
00252      VECCOPY(pp[id],ppc)
00253      rad=dradius[id];
00254      VECSUB(v,ppc,u)          //(v-pp) vector from centre of pattern
00255      if((a=sqrt((u[0])*(u[0])+
00256                 (u[1])*(u[1])+
00257                 (u[2])*(u[2]))) < rad){
00258        double mu,moddn,rmu;
00259        vector c,dn;
00260        mu=DOT(u,n);
00261        c[0]=ppc[0]+mu*n[0];
00262        c[1]=ppc[1]+mu*n[1];
00263        c[2]=ppc[2]+mu*n[2];
00264        VECSUB(v,c,dn)
00265        moddn=sqrt(dn[0]*dn[0]+dn[1]*dn[1]+dn[2]*dn[2]);
00266        rmu=sqrt(rad*rad-mu*mu);
00267        if(moddn < rmu){
00268          a=1.0-moddn/rmu;
00269          normalize(dn);
00270          VECSCALE(-1.0,dn,dn);  // dimples
00271 //         a=sqrt(sqrt(a)); //(1)  // rough
00272          a=0.5+0.5*a*a; // (2)  // carved
00273 //         a=0.5*(double)((int)(a*2.0)); //(3) use with discrete gradient
00274          VECSUM((1.0-a)*dn,(a)*n,n)
00275          normalize(n);
00276        }
00277      }
00278    }
00279  }
00280  xx += 20.0; yy += 21.0; zz += 22.0;
00281  xx *= 1.2; yy *= 1.2; zz *=1.2;
00282  }
00283  return 1;
00284 }
00285 void _ExternalTextureClose(X__SHADER *lpEVI){
00286  UnloadCompiledShader(tGLshaderID);
00287 }
00288 
00289 long _ExternalTextureProcedureGL(
00290   double bump_scale,
00291   unsigned char sc[3],
00292   unsigned char ac[3],
00293   X__SHADER *lpEVI
00294 ){
00295  // Set any shader specific uniform variables here.
00296  SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)ac[0]/255.0,(GLfloat)ac[1]/255.0,(GLfloat)ac[2]/255.0);
00297  SetUniformVector(tGLshaderID,"ScalingV",4.0/x,4.0/y,4.0/z);
00298  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00299  return 1;
00300 }
00302 
00303 void CentreDialogOnScreen(HWND hwnd){
00304  RECT rcDlg;
00305  long Xres,Yres;
00306  Yres=GetSystemMetrics(SM_CYSCREEN);
00307  Xres=GetSystemMetrics(SM_CXSCREEN);
00308  GetWindowRect(hwnd,&rcDlg);
00309  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00310  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00311  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00312  return;
00313 }
00314 
00315 static void SetColour(double *colour, HWND parent){
00316  CHOOSECOLOR cc;
00317  static COLORREF CustColours[16]={
00318    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00319    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00320    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00321    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00322  cc.lStructSize=sizeof(CHOOSECOLOR);
00323  cc.hwndOwner=parent;
00324  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00325  cc.lpCustColors=(LPDWORD)CustColours;
00326  cc.Flags= CC_RGBINIT;
00327  cc.lCustData=(DWORD)0;
00328  if(ChooseColor(&cc)){
00329    colour[0]=(double)GetRValue(cc.rgbResult);
00330    colour[1]=(double)GetGValue(cc.rgbResult);
00331    colour[2]=(double)GetBValue(cc.rgbResult);
00332  }
00333 }
00334 
00335 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00336 
00337 #if 0
00338 char * CALLBACK SetExternalParameters(
00339 #else
00340 char * _SetExternalParameters(
00341 #endif
00342   char *Op,                 /* string for the parameters                  */
00343   HWND hWnd,                /* parent window                              */
00344   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00345                              ){
00346  char szbuf[255],*Op1;
00347  if(Op != NULL){  /* parameters exist so read them off the list */
00348    Op1=Op;
00349    Op1++;
00350    sscanf(Op1,"%f %f %f",
00351          &x,&y,&z);
00352  }
00353  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00354               (DLGPROC)DlgProc) == FALSE)return Op;
00355  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00356  sprintf(szbuf,"# %.3f %.3f %.3f",
00357          x,y,z);
00358  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00359   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00360                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00361    return NULL;
00362  }
00363  strcpy(Op,szbuf);
00364  return Op;
00365 }
00366 
00367 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00368  char str[16];
00369  switch( msg ) {
00370    case WM_INITDIALOG:
00371      sprintf(str,"%.2f",x);
00372      SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00373      SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00374      sprintf(str,"%.2f",y);
00375      SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00376      SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00377      sprintf(str,"%.2f",z);
00378      SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00379      SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00380      CentreDialogOnScreen(hwnd);
00381      return TRUE;
00382    case WM_COMMAND:
00383      switch(LOWORD(wparam)){
00384         case IDCANCEL:
00385           EndDialog(hwnd,FALSE);
00386           return(TRUE);
00387         case IDOK:
00388           if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00389              EndDialog(hwnd,FALSE);
00390           if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00391           if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00392              EndDialog(hwnd,FALSE);
00393           if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00394           if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00395              EndDialog(hwnd,FALSE);
00396           if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00397           EndDialog(hwnd,TRUE);
00398           return(TRUE);
00399         default:
00400           break;
00401       }
00402       break;
00403     default: break;
00404  }
00405  return FALSE;
00406 }
Generated on Tue Jan 28 06:18:31 2014 for OpenFX by  doxygen 1.6.3