3DSSAVE.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 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 /* File OBJSAVE.C      object file format saver  in LOADER.C */
00025 
00026 static void WriteWireframe(void);
00027 static void WriteBezierCurve(void);
00028 static void WriteVertexMapping(short status);
00029 static void WriteVerticesWithOffset(point p, long invert, short short_form,
00030                                     short status);
00031 static void WriteOffsetTextures(point p, unsigned char maps, long invert);
00032 static void WriteFacesWithMapCheck(short short_form);
00033 static void WriteShaders(short status);
00034 static void WriteShadersAxes(void);
00035 static void WriteOffsetShadersAxes(point p, long invert);
00036 
00037 #ifdef __X__WINDOWS__
00038 #else
00039 static char *file_check_list[]={"Cancel","Save Over"};
00040 #endif
00041 
00042 void SaveObject(char *Filename, short status){
00043   long pos1,pos2,pos3,pos4,pos5,pos6,pos7,pos8,pos9,posA,posB,
00044        posC,posD,posE,posF,pose;
00045   long FORMsize;
00046   short id,short_form=0;
00047   FORMsize=0; newvert=0; newface=0; newedge=0; newglue=0;
00048 #ifdef __DEMO__
00049   inform("NOT IN DEMO VERSION"); pause(30); disinform();
00050   return;
00051 #endif
00052   /* status = 3 -> saving with memory problem - no extra display  !! */
00053   if(status < 3){   /* no memory problem */
00054 #ifdef __X__WINDOWS__
00055 ;
00056 #else
00057     if( (fo=fopen(Filename,"r")) != NULL){ /* check for old file */
00058       fclose(fo);
00059       id=RequestItemSelect(2,file_check_list,"File exists Save Over ?");
00060       if(id < 1)return;
00061     }
00062 #endif
00063   }
00064   if(status == 1)EDIT_ACTION=NO;
00065   if( (fo=fopen(Filename,"wb")) == NULL){   /* now open for reading */
00066 #ifdef __X__WINDOWS__
00067 #else
00068     Output_Message(G_FILEOPENFAIL);
00069 #endif
00070     return;
00071   }
00072 #ifdef __X__WINDOWS__
00073 #else
00074   if(status < 3)DrawOldMarker();
00075   if(status < 2)inform("Saving ...");
00076 #endif
00077   fprintf(fo,"FORM");
00078   pos1=ftell(fo); outlng(FORMsize);
00079   fprintf(fo,"OFXM");
00080   fprintf(fo,"AXIS"); outlng(48L); /* size of data chunk */
00081   if(status == 2){  /* dont use offset for rendering in triview */
00082     outlng(0); outlng(0); outlng(0);
00083   }
00084   else{
00085     outlng(ObjectAxis.Origin.xyz[0]);
00086     outlng(ObjectAxis.Origin.xyz[1]);
00087     outlng(ObjectAxis.Origin.xyz[2]);
00088   }
00089   outlng(iSha[0].P[0]);  /* store the algorithmic texture origin */
00090   outlng(iSha[0].P[1]);  /* in the object axis structure         */
00091   outlng(iSha[0].P[2]);
00092   outlng(iSha[0].X[0]);
00093   outlng(iSha[0].X[1]);
00094   outlng(iSha[0].X[2]);
00095   outlng(iSha[0].Y[0]);
00096   outlng(iSha[0].Y[1]);
00097   outlng(iSha[0].Y[2]);
00098   fprintf(fo,"OFFS"); outlng(16L);      /* follow point */
00099   outlng(3L);
00100   outlng(ObjectAxis.Offset.xyz[0]);
00101   outlng(ObjectAxis.Offset.xyz[1]);
00102   outlng(ObjectAxis.Offset.xyz[2]);
00103   if(Nvert > 0){
00104     fprintf(fo,"VERT"); pos2=ftell(fo); outlng(12*newvert);
00105     WriteVertices(status);
00106   }
00107   else pos2 = -1;
00108   if(Nedge > 0){
00109     fprintf(fo,"EDGE"); pos3=ftell(fo); outlng( 8*newedge); WriteEdges(0);
00110   }
00111   else pos3 = -1;
00112   if(Nface > 0){
00113     if(nSha <= 1){
00114       fprintf(fo,"FACE"); pos4=ftell(fo); outlng(20*newface); WriteFaces(0);
00115     }
00116     else{
00117       fprintf(fo,"SFAC"); pos4=ftell(fo); outlng(21*newface); WriteFaces(1);
00118     }
00119   }
00120   else pos4 = -1;
00121   if(NvertGlue > 0){
00122     fprintf(fo,"VTEX"); posB=ftell(fo); outlng(12*newglue);
00123     WriteVertexMapping(status);
00124   }
00125   else posB = -1;
00126   if(xShaders[0].in_use || xShaders[1].in_use ||
00127      xShaders[2].in_use || xShaders[3].in_use){
00128     fprintf(fo,"SHDR"); posC=ftell(fo); outlng(0L);
00129     WriteShaders(status);
00130     posD=ftell(fo);
00131   }
00132   else posC = -1;
00133   if(nSha > 1){
00134     fprintf(fo,"AXES"); posE=ftell(fo); outlng(68*(nSha-1));
00135     WriteShadersAxes();
00136     posF=ftell(fo);
00137   }
00138   else posE = -1;
00139   if(nImaps > 0){
00140     fprintf(fo,"TEXT"); pos5=ftell(fo); outlng(0L);
00141     WriteTextures(1);
00142     pos6=ftell(fo);
00143   }
00144   else pos5 = -1;         
00145   if((status == 1 || status == 3) &&
00146       Nskel > 1){/* if saving whole object then save skeleton */
00147     fprintf(fo,"SK02"); pos7=ftell(fo); outlng(0L);
00148     WriteSkeleton();
00149     pos8=ftell(fo);
00150   }
00151   else pos7 = -1;
00152   if(MirrorFlag >= 0 && (status == 1 || status == 3)){ /* only save if full */
00153     fprintf(fo,"MPID"); outlng((long)(1*sizeof(long)));
00154     outlng((long)MirrorFlag);
00155   }
00156   fprintf(fo,"MATL"); outlng((long)(5*sizeof(long)));
00157   outlng(4L);
00158   outlng((long)ShadowFlag);
00159   outlng(DefaultBrilliance);     /* these are not used any more       */
00160   outlng(DefaultTransparency);
00161   outlng(DefaultReflectivity);   /* but remain for file compatibility */
00162   fprintf(fo,"UNIT"); outlng((long)(7*sizeof(long)+8));
00163   outlng((long)ruler);
00164   fwrite(ruler_name,1,8,fo);
00165   outlng(lrulerx); outlng(lrulery); outlng(lrulerz);
00166   outlng(rulerx);  outlng(rulery);  outlng(rulerz);
00167   fprintf(fo,"GRID"); outlng((long)(2*sizeof(long)));
00168   outlng(grid_size); outlng(grid_size); /* second is unused */
00169   WriteWireframe();
00170   if((status == 1 || status == 3) && N_Bcurves > 0){
00171      fprintf(fo,"BEZ1"); pos9=ftell(fo); outlng(0L);
00172      WriteBezierCurve();
00173      posA=ftell(fo);
00174   }
00175   else pos9 = -1;
00176   pose=ftell(fo);  /* the end of the object */
00177   if(pos2 > 0){fseek(fo,pos2,0); outlng(12*newvert);}
00178   if(short_form){
00179     if(pos3 > 0){fseek(fo,pos3,0); outlng( 4*newedge);}
00180     if(pos4 > 0){fseek(fo,pos4,0); outlng(14*newface);}
00181   }
00182   else{
00183     if(pos3 > 0){fseek(fo,pos3,0); outlng( 8*newedge);}
00184     if(pos4 > 0){
00185       fseek(fo,pos4,0);
00186       if(nSha <= 1)outlng(20*newface);
00187       else         outlng(21*newface);
00188     }
00189   }
00190   if(posB > 0){fseek(fo,posB,0); outlng(12*newglue);}
00191   if(posE > 0){fseek(fo,posE,0); outlng(posF-posE-4);} /* shaders new axes  */
00192   if(posC > 0){fseek(fo,posC,0); outlng(posD-posC-4);} /* extern shader     */
00193   if(pos5 > 0){fseek(fo,pos5,0); outlng(pos6-pos5-4);} /* brushes !inc size */
00194   if(pos7 > 0){fseek(fo,pos7,0); outlng(pos8-pos7-4);} /* skeleton          */
00195   if(pos9 > 0){fseek(fo,pos9,0); outlng(posA-pos9-4);} /* bezier curves     */
00196 
00197   fseek(fo,pos1,0); outlng(pose-8);
00198 #ifdef __X__WINDOWS__
00199 #else
00200   if(status < 2)disinform();
00201   if(status < 3)DrawOldMarker();
00202 #endif
00203   fclose(fo);
00204 }
00205 
00206 static void WriteShadersAxes(void){
00207  long i,j;
00208  for(i=1;i<nSha;i++){
00209    fwrite(iSha[i].N,1,32,fo);
00210    for(j=0;j<3;j++)outlng(iSha[i].P[j]);
00211    for(j=0;j<3;j++)outlng(iSha[i].X[j]);
00212    for(j=0;j<3;j++)outlng(iSha[i].Y[j]);
00213  }
00214 }
00215 
00216 void WriteTextures(short version){
00217  long i,temp;
00218  skel *sp;
00219  vertex *v;
00220  char tempstr[256]="VERSION1.TXU";
00221  i=0;
00222  sp=FirstSp; while(sp != NULL){ /* set up sk id */
00223    sp->id=i; i++;
00224    sp=sp->next;
00225  }
00226  fwrite(&nImaps,1,1,fo);
00227  for(i=0;i<nImaps;i++){
00228    outlng(256);                 /* size of Texture list string */
00229    fwrite(tempstr,1,256,fo);    /* to maintain compatibility   */
00230    outlng(iMap[i].P[0]); outlng(iMap[i].P[1]); outlng(iMap[i].P[2]);
00231    outlng(iMap[i].X[0]); outlng(iMap[i].X[1]); outlng(iMap[i].X[2]);
00232    outlng(iMap[i].Y[0]); outlng(iMap[i].Y[1]); outlng(iMap[i].Y[2]);
00233    temp=iMap[i].Type; outlng(temp);
00234    temp=iMap[i].AnimFF; outlng(temp);
00235    temp=iMap[i].AnimDL; outlng(temp);
00236    temp=iMap[i].AnimLF; outlng(temp);
00237    if(iMap[i].Sk != NULL){
00238      temp=((iMap[i].Sk)->id)+1; outlng(temp);/* 1 is first file brush*/
00239    }
00240    else{
00241      temp=0; outlng(temp);
00242    }
00243    temp=iMap[i].Map; outlng(temp);   /* 0 = plane 1 = cyl. map  2/3 = moz */
00244    if(version == 0)temp=0;
00245    else{
00246      temp=32+3+6+9+2;    /* 52 bytes + */
00247      if(iMap[i].s)temp += 256;
00248      if(iMap[i].r)temp += 256;
00249      if(iMap[i].b)temp += 256;
00250      temp /= 4;   /* make 4 byte long equivalent */
00251    }
00252    temp += 5;          outlng(temp); /* for expansion, count - from here */
00253    temp=iMap[i].Angle; outlng(temp); /* angle for cylinder brushes */
00254    if(iMap[i].Lock &&
00255       iMap[i].Vlock[0]->pad >= 0 &&        /* out a tex map if lock */
00256       iMap[i].Vlock[1]->pad >= 0 &&        /* and if vertices OK    */
00257       iMap[i].Vlock[2]->pad >= 0 ){
00258      temp=iMap[i].Lock;  outlng(temp);
00259      v=iMap[i].Vlock[0];
00260      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00261      v=iMap[i].Vlock[1];
00262      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00263      v=iMap[i].Vlock[2];
00264      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00265    }
00266    else{  /* map is not locked */
00267      temp=0; outlng(temp); outlng(temp); outlng(temp); outlng(temp);
00268    }
00269    if(version > 0){
00270      fwrite(iMap[i].N,1,32,fo);
00271      fwrite(&iMap[i].s,1,1,fo);
00272      fwrite(&iMap[i].r,1,1,fo);
00273      fwrite(&iMap[i].b,1,1,fo);
00274      outsht(iMap[i].sp);
00275      outsht(iMap[i].rp);
00276      outsht(iMap[i].bp);
00277      fwrite(iMap[i].d_colour,1,3,fo);
00278      fwrite(iMap[i].s_colour,1,3,fo);
00279      fwrite(iMap[i].a_colour,1,3,fo);
00280      if(iMap[i].s)fwrite(iMap[i].S,1,256,fo);
00281      if(iMap[i].r)fwrite(iMap[i].R,1,256,fo);
00282      if(iMap[i].b)fwrite(iMap[i].B,1,256,fo);
00283      outsht(0); /* to make up to multiple of 4 bytes and possible expansion */
00284    }
00285  }
00286 }
00287 
00288 void WriteVertices(short status){
00289  long i;
00290  vertex  *vp,*fv;
00291  fv=NULL; vp=MainVp; while(vp != NULL){fv=vp; vp=vp->last;}
00292  i=0;
00293  vp=fv; while(vp != NULL){
00294   if(status == 2){ /* for use in renderer */
00295     if(intriview(vp)){
00296       outlng(vp->xyz[0]); outlng(vp->xyz[1]); outlng(vp->xyz[2]);
00297       vp->pad = (char)(i >> 16);
00298       vp->id=(unsigned short)(i & 0x0000ffff);
00299       i++; newvert++;
00300     }
00301     else vp->pad = -1;
00302   }
00303   else if( (status==1) || (status == 3) || (vp->status==SELECTED) ){
00304     outlng(vp->xyz[0]); outlng(vp->xyz[1]); outlng(vp->xyz[2]);
00305     vp->pad = (char)(i >> 16);
00306     vp->id=(unsigned short)(i & 0x0000ffff);
00307     i++; newvert++;
00308   }
00309   else vp->pad = -1;
00310   vp=vp->next;
00311  }
00312 }
00313 
00314 static void WriteVerticesWithOffset(point p, long invert, short short_form,
00315                                     short status){
00316  long i;
00317  vertex  *vp,*fv;
00318  fv=NULL; vp=MainVp; while(vp != NULL){fv=vp; vp=vp->last;}
00319  i=0;
00320  vp=fv; while(vp != NULL){
00321   if(vp->status==status){
00322     outlng((vp->xyz[0]-p[0])*invert);
00323     outlng((vp->xyz[1]-p[1])*invert);
00324     outlng(vp->xyz[2]-p[2]);
00325     vp->pad = (char)(i >> 16);
00326     vp->id=(unsigned short)(i & 0x0000ffff);
00327     i++; newvert++;
00328   }
00329   else vp->pad = -1;
00330   vp=vp->next;
00331  }
00332 }
00333 
00334 void WriteVertexMapping(short status){
00335  long i,ix,iy;
00336  vertex *vp,*fv;
00337  fv=NULL; vp=MainVp; while(vp != NULL){fv=vp; vp=vp->last;}
00338  i=0;
00339  vp=fv; while(vp != NULL){
00340   if(status == 2){ /* for use in renderer */
00341     if(intriview(vp)){
00342 #if o
00343       if(vp->gp){
00344         ix=(long)(vp->gpx * 1.0e6); iy=(long)(vp->gpy * 1.0e6);
00345         outlng(i); outlng(ix); outlng(iy);
00346         newglue++;
00347       }
00348 #else
00349       if(vp->gp != NULL){
00350         ix=(long)(vp->gp->x * 1.0e6); iy=(long)(vp->gp->y * 1.0e6);
00351         outlng(i); outlng(ix); outlng(iy);
00352         newglue++;
00353       }
00354 #endif
00355       i++;
00356     }
00357   }
00358   else if( (status==1) || (status == 3) || (vp->status==SELECTED) ){
00359     if(vp->gp != NULL){
00360       ix=(long)(vp->gp->x * 1.0e6); iy=(long)(vp->gp->y * 1.0e6);
00361       outlng(i); outlng(ix); outlng(iy);
00362       newglue++;
00363     }
00364     i++;
00365   }
00366   vp=vp->next;
00367  }
00368 }
00369 
00370 void WriteEdges(short short_form){
00371  long id;
00372  edge *ep;
00373  ep=MainEp;
00374  while(ep != NULL){
00375    if((ep->V[0]->pad >= 0) && (ep->V[1]->pad >= 0)){
00376      id=(((long)ep->V[0]->id) | ((long)ep->V[0]->pad << 16)); outlng(id);
00377      id=(((long)ep->V[1]->id) | ((long)ep->V[1]->pad << 16)); outlng(id);
00378      newedge++;
00379    }
00380    ep=ep->last;
00381  }
00382 }
00383 
00384 void WriteFaces(short shader){
00385  face *f,*ff;
00386  long id;
00387  ff=NULL; f=MainFp; while(f != NULL){ff=f; f=f->last;}
00388  if((f=ff) != NULL)while(f != NULL){
00389    if((f->V[0]->pad >= 0) &&
00390       (f->V[1]->pad >= 0) &&
00391       (f->V[2]->pad >= 0)){
00392      id=(((long)f->V[0]->id) | ((long)f->V[0]->pad << 16)); outlng(id);
00393      id=(((long)f->V[1]->id) | ((long)f->V[1]->pad << 16)); outlng(id);
00394      id=(((long)f->V[2]->id) | ((long)f->V[2]->pad << 16)); outlng(id);
00395      fwrite(f->color,1,3,fo);
00396      fwrite(&f->texture,1,1,fo);
00397      fwrite(f->matcol,1,3,fo);
00398      fwrite(&f->brush,1,1,fo);
00399      if(shader)fwrite(&f->axis,1,1,fo);
00400      newface++;
00401    }
00402    f=f->next;
00403  }
00404 }
00405 
00406 static void WriteFacesWithMapCheck(short short_form){
00407  unsigned char map;
00408  face *f,*ff;
00409  long id;
00410  ff=NULL; f=MainFp; while(f != NULL){ff=f; f=f->last;}
00411  if((f=ff) != NULL)while(f != NULL){
00412    if((f->V[0]->pad >= 0) &&
00413       (f->V[1]->pad >= 0) &&
00414       (f->V[2]->pad >= 0)){
00415      id=(((long)f->V[0]->id) | ((long)f->V[0]->pad << 16)); outlng(id);
00416      id=(((long)f->V[1]->id) | ((long)f->V[1]->pad << 16)); outlng(id);
00417      id=(((long)f->V[2]->id) | ((long)f->V[2]->pad << 16)); outlng(id);
00418      fwrite(f->color,1,3,fo);
00419      fwrite(&f->texture,1,1,fo);
00420      fwrite(f->matcol,1,3,fo);
00421      if((f->texture & 0x40) == 0x40){/* map in use */
00422        map=(f->brush & 0x1f);
00423        map=(unsigned char)(iMap[(long)map].in_use);  /* this must be >= 0*/
00424        map=((f->brush & 0xe0) | map);
00425        fwrite(&map,1,1,fo);
00426      }
00427      else fwrite(&f->brush,1,1,fo);
00428      newface++;
00429    }
00430    f=f->next;
00431  }
00432 }
00433 
00434 static void WriteBezierCurve(void){
00435  long i,j,id;
00436  outlng(N_Bcurves);
00437  for(i=0;i<N_Bcurves;i++){
00438    outlng((long)Bcurves[i].Nc); outlng((long)Bcurves[i].Np);
00439    fwrite((char *)Bcurves[i].name,1,8,fo);
00440    for(j=0;j<Bcurves[i].Nc;j++){
00441      id=((long)((Bcurves[i].Vc[j])->id) |
00442         ((long)((Bcurves[i].Vc[j])->pad) << 16));
00443      outlng(id);
00444    }
00445    for(j=0;j<Bcurves[i].Np;j++){
00446      id=((long)((Bcurves[i].Vp[j])->id) |
00447         ((long)((Bcurves[i].Vp[j])->pad) << 16));
00448      outlng(id);
00449    }
00450  }
00451 }
00452 
00453 void WriteSkeleton(void){
00454  short i,j;
00455  skel *sp;
00456  vertex *vp, *fv;
00457  long l;
00458  i=0;
00459  sp=FirstSp; while(sp != NULL){
00460    sp->id=i; i++;
00461    sp=sp->next;
00462  }
00463  outlng(Nskel);
00464  sp=FirstSp; while(sp != NULL){
00465    outlng(sp->xyz[0]); outlng(sp->xyz[1]); outlng(sp->xyz[2]);
00466    if(sp->at != NULL)outsht(sp->at->id);
00467    else              outsht(0);
00468    fwrite(sp->name,sizeof(char),16,fo);
00469    for(j=0;j<3;j++){l=(long)(sp->u[j]*1.0e8); outlng(l);}
00470    for(j=0;j<3;j++){l=(long)(sp->v[j]*1.0e8); outlng(l);}
00471    for(j=0;j<3;j++){l=(long)(sp->w[j]*1.0e8); outlng(l);}
00472    for(i=0;i<8;i++)for(j=0;j<3;j++)outlng(sp->bx[i][j]);
00473    sp=sp->next;
00474  }
00475  outlng(Nvert);
00476  fv=NULL; vp=MainVp; while(vp != NULL){fv=vp; vp=vp->last;}
00477  vp=fv; while(vp != NULL){
00478    if(vp->sp != NULL)outsht(vp->sp->id);
00479    else              outsht(0);
00480    vp=vp->next;
00481  }
00482 }
00483 
00484 static void WriteWireframe(void){
00485  long i;
00486  if(w_frame.Np == 0 || w_frame.Ne == 0)return;
00487  fprintf(fo,"WFRM");
00488  outlng((long)(((w_frame.Np*3)+(w_frame.Ne*2)+2)*sizeof(long)));
00489  outlng(w_frame.Np); outlng(w_frame.Ne);
00490  for(i=0;i<w_frame.Np;i++){
00491    outlng(w_frame.p[i][0]);
00492    outlng(w_frame.p[i][1]);
00493    outlng(w_frame.p[i][2]);
00494  }
00495  for(i=0;i<w_frame.Ne;i++){
00496    outlng(w_frame.e[i][0]); outlng(w_frame.e[i][1]);
00497  }
00498 }
00499 
00500 void SaveObjects(char *rootname, short do_all, short rotate180){
00501  char Filename[255],NodeName[16];
00502  vertex *vp;
00503  face   *fp;
00504  edge   *ep;
00505  skel   *sp,*sp1;   /* sp1 gives the offset for follow point */
00506  long i,nf,ne,map,invert;
00507  long pos1,pos2,pos3,pos4,pos5,pos6,posA,posB,posC,posD,pose;
00508  long FORMsize;
00509  short id;
00510 #ifdef __DEMO__
00511  inform("NOT IN DEMO VERSION"); pause(30); disinform();
00512  return;
00513 #endif
00514  if(rotate180)invert = -1;
00515  else         invert =  1;
00516  sp=MainSp; while(sp != NULL){
00517    if(sp->at == FirstSp || do_all){
00518      vp=MainVp; while(vp != NULL){
00519        if(vp->status == SELECTED && vp->sp == sp)vp->status=INEDITOR;
00520        vp=vp->last;
00521      }
00522      sp1=MainSp; while(sp1 != NULL){
00523        if(sp1->at == sp)break;
00524        sp1=sp1->last;
00525      }
00526      if(nImaps > 0)for(i=0;i<nImaps;i++)iMap[i].in_use = -1;
00527      nf=0; fp=MainFp; while(fp != NULL){
00528        if(fp->V[0]->status == INEDITOR && fp->V[1]->status == INEDITOR &&
00529           fp->V[2]->status == INEDITOR){
00530             if((fp->texture & 0x40) == 0x40){/* map in use */
00531               map=(long)(fp->brush & 0x1f);
00532               iMap[map].in_use=1;
00533             }
00534             nf++;
00535           }
00536        fp=fp->last;
00537      }
00538      map=0;
00539      if(nImaps > 0)for(i=0;i<nImaps;i++){
00540        if(iMap[i].in_use == 1){
00541          iMap[i].in_use = (short)map;
00542          map++;
00543        }
00544      }
00545      ne=0; if(nf == 0){
00546        ep=MainEp; while(ep != NULL){/* no faces check edges */
00547          if(ep->V[0]->status == INEDITOR && ep->V[1]->status == INEDITOR)ne++;
00548          ep=ep->last;
00549        }
00550      }
00551      if(nf > 0 || ne > 0){ /* only write if there are any faces or edges */
00552        FORMsize=0; newvert=0; newface=0; newedge=0;  /* edges => faces   */
00553        strcpy(NodeName,sp->name);
00554        id=min(strlen(sp->name),8); NodeName[id]=0;
00555        sprintf(Filename,"Saving: %s%s.mfx ",rootname,NodeName);
00556 #ifdef __X__WINDOWS__
00557 #else
00558        inform(Filename); pause(1); disinform();
00559 #endif
00560        sprintf(Filename,"%s%s.mfx",rootname,NodeName);
00561        if( (fo=fopen(Filename,"r")) != NULL){ /* check for old file */
00562          fclose(fo);
00563 #ifdef __X__WINDOWS__
00564 #else
00565          id=RequestItemSelect(2,file_check_list,"File exists Save Over ?");
00566          if(id < 1)goto SKIPIT;
00567 #endif
00568        }
00569        if( (fo=fopen(Filename,"wb")) == NULL){   /* now open for reading */
00570 #ifdef __X__WINDOWS__
00571 #else
00572          Output_Message(G_FILEOPENFAIL);
00573 #endif
00574          goto SKIPIT;
00575        }
00576        fprintf(fo,"FORM");
00577        pos1=ftell(fo); outlng(FORMsize);
00578        fprintf(fo,"OFXM");
00579        fprintf(fo,"AXIS"); outlng(48L); /* size of data chunk */
00580        outlng(0);  outlng(0);  outlng(0);
00581        outlng((iSha[0].P[0]-sp->xyz[0])*invert);  /* store the algorithmic texture origin */
00582        outlng((iSha[0].P[1]-sp->xyz[1])*invert);  /* in the object axis structure         */
00583        outlng( iSha[0].P[2]-sp->xyz[2]);
00584        outlng((iSha[0].X[0]-sp->xyz[0])*invert);
00585        outlng((iSha[0].X[1]-sp->xyz[1])*invert);
00586        outlng( iSha[0].X[2]-sp->xyz[2]);
00587        outlng((iSha[0].Y[0]-sp->xyz[0])*invert);
00588        outlng((iSha[0].Y[1]-sp->xyz[1])*invert);
00589        outlng( iSha[0].Y[2]-sp->xyz[2]);
00590        fprintf(fo,"OFFS"); outlng(16L);      /* follow point */
00591        outlng(3L);
00592        outlng((sp1->xyz[0]-sp->xyz[0])*invert);
00593        outlng((sp1->xyz[1]-sp->xyz[1])*invert);
00594        outlng(sp1->xyz[2]-sp->xyz[2]);
00595        fprintf(fo,"VERT"); pos2=ftell(fo); outlng(12*newvert);
00596        WriteVerticesWithOffset(sp->xyz,invert,0,INEDITOR);
00597        fprintf(fo,"EDGE"); pos3=ftell(fo); outlng( 8*newedge);
00598        WriteEdges(0);
00599        if(nf > 0){
00600          fprintf(fo,"FACE"); pos4=ftell(fo); outlng(20*newface);
00601          WriteFacesWithMapCheck(0);
00602        }
00603        else pos4 = -1;
00604        if(map > 0){
00605          fprintf(fo,"TEXT"); pos5=ftell(fo); outlng(0L);
00606          WriteOffsetTextures(sp->xyz,(unsigned char)map,invert);
00607          pos6=ftell(fo);
00608        }
00609        else pos5 = -1;
00610 
00611        if(xShaders[0].in_use || xShaders[1].in_use ||
00612           xShaders[2].in_use || xShaders[3].in_use){
00613          fprintf(fo,"SHDR"); posA=ftell(fo); outlng(0L);
00614          WriteShaders(1);
00615          posB=ftell(fo);
00616        }
00617        else posA = -1;
00618        if(nSha > 1){
00619          fprintf(fo,"AXES"); posC=ftell(fo); outlng(68*(nSha-1));
00620          WriteOffsetShadersAxes(sp->xyz,invert);
00621          posD=ftell(fo);
00622        }
00623        else posC = -1;
00624 
00625        fprintf(fo,"MATL"); outlng((long)(5*sizeof(long)));
00626        outlng(4L);
00627        outlng((long)ShadowFlag);
00628        outlng(0); outlng(0); outlng(0); /* not used now */
00629        fprintf(fo,"UNIT"); outlng((long)(7*sizeof(long)+8));
00630        outlng((long)ruler);
00631        fwrite(ruler_name,1,8,fo);
00632        outlng(lrulerx); outlng(lrulery); outlng(lrulerz);
00633        outlng(rulerx);  outlng(rulery);  outlng(rulerz);
00634        fprintf(fo,"GRID"); outlng((long)(2*sizeof(long)));
00635        outlng(grid_size); outlng(grid_size); /* second is unused */
00636        pose=ftell(fo);  /* the end of the object */
00637        if(pos2 > 0){fseek(fo,pos2,0); outlng(12*newvert);}
00638        if(pos3 > 0){fseek(fo,pos3,0); outlng( 8*newedge);}
00639        if(pos4 > 0){fseek(fo,pos4,0); outlng(20*newface);}
00640        if(pos5 > 0){fseek(fo,pos5,0); outlng(pos6-pos5-4);} /* not include count */
00641        if(posA > 0){fseek(fo,posA,0); outlng(posB-posA-4);}
00642        if(posC > 0){fseek(fo,posC,0); outlng(posD-posC-4);}
00643        fseek(fo,pos1,0); outlng(pose-8);
00644        fclose(fo);
00645      }
00646      SKIPIT:
00647      vp=MainVp; while(vp != NULL){ /* reset status */
00648        if(vp->status == INEDITOR)vp->status=SELECTED;
00649        vp=vp->last;
00650      }
00651    }
00652    sp=sp->last;
00653  }
00654 }
00655 
00656 static void WriteOffsetTextures(point p, unsigned char nmap, long invert){
00657  long i,temp,k;
00658  skel *sp;
00659  vertex *v;
00660  char tempstr[256]="VERSION1.TXU";
00661  i=0;
00662  sp=FirstSp; while(sp != NULL){ /* set up sk id */
00663    sp->id=i; i++;
00664    sp=sp->next;
00665  }
00666  fwrite(&nmap,1,1,fo); k=0;
00667  for(i=0;i<nImaps;i++){
00668    if(iMap[i].in_use < 0)continue;  /* image map not in use        */
00669    k++;
00670    outlng(256);                     /* size of map list string     */
00671    fwrite(tempstr,1,256,fo);        /* to maintain compatibility   */
00672    outlng((iMap[i].P[0]-p[0])*invert);
00673    outlng((iMap[i].P[1]-p[1])*invert);
00674    outlng( iMap[i].P[2]-p[2]);
00675    outlng((iMap[i].X[0]-p[0])*invert);
00676    outlng((iMap[i].X[1]-p[1])*invert);
00677    outlng( iMap[i].X[2]-p[2]);
00678    outlng((iMap[i].Y[0]-p[0])*invert);
00679    outlng((iMap[i].Y[1]-p[1])*invert);
00680    outlng( iMap[i].Y[2]-p[2]);
00681    temp=iMap[i].Type; outlng(temp);
00682    temp=iMap[i].AnimFF; outlng(temp);
00683    temp=iMap[i].AnimDL; outlng(temp);
00684    temp=iMap[i].AnimLF; outlng(temp);
00685    if(iMap[i].Sk != NULL){
00686      temp=((iMap[i].Sk)->id)+1; outlng(temp);/* 1 is first file brush*/
00687    }
00688    else{
00689      temp=0; outlng(temp);
00690    }
00691    temp=iMap[i].Map; outlng(temp);   /* 0 = plane 1 = cyl. map  2/3 = moz */
00692    temp=32+3+6+9+2;    /* 52 bytes + */
00693    if(iMap[i].s)temp += 256;
00694    if(iMap[i].r)temp += 256;
00695    if(iMap[i].b)temp += 256;
00696    temp /= 4;   /* make 4 byte long equivalent */
00697    temp += 5;          outlng(temp); /* for expansion, count - from here */
00698    temp=iMap[i].Angle; outlng(temp); /* angle for cylinder brushes */
00699    if(iMap[i].Lock &&
00700       iMap[i].Vlock[0]->pad >= 0 &&        /* out a tex map if lock */
00701       iMap[i].Vlock[1]->pad >= 0 &&        /* and if vertices OK    */
00702       iMap[i].Vlock[2]->pad >= 0 ){
00703      temp=iMap[i].Lock;  outlng(temp);
00704      v=iMap[i].Vlock[0];
00705      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00706      v=iMap[i].Vlock[1];
00707      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00708      v=iMap[i].Vlock[2];
00709      temp=(((long)v->id) | ((long)v->pad << 16)); outlng(temp);
00710    }
00711    else{  /* map is not locked */
00712      temp=0; outlng(temp); outlng(temp); outlng(temp); outlng(temp);
00713    }
00714    fwrite(iMap[i].N,1,32,fo);
00715    fwrite(&iMap[i].s,1,1,fo);
00716    fwrite(&iMap[i].r,1,1,fo);
00717    fwrite(&iMap[i].b,1,1,fo);
00718    outsht(iMap[i].sp);
00719    outsht(iMap[i].rp);
00720    outsht(iMap[i].bp);
00721    fwrite(iMap[i].d_colour,1,3,fo);
00722    fwrite(iMap[i].s_colour,1,3,fo);
00723    fwrite(iMap[i].a_colour,1,3,fo);
00724    if(iMap[i].s)fwrite(iMap[i].S,1,256,fo);
00725    if(iMap[i].r)fwrite(iMap[i].R,1,256,fo);
00726    if(iMap[i].b)fwrite(iMap[i].B,1,256,fo);
00727    outsht(0); /* to make up to multiple of 4 bytes and possible expansion */
00728  }
00729  if(k != (long)nmap){
00730 #ifdef __X__WINDOWS__
00731 #else
00732    inform("Error in writing maps - file corrupt");
00733    pause(200); disinform();
00734 #endif
00735  }
00736 }
00737 
00738 static void WriteOffsetShadersAxes(point p, long invert){
00739  long i;
00740  for(i=1;i<nSha;i++){
00741    fwrite(iSha[i].N,1,32,fo);
00742    outlng((iSha[i].P[0]-p[0])*invert);
00743    outlng((iSha[i].P[1]-p[1])*invert);
00744    outlng( iSha[i].P[2]-p[2]);
00745    outlng((iSha[i].X[0]-p[0])*invert);
00746    outlng((iSha[i].X[1]-p[1])*invert);
00747    outlng( iSha[i].X[2]-p[2]);
00748    outlng((iSha[i].Y[0]-p[0])*invert);
00749    outlng((iSha[i].Y[1]-p[1])*invert);
00750    outlng( iSha[i].Y[2]-p[2]);
00751  }
00752 }
00753 
00754 static void WriteShaders(short status){
00755  long i,lp;
00756  outlng(4);
00757  for(i=0;i<4;i++){
00758    outlng(xShaders[i].in_use);
00759    if(xShaders[i].in_use){
00760      lp=strlen(xShaders[i].parameters)+1; /* include the trailing zero */
00761      outlng(128); outlng(lp);
00762      fwrite(xShaders[i].name,1,128,fo);
00763      fwrite(xShaders[i].parameters,1,lp,fo);
00764    }
00765  }
00766 }

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