MAPPING.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 
00006 /* file MAPPING.C */
00007 
00008 // This file handles MAPPING 
00009 
00010 #define MODULE_MAPPING 1
00011 
00012 #include "design.h"
00013 #include "..\animate\spin_dll.h"
00014 
00015 static int E_MapToPlaneBrush(vector vi,
00016                             vector p0, vector p1, vector p2,
00017                             double *a, double *b);
00018 static double Distance3D(point a, long *b);
00019 
00020 #define BRUSHBIT   0x40
00021 
00022 static char *GetFlicFromDisk(int id, char *p, HWND parent, int type);
00023 static char *GetMapFromDisk(char *p, HWND parent, BOOL *bLoaded);
00024 static char *GetPresetMap(char *p, HWND parent);
00025 static void EditImageFile(char *pathname);
00026 static void PlayMoviePreview(char *pathname);
00027 static void AssignFaceMappingFromVertexMapping(void);
00028 static void AssignVertexMappingFromFaceMapping(void);
00029 static void RemoveMappingCoords(BOOL);
00030 static void FixUpMapEdge(double a[]);
00031 
00032 static int IdentifiedBrushPoint=-1;
00033 static int LastUsedMapID=0;
00034 // Mapping Dialog
00035 static HBITMAP MapBtnBitmaps[8]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
00036 static HBITMAP MapButtonBitmaps[6]={NULL,NULL,NULL,NULL,NULL,NULL};
00037 
00038 
00039 static void UpdateOpenGLMapping(void){
00040  if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+4),0,0);
00041 }
00042 
00043 static void UpdateTypeMappingSection(HWND hdlg,int m){
00044  int active;
00045  char str[32];
00046  if(iMap[m].Map == MAP_BY_VERTEX)active=TRUE; else active=FALSE; 
00047  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_G),active);
00048 
00049  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_MOVE),TRUE);
00050  if(nImaps >= NMAPSMAX)EnableWindow(GetDlgItem(hdlg,DLG_MAPS_NEW),FALSE);
00051  if(iMap[m].Map == PLANE || iMap[m].Map == PLANE_MOZIAC)active=TRUE; else active=FALSE;
00052  SendDlgItemMessage(hdlg,DLG_MAPS_P,BM_SETCHECK,active,0);
00053  if(iMap[m].Map == CYLINDER || iMap[m].Map == CYLINDER_MOZIAC)active=TRUE; else active=FALSE;
00054  SendDlgItemMessage(hdlg,DLG_MAPS_C,BM_SETCHECK,active,0);
00055  if(iMap[m].Map == MAP_SPHERICAL)active=TRUE; else active=FALSE;
00056  SendDlgItemMessage(hdlg,DLG_MAPS_S,BM_SETCHECK,active,0);
00057  if(iMap[m].Map == MAP_BY_VERTEX)active=TRUE; else active=FALSE;
00058  SendDlgItemMessage(hdlg,DLG_MAPS_G,BM_SETCHECK,active,0);
00059  // PM now reps plain tile CM reps Mozaic tile
00060  if(iMap[m].Map == PLANE_MOZIAC || iMap[m].Map == CYLINDER_MOZIAC)active=TRUE; else active=FALSE;
00061  SendDlgItemMessage(hdlg,DLG_MAPS_CM,BM_SETCHECK,active,0);
00062  if(iMap[m].Map == PLANE || iMap[m].Map == CYLINDER)active=TRUE; else active=FALSE;
00063  SendDlgItemMessage(hdlg,DLG_MAPS_PM,BM_SETCHECK,active,0);
00064  if(iMap[m].Map == PLANE || iMap[m].Map == CYLINDER ||
00065     iMap[m].Map == PLANE_MOZIAC || iMap[m].Map == CYLINDER_MOZIAC)
00066     active=TRUE; else active=FALSE;
00067  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_CM),active);
00068  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_PM),active);
00069  SendDlgItemMessage(hdlg,DLG_MAPS_C_SCROLL,TBM_SETPOS,TRUE,iMap[m].Angle);
00070  sprintf(str,"%ld",iMap[m].Angle);
00071  SendDlgItemMessage(hdlg,DLG_MAPS_C_EDIT,WM_SETTEXT,0,(LPARAM)str);
00072  if(iMap[m].Map == CYLINDER ||
00073     iMap[m].Map == CYLINDER_MOZIAC)active=SW_SHOW; else active=SW_HIDE;
00074  ShowWindow(GetDlgItem(hdlg,DLG_MAPS_C_SCROLL),active);
00075  ShowWindow(GetDlgItem(hdlg,DLG_MAPS_C_EDIT),active);
00076  SendDlgItemMessage(hdlg,DLG_MAPS_KEY_CHOSEN,BM_SETCHECK,active,0);
00077  UpdateOpenGLMapping();
00078  return;
00079 }
00080 
00081 static void UpdateSurfaceMappingSection(HWND hdlg,int m){
00082  BOOL active;
00083  char str[32],truncated[256];
00084  if(iMap[m].S == NULL){
00085    active=FALSE;
00086    SendDlgItemMessage(hdlg,DLG_MAPS_S_NAME,WM_SETTEXT,0,(LPARAM)"<No image>");
00087  }
00088  else{
00089    active=TRUE;
00090    SendDlgItemMessage(hdlg,DLG_MAPS_S_NAME,WM_SETTEXT,0,
00091                       (LPARAM)TruncateTextString(iMap[m].S,truncated,35));
00092  }
00093  SendDlgItemMessage(hdlg,DLG_MAPS_S_ACTIVE,BM_SETCHECK,active,0);
00094  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_DROP),active);
00095 // EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_ANIMATED),active);
00096  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_SCROLL),active);
00097  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_VIEW),active);
00098  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_MODIFY),active);
00099  if(iMap[m].Type == ANIMBRUSH)active=TRUE; else active=FALSE;
00100  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_S_PRESET),!active);
00101 // SendDlgItemMessage(hdlg,DLG_MAPS_S_STILL,BM_SETCHECK,!active,0);
00102  SendDlgItemMessage(hdlg,DLG_MAPS_S_ANIMATED,BM_SETCHECK,active,0);
00103  SendDlgItemMessage(hdlg,DLG_MAPS_S_SCROLL,TBM_SETPOS,TRUE,iMap[m].sp);
00104  sprintf(str,"%ld",iMap[m].sp);
00105  SendDlgItemMessage(hdlg,DLG_MAPS_S_EDIT,WM_SETTEXT,0,(LPARAM)str);
00106  UpdateOpenGLMapping();
00107  return;
00108 }
00109 
00110 static void UpdateReflectionMappingSection(HWND hdlg,int m){
00111  BOOL active;
00112  char str[32],truncated[256];
00113  if(iMap[m].R == NULL){
00114    active=FALSE;
00115    SendDlgItemMessage(hdlg,DLG_MAPS_R_NAME,WM_SETTEXT,0,(LPARAM)"<No image>");
00116  }
00117  else{
00118    active=TRUE;
00119    SendDlgItemMessage(hdlg,DLG_MAPS_R_NAME,WM_SETTEXT,0,
00120                       (LPARAM)TruncateTextString(iMap[m].R,truncated,35));
00121  }
00122  SendDlgItemMessage(hdlg,DLG_MAPS_R_ACTIVE,BM_SETCHECK,active,0);
00123  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_R_VIEW),active);
00124  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_R_MODIFY),active);
00125  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_R_DROP),active);
00126 // EnableWindow(GetDlgItem(hdlg,DLG_MAPS_R_ANIMATED),active);
00127  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_R_SCROLL),active);
00128  if(iMap[m].TypeR == ANIMBRUSH)active=TRUE; else active=FALSE;
00129 // SendDlgItemMessage(hdlg,DLG_MAPS_R_STILL,BM_SETCHECK,!active,0);
00130  SendDlgItemMessage(hdlg,DLG_MAPS_R_ANIMATED,BM_SETCHECK,active,0);
00131  SendDlgItemMessage(hdlg,DLG_MAPS_R_SCROLL,TBM_SETPOS,TRUE,iMap[m].rp);
00132  sprintf(str,"%ld",iMap[m].rp);
00133  SendDlgItemMessage(hdlg,DLG_MAPS_R_EDIT,WM_SETTEXT,0,(LPARAM)str);
00134  UpdateOpenGLMapping();
00135  return;
00136 }
00137 
00138 static void UpdateBumpMappingSection(HWND hdlg,int m){
00139  BOOL active;
00140  char str[32],truncated[256];
00141  if(iMap[m].B == NULL){
00142    active=FALSE;
00143    SendDlgItemMessage(hdlg,DLG_MAPS_B_NAME,WM_SETTEXT,0,(LPARAM)"<No image>");
00144  }
00145  else{
00146    active=TRUE;
00147    SendDlgItemMessage(hdlg,DLG_MAPS_B_NAME,WM_SETTEXT,0,
00148                       (LPARAM)TruncateTextString(iMap[m].B,truncated,35));
00149  }
00150  SendDlgItemMessage(hdlg,DLG_MAPS_B_ACTIVE,BM_SETCHECK,active,0);
00151  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_B_VIEW),active);
00152  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_B_MODIFY),active);
00153  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_B_DROP),active);
00154 // EnableWindow(GetDlgItem(hdlg,DLG_MAPS_B_ANIMATED),active);
00155  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_B_SCROLL),active);
00156  if(iMap[m].TypeB == ANIMBRUSH)active=TRUE; else active=FALSE;
00157 // SendDlgItemMessage(hdlg,DLG_MAPS_B_STILL,BM_SETCHECK,!active,0);
00158  SendDlgItemMessage(hdlg,DLG_MAPS_B_ANIMATED,BM_SETCHECK,active,0);
00159  SendDlgItemMessage(hdlg,DLG_MAPS_B_SCROLL,TBM_SETPOS,TRUE,iMap[m].bp);
00160  sprintf(str,"%ld",iMap[m].bp);
00161  SendDlgItemMessage(hdlg,DLG_MAPS_B_EDIT,WM_SETTEXT,0,(LPARAM)str);
00162  UpdateOpenGLMapping();
00163  return;
00164 }
00165 
00166 static void UpdateTransMappingSection(HWND hdlg,int m){
00167  BOOL active;
00168  char str[32],truncated[256];
00169  if(iMap[m].T == NULL){
00170    active=FALSE;
00171    SendDlgItemMessage(hdlg,DLG_MAPS_T_NAME,WM_SETTEXT,0,(LPARAM)"<No image>");
00172  }
00173  else{
00174    active=TRUE;
00175    SendDlgItemMessage(hdlg,DLG_MAPS_T_NAME,WM_SETTEXT,0,
00176                       (LPARAM)TruncateTextString(iMap[m].T,truncated,35));
00177  }
00178  SendDlgItemMessage(hdlg,DLG_MAPS_T_ACTIVE,BM_SETCHECK,active,0);
00179  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_T_VIEW),active);
00180  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_T_MODIFY),active);
00181  EnableWindow(GetDlgItem(hdlg,DLG_MAPS_T_DROP),active);
00182 // EnableWindow(GetDlgItem(hdlg,DLG_MAPS_T_ANIMATED),active);
00183 // EnableWindow(GetDlgItem(hdlg,DLG_MAPS_T_SCROLL),active);
00184  if(iMap[m].TypeT == ANIMBRUSH)active=TRUE; else active=FALSE;
00185 // SendDlgItemMessage(hdlg,DLG_MAPS_T_STILL,BM_SETCHECK,!active,0);
00186  SendDlgItemMessage(hdlg,DLG_MAPS_T_ANIMATED,BM_SETCHECK,active,0);
00187 // SetScrollPos(GetDlgItem(hdlg,DLG_MAPS_T_SCROLL),SB_CTL,iMap[m].tp,TRUE);
00188 // sprintf(str,"%ld",iMap[m].tp);
00189 // SendDlgItemMessage(hdlg,DLG_MAPS_T_EDIT,WM_SETTEXT,0,(LPARAM)str);
00190  UpdateOpenGLMapping();
00191  return;
00192 }
00193 
00194 static void UpdateSurfaceTypeMapping(HWND hdlg,int m){
00195  BOOL active;
00196  if(iMap[m].bTiled)active=TRUE; else active=FALSE;
00197  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_SINGLE,BM_SETCHECK,(WPARAM)!active,0);
00198  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_TILE,BM_SETCHECK,(WPARAM)active,0);
00199  if(iMap[m].bShaded)active=TRUE; else active=FALSE;
00200  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_SHADED,BM_SETCHECK,(WPARAM)active,0);
00201  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_UNSHADED,BM_SETCHECK,(WPARAM)!active,0);
00202  if(iMap[m].bDecal)active=TRUE; else active=FALSE;
00203  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_OPAQUE,BM_SETCHECK,(WPARAM)!active,0);
00204  SendDlgItemMessage(hdlg,DLG_ATTRIBS_MAP_CLEAR,BM_SETCHECK,(WPARAM)active,0);
00205  UpdateOpenGLMapping();
00206 }
00207 
00208 
00209 static UpdateMappingDialog(HWND hdlg,int mapid){
00210  UpdateTypeMappingSection(hdlg,mapid);
00211  UpdateSurfaceMappingSection(hdlg,mapid);
00212  UpdateReflectionMappingSection(hdlg,mapid);
00213  UpdateBumpMappingSection(hdlg,mapid);
00214  UpdateTransMappingSection(hdlg,mapid);
00215  UpdateSurfaceTypeMapping(hdlg,mapid);
00216 }
00217 
00218 static BOOL CALLBACK MappingDlgProc(HWND hdlg,UINT msg,
00219                                     WPARAM wparam,LPARAM lparam){
00220  static MapID;
00221  HWND hctl;
00222  BOOL err;
00223  BOOL bMapLoaded;
00224  int i,iMin,iMax;
00225  LPDRAWITEMSTRUCT lpdis;
00226  switch( msg ) {
00227    case WM_PAINT:
00228      PaintDialogBackground(hdlg,ghinst_main);
00229      break;
00230    case WM_INITDIALOG:
00231      EDIT_ACTION=YES;
00232      EnableWindow(ghwnd_main,TRUE);
00233      MapID=(int)lparam;
00234      MapBtnBitmaps[0]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS3));
00235      MapBtnBitmaps[1]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS1));
00236      MapBtnBitmaps[2]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS2));
00237      MapBtnBitmaps[3]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS4));
00238      MapBtnBitmaps[4]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS6));
00239      MapBtnBitmaps[5]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAPS5));
00240      MapBtnBitmaps[6]=(HBITMAP)LoadImage(ghinst_main,"DELETEX",IMAGE_ICON,
00241                                0,0,LR_DEFAULTCOLOR); // ICON
00242      MapBtnBitmaps[7]=(HBITMAP)LoadImage(ghinst_main,"FOLDERS",IMAGE_ICON,
00243                                0,0,LR_DEFAULTCOLOR); // ICON
00244      MapButtonBitmaps[0]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX1));
00245      MapButtonBitmaps[1]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX2));
00246      MapButtonBitmaps[2]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX3));
00247      MapButtonBitmaps[3]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX4));
00248      MapButtonBitmaps[4]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX5));
00249 // for bitmap
00250 //       MapButtonBitmaps[5]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_MAP_FX6));
00251      MapButtonBitmaps[5]=(HBITMAP)LoadImage(ghinst_main,"MAPFX6",IMAGE_ICON,
00252                               0,0,LR_DEFAULTCOLOR); // ICON
00253      SendMessage(GetDlgItem(hdlg,DLG_MAPS_S_DROP),BM_SETIMAGE,
00254                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[6]);
00255      SendMessage(GetDlgItem(hdlg,DLG_MAPS_R_DROP),BM_SETIMAGE,
00256                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[6]);
00257      SendMessage(GetDlgItem(hdlg,DLG_MAPS_B_DROP),BM_SETIMAGE,
00258                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[6]);
00259      SendMessage(GetDlgItem(hdlg,DLG_MAPS_T_DROP),BM_SETIMAGE,
00260                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[6]);
00261 
00262      SendMessage(GetDlgItem(hdlg,DLG_MAPS_S_SET),BM_SETIMAGE,
00263                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[7]);
00264      SendMessage(GetDlgItem(hdlg,DLG_MAPS_R_SET),BM_SETIMAGE,
00265                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[7]);
00266      SendMessage(GetDlgItem(hdlg,DLG_MAPS_B_SET),BM_SETIMAGE,
00267                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[7]);
00268      SendMessage(GetDlgItem(hdlg,DLG_MAPS_T_SET),BM_SETIMAGE,
00269                  (WPARAM)IMAGE_ICON,(LPARAM)MapBtnBitmaps[7]);
00270 
00271      SendMessage(GetDlgItem(hdlg,DLG_MAPS_P),BM_SETIMAGE,
00272                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[0]);
00273      SendMessage(GetDlgItem(hdlg,DLG_MAPS_C),BM_SETIMAGE,
00274                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[1]);
00275      SendMessage(GetDlgItem(hdlg,DLG_MAPS_S),BM_SETIMAGE,
00276                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[2]);
00277      SendMessage(GetDlgItem(hdlg,DLG_MAPS_G),BM_SETIMAGE,
00278                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[3]);
00279      SendMessage(GetDlgItem(hdlg,DLG_MAPS_PM),BM_SETIMAGE,
00280                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[4]);
00281      SendMessage(GetDlgItem(hdlg,DLG_MAPS_CM),BM_SETIMAGE,
00282                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapBtnBitmaps[5]);
00283 
00284      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_SHADED),BM_SETIMAGE,
00285                  (WPARAM)IMAGE_BITMAP,(LPARAM)MapButtonBitmaps[0]);
00286      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_UNSHADED),BM_SETIMAGE,
00287                  (WPARAM)0,(LPARAM)MapButtonBitmaps[1]);
00288      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_SINGLE),BM_SETIMAGE,
00289                  (WPARAM)0,(LPARAM)MapButtonBitmaps[2]);
00290      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_TILE),BM_SETIMAGE,
00291                  (WPARAM)0,(LPARAM)MapButtonBitmaps[3]);
00292      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_OPAQUE),BM_SETIMAGE,
00293                  (WPARAM)0,(LPARAM)MapButtonBitmaps[4]);
00294      SendMessage(GetDlgItem(hdlg,DLG_ATTRIBS_MAP_CLEAR),BM_SETIMAGE,
00295                  (WPARAM)IMAGE_ICON,(LPARAM)MapButtonBitmaps[5]);
00296 
00297 //     SetWindowLong(hdlg,GWL_USERDATA,(long)MapID);
00298      SendDlgItemMessage(hdlg,DLG_MAPS_C_SCROLL,TBM_SETRANGE,
00299                                 (WPARAM)TRUE,(LPARAM)MAKELONG(0,360));
00300      SendDlgItemMessage(hdlg,DLG_MAPS_S_SCROLL,TBM_SETRANGE,
00301                                 (WPARAM)TRUE,(LPARAM)MAKELONG(0,100));
00302      SendDlgItemMessage(hdlg,DLG_MAPS_R_SCROLL,TBM_SETRANGE,
00303                                 (WPARAM)TRUE,(LPARAM)MAKELONG(0,100));
00304      SendDlgItemMessage(hdlg,DLG_MAPS_B_SCROLL,TBM_SETRANGE,
00305                                 (WPARAM)TRUE,(LPARAM)MAKELONG(0,100));
00306 //     SendDlgItemMessage(hdlg,DLG_MAPS_T_SCROLL,TBM_SETRANGE,
00307 //                                (WPARAM)TRUE,(LPARAM)MAKELONG(0,100));
00308      for(i=0;i<100;i+=10){
00309        SendDlgItemMessage(hdlg,DLG_MAPS_S_SCROLL,TBM_SETTIC,0,(LPARAM)i);
00310        SendDlgItemMessage(hdlg,DLG_MAPS_R_SCROLL,TBM_SETTIC,0,(LPARAM)i);
00311        SendDlgItemMessage(hdlg,DLG_MAPS_B_SCROLL,TBM_SETTIC,0,(LPARAM)i);
00312 //       SendDlgItemMessage(hdlg,DLG_MAPS_T_SCROLL,TBM_SETTIC,0,(LPARAM)i);
00313      }
00314      for(i=0;i<360;i+=90)
00315        SendDlgItemMessage(hdlg,DLG_MAPS_C_SCROLL,TBM_SETTIC,0,(LPARAM)i);
00316      for(i=0;i<nImaps;i++){
00317        SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_ADDSTRING,0,
00318                                (LPARAM)iMap[i].N);
00319      }
00320      SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_SELECTSTRING,0,
00321                              (LPARAM)iMap[MapID].N);
00322      SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_LIMITTEXT,30,0);
00323 
00324      UpdateMappingDialog(hdlg,MapID);
00325      CentreDialogOnScreen(hdlg);
00326      return (TRUE);
00327    case WM_DESTROY:
00328      for(i=0;i<6;i++){  // the 7th and 8th are ICONs
00329        if(MapBtnBitmaps[i] != NULL){
00330          if(!DeleteObject(MapBtnBitmaps[i]))MessageBox(NULL,"Bad Delete",NULL,MB_OK);
00331          MapBtnBitmaps[i]=NULL;
00332        }
00333      }
00334      for(i=0;i<5;i++){  // the 6th is an ICON
00335        if(MapButtonBitmaps[i] != NULL){
00336          if(!DeleteObject(MapButtonBitmaps[i]))MessageBox(NULL,"Bad Delete",NULL,MB_OK);
00337          MapButtonBitmaps[i]=NULL;
00338        }
00339      }
00340      break;
00341    case WM_DRAWITEM:{
00342        HBRUSH   hbr,hbrold;
00343        BYTE r,g,b;
00344        lpdis=(LPDRAWITEMSTRUCT)lparam;
00345        if(lpdis->CtlID == DLG_MAPS_KEY_COLOUR){
00346          r=iMap[MapID].k_colour[0];
00347          g=iMap[MapID].k_colour[1];
00348          b=iMap[MapID].k_colour[2];
00349          if(lpdis->itemState & ODS_SELECTED)
00350            InvertRect(lpdis->hDC,&(lpdis->rcItem));
00351          else{
00352            hbr=CreateSolidBrush(RGB(r,g,b));
00353            hbrold=SelectObject(lpdis->hDC,hbr);
00354            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00355                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00356            SelectObject(lpdis->hDC,hbrold);
00357            DeleteObject(hbr);
00358          }
00359        }
00360      }
00361      return TRUE;
00362    case WM_HSCROLL:
00363      if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_MAPS_C_SCROLL))){
00364        iMin=SendMessage(hctl,TBM_GETRANGEMIN,0,0);
00365        iMax=SendMessage(hctl,TBM_GETRANGEMAX,0,0);
00366        switch (LOWORD(wparam)) {
00367          case TB_PAGEDOWN: iMap[MapID].Angle = min(iMax,iMap[MapID].Angle+45); break;
00368          case TB_LINEDOWN: iMap[MapID].Angle = min(iMax,iMap[MapID].Angle+1); break;
00369          case TB_PAGEUP:   iMap[MapID].Angle = max(iMin,iMap[MapID].Angle-45); break;
00370          case TB_LINEUP:   iMap[MapID].Angle = max(iMin,iMap[MapID].Angle-1); break;
00371          case TB_THUMBTRACK:
00372          case TB_THUMBPOSITION:
00373            iMap[MapID].Angle=HIWORD(wparam);  break;
00374          default: break;
00375        }
00376        UpdateTypeMappingSection(hdlg,MapID);
00377      }
00378      else if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_MAPS_S_SCROLL))){
00379        iMin=SendMessage(hctl,TBM_GETRANGEMIN,0,0);
00380        iMax=SendMessage(hctl,TBM_GETRANGEMAX,0,0);
00381        switch (LOWORD(wparam)) {
00382          case TB_PAGEDOWN: iMap[MapID].sp = min(iMax,iMap[MapID].sp+20); break;
00383          case TB_LINEDOWN: iMap[MapID].sp = min(iMax,iMap[MapID].sp+1); break;
00384          case TB_PAGEUP:   iMap[MapID].sp = max(iMin,iMap[MapID].sp-20); break;
00385          case TB_LINEUP:   iMap[MapID].sp = max(iMin,iMap[MapID].sp-1); break;
00386          case TB_THUMBTRACK:
00387          case TB_THUMBPOSITION:
00388            iMap[MapID].sp=HIWORD(wparam);  break;
00389          default: break;
00390        }
00391        UpdateSurfaceMappingSection(hdlg,MapID);
00392      }
00393      else if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_MAPS_R_SCROLL))){
00394        iMin=SendMessage(hctl,TBM_GETRANGEMIN,0,0);
00395        iMax=SendMessage(hctl,TBM_GETRANGEMAX,0,0);
00396        switch (LOWORD(wparam)) {
00397          case TB_PAGEDOWN: iMap[MapID].rp = min(iMax,iMap[MapID].rp+20); break;
00398          case TB_LINEDOWN: iMap[MapID].rp = min(iMax,iMap[MapID].rp+1); break;
00399          case TB_PAGEUP:   iMap[MapID].rp = max(iMin,iMap[MapID].rp-20); break;
00400          case TB_LINEUP:   iMap[MapID].rp = max(iMin,iMap[MapID].rp-1); break;
00401          case TB_THUMBTRACK:
00402          case TB_THUMBPOSITION:
00403            iMap[MapID].rp=HIWORD(wparam);  break;
00404          default: break;
00405        }
00406        UpdateReflectionMappingSection(hdlg,MapID);
00407      }
00408      else if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_MAPS_B_SCROLL))){
00409        iMin=SendMessage(hctl,TBM_GETRANGEMIN,0,0);
00410        iMax=SendMessage(hctl,TBM_GETRANGEMAX,0,0);
00411        switch (LOWORD(wparam)) {
00412          case TB_PAGEDOWN: iMap[MapID].bp = min(iMax,iMap[MapID].bp+20); break;
00413          case TB_LINEDOWN: iMap[MapID].bp = min(iMax,iMap[MapID].bp+1); break;
00414          case TB_PAGEUP:   iMap[MapID].bp = max(iMin,iMap[MapID].bp-20); break;
00415          case TB_LINEUP:   iMap[MapID].bp = max(iMin,iMap[MapID].bp-1); break;
00416          case TB_THUMBTRACK:
00417          case TB_THUMBPOSITION:
00418            iMap[MapID].bp=HIWORD(wparam);  break;
00419          default: break;
00420        }
00421        UpdateBumpMappingSection(hdlg,MapID);
00422      }
00423 //     renderer assummes this is 0 and if used must be changed there too
00424 //     else if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_MAPS_T_SCROLL))){
00425 //       iMin=SendMessage(hctl,TBM_GETRANGEMIN,0,0);
00426 //       iMax=SendMessage(hctl,TBM_GETRANGEMAX,0,0);
00427 //       switch (LOWORD(wparam)) {
00428 //         case TB_PAGEDOWN: iMap[MapID].tp = min(iMax,iMap[MapID].tp+20); break;
00429 //         case TB_LINEDOWN: iMap[MapID].tp = min(iMax,iMap[MapID].tp+1); break;
00430 //         case TB_PAGEUP:   iMap[MapID].tp = max(iMin,iMap[MapID].tp-20); break;
00431 //         case TB_LINEUP:   iMap[MapID].tp = max(iMin,iMap[MapID].tp-1); break;
00432 //         case TB_THUMBTRACK:
00433 //         case TB_THUMBPOSITION:
00434 //           iMap[MapID].tp=HIWORD(wparam);  break;
00435 //         default: break;
00436 //       }
00437 //       UpdateTransMappingSection(hdlg,MapID);
00438 //     }
00439      break;
00440    case WM_COMMAND:
00441      switch(HIWORD(wparam)){
00442        case CBN_EDITCHANGE:
00443          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,WM_GETTEXT,(WPARAM)30,
00444                             (LPARAM)iMap[MapID].N);
00445          if(strlen(iMap[MapID].N) == 0)strcpy(iMap[MapID].N,"$");
00446          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_DELETESTRING,
00447                                 (WPARAM)MapID,0);
00448          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_INSERTSTRING,
00449                                 (WPARAM)MapID,(LPARAM)iMap[MapID].N);
00450          break;
00451        case CBN_SELENDOK:
00452          i=(int)SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_GETCURSEL,0,0);
00453          if(i != CB_ERR){
00454            MapID=(long)i;
00455            LastUsedMapID=MapID; // save global
00456            UpdateMappingDialog(hdlg,MapID);
00457            SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_SELECTSTRING,0,
00458                            (LPARAM)iMap[MapID].N);
00459          }
00460          break;
00461        default:
00462          break;
00463      }
00464      switch(LOWORD(wparam)){
00465        case DLG_MAPS_MOVE:
00466          // if openGL then update the OpenGL maps
00467          UpdateOpenGLMapping();
00468          EndDialog(hdlg,MapID);
00469          return(TRUE);
00470        case DLG_MAPS_NEW:
00471          MapID=nImaps;
00472          LastUsedMapID=MapID; // save global
00473          CreateImageMap();
00474          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_ADDSTRING,0,
00475                                (LPARAM)iMap[MapID].N);
00476          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_SELECTSTRING,0,
00477                            (LPARAM)iMap[MapID].N);
00478          UpdateMappingDialog(hdlg,MapID);
00479          break;
00480        case DLG_MAPS_DELETE:
00481          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_DELETESTRING,
00482                                 (WPARAM)MapID,0);
00483          DeleteImageMap(MapID);
00484          // if openGL then update the OpenGL maps
00485          UpdateOpenGLMapping();
00486          if(nImaps == 0){
00487            EndDialog(hdlg,-1);
00488            return(TRUE);
00489          }
00490          if(MapID >= nImaps)MapID=nImaps-1;
00491          LastUsedMapID=MapID; // save global
00492          UpdateMappingDialog(hdlg,MapID);
00493          SendDlgItemMessage(hdlg,DLG_MAPS_LIST,CB_SELECTSTRING,0,
00494                            (LPARAM)iMap[MapID].N);
00495          break;
00496        case DLG_MAPS_G:
00497          //iMap[MapID].Map=MAP_BY_VERTEX; // DON'T allow this to be assigned ONLT for INFORMATION
00498          UpdateTypeMappingSection(hdlg,MapID);
00499          break;
00500        case DLG_MAPS_P:
00501          if(iMap[MapID].Map == CYLINDER_MOZIAC)iMap[MapID].Map=PLANE_MOZIAC;
00502          else iMap[MapID].Map=PLANE;
00503          UpdateTypeMappingSection(hdlg,MapID);
00504          break;
00505        case DLG_MAPS_C:
00506          if(iMap[MapID].Map == PLANE_MOZIAC)iMap[MapID].Map=CYLINDER_MOZIAC;
00507          else iMap[MapID].Map=CYLINDER;
00508          UpdateTypeMappingSection(hdlg,MapID);
00509          break;
00510        case DLG_MAPS_S:
00511          iMap[MapID].Map=MAP_SPHERICAL;
00512          UpdateTypeMappingSection(hdlg,MapID);
00513          break;
00514        case DLG_MAPS_PM:
00515          if(iMap[MapID].Map == PLANE_MOZIAC)iMap[MapID].Map=PLANE;
00516          if(iMap[MapID].Map == CYLINDER_MOZIAC)iMap[MapID].Map=CYLINDER;
00517          UpdateTypeMappingSection(hdlg,MapID);
00518          break;
00519        case DLG_MAPS_CM:
00520          if(iMap[MapID].Map == PLANE)iMap[MapID].Map=PLANE_MOZIAC;
00521          if(iMap[MapID].Map == CYLINDER)iMap[MapID].Map=CYLINDER_MOZIAC;
00522          UpdateTypeMappingSection(hdlg,MapID);
00523          break;
00524 //       case DLG_MAPS_KEY_INDEX:
00525 //         iMap[MapID].Key=0;
00526 //         UpdateTypeMappingSection(hdlg,MapID);
00527 //         break;
00528 //       case DLG_MAPS_KEY_CHOSEN:
00529 //         iMap[MapID].Key=1;
00530 //         UpdateTypeMappingSection(hdlg,MapID);
00531          break;
00532        case DLG_MAPS_KEY_COLOUR:
00533          SetSfxColour(iMap[MapID].k_colour,IDX_MISC_KEYCOLOUR,hdlg);
00534          InvalidateRect(GetDlgItem(hdlg,DLG_MAPS_KEY_COLOUR),NULL,FALSE);
00535          iMap[MapID].Key=1;
00536          break;
00537        case DLG_MAPS_S_ACTIVE:
00538          if(iMap[MapID].S == NULL)SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_SET,0);
00539          else                     SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_DROP,0);
00540          break;
00541        case DLG_MAPS_S_SET:
00542          bMapLoaded=FALSE;
00543          if(iMap[MapID].Type == ANIMBRUSH)
00544               iMap[MapID].S=GetFlicFromDisk(MapID,iMap[MapID].S,hdlg,0);
00545          else iMap[MapID].S=GetMapFromDisk(iMap[MapID].S,hdlg,&bMapLoaded);
00546          if(iMap[MapID].S == NULL)iMap[MapID].s=0;
00547          else {
00548            iMap[MapID].s=1;
00549            if(iMap[MapID].Type != ANIMBRUSH && bMapLoaded)
00550                LoadRamImage(&(iMap[MapID].si),iMap[MapID].S);
00551          }
00552          UpdateSurfaceMappingSection(hdlg,MapID);
00553          break;
00554        case DLG_MAPS_S_PRESET:
00555          if((iMap[MapID].S=GetPresetMap(iMap[MapID].S,hdlg)) == NULL)
00556               iMap[MapID].s=0;
00557          else iMap[MapID].s=1;
00558          UpdateSurfaceMappingSection(hdlg,MapID);
00559          break;
00560        case DLG_MAPS_S_DROP:
00561          UnloadRamImage(&(iMap[MapID].si));
00562          if(iMap[MapID].S != NULL)X__Free(iMap[MapID].S);
00563          iMap[MapID].S=NULL; iMap[MapID].s=0;
00564          UpdateSurfaceMappingSection(hdlg,MapID);
00565          break;
00566        case DLG_MAPS_S_VIEW:
00567          if(iMap[MapID].Type == ANIMBRUSH)PlayMoviePreview(iMap[MapID].S);
00568          else if(iMap[MapID].S != NULL)
00569            DisplayImageFromStore(&(iMap[MapID].si),iMap[MapID].S);
00570          break;
00571        case DLG_MAPS_S_MODIFY:
00572          if(iMap[MapID].S != NULL)EditImageFile(iMap[MapID].S);
00573          break;
00574        case DLG_MAPS_S_ANIMATED:
00575        case DLG_MAPS_S_STILL:
00576          if(iMap[MapID].Type == ANIMBRUSH){
00577            iMap[MapID].Type=STATICBRUSH;
00578            if(iMap[MapID].S != NULL){
00579               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_DROP,0);
00580               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_SET,0);
00581            }
00582            else UpdateSurfaceMappingSection(hdlg,MapID);
00583          }
00584          else if(iMap[MapID].Type != ANIMBRUSH){
00585            iMap[MapID].Type=ANIMBRUSH;
00586            if(iMap[MapID].S != NULL){
00587              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_DROP,0);
00588              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_S_SET,0);
00589            }
00590            else UpdateSurfaceMappingSection(hdlg,MapID);
00591          }
00592          break;
00593        case DLG_MAPS_R_ACTIVE:
00594          if(iMap[MapID].R == NULL)SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_SET,0);
00595          else                     SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_DROP,0);
00596          break;
00597        case DLG_MAPS_R_SET:
00598          bMapLoaded=FALSE;
00599          if(iMap[MapID].TypeR == ANIMBRUSH)
00600               iMap[MapID].R=GetFlicFromDisk(MapID,iMap[MapID].R,hdlg,1);
00601          else iMap[MapID].R=GetMapFromDisk(iMap[MapID].R,hdlg,&bMapLoaded);
00602          if(iMap[MapID].R == NULL)iMap[MapID].r=0;
00603          else{
00604            iMap[MapID].r=1;
00605            if(iMap[MapID].TypeR != ANIMBRUSH && bMapLoaded)
00606                LoadRamImage(&(iMap[MapID].ri),iMap[MapID].R);
00607          }
00608          UpdateReflectionMappingSection(hdlg,MapID);
00609          break;
00610        case DLG_MAPS_R_DROP:
00611          UnloadRamImage(&(iMap[MapID].ri));
00612          if(iMap[MapID].R != NULL)X__Free(iMap[MapID].R);
00613          iMap[MapID].R=NULL; iMap[MapID].r=0;
00614          UpdateReflectionMappingSection(hdlg,MapID);
00615          break;
00616        case DLG_MAPS_R_VIEW:
00617          if(iMap[MapID].Type == ANIMBRUSH)PlayMoviePreview(iMap[MapID].R);
00618          else if(iMap[MapID].R != NULL)
00619            DisplayImageFromStore(&(iMap[MapID].ri),iMap[MapID].R);
00620          break;
00621        case DLG_MAPS_R_MODIFY:
00622          if(iMap[MapID].R != NULL)EditImageFile(iMap[MapID].R);
00623          break;
00624        case DLG_MAPS_R_STILL:
00625        case DLG_MAPS_R_ANIMATED:
00626          if(iMap[MapID].TypeR == ANIMBRUSH){
00627            iMap[MapID].TypeR=STATICBRUSH;
00628            if(iMap[MapID].R != NULL){
00629               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_DROP,0);
00630               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_SET,0);
00631            }
00632            else UpdateReflectionMappingSection(hdlg,MapID);
00633          }
00634          else if(iMap[MapID].TypeR != ANIMBRUSH){
00635            iMap[MapID].TypeR=ANIMBRUSH;
00636            if(iMap[MapID].R != NULL){
00637              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_DROP,0);
00638              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_R_SET,0);
00639            }
00640            else UpdateReflectionMappingSection(hdlg,MapID);
00641          }
00642          break;
00643        case DLG_MAPS_B_ACTIVE:
00644          if(iMap[MapID].B == NULL)SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_SET,0);
00645          else                     SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_DROP,0);
00646          break;
00647        case DLG_MAPS_B_SET:
00648          bMapLoaded=FALSE;
00649          if(iMap[MapID].TypeB == ANIMBRUSH)
00650               iMap[MapID].B=GetFlicFromDisk(MapID,iMap[MapID].B,hdlg,2);
00651          else iMap[MapID].B=GetMapFromDisk(iMap[MapID].B,hdlg,&bMapLoaded);
00652          if(iMap[MapID].B == NULL)iMap[MapID].b=0;
00653          else{
00654            iMap[MapID].b=1;
00655            if(iMap[MapID].TypeB != ANIMBRUSH && bMapLoaded)
00656                LoadRamImage(&(iMap[MapID].bi),iMap[MapID].B);
00657          }
00658          UpdateBumpMappingSection(hdlg,MapID);
00659          break;
00660        case DLG_MAPS_B_DROP:
00661          UnloadRamImage(&(iMap[MapID].bi));
00662          if(iMap[MapID].B != NULL)X__Free(iMap[MapID].B);
00663          iMap[MapID].B=NULL; iMap[MapID].b=0;
00664          UpdateBumpMappingSection(hdlg,MapID);
00665          break;
00666        case DLG_MAPS_B_VIEW:
00667          if(iMap[MapID].Type == ANIMBRUSH)PlayMoviePreview(iMap[MapID].B);
00668          else if(iMap[MapID].B != NULL)
00669            DisplayImageFromStore(&(iMap[MapID].bi),iMap[MapID].B);
00670          break;
00671        case DLG_MAPS_B_MODIFY:
00672          if(iMap[MapID].B != NULL)EditImageFile(iMap[MapID].B);
00673          break;
00674        case DLG_MAPS_B_ANIMATED:
00675        case DLG_MAPS_B_STILL:
00676          if(iMap[MapID].TypeB == ANIMBRUSH){
00677            iMap[MapID].TypeB=STATICBRUSH;
00678            if(iMap[MapID].B != NULL){
00679               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_DROP,0);
00680               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_SET,0);
00681            }
00682            else UpdateBumpMappingSection(hdlg,MapID);
00683          }
00684          else if(iMap[MapID].TypeB != ANIMBRUSH){
00685            iMap[MapID].TypeB=ANIMBRUSH;
00686            if(iMap[MapID].B != NULL){
00687              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_DROP,0);
00688              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_B_SET,0);
00689            }
00690            else UpdateBumpMappingSection(hdlg,MapID);
00691          }
00692          break;
00693        case DLG_MAPS_T_ACTIVE:
00694          if(iMap[MapID].T == NULL)SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_SET,0);
00695          else                     SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_DROP,0);
00696          break;
00697        case DLG_MAPS_T_SET:
00698          bMapLoaded=FALSE;
00699          if(iMap[MapID].TypeT == ANIMBRUSH)
00700               iMap[MapID].T=GetFlicFromDisk(MapID,iMap[MapID].T,hdlg,3);
00701          else iMap[MapID].T=GetMapFromDisk(iMap[MapID].T,hdlg,&bMapLoaded);
00702          if(iMap[MapID].T == NULL)iMap[MapID].t=0;
00703          else{
00704            iMap[MapID].t=1;
00705            if(iMap[MapID].TypeT != ANIMBRUSH && bMapLoaded)
00706                LoadRamImage(&(iMap[MapID].ti),iMap[MapID].T);
00707          }
00708          UpdateTransMappingSection(hdlg,MapID);
00709          break;
00710        case DLG_MAPS_T_DROP:
00711          UnloadRamImage(&(iMap[MapID].ti));
00712          if(iMap[MapID].T != NULL)X__Free(iMap[MapID].T);
00713          iMap[MapID].T=NULL; iMap[MapID].t=0;
00714          UpdateTransMappingSection(hdlg,MapID);
00715          break;
00716        case DLG_MAPS_T_VIEW:
00717          if(iMap[MapID].Type == ANIMBRUSH)PlayMoviePreview(iMap[MapID].T);
00718          else if(iMap[MapID].T != NULL)
00719            DisplayImageFromStore(&(iMap[MapID].ti),iMap[MapID].T);
00720          break;
00721        case DLG_MAPS_T_MODIFY:
00722          if(iMap[MapID].T != NULL)EditImageFile(iMap[MapID].T);
00723          break;
00724        case DLG_MAPS_T_ANIMATED:
00725        case DLG_MAPS_T_STILL:
00726          if(iMap[MapID].TypeT == ANIMBRUSH){
00727            iMap[MapID].TypeT=STATICBRUSH;
00728            if(iMap[MapID].T != NULL){
00729               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_DROP,0);
00730               SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_SET,0);
00731            }
00732            else UpdateTransMappingSection(hdlg,MapID);
00733          }
00734          else if(iMap[MapID].TypeT != ANIMBRUSH){
00735            iMap[MapID].TypeT=ANIMBRUSH;
00736            if(iMap[MapID].T != NULL){
00737              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_DROP,0);
00738              SendMessage(hdlg,WM_COMMAND,DLG_MAPS_T_SET,0);
00739            }
00740            else UpdateTransMappingSection(hdlg,MapID);
00741          }
00742          break;
00743        case DLG_ATTRIBS_MAP_SINGLE:
00744          iMap[MapID].bTiled=FALSE;
00745          UpdateSurfaceTypeMapping(hdlg,MapID);
00746          break;
00747        case DLG_ATTRIBS_MAP_TILE:
00748          iMap[MapID].bTiled=TRUE;
00749          UpdateSurfaceTypeMapping(hdlg,MapID);
00750          break;
00751        case DLG_ATTRIBS_MAP_SHADED:
00752          iMap[MapID].bShaded=TRUE;
00753          UpdateSurfaceTypeMapping(hdlg,MapID);
00754          break;
00755        case DLG_ATTRIBS_MAP_UNSHADED:
00756          iMap[MapID].bShaded=FALSE;
00757          UpdateSurfaceTypeMapping(hdlg,MapID);
00758          break;
00759        case DLG_ATTRIBS_MAP_OPAQUE:
00760          iMap[MapID].bDecal=FALSE;
00761          UpdateSurfaceTypeMapping(hdlg,MapID);
00762          break;
00763        case DLG_ATTRIBS_MAP_CLEAR:
00764          iMap[MapID].bDecal=TRUE;
00765          UpdateSurfaceTypeMapping(hdlg,MapID);
00766          break;
00767        case DLG_MAPS_EMBED:
00768          EmbedMapsForMap(MapID);
00769          break;
00770        case DLG_MAPS_EXTRACT_EMBED:
00771          SaveRamImagesToFiles(MapID);
00772          UnloadRamImagesFromMap(MapID);
00773          break;
00774        case DLG_MAPS_APPLY_ALL:
00775        case DLG_MAPS_APPLY_SELECTED:{
00776           int mapt,type; 
00777           mapt=iMap[MapID].Map;
00778           if     (mapt == PLANE)type=0;
00779           else if(mapt == CYLINDER)type=1;         
00780           else if(mapt == PLANE_MOZIAC)type=0;
00781           else if(mapt == CYLINDER_MOZIAC)type=1;
00782           else if(mapt == MAP_SPHERICAL)type=2;
00783           if(type >= 0){
00784             if(LOWORD(wparam) == DLG_MAPS_APPLY_ALL){
00785               if(MessageBox(hdlg,"Apply to All Faces with This Map","Are you sure?",MB_YESNO) == IDYES)
00786                 MapFacesByImageMap(MapID,type,TRUE);
00787             }
00788             else {
00789               MapVerticesByImageMap(MapID,type); 
00790               MapFacesByImageMap(MapID,type,FALSE);
00791             }
00792           }
00793           UpdateOpenGLMapping();
00794          }
00795          break;
00796        case DLG_MAPS_REMOVE_COORDS:
00797          RemoveMappingCoords(FALSE);
00798          UpdateOpenGLMapping();
00799          break;
00800        case DLG_MAPS_PREVIEW:
00801          SendMessage(ghwnd_main,WM_COMMAND,(WPARAM)IDM_VIEW_RENDERINWINDOW,0);
00802          break;
00803        case IDCANCEL:
00804        case DLG_MAPS_DONE:
00805          // if openGL then update the OpenGL maps
00806          UpdateOpenGLMapping();
00807          EndDialog(hdlg,-1);
00808          return(TRUE);
00809        default:
00810          break;
00811      }
00812      break;
00813    default: break;
00814  }
00815  return(FALSE);
00816 }
00817 // End Mapping Dialog
00818 
00819 static void EditImageFile(char *pathname){
00820  char appname[256];
00821  GetPrivateProfileString("APREFERENCES","EDITAPP","$$$",
00822                          appname,sizeof(appname),IniFilename);
00823  if(strncmp(appname,"$$$",3) != 0){
00824    ShellExecute(ghwnd_main,NULL,appname,
00825                 pathname,appname,SW_SHOW);
00826  }
00827  return;
00828 }
00829 
00830 static void PlayMoviePreview(char *pathname){
00831  LoadUtility("ofxmediaplayer.exe",NULL,-1,pathname);
00832 
00833  return;
00834 }
00835 
00836 void EditImageMap(int id){
00837  int id1;
00838  if(id < 0){
00839   if(id == -2){ // create a new map;
00840     id1=nImaps;
00841     if(CreateImageMap() == FAIL)return;
00842 
00843   }
00844   else{
00845     id1=LastUsedMapID;
00846     if(id1 >= nImaps)id1=0;
00847     if(id1 == nImaps){
00848       if(CreateImageMap() == FAIL)return;
00849     }
00850   }
00851   id=id1;
00852  }
00853  EnableToolPannels(SELECT_PANNEL|COMMAND_PANNEL|TOOL_PANNEL|
00854                    ACTION_PANNEL|COORD_PANNEL|LOCK_PANNEL,FALSE);
00855  ActivateAllMenus(ghwnd_main,MF_GRAYED);
00856  id1=(int)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_MAPS),ghwnd_main,
00857             (DLGPROC)MappingDlgProc,(LPARAM)id);
00858  ActivateAllMenus(ghwnd_main,MF_ENABLED);
00859  EnableToolPannels(SELECT_PANNEL|COMMAND_PANNEL|TOOL_PANNEL|
00860                    ACTION_PANNEL|COORD_PANNEL|LOCK_PANNEL,TRUE);
00861  if(id1 >= 0){
00862    axis_move_flag=id1;
00863    PositionBrushOnOff(1,id1);
00864  }
00865  else if(image_edit_flag == 1) /* go back to the faces dialog */
00866    PostMessage(ghwnd_main,WM_COMMAND,IDM_ATTRIBUTES_FACE,0);
00867 }
00868 
00869 int RequestMapID(HWND parent,char *message,int new){
00870  int i,id;
00871  long N,N1;
00872  char **ItemList,newname[32]="< new >";
00873  N=nImaps;
00874  if(new)N1=N+1; else N1=N;
00875  if((ItemList = (char **)X__Malloc(N1*sizeof(char *))) == NULL){
00876    SendPrgmQuery(IDQ_NOMEM2,0);
00877    return -1;
00878  }
00879  for(i=0;i<N;i++)ItemList[i] = iMap[i].N;
00880  if(new)ItemList[N] = newname;
00881  id=SelectScrolledItemList(N1,ItemList,message,parent);
00882  X__Free(ItemList);
00883  return id;
00884 }
00885 
00886 int CreateImageMap(void){
00887   long i;
00888   EDIT_ACTION=YES;
00889   if(nImaps >= NMAPSMAX)return FAIL;
00890   iMap[nImaps].version=1;
00891   iMap[nImaps].Key=1;
00892   iMap[nImaps].s=0;    iMap[nImaps].r=0;    iMap[nImaps].b=0;     iMap[nImaps].t=0;
00893   iMap[nImaps].S=NULL; iMap[nImaps].R=NULL; iMap[nImaps].B=NULL;  iMap[nImaps].T=NULL;
00894   iMap[nImaps].sp=100; iMap[nImaps].rp=50;  iMap[nImaps].bp=50;   iMap[nImaps].tp=0;
00895   InitialiseRamImage(&(iMap[nImaps].si));
00896   InitialiseRamImage(&(iMap[nImaps].ri));
00897   InitialiseRamImage(&(iMap[nImaps].bi));
00898   InitialiseRamImage(&(iMap[nImaps].ti));
00899   for(i=0;i<3;i++){
00900     iMap[nImaps].d_colour[i]=0;
00901     iMap[nImaps].s_colour[i]=0;
00902     iMap[nImaps].a_colour[i]=0;
00903     iMap[nImaps].t_colour[i]=0;
00904     iMap[nImaps].k_colour[i]=0;
00905   }
00906   sprintf(iMap[nImaps].N,"Map%ld",nImaps+1);
00907   if(ActiveView == TRITOP){
00908     iMap[nImaps].P[0] = TVpointX + TVsizeX/10;
00909     iMap[nImaps].P[1] = TVpointY + TVsizeY-TVsizeY/10;
00910     iMap[nImaps].P[2] = TVpointZ + TVsizeZ/2;
00911     iMap[nImaps].X[0] = TVpointX + TVsizeX-TVsizeX/10;
00912     iMap[nImaps].X[1] = TVpointY + TVsizeY-TVsizeY/10;
00913     iMap[nImaps].X[2] = TVpointZ + TVsizeZ/2;
00914     iMap[nImaps].Y[0] = TVpointX + TVsizeX/10;
00915     iMap[nImaps].Y[1] = TVpointY + TVsizeY/10;
00916     iMap[nImaps].Y[2] = TVpointZ + TVsizeZ/2;
00917   }
00918   else if(ActiveView == TRIRIGHT){
00919     iMap[nImaps].P[0] = TVpointX + TVsizeX/2;
00920     iMap[nImaps].P[1] = TVpointY + TVsizeY/10;
00921     iMap[nImaps].P[2] = TVpointZ + TVsizeZ - TVsizeZ/10;
00922     iMap[nImaps].X[0] = TVpointX + TVsizeX/2;
00923     iMap[nImaps].X[1] = TVpointY + TVsizeY - TVsizeY/10;
00924     iMap[nImaps].X[2] = TVpointZ + TVsizeZ - TVsizeZ/10;
00925     iMap[nImaps].Y[0] = TVpointX + TVsizeX/2;
00926     iMap[nImaps].Y[1] = TVpointY + TVsizeY/10;
00927     iMap[nImaps].Y[2] = TVpointZ + TVsizeZ/10;
00928   }
00929   else{
00930     iMap[nImaps].P[0] = TVpointX + TVsizeX/10;
00931     iMap[nImaps].P[1] = TVpointY + TVsizeY/2;
00932     iMap[nImaps].P[2] = TVpointZ + TVsizeZ - TVsizeZ/10;
00933     iMap[nImaps].X[0] = TVpointX + TVsizeX - TVsizeX/10;
00934     iMap[nImaps].X[1] = TVpointY + TVsizeY/2;
00935     iMap[nImaps].X[2] = TVpointZ + TVsizeZ - TVsizeZ/10;
00936     iMap[nImaps].Y[0] = TVpointX + TVsizeX/10;
00937     iMap[nImaps].Y[1] = TVpointY + TVsizeY/2;
00938     iMap[nImaps].Y[2] = TVpointZ + TVsizeZ/10;
00939   }
00940   iMap[nImaps].Type = STATICBRUSH;    /* Still Anim */
00941   iMap[nImaps].Angle  = 360;          /* full rotation if required */
00942   iMap[nImaps].TypeR = STATICBRUSH;
00943   iMap[nImaps].TypeB = STATICBRUSH;
00944   iMap[nImaps].TypeT = STATICBRUSH;
00945   iMap[nImaps].Lock = 0;         /* not locked */
00946   iMap[nImaps].Vlock[0] = -1;    /* lock P */
00947   iMap[nImaps].Vlock[1] = -1;    /* lock X */
00948   iMap[nImaps].Vlock[2] = -1;    /* lock Y */
00949   iMap[nImaps].Map=PLANE;        /* planar brush map */
00950   iMap[nImaps].bTiled=TRUE;
00951   iMap[nImaps].bShaded=TRUE;
00952   iMap[nImaps].bDecal=FALSE;
00953 
00954   iMap[nImaps].AnimFF = 1;
00955   iMap[nImaps].AnimDL = 1;
00956   iMap[nImaps].AnimLF = 1;
00957   iMap[nImaps].AnimFFr = 1;
00958   iMap[nImaps].AnimDLr = 1;
00959   iMap[nImaps].AnimLFr = 1;
00960   iMap[nImaps].AnimFFb = 1;
00961   iMap[nImaps].AnimDLb = 1;
00962   iMap[nImaps].AnimLFb = 1;
00963   iMap[nImaps].AnimFFt = 1;
00964   iMap[nImaps].AnimDLt = 1;
00965   iMap[nImaps].AnimLFt = 1;
00966   nImaps++;
00967   return OK;
00968 }
00969 
00970 void DeleteImageMap(int idd){
00971   int bid,id,i,j;
00972   face *f;
00973   if(nImaps == 0){
00974    SendPrgmQuery(IDQ_NOBRUSH,0);
00975     return;
00976   }
00977   if(idd < 0)id=RequestMapID(ghwnd_main,"Choose Map to delete",0);
00978   else id=idd;
00979   if(id < 0 )return;
00980   EDIT_ACTION=YES;
00981   if((f=MainFp) != NULL && Nface > 0)for(i=0;i<Nface;i++){
00982     bid=f->imagemap;                      /* extract map id    */
00983     if(bid == id){
00984       f->imagemap= -1;             /* no more maps this face    */
00985     }                        /* zero bit 6 leave others   */
00986     else if(bid > id){       /* slide all the map id's down one */
00987       bid--;
00988       f->imagemap = bid;
00989     }
00990     f++;
00991   }
00992   if(iMap[id].Lock)nLockediMaps--;
00993   if(iMap[id].s && iMap[id].S != NULL)X__Free(iMap[id].S);
00994   if(iMap[id].r && iMap[id].R != NULL)X__Free(iMap[id].R);
00995   if(iMap[id].b && iMap[id].B != NULL)X__Free(iMap[id].B);
00996   if(iMap[id].t && iMap[id].T != NULL)X__Free(iMap[id].T);
00997   UnloadRamImage(&(iMap[id].si));
00998   UnloadRamImage(&(iMap[id].ri));
00999   UnloadRamImage(&(iMap[id].bi));
01000   UnloadRamImage(&(iMap[id].ti));
01001   if(id < nImaps-1)for(i=id;i<nImaps-1;i++){
01002     memcpy(&(iMap[i]),&(iMap[i+1]), sizeof(IMAGEMAP));
01003 #if 0
01004     strcpy(iMap[i].N,iMap[i+1].N);
01005     for(j=0;j<3;j++){
01006       iMap[i].P[j] = iMap[i+1].P[j];
01007       iMap[i].X[j] = iMap[i+1].X[j];
01008       iMap[i].Y[j] = iMap[i+1].Y[j];
01009       iMap[i].d_colour[j]=iMap[i+1].d_colour[j];
01010       iMap[i].s_colour[j]=iMap[i+1].s_colour[j];
01011       iMap[i].a_colour[j]=iMap[i+1].a_colour[j];
01012       iMap[i].k_colour[j]=iMap[i+1].k_colour[j];
01013     }
01014     iMap[i].Type = iMap[i+1].Type;
01015     iMap[i].AnimFF = iMap[i+1].AnimFF;
01016     iMap[i].AnimDL = iMap[i+1].AnimDL;
01017     iMap[i].AnimLF = iMap[i+1].AnimLF;
01018     iMap[i].TypeR = iMap[i+1].TypeR;
01019     iMap[i].AnimFFr = iMap[i+1].AnimFFr;
01020     iMap[i].AnimDLr = iMap[i+1].AnimDLr;
01021     iMap[i].AnimLFr = iMap[i+1].AnimLFr;
01022     iMap[i].TypeB = iMap[i+1].TypeR;
01023     iMap[i].AnimFFb = iMap[i+1].AnimFFr;
01024     iMap[i].AnimDLb = iMap[i+1].AnimDLr;
01025     iMap[i].AnimLFb = iMap[i+1].AnimLFr;
01026     iMap[i].TypeT = iMap[i+1].TypeT;
01027     iMap[i].AnimFFt = iMap[i+1].AnimFFt;
01028     iMap[i].AnimDLt = iMap[i+1].AnimDLt;
01029     iMap[i].AnimLFt = iMap[i+1].AnimLFt;
01030     iMap[i].Angle  = iMap[i+1].Angle;
01031     iMap[i].Map=iMap[i+1].Map;
01032     iMap[i].Lock=iMap[i+1].Lock;
01033     iMap[i].Key=iMap[i+1].Key;
01034     iMap[i].Vlock[0]=iMap[i+1].Vlock[0];
01035     iMap[i].Vlock[1]=iMap[i+1].Vlock[1];
01036     iMap[i].Vlock[2]=iMap[i+1].Vlock[2];
01037     iMap[i].s=iMap[i+1].s;
01038     iMap[i].r=iMap[i+1].r;
01039     iMap[i].b=iMap[i+1].b;
01040     iMap[i].t=iMap[i+1].t;
01041     iMap[i].S=iMap[i+1].S;
01042     iMap[i].R=iMap[i+1].R;
01043     iMap[i].B=iMap[i+1].B;
01044     iMap[i].T=iMap[i+1].T;
01045     iMap[i].si.in_use  =iMap[i+1].si.in_use;
01046     iMap[i].si.size    =iMap[i+1].si.size;
01047     iMap[i].si.filename=iMap[i+1].si.filename;
01048     iMap[i].si.data    =iMap[i+1].si.data;
01049 
01050     iMap[i].ri.in_use  =iMap[i+1].ri.in_use;
01051     iMap[i].ri.size    =iMap[i+1].ri.size;
01052     iMap[i].ri.filename=iMap[i+1].ri.filename;
01053     iMap[i].ri.data    =iMap[i+1].ri.data;
01054 
01055     iMap[i].bi.in_use  =iMap[i+1].bi.in_use;
01056     iMap[i].bi.size    =iMap[i+1].bi.size;
01057     iMap[i].bi.filename=iMap[i+1].bi.filename;
01058     iMap[i].bi.data    =iMap[i+1].bi.data;
01059 
01060     iMap[i].ti.in_use  =iMap[i+1].ti.in_use;
01061     iMap[i].ti.size    =iMap[i+1].ti.size;
01062     iMap[i].ti.filename=iMap[i+1].ti.filename;
01063     iMap[i].ti.data    =iMap[i+1].ti.data;
01064 
01065     iMap[i].sp=iMap[i+1].sp;
01066     iMap[i].rp=iMap[i+1].rp;
01067     iMap[i].bp=iMap[i+1].bp;
01068     iMap[i].tp=iMap[i+1].tp;
01069     iMap[i].bShaded=iMap[i+1].bShaded;
01070     iMap[i].bTiled=iMap[i+1].bTiled;
01071     iMap[i].bDecal=iMap[i+1].bDecal;
01072 #endif
01073   }
01074   iMap[nImaps-1].S=NULL; iMap[nImaps-1].s=0; iMap[nImaps-1].si.in_use=0;
01075   iMap[nImaps-1].R=NULL; iMap[nImaps-1].r=0; iMap[nImaps-1].ri.in_use=0;
01076   iMap[nImaps-1].B=NULL; iMap[nImaps-1].b=0; iMap[nImaps-1].ri.in_use=0;
01077   iMap[nImaps-1].T=NULL; iMap[nImaps-1].t=0; iMap[nImaps-1].ri.in_use=0;
01078   /* Fixup the identity of the last used brush */
01079   nImaps--;
01080   return;
01081 }
01082 
01083 void PurgeUnusedMaps(void){ /* remove any maps not in use by any face */
01084  int i,j,bid;
01085  BOOL found;
01086  face *f;
01087  LOOP:
01088  if(nImaps < 1)return;
01089  for(j=0;j<nImaps;j++){
01090    found=FALSE;
01091    if((f=MainFp) != NULL && Nface > 0)for(i=0;i<Nface;i++){
01092      bid=(int)(f->imagemap);
01093      if(bid == j)found=TRUE;
01094      f++;
01095    }
01096    if(!found){     /* map not needed so scrap it      */
01097      DeleteImageMap(j);
01098      goto LOOP;    /* go back until all maps are done */
01099    }
01100  }
01101  // if openGL then update the OpenGL maps
01102  if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+4),0,0);
01103 }
01104 
01105 void PurgeDuplicateMaps(long startat){
01106  long i,j,k;
01107  face *f;
01108  startagain:
01109  if(nImaps < 2)return;
01110  if(startat >= nImaps)return;
01111  for(i=0;i<startat;i++){
01112   for(j=startat;j<nImaps;j++){
01113     if(stricmp(iMap[i].N,iMap[j].N) == 0){
01114       if((f=MainFp) != NULL && Nface > 0){
01115         for(k=0;k<Nface;k++,f++){  // reassign imagemap
01116           if((f->imagemap) == j)f->imagemap=i;
01117         }
01118       }  
01119       //{char ttt[256]; sprintf(ttt,"MAP %ld is same as %ld [%s] deleting %ld",j,i,iMap[i].N,j);
01120       // MessageBox(NULL,ttt,"Purging Image Maps",MB_OK);}
01121       DeleteImageMap(j);
01122       goto startagain;
01123     }
01124   }
01125  }
01126 }
01127 
01128 void VectorMaps(void){
01129  char temp[MAX_FILE],new_dir[MAX_DIR],text_string[128];
01130  PSTR c,p;
01131  int j,l;
01132  if(nImaps < 1)return;
01133  strcpy(temp,"temp.txt"); strcpy(new_dir,gszHomeDir);
01134  LoadString(ghinst_main,IDX_MISC_NEWMAPFOLDER,text_string,sizeof(text_string));
01135  if(SelectDirectoryName(temp,new_dir,text_string,"(*.txt)|*.txt|",ghwnd_main) == FALSE)return;
01136  if(strlen(new_dir) == 2)strcat(new_dir,"\\");
01137 
01138  //strcpy(new_dir,gszHomeDir);strcat(new_dir,"maps\\");
01139  //if(!RequestCharString(64,new_dir,"Root directory",ghwnd_main))return;
01140  //MessageBox(NULL,new_dir,"New Path",MB_OK);
01141  if((j=strlen(new_dir)) < 3){
01142    return;
01143  }
01144  if(new_dir[j-1] != '\\')strcat(new_dir,"\\");
01145  for(j=0;j<nImaps;j++){
01146   if(iMap[j].S != NULL && iMap[j].s == 1){
01147     if((c=FileInPath(iMap[j].S)) != NULL){
01148       strcpy(temp,new_dir); strcat(temp,c); l=strlen(temp); p=(char *)X__Malloc(l+1);     
01149       if(p != NULL){strcpy(p,temp); X__Free(iMap[j].S); iMap[j].S=p;}
01150     }
01151   }
01152   if(iMap[j].R != NULL && iMap[j].r == 1){
01153     if((c=FileInPath(iMap[j].R)) != NULL){
01154       strcpy(temp,new_dir); strcat(temp,c); l=strlen(temp); p=(char *)X__Malloc(l+1);     
01155       if(p != NULL){strcpy(p,temp); X__Free(iMap[j].R); iMap[j].R=p;}
01156     }
01157   }
01158   if(iMap[j].B != NULL && iMap[j].b == 1){
01159     if((c=FileInPath(iMap[j].B)) != NULL){
01160       strcpy(temp,new_dir); strcat(temp,c); l=strlen(temp); p=(char *)X__Malloc(l+1);     
01161       if(p != NULL){strcpy(p,temp); X__Free(iMap[j].B); iMap[j].B=p;}
01162     }
01163   }
01164   if(iMap[j].T != NULL && iMap[j].t == 1){
01165     if((c=FileInPath(iMap[j].T)) != NULL){
01166       strcpy(temp,new_dir); strcat(temp,c); l=strlen(temp); p=(char *)X__Malloc(l+1);     
01167       if(p != NULL){strcpy(p,temp); X__Free(iMap[j].T); iMap[j].T=p;}
01168     }
01169   }
01170  }
01171 }
01172 
01173 void DrawBrushInOne(HDC hDC,int view,int j){
01174  HRGN hRgn;
01175  POINT ptp[14];
01176  HPEN holdPen;
01177  HBRUSH holdBrush;
01178  int  oldROP;
01179  int i,k,N=12,map=0;
01180  int sho,svo,shx,svx,shy,svy,sht,svt;
01181  vector n,xp,py,p,q,pp;
01182  double d,r,nn,dtheta,theta,cs,ss;
01183  long x,y,z;
01184  if(iMap[j].Map == CYLINDER ||
01185     iMap[j].Map == MAP_SPHERICAL ||
01186     iMap[j].Map == CYLINDER_MOZIAC)map=1;
01187  if(map){
01188    if(View != TRIVIEW)N *= 2;
01189    VECSUB((double)iMap[j].X,(double)iMap[j].P,xp)
01190    VECSUB((double)iMap[j].P,(double)iMap[j].Y,py)
01191    nn=DOT(py,py);
01192    if(nn > 1.0){
01193      nn=DOT(xp,py)/nn;
01194      VECSUB((double)iMap[j].X,nn*py,p)
01195      VECSUB(p,(double)iMap[j].P,xp)
01196      CROSS(py,xp,n);
01197      nn=(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
01198      if(nn > 1.0){
01199        VECCOPY(iMap[j].P,p)
01200        VECCOPY(iMap[j].Y,pp)
01201        r=sqrt(xp[0]*xp[0]+xp[1]*xp[1]+xp[2]*xp[2]);
01202        nn=r/sqrt(nn);
01203        VECSCALE(nn,n,n)
01204        dtheta=iMap[j].Angle/180.0*PI/(double)N;
01205      }
01206      else map=0;
01207    }
01208    else map=0;
01209  }
01210  holdPen=SelectObject(hDC,ghInvertPen);
01211  holdBrush=SelectObject(hDC,GetStockObject(HOLLOW_BRUSH));
01212  oldROP=SetROP2(hDC,R2_XORPEN);
01213  SelectPalette(hDC,ghpaletteScreen,FALSE);
01214  RealizePalette(hDC);
01215  GetWindowCoords(view,iMap[j].P[0],iMap[j].P[1],iMap[j].P[2],&sho,&svo);
01216  GetWindowCoords(view,iMap[j].X[0],iMap[j].X[1],iMap[j].X[2],&shx,&svx);
01217  GetWindowCoords(view,iMap[j].Y[0],iMap[j].Y[1],iMap[j].Y[2],&shy,&svy);
01218  GetWindowCoords(view,
01219                       iMap[j].Y[0]+(iMap[j].X[0]-iMap[j].P[0]),
01220                       iMap[j].Y[1]+(iMap[j].X[1]-iMap[j].P[1]),
01221                       iMap[j].Y[2]+(iMap[j].X[2]-iMap[j].P[2]),&sht,&svt);
01222  Rectangle(hDC,sho-5,svo-5,sho+5,svo+5);
01223  Rectangle(hDC,shx-2,svx-2,shx+2,svx+2);
01224  MoveToEx(hDC,shy-6,svy-3,NULL); LineTo(hDC,shy+5,svy-3);
01225  MoveToEx(hDC,shy+6,svy-3,NULL); LineTo(hDC,shy,svy+5);
01226  MoveToEx(hDC,shy-1,svy+4,NULL); LineTo(hDC,shy-6,svy-2);
01227  if(map){  /* cylindrical mapping */
01228    MoveToEx(hDC,sho,svo,NULL); //_setcolor(COLOUR05);
01229    LineTo(hDC,shx,svx);       // _setcolor(COLOUR14); 14=invert
01230    MoveToEx(hDC,shy,svy,NULL); LineTo(hDC,sho,svo);
01231    theta=0;
01232    for(k=0;k<=N;k++){
01233      cs=cos(theta); ss=sin(theta);
01234      VECSUM(cs*xp,ss*n,q)
01235      x=(long)(p[0]+q[0]); y=(long)(p[1]+q[1]); z=(long)(p[2]+q[2]);
01236      if(k > 0)MoveToEx(hDC,shy,svy,NULL);
01237      GetWindowCoords(view,x,y,z,&shy,&svy);
01238      if(k > 0)LineTo(hDC,shy,svy);
01239      x=(long)(pp[0]+0.98*q[0]);
01240      y=(long)(pp[1]+0.98*q[1]);
01241      z=(long)(pp[2]+0.98*q[2]);
01242      if(k > 0)MoveToEx(hDC,sht,svt,NULL);
01243      GetWindowCoords(view,x,y,z,&sht,&svt);
01244      if(k > 0)LineTo(hDC,sht,svt);
01245      else{
01246        LineTo(hDC,shy,svy);
01247        LineTo(hDC,sht,svt);
01248      }
01249      theta += dtheta;
01250    }
01251  }
01252  else{
01253    MoveToEx(hDC,sho,svo,NULL);
01254    LineTo(hDC,shx,svx);  LineTo(hDC,sht,svt);
01255    LineTo(hDC,shy,svy);  LineTo(hDC,sho,svo);
01256    ptp[0].x=sho; ptp[0].y=svo;
01257    ptp[1].x=shx; ptp[1].y=svx;
01258    ptp[2].x=sht; ptp[2].y=svt;
01259    ptp[3].x=shy; ptp[3].y=svy;
01260    hRgn=CreatePolygonRgn(ptp,4,WINDING);
01261    InvertRgn(hDC,hRgn);
01262    DeleteObject(hRgn);
01263  }
01264  SelectObject(hDC,holdPen);
01265  SelectObject(hDC,holdBrush);
01266  SetROP2(hDC,oldROP);
01267  return;
01268 }
01269 
01270 void PositionBrushOnOff(int OnOff,int id){
01271  int i;
01272  static int LastModellerBrushUsed = -1;
01273  if(!OnOff){
01274    lock_visible=NO;
01275    if(ghwndLock)ShowWindow(ghwndLock,SW_HIDE);
01276    controls_visible=YES;
01277    EnableToolPannels(COMMAND_PANNEL|SELECT_PANNEL|TOOL_PANNEL|ACTION_PANNEL,TRUE);
01278    ActivateAllMenus(ghwnd_main,MF_ENABLED);
01279    EnableMenuItem(GetMenu(ghwnd_main),IDM_STOP,MF_GRAYED);
01280    DrawMenuBar(ghwnd_main);
01281    DrawBrush(SelectedBrush);
01282    if(ghwndOpenGLview != NULL)
01283      PostMessage(ghwndOpenGLview,(WM_USER+6),(WPARAM)FALSE,0); // GL map axis
01284    SelectedBrush = -1;
01285    if(IsWindow(ghwndDlgAttribs))ShowWindow(ghwndDlgAttribs,SW_SHOW);
01286    if(axis_move_flag >= 0){
01287      PostMessage(ghwnd_main,WM_COMMAND,IDM_ATTRIBUTES_MAP,0);
01288    }
01289    return;
01290  }
01291  if(SelectedBrush >= 0)return;
01292  if(nImaps == 0){
01293    SendPrgmQuery(IDQ_NOBRUSH,0);
01294    return;
01295  }
01296  if(id < 0){
01297    if(nImaps == 1)id=0;
01298    else if((id=RequestMapID(ghwnd_main,"Choose Map",0)) < 0)return;
01299  }
01300  EDIT_ACTION=YES;
01301  SelectedBrush=id;
01302  LastModellerBrushUsed=SelectedBrush;
01303  lock_visible=YES;
01304  if(ghwndLock)ShowWindow(ghwndLock,SW_SHOW);
01305  if(IsWindow(ghwndDlgAttribs))ShowWindow(ghwndDlgAttribs,SW_HIDE);
01306  controls_visible=NO;
01307  EnableToolPannels(COMMAND_PANNEL|SELECT_PANNEL|TOOL_PANNEL|ACTION_PANNEL,FALSE);
01308  ActivateAllMenus(ghwnd_main,MF_GRAYED);
01309  EnableMenuItem(GetMenu(ghwnd_main),IDM_STOP,MF_ENABLED);
01310  DrawMenuBar(ghwnd_main);
01311  DrawBrush(SelectedBrush);
01312  if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,
01313    (WM_USER+6),(WPARAM)TRUE,(LPARAM)SelectedBrush); // GL map axis
01314  return;
01315 }
01316 
01317 void GrabBrushPoint(int x,int y){
01318  int id,x0,y0,x1,y1,x2,y2;
01319  double d,dmin;
01320  if(SelectedBrush < 0)return;
01321  GetWindowCoords(ActiveView,iMap[SelectedBrush].P[0],
01322            iMap[SelectedBrush].P[1],iMap[SelectedBrush].P[2],&x0,&y0);
01323  GetWindowCoords(ActiveView,iMap[SelectedBrush].X[0],
01324            iMap[SelectedBrush].X[1],iMap[SelectedBrush].X[2],&x1,&y1);
01325  GetWindowCoords(ActiveView,iMap[SelectedBrush].Y[0],
01326            iMap[SelectedBrush].Y[1],iMap[SelectedBrush].Y[2],&x2,&y2);
01327  id = -1; dmin=(double)TVsizeX*(double)TVsizeY*2.0;
01328  if(abs(x-x0) < 4 && abs(y-y0) < 4){
01329    d=DIS2(iMap[SelectedBrush].P); if(d < dmin){id = 0; dmin=d;}
01330  }
01331  if(abs(x-x1) < 4 && abs(y-y1) < 4){
01332    d=DIS2(iMap[SelectedBrush].X); if(d < dmin){id = 1; dmin=d;}
01333  }
01334  if(abs(x-x2) < 4 && abs(y-y2) < 4){
01335    d=DIS2(iMap[SelectedBrush].Y); if(d < dmin){id = 2; dmin=d;}
01336  }
01337  if(id >= 0){
01338    if(iMap[SelectedBrush].Lock){
01339     MessageBeep(MB_OK);
01340     SendPrgmMessage(IDS_MAPLOCKED,1);
01341    }
01342    else IdentifiedBrushPoint=id;
01343  }
01344 }
01345 
01346 void UnGrabBrushPoint(void){
01347   IdentifiedBrushPoint=-1;
01348   if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+3),0,0);
01349 }
01350 
01351 void PullBrushPoint(int x,int y){
01352  int i,p,sb,ix,iy,iz;
01353  long x1,y1,z1,dx,dy,dz;
01354  if((p=IdentifiedBrushPoint) >= 0){
01355    sb=SelectedBrush;
01356    DrawBrush(sb);
01357    GetWorldCoords(ActiveView,&x1,&y1,&z1,x,y);
01358    ix=iy=iz=1;
01359    if     (ActiveView == TRITOP  )iz=0;
01360    else if(ActiveView == TRIFRONT)iy=0;
01361    else if(ActiveView == TRIRIGHT)ix=0;
01362    if(p == 0){
01363      dx=iMap[sb].X[0]-iMap[sb].P[0];
01364      dy=iMap[sb].X[1]-iMap[sb].P[1];
01365      dz=iMap[sb].X[2]-iMap[sb].P[2];
01366      if(ix)iMap[sb].X[0]=x1+dx;
01367      if(iy)iMap[sb].X[1]=y1+dy;
01368      if(iz)iMap[sb].X[2]=z1+dz;
01369      dx=iMap[sb].Y[0]-iMap[sb].P[0];
01370      dy=iMap[sb].Y[1]-iMap[sb].P[1];
01371      dz=iMap[sb].Y[2]-iMap[sb].P[2];
01372      if(ix){iMap[sb].Y[0]=x1+dx; iMap[sb].P[0]=x1;}
01373      if(iy){iMap[sb].Y[1]=y1+dy; iMap[sb].P[1]=y1;}
01374      if(iz){iMap[sb].Y[2]=z1+dz; iMap[sb].P[2]=z1;}
01375    }
01376    else if(p == 1){
01377      if(ix)iMap[sb].X[0]=x1;
01378      if(iy)iMap[sb].X[1]=y1;
01379      if(iz)iMap[sb].X[2]=z1;
01380    }
01381    else if(p == 2){
01382      if(ix)iMap[sb].Y[0]=x1;
01383      if(iy)iMap[sb].Y[1]=y1;
01384      if(iz)iMap[sb].Y[2]=z1;
01385    }
01386    DrawBrush(SelectedBrush);
01387    // inserted to draw brush in background windows
01388    UpdateWindow(ghwnd_triview[ActiveView]);
01389  }
01390 }
01391 
01392 
01393 int RequestMirrorID(HWND parent){ // Not used now
01394 #if 0
01395  int i,id;
01396  long N,N1;
01397  char **ItemList,newname[32]="< none >";
01398  N=nSha;
01399  N1=N+1;
01400  if((ItemList = (char **)X__Malloc(N1*sizeof(char *))) == NULL){
01401    SendPrgmQuery(IDQ_NOMEM2,0);
01402    return -1;
01403  }
01404  for(i=0;i<N;i++)ItemList[i] = iSha[i].N;
01405  ItemList[N] = newname;
01406  id=SelectScrolledItemList(N1,ItemList,"Mirror Plane Axis",parent);
01407  X__Free(ItemList);
01408  if(id == N)return -1;
01409  EDIT_ACTION=YES;
01410  return id;
01411 #endif
01412  return -1;
01413 }
01414 
01415 static char *GetMapFromDisk(char *p, HWND parent, BOOL *bLoaded){
01416  long l;
01417  *bLoaded=FALSE;
01418  if(p != NULL)strcpy(gszIMGfile,p);
01419  if(SelectSfxFileName(0,gszIMGfile,gszIMGdir,IDX_MISC_IMAGEFORMAP,
01420      "All Image Formats|*.bmp;*.gif;*.tga;*.tif;*.jpg;*.png|"
01421      "BMP (*.BMP) |*.bmp|"
01422      "Compuserve GIF (*.GIF) |*.gif|"
01423      "Targa TGA (*.TGA) |*.tga|"
01424      "TIFF (*.TIF) |*.tif|"
01425      "JPEG (*.JPG) |*.jpg|"
01426      "PNG (*.PNG) |*.png|"
01427                    ,parent) == TRUE){
01428    if(p != NULL)X__Free(p);
01429    l=strlen(gszIMGfile);
01430    if(l == 0)return NULL;
01431    p=(char *)X__Malloc(l+1);
01432    if(p == NULL)return NULL;
01433    strcpy(p,gszIMGfile);
01434    *bLoaded=TRUE;
01435  }
01436  else{
01437    //if(p != NULL)X__Free(p); p=NULL;
01438  }
01439  return p;
01440 }
01441 
01442 static char *GetFlicFromDisk(int id, char *p, HWND parent, int type){
01443  long l;
01444  if(p != NULL)strcpy(gszAVIfile,p);
01445  if(SelectSfxFileName(0,gszAVIfile,gszAVIdir,IDX_MISC_FIRSTIMAGE,
01446    "Movie Files|*.avi|*.avi|*.avi|",parent) == TRUE){
01447    if(p != NULL)X__Free(p);
01448    l=strlen(gszAVIfile);
01449    if(l == 0)return NULL;
01450    p=(char *)X__Malloc(l+1);
01451    if(p == NULL)return NULL;
01452    strcpy(p,gszAVIfile);
01453  }
01454  else{
01455    if(p != NULL)X__Free(p); p=NULL;
01456  }
01457  return p;
01458 }
01459 
01460 static char *GetPresetMap(char *p, HWND parent){
01461  int id;
01462  char *pp,lname[255];
01463  HMODULE hLib;
01464  FARPROC fpFun;
01465  int (*fpFun1)(HWND, char *);
01466  EDIT_ACTION=YES;
01467  strcpy(lname,gszHomeDir); strcat(lname,"premap.dll");
01468  if((hLib=LoadLibrary(lname)) != NULL){
01469    if((fpFun=GetProcAddress(hLib,"_GetPresetMapImage")) != NULL){
01470      fpFun1 = (void *)fpFun;
01471      strcpy(lname,gszHomeDir); strcat(lname,"maps\\presets\\textures.bmp");
01472      id=(*fpFun1)(parent,lname);
01473      if(id > 0 && id <= 30){
01474        if(p == NULL){
01475          pp=(char *)X__Malloc(256);
01476          if(pp == NULL)return p; else p=pp;
01477        }
01478        sprintf(p,"%smaps\\presets\\tx%03ld.gif",gszHomeDir,id);
01479      }
01480    }
01481    else SendPrgmQuery(IDQ_FAILEDFUNCTION,3);
01482    FreeLibrary(hLib);
01483  }
01484  else SendPrgmQuery(IDQ_FAILEDLIBRARY,3);
01485  return p;
01486 }
01487 
01488 static double Distance3D(point a, long *b){
01489  return sqrt((double)(a[0]-b[0])*(double)(a[0]-b[0])+
01490              (double)(a[1]-b[1])*(double)(a[1]-b[1])+
01491              (double)(a[2]-b[2])*(double)(a[2]-b[2]));
01492 }
01493 
01494 static int E_MapToPlaneBrush(vector vi,
01495                             vector p0, vector p1, vector p2,
01496                             double *a, double *b){
01497  double ve1,ve2,ve3,vp1,vp2,vp3,q1,q2,q3,det,
01498         det1,det2,det3,detmax,dm;
01499  int k;
01500   q1=vi[0]-p0[0];  q2=vi[1]-p0[1];  q3=vi[2]-p0[2];
01501  ve1=p2[0]-p0[0]; ve2=p2[1]-p0[1]; ve3=p2[2]-p0[2];
01502  vp1=p1[0]-p0[0]; vp2=p1[1]-p0[1]; vp3=p1[2]-p0[2];
01503  det1=ve1*vp2-vp1*ve2;    /* new way to ensure optimum numerics */
01504  det2=ve2*vp3-vp2*ve3;
01505  det3=ve1*vp3-vp1*ve3;
01506  k=0; detmax=200;
01507  if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
01508  if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
01509  if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
01510  if(k == 0)return 0;
01511  else if(k == 1){
01512    *a=( vp2*q1-vp1*q2)/det1;
01513    *b=(-ve2*q1+ve1*q2)/det1;
01514  }
01515  else if(k == 2){
01516    *a=( vp3*q2-vp2*q3)/det2;
01517    *b=(-ve3*q2+ve2*q3)/det2;
01518  }
01519  else if(k == 3){
01520    *a=( vp3*q1-vp1*q3)/det3;
01521    *b=(-ve3*q1+ve1*q3)/det3;
01522  }
01523  else return 0;
01524 /* a=1 at p2      b=1 at p1  */
01525  return 1;
01526 }
01527 
01528 static double E_MapToSphereBrush(vector n, vector dx, vector dy, vector p0, vector p,
01529                 double * a, double * b){
01530   /* p0    is at centre of map
01531      dx    is vector in direction of seam
01532      dy    is directed to south pole
01533      p     is point of vertex to be assigned mapping coordinates
01534      a     is  phi  [0 - 1] (0 along x axis)
01535      b     is theta [0 - 1] (0  at north pole)
01536      n     is at right angles to dx and dy
01537   */
01538   vector x,z,r;
01539   VECCOPY(dx,x)
01540   O_normalize(x);
01541   VECSCALE(-1.0,dy,z)
01542   O_normalize(z);
01543   VECSUB(p,p0,r)
01544   O_normalize(r);
01545   *b = -acos(DOT(r,z))*0.3183;              /*  theta/pi                    */
01546   *a = -atan2(DOT(r,n),DOT(r,x))*0.1592;    /*  phi/(2 pi)    0   < a < 0.5 */
01547   if(*a < 0.0) *a = 1.0 + *a;              /*                0.5 < a < 1.0 */
01548   return 0.0;
01549 }
01550 
01551 static BOOL CALLBACK MapFromBrushDlgProc(HWND hdlg,UINT msg,
01552                            WPARAM wparam,LPARAM lparam){
01553  struct TEMP {int it; int id;} *tc;
01554  int i;
01555  HWND hctl;
01556  switch( msg ) {
01557    case WM_PAINT:
01558      PaintDialogBackground(hdlg,ghinst_main);
01559      break;
01560    case WM_INITDIALOG:
01561      tc=(struct TEMP *)lparam;
01562      SetWindowLong(hdlg,GWL_USERDATA,lparam);
01563      EnableToolPannels(ALL_PANNELS,FALSE);
01564      if(tc->it == 0)
01565        SendDlgItemMessage(hdlg,DLG_MAPMAP_P,BM_SETCHECK,TRUE,0);
01566      else if(tc->it == 1)
01567        SendDlgItemMessage(hdlg,DLG_MAPMAP_P,BM_SETCHECK,TRUE,0);
01568      else
01569        SendDlgItemMessage(hdlg,DLG_MAPMAP_S,BM_SETCHECK,TRUE,0);
01570      hctl=GetDlgItem(hdlg,DLG_MAPMAP_LIST);
01571      for(i=0;i<nImaps;i++){
01572        SendMessage(hctl,LB_ADDSTRING,0,(LPARAM)iMap[i].N);
01573      }
01574      SendDlgItemMessage(hdlg,DLG_MAPMAP_LIST,LB_SETCURSEL,0,0);
01575      CentreDialogOnCursor(hdlg);
01576      return (TRUE);
01577    case WM_DESTROY:
01578      EnableToolPannels(ALL_PANNELS,TRUE);
01579      break;
01580    case WM_COMMAND:
01581       tc=(struct TEMP *)GetWindowLong(hdlg,GWL_USERDATA);
01582       switch(LOWORD(wparam)){
01583         case DLG_MAPMAP_LIST:
01584           switch(HIWORD(wparam)){
01585             case LBN_DBLCLK:
01586               SendMessage(hdlg,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
01587               break;
01588             default:
01589               break;
01590           }                                                                           break;
01591         case IDCANCEL:
01592           EndDialog(hdlg,FALSE);
01593           return(TRUE);
01594         case IDOK:
01595           if(SendDlgItemMessage(hdlg,DLG_MAPMAP_S,BM_GETCHECK,0,0))
01596                tc->it=2;
01597           else if(SendDlgItemMessage(hdlg,DLG_MAPMAP_C,BM_GETCHECK,0,0))
01598                tc->it=1;
01599           else tc->it=0;
01600           hctl=GetDlgItem(hdlg,DLG_MAPMAP_LIST);
01601           tc->id=SendMessage(hctl,LB_GETCURSEL,0,0);
01602           EndDialog(hdlg,TRUE);
01603           return(TRUE);
01604         default:  break;
01605       }
01606       break;
01607     default: break;
01608  }
01609  return(FALSE);
01610 }
01611 
01612 void SelectMapAndMapVertices(void){
01613  struct TEMP {int it; int id;} tc;
01614  int id,it;
01615  if(NvertSelect == 0){
01616    SendPrgmQuery(IDQ_OLD2,0);
01617    return;
01618  }
01619  if(nImaps == 0){
01620    SendPrgmQuery(IDQ_NOBRUSH,0);
01621    return;
01622  }
01623  tc.it=0; tc.id=0;
01624  if(!DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_MAPMAP),ghwnd_main,
01625     (DLGPROC)MapFromBrushDlgProc,(LPARAM)&tc))return;
01626  id=tc.id;
01627  it=tc.it;
01628  MapVerticesByImageMap(id,it);
01629  MapFacesByImageMap(id,it,FALSE);
01630 }
01631 
01632 #define MAPDELTA 0.3333333
01633 
01634 static void FixUpMapEdge(double a[]){
01635  if(a[0] < MAPDELTA){if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; return;}
01636  if(a[1] < MAPDELTA){if(a[2] >= 1.0-MAPDELTA)a[2] -= 1.0; if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; return;}
01637  if(a[2] < MAPDELTA){if(a[0] >= 1.0-MAPDELTA)a[0] -= 1.0; if(a[1] >= 1.0-MAPDELTA)a[1] -= 1.0; return;}
01638 }
01639 
01640 void MapFacesByImageMap(int id, int it, BOOL all){
01641  face *fp;
01642  int i,j;
01643  vector n,vi,p0,p1,p2,p10,p20,dv;
01644  double nn,a,b,av[3],bv[3];
01645  vertex *vp[3];
01646  if(!all && NvertSelect == 0)return; if(Nface == 0)return;
01647  EDIT_ACTION=YES;
01648  if(it == 0){  // planar
01649    POINT2VECTOR(iMap[id].P,p1)   // this must ensure that the
01650    POINT2VECTOR(iMap[id].Y,p0)   // mapping coords is origin at bottom left
01651    POINT2VECTOR(iMap[id].X,p2)   //
01652    VECSUB(p1,p0,p10)             //
01653    VECSUB(p2,p1,p20)             //
01654    VECSUM(p0,p20,p2)             //
01655    CROSS(p20,p10,n)              //
01656    if(O_normalize(n) != OK)return;
01657    fp=MainFp; for(i=0;i<Nface;i++,fp++){
01658      for(j=0;j<3;j++)vp[j]=(MainVp + fp->V[j]);
01659      //{char tt[255]; sprintf(tt,"face %ld (gp %ld) mapid %ld  (id it all %ld %ld %ld)",i,fp->gp,fp->imagemap,id,it,all);
01660      //    MessageBox(NULL,tt,"Face mapping",MB_OK);}
01661      if(( all && fp->imagemap == id) || 
01662         (!all && (vp[0]->status == SELECTED && vp[1]->status == SELECTED && vp[2]->status == SELECTED))){
01663        fp->gp=TRUE;
01664        for(j=0;j<3;j++){
01665          VECSUB(p0,(double)vp[j]->xyz,vi)
01666          nn=DOT(vi,n);
01667          VECSCALE(nn,n,dv)
01668          VECSUM((double)vp[j]->xyz,dv,vi)
01669          if(E_MapToPlaneBrush(vi,p0,p1,p2,&a,&b)){
01670            fp->x[j]=(float)a;
01671            fp->y[j]=(float)b;
01672          }
01673          if(all){vp[j]->gp = 1; vp[j]->x=fp->x[j]; vp[j]->y=fp->y[j];} 
01674          //{char tt[255]; sprintf(tt,"face %ld (%ld) x= %lf y=%lf",i,fp->gp,fp->x[j],fp->y[j]);
01675          //MessageBox(NULL,tt,"Face mapping set",MB_OK);}
01676        }
01677      }
01678    }
01679  }
01680  else if(it == 1){ /* cylindrical map */
01681    double theta,RTD=0.159154943;
01682    vector y,q;
01683    POINT2VECTOR(iMap[id].P,p0)
01684    POINT2VECTOR(iMap[id].Y,p1)
01685    POINT2VECTOR(iMap[id].X,p2)
01686    VECSUB(p1,p0,y)
01687    VECSUB(p2,p0,p20)
01688    CROSS(y,p20,n)
01689    if(O_normalize(n) != OK)return;
01690    fp=MainFp; for(i=0;i<Nface;i++,fp++){
01691      for(j=0;j<3;j++)vp[j]=(MainVp + fp->V[j]);
01692      if(( all && fp->imagemap == id) || 
01693         (!all && (vp[0]->status == SELECTED && vp[1]->status == SELECTED && vp[2]->status == SELECTED))){
01694        fp->gp=TRUE;
01695        for(j=0;j<3;j++){
01696          VECSUB(p0,(double)vp[j]->xyz,p1)
01697          b=DOT(p1,y)/DOT(y,y);
01698          VECSCALE(b,y,p2)
01699          VECSUB(p1,p2,q)
01700          O_normalize(q);
01701          nn=DOT(q,n);
01702          if     (nn >  1.0)nn =  1.0;
01703          else if(nn < -1.0)nn = -1.0;
01704          theta=acos(nn)*RTD;
01705          CROSS(q,n,p1)
01706          if(DOT(p1,y) <= 0.0){
01707            if(theta <= 0.25) a = (0.25 - theta);
01708            else  a = (1.25 - theta);
01709          }
01710          else    a = (0.25 + theta);
01711          av[j] = a; bv[j]=b;
01712        }
01713        FixUpMapEdge(av);
01714        for(j=0;j<3;j++){
01715          av[j] *= 360.0/(double)iMap[id].Angle;
01716          fp->x[j]=(float)av[j];
01717          fp->y[j]=(float)bv[j] + 1.0;   // to ensure image (0,0) is at bottom left
01718          if(all){vp[j]->gp = 1; vp[j]->x=fp->x[j]; vp[j]->y=fp->y[j];} 
01719        }
01720      }
01721    }
01722  }
01723  else{ /* spherical map */
01724    vector y,p;
01725    POINT2VECTOR(iMap[id].P,p0)
01726    POINT2VECTOR(iMap[id].Y,p1)
01727    POINT2VECTOR(iMap[id].X,p2)
01728    VECSUB(p1,p0,y)
01729    VECSUB(p2,p0,p20)
01730    CROSS(y,p20,n)
01731    if(O_normalize(n) != OK)return;
01732    fp=MainFp; for(i=0;i<Nface;i++,fp++){
01733      for(j=0;j<3;j++)vp[j]=(MainVp + fp->V[j]);
01734      if(( all && fp->imagemap == id) || 
01735         (!all && (vp[0]->status == SELECTED && vp[1]->status == SELECTED && vp[2]->status == SELECTED))){
01736        fp->gp=TRUE;
01737        for(j=0;j<3;j++){
01738          POINT2VECTOR(vp[j]->xyz,p)
01739          E_MapToSphereBrush(n,p20,y,p0,p,&(av[j]),&(bv[j]));
01740        }
01741        FixUpMapEdge(av);
01742        for(j=0;j<3;j++){
01743          fp->x[j]=(float)av[j];
01744          fp->y[j]=(float)bv[j] + 1.0; // to ensure origin is at bottom left
01745          if(all){vp[j]->gp = 1; vp[j]->x=fp->x[j]; vp[j]->y=fp->y[j];} 
01746        }
01747      }
01748    }
01749  }
01751 // AssignVertexMappingFromFaceMapping(); // just for testing
01752 }
01753 
01754 void MapVerticesByImageMap(int id, int it){
01755  vector n,vi,p0,p1,p2,p10,p20,dv;
01756  double nn,a,b;
01757  vertex *vp;
01758  long i;
01759  EDIT_ACTION=YES;
01760  if(it == 0){  // planar
01761    POINT2VECTOR(iMap[id].P,p1)   // this must ensure that the
01762    POINT2VECTOR(iMap[id].Y,p0)   // mapping coords is origin at bottom left
01763    POINT2VECTOR(iMap[id].X,p2)   //
01764    VECSUB(p1,p0,p10)             //
01765    VECSUB(p2,p1,p20)             //
01766    VECSUM(p0,p20,p2)             //
01767    CROSS(p20,p10,n)              //
01768    if(O_normalize(n) != OK)return;
01769    vp=MainVp; for(i=0;i<Nvert;i++){
01770      if(vp->status == SELECTED){
01771        VECSUB(p0,(double)vp->xyz,vi)
01772        nn=DOT(vi,n);
01773        VECSCALE(nn,n,dv)
01774        VECSUM((double)vp->xyz,dv,vi)
01775        if(E_MapToPlaneBrush(vi,p0,p1,p2,&a,&b)){
01776          if(vp->gp == 1){
01777            vp->x=(float)a;
01778            vp->y=(float)b;
01779          }
01780          else{
01781            vp->gp=1;
01782            vp->x=(float)a;
01783            vp->y=(float)b;
01784          }
01785        }
01786      }
01787      vp++;
01788    }
01789  }
01790  else if(it == 1){ /* cylindrical map */
01791    double theta,RTD=0.159154943;
01792    vector y,q;
01793    POINT2VECTOR(iMap[id].P,p0)
01794    POINT2VECTOR(iMap[id].Y,p1)
01795    POINT2VECTOR(iMap[id].X,p2)
01796    VECSUB(p1,p0,y)
01797    VECSUB(p2,p0,p20)
01798    CROSS(y,p20,n)
01799    if(O_normalize(n) != OK)return;
01800    vp=MainVp; for(i=0;i<Nvert;i++){
01801      if(vp->status == SELECTED){
01802        VECSUB(p0,(double)vp->xyz,p1)
01803        b=DOT(p1,y)/DOT(y,y);
01804        VECSCALE(b,y,p2)
01805        VECSUB(p1,p2,q)
01806        O_normalize(q);
01807        nn=DOT(q,n);
01808        if     (nn >  1.0)nn =  1.0;
01809        else if(nn < -1.0)nn = -1.0;
01810        theta=acos(nn)*RTD;
01811        CROSS(q,n,p1)
01812        if(DOT(p1,y) <= 0.0){
01813          if(theta <= 0.25) a = (0.25 - theta);
01814          else  a = (1.25 - theta);
01815        }
01816        else    a = (0.25 + theta);
01817        a *= 360.0/(double)iMap[id].Angle;
01818        if(vp->gp == 1){
01819          vp->x=(float)a;
01820          vp->y=(float)b + 1.0;  // to ensure mapping coord is at bottom left
01821        }
01822        else{
01823          vp->gp=1;
01824          vp->x=(float)a;
01825          vp->y=(float)b + 1.0;
01826        }
01827      }
01828      vp++;
01829    }
01830  }
01831  else{ /* spherical map */
01832    vector y,p;
01833    POINT2VECTOR(iMap[id].P,p0)
01834    POINT2VECTOR(iMap[id].Y,p1)
01835    POINT2VECTOR(iMap[id].X,p2)
01836    VECSUB(p1,p0,y)
01837    VECSUB(p2,p0,p20)
01838    CROSS(y,p20,n)
01839    if(O_normalize(n) != OK)return;
01840    vp=MainVp; for(i=0;i<Nvert;i++){
01841      if(vp->status == SELECTED){
01842        POINT2VECTOR(vp->xyz,p)
01843        E_MapToSphereBrush(n,p20,y,p0,p,&a,&b);
01844        if(vp->gp == 1){
01845          vp->x=(float)a;
01846          vp->y=(float)b + 1.0;  // to ensure map bottom left in right place
01847        }
01848        else{
01849          vp->gp=1;
01850          vp->x=(float)a;
01851          vp->y=(float)b + 1.0;
01852        }
01853      }
01854      vp++;
01855    }
01856  }
01857 }
01858 
01859 static BOOL CALLBACK MapOntoPathDlgProc(HWND hdlg,UINT msg,
01860                            WPARAM wparam,LPARAM lparam){
01861  char tempstr[16];
01862  struct TEMP {int type; long n;} *tc;
01863  switch( msg ) {
01864    case WM_PAINT:
01865      PaintDialogBackground(hdlg,ghinst_main);
01866      break;
01867    case WM_INITDIALOG:
01868      tc=(struct TEMP *)lparam;
01869      SetWindowLong(hdlg,GWL_USERDATA,lparam);
01870      EnableToolPannels(ALL_PANNELS,FALSE);
01871      if(tc->type == 0)
01872        SendDlgItemMessage(hdlg,DLG_MAPCURVE_LIN,BM_SETCHECK,TRUE,0);
01873      else
01874        SendDlgItemMessage(hdlg,DLG_MAPCURVE_ONE,BM_SETCHECK,TRUE,0);
01875      sprintf(tempstr,"%d",tc->n);
01876      SendDlgItemMessage(hdlg,DLG_MAPCURVE_N,WM_SETTEXT,0,(LPARAM)tempstr);
01877      SendDlgItemMessage(hdlg,DLG_MAPCURVE_N,EM_LIMITTEXT,(WPARAM)4,0);
01878      SendDlgItemMessage(hdlg,DLG_MAPCURVE_NS,SPNM_SETRANGE,0,
01879                         MAKELPARAM(1,9999));
01880      SendDlgItemMessage(hdlg,DLG_MAPCURVE_NS,SPNM_SETCRNTVALUE,
01881                         (WPARAM)tc->n,0);
01882      SendDlgItemMessage(hdlg,DLG_MAPCURVE_NS,SPNM_SETEDITCTRL,0,
01883                         (LPARAM)GetDlgItem(hdlg,DLG_MAPCURVE_N));
01884      CentreDialogOnCursor(hdlg);
01885      return (TRUE);
01886    case WM_DESTROY:
01887      EnableToolPannels(ALL_PANNELS,TRUE);
01888      break;
01889    case WM_COMMAND:
01890       tc=(struct TEMP *)GetWindowLong(hdlg,GWL_USERDATA);
01891       switch(LOWORD(wparam)){
01892         case IDCANCEL:
01893           EndDialog(hdlg,FALSE);
01894           return(TRUE);
01895         case IDOK:
01896           if(GetDlgItemText(hdlg,DLG_MAPCURVE_N,tempstr,10) == 0){
01897             EndDialog(hdlg,FALSE);
01898             return(TRUE);
01899           }
01900           tc->n=atoi(tempstr);
01901           if(SendDlgItemMessage(hdlg,DLG_MAPCURVE_ONE,BM_GETCHECK,0,0))
01902                tc->type=1;
01903           else tc->type=0;
01904           EndDialog(hdlg,TRUE);
01905           return(TRUE);
01906         default:  break;
01907       }
01908       break;
01909     default: break;
01910  }
01911  return(FALSE);
01912 }
01913 
01914 void MapOntoPath(void){
01915  struct TEMP {int type; long n;} tc;
01916  vertex *Vp,*Va,*Va1;
01917  long i,*va,vp,np,n;
01918  int id;
01919  double a,l,ll;
01920  tc.n=1;
01921  tc.type=0;
01922  if(!DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_MAPCURVE),ghwnd_main,
01923     (DLGPROC)MapOntoPathDlgProc,(LPARAM)&tc))return;
01924  id=tc.type;
01925  n=max(1,tc.n);
01926  EDIT_ACTION=YES;
01927  if((va=GetPathList(&np)) != NULL){
01928    if(id == 0){
01929      l=0; /* get length of path */
01930      for(i=1;i<np;i++){
01931        Va=(MainVp+va[i]); Va1=(MainVp+va[i-1]);
01932        l += sqrt(
01933        (double)(Va->xyz[0] - Va1->xyz[0])*
01934        (double)(Va->xyz[0] - Va1->xyz[0])+
01935        (double)(Va->xyz[1] - Va1->xyz[1])*
01936        (double)(Va->xyz[1] - Va1->xyz[1])+
01937        (double)(Va->xyz[2] - Va1->xyz[2])*
01938        (double)(Va->xyz[2] - Va1->xyz[2]));
01939      }
01940    }
01941    a=0.0; ll=0.0;
01942    for(i=0;i<np;i++){
01943      Vp=(MainVp+va[i]);
01944      if(Vp->gp == 1){
01945        Vp->x=(float)a;
01946        Vp->y=0.0;
01947      }
01948      else{
01949        Vp->gp=1;
01950        Vp->x=(float)a;
01951        Vp->y=0.0;
01952      }
01953      if(id == 0){
01954        if(i < np-1){
01955          Va=(MainVp+va[i]); Va1=(MainVp+va[i+1]);
01956          ll += sqrt(
01957          (double)(Va1->xyz[0] - Va->xyz[0])*
01958          (double)(Va1->xyz[0] - Va->xyz[0])+
01959          (double)(Va1->xyz[1] - Va->xyz[1])*
01960          (double)(Va1->xyz[1] - Va->xyz[1])+
01961          (double)(Va1->xyz[2] - Va->xyz[2])*
01962          (double)(Va1->xyz[2] - Va->xyz[2]));
01963        }
01964        a = ll/l*(double)n;
01965      }
01966      else a += 1.0;
01967      if(Vp->status == DESELECTED){ /* so that we don't need to redraw */
01968        Vp->status=SELECTED;
01969        NvertSelect++; NvertDeselect--;
01970      }
01971    }
01972    X__Free(va);
01973    DrawVerticesOnly(NULL);
01974    UpdateCounters();
01975  }
01976 }
01977 
01978 static BOOL CALLBACK SetMapCoordsDlgProc(HWND hdlg,UINT msg,
01979                            WPARAM wparam,LPARAM lparam){
01980  char tempstr[16];
01981  struct TEMP {int type; double v;} *tc;
01982  switch( msg ) {
01983    case WM_PAINT:
01984      PaintDialogBackground(hdlg,ghinst_main);
01985      break;
01986    case WM_INITDIALOG:
01987      tc=(struct TEMP *)lparam;
01988      SetWindowLong(hdlg,GWL_USERDATA,lparam);
01989      EnableToolPannels(ALL_PANNELS,FALSE);
01990      if(tc->type == 0)
01991        SendDlgItemMessage(hdlg,DLG_MAPCOORD_H,BM_SETCHECK,TRUE,0);
01992      else
01993        SendDlgItemMessage(hdlg,DLG_MAPCOORD_V,BM_SETCHECK,TRUE,0);
01994      sprintf(tempstr,"%.2lf",tc->v);
01995      SendDlgItemMessage(hdlg,DLG_MAPCOORD_VALUE,WM_SETTEXT,0,(LPARAM)tempstr);
01996      SendDlgItemMessage(hdlg,DLG_MAPCOORD_VALUE,EM_LIMITTEXT,(WPARAM)12,0);
01997      CentreDialogOnCursor(hdlg);
01998      return (TRUE);
01999    case WM_DESTROY:
02000      EnableToolPannels(ALL_PANNELS,TRUE);
02001      break;
02002    case WM_COMMAND:
02003       tc=(struct TEMP *)GetWindowLong(hdlg,GWL_USERDATA);
02004       switch(LOWORD(wparam)){
02005         case IDCANCEL:
02006           EndDialog(hdlg,FALSE);
02007           return(TRUE);
02008         case IDOK:
02009           if(GetDlgItemText(hdlg,DLG_MAPCOORD_VALUE,tempstr,10) == 0){
02010             EndDialog(hdlg,FALSE);
02011             return(TRUE);
02012           }
02013           tc->v=atof(tempstr);
02014           if(SendDlgItemMessage(hdlg,DLG_MAPCOORD_V,BM_GETCHECK,0,0))
02015                tc->type=1;
02016           else tc->type=0;
02017           EndDialog(hdlg,TRUE);
02018           return(TRUE);
02019         default:  break;
02020       }
02021       break;
02022     default: break;
02023  }
02024  return(FALSE);
02025 }
02026 
02027 void SetMapCoords(void){
02028  int it;
02029  double v;
02030  vertex *vp;
02031  face   *fp;
02032  long i,j;
02033  struct TEMP {int type; double v;} tc;
02034  if(NvertSelect == 0){
02035    SendPrgmQuery(IDQ_OLD2,0);
02036    return;
02037  }
02038  tc.type=0; tc.v=1.0;
02039  if(!DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_MAPCOORD),ghwnd_main,
02040     (DLGPROC)SetMapCoordsDlgProc,(LPARAM)&tc))return;
02041  it=tc.type;
02042  v=tc.v;
02043 
02044  EDIT_ACTION=YES;
02045 // vp=MainVp; for(i=0;i<Nvert;i++){
02046 //   if(vp->status == SELECTED){
02047 //     if(it == 0)vp->x=v;
02048 //     else       vp->y=v;
02049 //   }
02050 //   vp++;
02051 // }
02052  fp=MainFp; for(i=0;i<Nface;i++){
02053    for(j=0;j<3;j++){
02054      vp=(MainVp+(fp->V[j]));
02055      if(vp->status == SELECTED){
02056        fp->gp=TRUE;
02057        if(it == 0)fp->x[j]=v;
02058        else       fp->y[j]=v;
02059      } 
02060    }
02061    fp++;
02062  }
02063 }
02064 
02065 static void AssignFaceMappingFromVertexMapping(void){ // NOT USED AT PRESENT
02066  face *fp;
02067  int i;
02068  vertex *v0,*v1,*v2;
02069  if(NvertSelect == 0)return;
02070  fp=MainFp; for(i=0;i<Nface;i++,fp++){
02071    v0=(MainVp + fp->V[0]); v1=(MainVp + fp->V[1]); v2=(MainVp + fp->V[2]);
02072    if(v0->status == SELECTED && v1->status == SELECTED && v2->status == SELECTED){
02073      fp->gp=TRUE;
02074      fp->x[0]=v0->x; fp->x[1]=v1->x; fp->x[2]=v2->x;
02075      fp->y[0]=v0->y; fp->y[1]=v1->y; fp->y[2]=v2->y;
02076    }
02077  }
02078 }
02079 
02080 static void AssignVertexMappingFromFaceMapping(void){ // NOT USED AT PRESENT
02081  face *fp;
02082  int i;
02083  vertex *v0,*v1,*v2;
02084  if(NvertSelect == 0)return;
02085  fp=MainFp; for(i=0;i<Nface;i++,fp++){
02086    v0=(MainVp + fp->V[0]); v1=(MainVp + fp->V[1]); v2=(MainVp + fp->V[2]);
02087    if(v0->status == SELECTED && v1->status == SELECTED && v2->status == SELECTED){
02088      v0->gp=1; v1->gp=1; v2->gp=1;
02089      v0->x=fp->x[0]; v1->x=fp->x[1]; v2->x=fp->x[2]; 
02090      v0->y=fp->y[0]; v1->y=fp->y[1]; v2->y=fp->y[2]; 
02091    }
02092  }
02093 }
02094 
02095 static void RemoveMappingCoords(BOOL all){
02096  int i,j;
02097  face *fp;
02098  vertex *vp,*v0,*v1,*v2;
02099  if((fp=MainFp) != NULL)for(i=0;i<Nface;i++){
02100    v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
02101    if(  (v0->status == SELECTED)
02102      && (v1->status == SELECTED)
02103      && (v2->status == SELECTED)){
02104      fp->gp=FALSE; for(j=0;j<3;j++){fp->x[j]=0.0; fp->y[j]=0.0;}
02105    }
02106    fp++;
02107  }
02108  if(Nvert > 0)for(i=0,vp=MainVp;i<Nvert;i++,vp++){
02109    if(vp->status == SELECTED){
02110      vp->gp=0; vp->x=vp->y=0.0;
02111    }
02112  }
02113 }
02114 
02115 void  ExecuteLockAction(int item, int sb){
02116  long k,dX[3],dY[3];
02117  if(sb >= 0){
02118    if(sb < 0 || sb >= nImaps)return;
02119    DrawBrush(sb);
02120    switch(item){
02121      case IDM_LOCK_SQUARE:
02122        for(k=0;k<3;k++){
02123          dX[k]=iMap[sb].X[k]-iMap[sb].P[k];
02124          dY[k]=iMap[sb].Y[k]-iMap[sb].P[k];
02125        }
02126        iMap[sb].P[0] = NpointerX;
02127        iMap[sb].P[1] = NpointerY;
02128        iMap[sb].P[2] = NpointerZ;
02129        for(k=0;k<3;k++){
02130          iMap[sb].X[k] = iMap[sb].P[k]+dX[k];
02131          iMap[sb].Y[k] = iMap[sb].P[k]+dY[k];
02132        }
02133        break;
02134      case IDM_LOCK_CIRCLE:
02135        iMap[sb].X[0] = NpointerX;
02136        iMap[sb].X[1] = NpointerY;
02137        iMap[sb].X[2] = NpointerZ;
02138        break;
02139      case IDM_LOCK_TRIANGLE:
02140        iMap[sb].Y[0] = NpointerX;
02141        iMap[sb].Y[1] = NpointerY;
02142        iMap[sb].Y[2] = NpointerZ;
02143        break;
02144      case IDM_LOCK_LOCK:{
02145          long mapt,type = -1;
02146          mapt=iMap[sb].Map;
02147          if     (mapt == PLANE)type=0;
02148          else if(mapt == CYLINDER)type=1;         
02149          else if(mapt == PLANE_MOZIAC)type=0;
02150          else if(mapt == CYLINDER_MOZIAC)type=1;
02151          else if(mapt == MAP_SPHERICAL)type=2;
02152          // don't reassign fixed mapping
02153          if(type >= 0){
02154            MapVerticesByImageMap(sb,type);
02155            MapFacesByImageMap(sb,type,FALSE);
02156            if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
02157 
02158          }
02159        }
02160        break;
02161      default: break;
02162    }
02163    DrawBrush(sb);
02164  }
02165  else { /* shader */
02166    sb=SelectedShader;
02167    if(sb < 0 || sb >= nMats)return;
02168    DrawShader(sb);
02169    switch(item){
02170      case IDM_LOCK_SQUARE:
02171        for(k=0;k<3;k++){
02172          dX[k]=iMat[sb].ax.X[k]-iMat[sb].ax.P[k];
02173          dY[k]=iMat[sb].ax.Y[k]-iMat[sb].ax.P[k];
02174        }
02175        iMat[sb].ax.P[0] = NpointerX;
02176        iMat[sb].ax.P[1] = NpointerY;
02177        iMat[sb].ax.P[2] = NpointerZ;
02178        for(k=0;k<3;k++){
02179          iMat[sb].ax.X[k] = iMat[sb].ax.P[k]+dX[k];
02180          iMat[sb].ax.Y[k] = iMat[sb].ax.P[k]+dY[k];
02181        }
02182        break;
02183      case IDM_LOCK_CIRCLE:
02184        iMat[sb].ax.X[0] = NpointerX;
02185        iMat[sb].ax.X[1] = NpointerY;
02186        iMat[sb].ax.X[2] = NpointerZ;
02187        break;
02188      case IDM_LOCK_TRIANGLE:
02189        iMat[sb].ax.Y[0] = NpointerX;
02190        iMat[sb].ax.Y[1] = NpointerY;
02191        iMat[sb].ax.Y[2] = NpointerZ;
02192        break;
02193      case IDM_LOCK_LOCK:
02194 //       MessageBeep(MB_OK);
02195        break;
02196      default: break;
02197    }
02198    DrawShader(sb);
02199  }
02200 }

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