Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

trilib.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 //
00023 // trilib.c: library for loading triangles from an Alias triangle file
00024 //
00025 
00026 #include <stdio.h>
00027 #include "cmdlib.h"
00028 #include "mathlib.h"
00029 #include "polyset.h"
00030 #include "trilib.h"
00031 
00032 // on disk representation of a face
00033 
00034 
00035 #define FLOAT_START 99999.0
00036 #define FLOAT_END   -FLOAT_START
00037 #define MAGIC       123322
00038 
00039 //#define NOISY 1
00040 
00041 typedef struct {
00042     float v[3];
00043 } vector;
00044 
00045 typedef struct
00046 {
00047     vector n;    /* normal */
00048     vector p;    /* point */
00049     vector c;    /* color */
00050     float  u;    /* u */
00051     float  v;    /* v */
00052 } aliaspoint_t;
00053 
00054 typedef struct {
00055     aliaspoint_t    pt[3];
00056 } tf_triangle;
00057 
00058 
00059 static void ByteSwapTri (tf_triangle *tri)
00060 {
00061     int     i;
00062     
00063     for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)
00064     {
00065         ((int *)tri)[i] = BigLong (((int *)tri)[i]);
00066     }
00067 }
00068 
00069 static void ReadPolysetGeometry( triangle_t *tripool, FILE *input, int count, triangle_t *ptri )
00070 {
00071     tf_triangle tri;
00072     int i;
00073 
00074     for (i = 0; i < count; ++i) {
00075         int     j;
00076 
00077         fread( &tri, sizeof(tf_triangle), 1, input );
00078         ByteSwapTri (&tri);
00079         for (j=0 ; j<3 ; j++)
00080         {
00081             int     k;
00082 
00083             for (k=0 ; k<3 ; k++)
00084             {
00085                 ptri->verts[j][k] = tri.pt[j].p.v[k];
00086                 ptri->normals[j][k] = tri.pt[j].n.v[k];
00087 //              ptri->colors[j][k] = tri.pt[j].c.v[k];
00088             }
00089 
00090             ptri->texcoords[j][0] = tri.pt[j].u;
00091             ptri->texcoords[j][1] = tri.pt[j].v;
00092         }
00093 
00094         ptri++;
00095         if ((ptri - tripool ) >= POLYSET_MAXTRIANGLES)
00096             Error ("Error: too many triangles; increase POLYSET_MAXTRIANGLES\n");
00097     }
00098 }
00099 
00100 void TRI_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets )
00101 {
00102     FILE        *input;
00103     float       start;
00104     char        name[256], tex[256];
00105     int         i, count, magic, pset = 0;
00106     triangle_t  *ptri;
00107     polyset_t   *pPSET;
00108     int         iLevel;
00109     int         exitpattern;
00110     float       t;
00111 
00112     t = -FLOAT_START;
00113     *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);
00114     *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);
00115     *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);
00116     *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);
00117 
00118     if ((input = fopen(filename, "rb")) == 0)
00119         Error ("reader: could not open file '%s'", filename);
00120 
00121     iLevel = 0;
00122 
00123     fread(&magic, sizeof(int), 1, input);
00124     if (BigLong(magic) != MAGIC)
00125         Error ("%s is not a Alias object separated triangle file, magic number is wrong.", filename);
00126 
00127     pPSET = calloc( 1, POLYSET_MAXPOLYSETS * sizeof( polyset_t ) );
00128     ptri = calloc( 1, POLYSET_MAXTRIANGLES * sizeof( triangle_t ) );
00129 
00130     *ppPSET = pPSET;
00131 
00132     while (feof(input) == 0) {
00133         if (fread(&start,  sizeof(float), 1, input) < 1)
00134             break;
00135         *(int *)&start = BigLong(*(int *)&start);
00136         if (*(int *)&start != exitpattern)
00137         {
00138             if (start == FLOAT_START) {
00139                 /* Start of an object or group of objects. */
00140                 i = -1;
00141                 do {
00142                     /* There are probably better ways to read a string from */
00143                     /* a file, but this does allow you to do error checking */
00144                     /* (which I'm not doing) on a per character basis.      */
00145                     ++i;
00146                     fread( &(name[i]), sizeof( char ), 1, input);
00147                 } while( name[i] != '\0' );
00148     
00149                 if ( i != 0 )
00150                     strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
00151                 else
00152                     strcpy( pPSET[pset].name , "(unnamed)" );
00153                 strlwr( pPSET[pset].name );
00154 
00155 //              indent();
00156 //              fprintf(stdout,"OBJECT START: %s\n",name);
00157                 fread( &count, sizeof(int), 1, input);
00158                 count = BigLong(count);
00159                 ++iLevel;
00160                 if (count != 0) {
00161 //                  indent();
00162 //                  fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
00163     
00164                     i = -1;
00165                     do {
00166                         ++i;
00167                         fread( &(tex[i]), sizeof( char ), 1, input);
00168                     } while( tex[i] != '\0' );
00169 
00170 /*
00171                     if ( i != 0 )
00172                         strncpy( pPSET[pset].texname, tex, sizeof( pPSET[pset].texname ) - 1 );
00173                     else
00174                         strcpy( pPSET[pset].texname, "(unnamed)" );
00175                     strlwr( pPSET[pset].texname );
00176 */
00177 
00178 //                  indent();
00179 //                  fprintf(stdout,"  Object texture name: '%s'\n",tex);
00180                 }
00181     
00182                 /* Else (count == 0) this is the start of a group, and */
00183                 /* no texture name is present. */
00184             }
00185             else if (start == FLOAT_END) {
00186                 /* End of an object or group. Yes, the name should be */
00187                 /* obvious from context, but it is in here just to be */
00188                 /* safe and to provide a little extra information for */
00189                 /* those who do not wish to write a recursive reader. */
00190                 /* Mea culpa. */
00191                 --iLevel;
00192                 i = -1;
00193                 do {
00194                     ++i;
00195                     fread( &(name[i]), sizeof( char ), 1, input);
00196                 } while( name[i] != '\0' );
00197 
00198                 if ( i != 0 )
00199                     strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
00200                 else
00201                     strcpy( pPSET[pset].name , "(unnamed)" );
00202 
00203                 strlwr( pPSET[pset].name );
00204     
00205 //              indent();
00206 //              fprintf(stdout,"OBJECT END: %s\n",name);
00207                 continue;
00208             }
00209         }
00210 
00211 //
00212 // read the triangles
00213 //      
00214         if ( count > 0 )
00215         {
00216             pPSET[pset].triangles = ptri;
00217             ReadPolysetGeometry( pPSET[0].triangles, input, count, ptri );
00218             ptri += count;
00219             pPSET[pset].numtriangles = count;
00220             if ( ++pset >= POLYSET_MAXPOLYSETS )
00221             {
00222                 Error ("Error: too many polysets; increase POLYSET_MAXPOLYSETS\n");
00223             }
00224         }
00225     }
00226 
00227     *numpsets = pset;
00228 
00229     fclose (input);
00230 }
00231 

Generated on Thu Aug 25 12:38:08 2005 for Quake III Arena by  doxygen 1.3.9.1