paving.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 //  paving.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 "paving.h"
00054 
00055 #if __WATCOMC__
00056 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00057 #else
00058 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00059 #endif
00060   HANDLE ghMod;
00061   switch (dwReason) {
00062     case DLL_PROCESS_ATTACH:
00063 #if __X__MIPS__
00064       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00065 #endif
00066       hDLLinstance = hDLL;  /* handle to DLL file */
00067       break;
00068     case DLL_PROCESS_DETACH:
00069 #if __X__MIPS__
00070       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00071 #endif
00072       break;
00073   }
00074   return (int)TRUE;
00075 }
00076 
00077 #if __SC__
00078 #pragma startaddress(DllMain)
00079 #endif
00080 
00081 static double flat_edge=0.025,bevel_edge=0.06,blend_edge=0.06;
00082 static double c1[3]={200.0,130.0, 90.0};
00083 static double x=1.0,y=1.0,z=1.0;
00084 
00085 #if 0
00086 long CALLBACK ExternalTextureStartup(
00087 #else
00088 long _ExternalTextureStartup(
00089 #endif
00090   long frame,long nframes,char *parameter_list, X__SHADER *lpEVI){
00091  if(parameter_list[0] != '#'){
00092    MessageBox ( GetFocus(),
00093                 (LPCTSTR) "External texture: Startup",
00094                 (LPCTSTR) "Parameter list missing",
00095                 MB_OK | MB_SYSTEMMODAL );
00096  }
00097  else {
00098   parameter_list++;
00099   sscanf(parameter_list,"%f %f %f  %f %f %f  %f %f %f",
00100          &x,&y,&z,&flat_edge,&bevel_edge,&blend_edge,
00101          &c1[0],&c1[1],&c1[2]);
00102  }
00103 return LoadAndCompileShader("paving");
00104 }
00105 
00106 #if 0
00107 long CALLBACK ExternalTextureMorph(
00108 #else
00109 long _ExternalTextureMorph(
00110 #endif
00111  char *parameter_list, double mr){
00112  int i;
00113  double flat_edge_m,bevel_edge_m,blend_edge_m;
00114  double c1_m[3],c2_m[3],c3_m[3];
00115  double x_m,y_m,z_m;
00116  parameter_list++;
00117  sscanf(parameter_list,"%f %f %f  %f %f %f  %f %f %f",
00118         &x_m,&y_m,&z_m,&flat_edge_m,&bevel_edge_m,&blend_edge_m,
00119         &c1_m[0],&c1_m[1],&c1_m[2]);
00120  for(i=0;i<3;i++)c1[i]=c1_m[i]+(c1[i]-c1_m[i])*mr;
00121  flat_edge=flat_edge_m+(flat_edge-flat_edge_m)*mr;
00122  bevel_edge=bevel_edge_m+(bevel_edge-bevel_edge_m)*mr;
00123  blend_edge=blend_edge_m+(blend_edge-blend_edge_m)*mr;
00124  x=x_m+(x-x_m)*mr;
00125  y=y_m+(y-y_m)*mr;
00126  z=z_m+(z-z_m)*mr;
00127  return 1;
00128 }
00129 
00130 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00131 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00132 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00133 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00134 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00135 #define CROSS(v1,v2,r)  { \
00136                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00137                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00138                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00139                         }
00140 #define IMOD(z,a) ((z) - ((z)/(a))*(a))
00141 #define PATTERN(x,y,z)   ( ((z)+16384L)*64536L +  \
00142                            ((y)+16384L)*32768L +  \
00143                            ((x)+16384L))
00144 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00145 #define FMOD(x,a) ((x) >= 0.0 ? fmod(x,a) :(a - fmod(-(x),a)))
00146 #define ROOT32 0.866025403
00147 #define ROOT3   1.73205080
00148 
00149 #include "randno.c"
00150 
00151 static long ip[27][3]={
00152    { 0, 0, 0},
00153    { 1, 0, 0},
00154    { 1, 1, 0},
00155    { 0, 1, 0},
00156    {-1, 1, 0},
00157    {-1, 0, 0},
00158    {-1,-1, 0},
00159    { 0,-1, 0},
00160    { 1,-1, 0},
00161    { 0, 0,-1},
00162    { 1, 0,-1},
00163    { 1, 1,-1},
00164    { 0, 1,-1},
00165    {-1, 1,-1},
00166    {-1, 0,-1},
00167    {-1,-1,-1},
00168    { 0,-1,-1},
00169    { 1,-1,-1},
00170    { 0, 0, 1},
00171    { 1, 0, 1},
00172    { 1, 1, 1},
00173    { 0, 1, 1},
00174    {-1, 1, 1},
00175    {-1, 0, 1},
00176    {-1,-1, 1},
00177    { 0,-1, 1},
00178    { 1,-1, 1}
00179  };
00180 
00181 static void mix(double *r, double *g, double *b, double mx,
00182                 double r1, double g1, double b1,
00183                 double r2, double g2, double b2){
00184  *r = mx*r1 + (1.0-mx)*r2;
00185  *g = mx*g1 + (1.0-mx)*g2;
00186  *b = mx*b1 + (1.0-mx)*b2;
00187 }
00188 
00189 #if 0
00190 long CALLBACK ExternalTextureProcedure(
00191 #else
00192 long _ExternalTextureProcedure(
00193 #endif
00194   long coord_type,  vector p, vector n,
00195   double alpha, double beta, double gamma,
00196   double bump,  double map_x,  double map_y,
00197   double *alpha_channel, unsigned char sc[3], double colour[3],
00198   double *reflectivity, double *transparency,
00199   X__SHADER *lpEVI
00200 ){
00201  double xx,yy,zz,r,g,b;
00202  double a;
00203  vector u,v;
00204  vector vclr[27];
00205  double dpoint[27];
00206  vector pp[10];
00207  double dx,dy,dz,cx,cy,cz,zb,ccc,dc,zbb,noiseH;
00208  long ix,iy,iz;
00209  BOOL ins;
00210  long i,j,jid,id,pattern,patterni;
00211 
00212  static double radius=1.0;
00213  static double vc=0.1;   // discolouration
00214 
00215  xx=alpha*4.0 / x;
00216  yy=beta*4.0  / y;
00217  zz=gamma*4.0 / z;
00218  id=0;
00219  ix=FLOOR(xx);
00220  iy=FLOOR(yy);
00221  iz=FLOOR(zz);
00222  cx=xx-(double)ix;
00223  cy=yy-(double)iy;
00224  cz=zz-(double)iz;
00225  zb=-10.0;
00226  ins=TRUE;
00227  for(i=0,j=0;j<27;j++){
00228    pattern=PATTERN(ix+ip[j][0],iy+ip[j][1],iz+ip[j][2]);
00229    pattern=IMOD(pattern,1900);   // should be N*pattern for n > 1
00230    jid=j+i;
00231    patterni=pattern+i;
00232    VECSUM((double)ip[j],rand_v[patterni],pp[i])
00233    VECCOPY(rand_v[patterni],vclr[jid])
00234    dpoint[jid] = -1.0;
00235    dx=(cx-pp[i][0]);
00236    dy=(cy-pp[i][1]);
00237    dz=(cz-pp[i][2]);
00238    if(fabs(dx) > radius)continue;
00239    if(fabs(dy) > radius)continue;
00240    if(fabs(dz) > radius)continue;
00241    if((a=sqrt(dx*dx+dy*dy+dz*dz)) < radius){
00242      dpoint[jid]=a;
00243      dc=(radius-a);
00244      if(dc > zb){
00245        id=jid;
00246        zb=dc;
00247      }
00248    }
00249  }
00250  zbb= -10.0;
00251  for(i=0;i<27;i++){
00252    if(i == id)continue;
00253    if(dpoint[i] >= 0.0){
00254      dc=(radius-dpoint[i]);
00255      if(dc > zbb){
00256        zbb=dc;
00257      }
00258    }
00259  }
00260  if((ccc=fabs(zbb - zb)) < flat_edge)ins=FALSE;
00261  if(ins){
00262    if(0){
00263      r=vclr[id][0];
00264      g=vclr[id][1];
00265      b=vclr[id][2];
00266    }
00267    else{
00268      r=colour[0]/255.0 + vc*(vclr[id][0]-0.5);
00269      g=colour[1]/255.0 + vc*(vclr[id][1]-0.5);
00270      b=colour[2]/255.0 + vc*(vclr[id][2]-0.5);
00271      r=min(r,1.0); g=min(g,1.0); b=min(b,1.0);
00272      nNoise(xx*2.0,yy*2.0,zz*2.0,&noiseH);
00273      r -= (noiseH*0.3);
00274      g -= (noiseH*0.3);
00275      b -= (noiseH*0.3);
00276      r=max(r,0.0); g=max(g,0.0); b=max(b,0.0);
00277    }
00278    if(ccc < bevel_edge){
00279      v[0]=(cx-pp[id][0]);
00280      v[1]=(cy-pp[id][1]);
00281      v[2]=(cz-pp[id][2]);
00282      normalize(v);
00283      CROSS(v,n,u)
00284      CROSS(n,u,v)
00285      normalize(v);
00286      a=0.4;
00287      VECSCALE(a,v,v)
00288      VECSCALE((1.0-a),n,n)
00289      VECSUM(v,n,n)
00290      normalize(n);
00291    }
00292    if(ccc < blend_edge)mix(&r,&g,&b,(ccc-flat_edge)/(blend_edge-flat_edge),
00293          r,g,b,
00294          (double)c1[0]/255.0,
00295          (double)c1[1]/255.0,
00296          (double)c1[2]/255.0
00297          );
00298  }
00299  else{
00300    r=c1[0]/255.0;
00301    g=c1[1]/255.0;
00302    b=c1[2]/255.0;
00303  }
00304  colour[0]=r*255;
00305  colour[1]=g*255;
00306  colour[2]=b*255;
00307 
00308  return 1;
00309 }
00310 
00311 void _ExternalTextureClose(X__SHADER *lpEVI){
00312  UnloadCompiledShader(tGLshaderID);
00313 }
00314 
00315 long _ExternalTextureProcedureGL(
00316   double bump_scale,
00317   unsigned char sc[3],
00318   unsigned char ac[3],
00319   X__SHADER *lpEVI
00320 ){
00321  SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)ac[0]/255.0,(GLfloat)ac[1]/255.0,(GLfloat)ac[2]/255.0);
00322  SetUniformVector(tGLshaderID,"ScalingV",4.0/x,4.0/y,4.0/z);
00323  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00324  return 1;
00325 }
00327 
00328 void CentreDialogOnScreen(HWND hwnd){
00329  RECT rcDlg;
00330  long Xres,Yres;
00331  Yres=GetSystemMetrics(SM_CYSCREEN);
00332  Xres=GetSystemMetrics(SM_CXSCREEN);
00333  GetWindowRect(hwnd,&rcDlg);
00334  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00335  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00336  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00337  return;
00338 }
00339 
00340 static void SetColour(double *colour, HWND parent){
00341  CHOOSECOLOR cc;
00342  static COLORREF CustColours[16]={
00343    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00344    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00345    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00346    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00347  cc.lStructSize=sizeof(CHOOSECOLOR);
00348  cc.hwndOwner=parent;
00349  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00350  cc.lpCustColors=(LPDWORD)CustColours;
00351  cc.Flags= CC_RGBINIT;
00352  cc.lCustData=(DWORD)0;
00353  if(ChooseColor(&cc)){
00354    colour[0]=(double)GetRValue(cc.rgbResult);
00355    colour[1]=(double)GetGValue(cc.rgbResult);
00356    colour[2]=(double)GetBValue(cc.rgbResult);
00357  }
00358 }
00359 
00360 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00361 
00362 #if 0
00363 char * CALLBACK SetExternalParameters(
00364 #else
00365 char * _SetExternalParameters(
00366 #endif
00367   char *Op,                 /* string for the parameters                  */
00368   HWND hWnd,                /* parent window                              */
00369   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00370                              ){
00371  char szbuf[255],*Op1;
00372  if(Op != NULL){  /* parameters exist so read them off the list */
00373    Op1=Op;
00374    Op1++;
00375    sscanf(Op1,"%f %f %f  %f %f %f  %f %f %f",
00376          &x,&y,&z,&flat_edge,&bevel_edge,&blend_edge,
00377          &c1[0],&c1[1],&c1[2]);
00378  }
00379  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00380               (DLGPROC)DlgProc) == FALSE)return Op;
00381  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00382  sprintf(szbuf,"# %.2f %.2f %.2f  %.3f %.3f %.3f "
00383                  "%.2f %.2f %.2f",
00384          x,y,z,flat_edge,bevel_edge,blend_edge,
00385          c1[0],c1[1],c1[2]);
00386  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00387   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00388                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00389    return NULL;
00390  }
00391  strcpy(Op,szbuf);
00392  return Op;
00393 }
00394 
00395 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00396  char str[16];
00397  switch( msg ) {
00398    case WM_INITDIALOG:
00399      sprintf(str,"%.2f",x);
00400      SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00401      SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00402      sprintf(str,"%.2f",y);
00403      SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00404      SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00405      sprintf(str,"%.2f",z);
00406      SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00407      SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00408      sprintf(str,"%.3f",flat_edge);
00409      SendDlgItemMessage(hwnd,DLG_SIZE,WM_SETTEXT,0,(LPARAM)str);
00410      SendDlgItemMessage(hwnd,DLG_SIZE,EM_LIMITTEXT,(WPARAM)12,0);
00411      sprintf(str,"%.3f",bevel_edge);
00412      SendDlgItemMessage(hwnd,DLG_DEPTH,WM_SETTEXT,0,(LPARAM)str);
00413      SendDlgItemMessage(hwnd,DLG_DEPTH,EM_LIMITTEXT,(WPARAM)12,0);
00414      sprintf(str,"%.3f",blend_edge);
00415      SendDlgItemMessage(hwnd,DLG_BLEND,WM_SETTEXT,0,(LPARAM)str);
00416      SendDlgItemMessage(hwnd,DLG_BLEND,EM_LIMITTEXT,(WPARAM)12,0);
00417      CentreDialogOnScreen(hwnd);
00418      return TRUE;
00419    case WM_DRAWITEM:{
00420        LPDRAWITEMSTRUCT lpdis;
00421        HBRUSH   hbr,hbrold;
00422        BYTE r,g,b;
00423        lpdis=(LPDRAWITEMSTRUCT)lparam;
00424        if(lpdis->CtlID == DLG_COLOUR){
00425          if(lpdis->CtlID == DLG_COLOUR){
00426            r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00427          }
00428          if(lpdis->itemState & ODS_SELECTED)
00429             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00430          else{
00431            hbr=CreateSolidBrush(RGB(r,g,b));
00432            hbrold=SelectObject(lpdis->hDC,hbr);
00433            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00434                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00435            SelectObject(lpdis->hDC,hbrold);
00436            DeleteObject(hbr);
00437          }
00438        }
00439      }
00440      break;
00441    case WM_COMMAND:
00442      switch(LOWORD(wparam)){
00443         case DLG_COLOUR:
00444           SetColour(c1,hwnd);
00445           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR),NULL,FALSE);
00446           break;
00447         case IDCANCEL:
00448           EndDialog(hwnd,FALSE);
00449           return(TRUE);
00450         case IDOK:
00451           if(GetDlgItemText(hwnd,DLG_SIZE,str,10) == 0)
00452              EndDialog(hwnd,FALSE);
00453           if((flat_edge=atof(str)) == 0)EndDialog(hwnd,FALSE);
00454           if(GetDlgItemText(hwnd,DLG_DEPTH,str,10) == 0)
00455              EndDialog(hwnd,FALSE);
00456           if((bevel_edge=atof(str)) == 0)EndDialog(hwnd,FALSE);
00457           if(GetDlgItemText(hwnd,DLG_BLEND,str,10) == 0)
00458              EndDialog(hwnd,FALSE);
00459           if((blend_edge=atof(str)) == 0)EndDialog(hwnd,FALSE);
00460           if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00461              EndDialog(hwnd,FALSE);
00462           if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00463           if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00464              EndDialog(hwnd,FALSE);
00465           if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00466           if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00467              EndDialog(hwnd,FALSE);
00468           if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00469           EndDialog(hwnd,TRUE);
00470           return(TRUE);
00471         default:
00472           break;
00473       }
00474       break;
00475     default: break;
00476  }
00477  return FALSE;
00478 }
Generated on Tue Jan 28 06:18:32 2014 for OpenFX by  doxygen 1.6.3