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

patch.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 #include "qbsp.h"
00023 
00024 
00025 void PrintCtrl( vec3_t ctrl[9] ) {
00026     int     i, j;
00027 
00028     for ( i = 0 ; i < 3 ; i++ ) {
00029         for ( j = 0 ; j < 3 ; j++ ) {
00030             _printf("(%5.2f %5.2f %5.2f) ", ctrl[i*3+j][0], ctrl[i*3+j][1], ctrl[i*3+j][2] );
00031         }
00032         _printf("\n");
00033     }
00034 }
00035 
00036 /*
00037 ================
00038 DrawSurfaceForMesh
00039 ================
00040 */
00041 mapDrawSurface_t    *DrawSurfaceForMesh( mesh_t *m ) {
00042     mapDrawSurface_t    *ds;
00043     int             i, j;
00044     mesh_t          *copy;
00045 
00046     // to make valid normals for patches with degenerate edges,
00047     // we need to make a copy of the mesh and put the aproximating
00048     // points onto the curve
00049     copy = CopyMesh( m );
00050     PutMeshOnCurve( *copy );
00051     MakeMeshNormals( *copy );
00052     for ( j = 0 ; j < m->width ; j++ ) {
00053         for ( i = 0 ; i < m->height ; i++ ) {
00054             VectorCopy( copy->verts[i*m->width+j].normal, m->verts[i*m->width+j].normal );
00055         }
00056     }
00057     FreeMesh( copy );
00058 
00059     ds = AllocDrawSurf();
00060     ds->mapBrush = NULL;
00061     ds->side = NULL;
00062 
00063     ds->patch = qtrue;
00064     ds->patchWidth = m->width;
00065     ds->patchHeight = m->height;
00066     ds->numVerts = ds->patchWidth * ds->patchHeight;
00067     ds->verts = malloc( ds->numVerts * sizeof( *ds->verts ) );
00068     memcpy( ds->verts, m->verts, ds->numVerts * sizeof( *ds->verts ) );
00069 
00070     ds->lightmapNum = -1;
00071     ds->fogNum = -1;
00072 
00073     return ds;
00074 }
00075 
00076 /*
00077 =================
00078 ParsePatch
00079 
00080 Creates a mapDrawSurface_t from the patch text
00081 =================
00082 */
00083 void ParsePatch( void ) {
00084     vec_t       info[5];
00085     int         i, j;
00086     parseMesh_t *pm;
00087     char        texture[MAX_QPATH];
00088     char        shader[MAX_QPATH];
00089     mesh_t      m;
00090     drawVert_t  *verts;
00091   epair_t *ep;
00092 
00093     MatchToken( "{" );
00094 
00095     // get texture
00096     GetToken (qtrue);
00097     strcpy( texture, token );
00098 
00099     // save the shader name for retexturing
00100     if ( numMapIndexedShaders == MAX_MAP_BRUSHSIDES ) {
00101         Error( "MAX_MAP_BRUSHSIDES" );
00102     }
00103     strcpy( mapIndexedShaders[numMapIndexedShaders], texture );
00104     numMapIndexedShaders++;
00105 
00106 
00107     Parse1DMatrix( 5, info );
00108     m.width = info[0];
00109     m.height = info[1];
00110     m.verts = verts = malloc( m.width * m.height * sizeof( m.verts[0] ) );
00111 
00112     if ( m.width < 0 || m.width > MAX_PATCH_SIZE
00113         || m.height < 0 || m.height > MAX_PATCH_SIZE ) {
00114         Error("ParsePatch: bad size");
00115     }
00116 
00117     MatchToken( "(" );
00118     for ( j = 0 ; j < m.width ; j++ ) {
00119         MatchToken( "(" );
00120         for ( i = 0 ; i < m.height ; i++ ) {
00121             Parse1DMatrix( 5, verts[i*m.width+j].xyz );
00122         }
00123         MatchToken( ")" );
00124     }
00125     MatchToken( ")" );
00126 
00127   // if brush primitives format, we may have some epairs to ignore here
00128   GetToken(qtrue);
00129   if (g_bBrushPrimit!=BPRIMIT_OLDBRUSHES && strcmp(token,"}"))
00130   {
00131     // NOTE: we leak that!
00132     ep = ParseEpair();
00133   }
00134   else
00135     UnGetToken();
00136 
00137     MatchToken( "}" );
00138     MatchToken( "}" );
00139 
00140     if ( noCurveBrushes ) {
00141         return;
00142     }
00143 
00144     // find default flags and values
00145     pm = malloc( sizeof( *pm ) );
00146     memset( pm, 0, sizeof( *pm ) );
00147 
00148     sprintf( shader, "textures/%s", texture );
00149     pm->shaderInfo = ShaderInfoForShader( shader ); 
00150     pm->mesh = m;
00151 
00152     // link to the entity
00153     pm->next = mapent->patches;
00154     mapent->patches = pm;
00155 }
00156 
00157 
00158 void GrowGroup_r( int patchNum, int patchCount, const byte *bordering, byte *group ) {
00159     int     i;
00160     const byte *row;
00161 
00162     if ( group[patchNum] ) {
00163         return;
00164     }
00165     group[patchNum] = 1;
00166     row = bordering + patchNum * patchCount;
00167     for ( i = 0 ; i < patchCount ; i++ ) {
00168         if ( row[i] ) {
00169             GrowGroup_r( i, patchCount, bordering, group );
00170         }
00171     }
00172 }
00173 
00174 
00175 /*
00176 =====================
00177 PatchMapDrawSurfs
00178 
00179 Any patches that share an edge need to choose their
00180 level of detail as a unit, otherwise the edges would
00181 pull apart.
00182 =====================
00183 */
00184 void PatchMapDrawSurfs( entity_t *e ) {
00185     parseMesh_t         *pm;
00186     parseMesh_t         *check, *scan;
00187     mapDrawSurface_t    *ds;
00188     int                 patchCount, groupCount;
00189     int                 i, j, k, l, c1, c2;
00190     drawVert_t          *v1, *v2;
00191     vec3_t              bounds[2];
00192     byte                *bordering;
00193     parseMesh_t         *meshes[MAX_MAP_DRAW_SURFS];
00194     qboolean            grouped[MAX_MAP_DRAW_SURFS];
00195     byte                group[MAX_MAP_DRAW_SURFS];
00196 
00197     qprintf( "----- PatchMapDrawSurfs -----\n" );
00198 
00199     patchCount = 0;
00200     for ( pm = e->patches ; pm ; pm = pm->next  ) {
00201         meshes[patchCount] = pm;
00202         patchCount++;
00203     }
00204 
00205     if ( !patchCount ) {
00206         return;
00207     }
00208     bordering = malloc( patchCount * patchCount );
00209     memset( bordering, 0, patchCount * patchCount );
00210 
00211     // build the bordering matrix
00212     for ( k = 0 ; k < patchCount ; k++ ) {
00213         bordering[k*patchCount+k] = 1;
00214 
00215         for ( l = k+1 ; l < patchCount ; l++ ) {
00216             check = meshes[k];
00217             scan = meshes[l];
00218             c1 = scan->mesh.width * scan->mesh.height;
00219             v1 = scan->mesh.verts;
00220 
00221             for ( i = 0 ; i < c1 ; i++, v1++ ) {
00222                 c2 = check->mesh.width * check->mesh.height;
00223                 v2 = check->mesh.verts;
00224                 for ( j = 0 ; j < c2 ; j++, v2++ ) {
00225                     if ( fabs( v1->xyz[0] - v2->xyz[0] ) < 1.0
00226                         && fabs( v1->xyz[1] - v2->xyz[1] ) < 1.0
00227                         && fabs( v1->xyz[2] - v2->xyz[2] ) < 1.0 ) {
00228                         break;
00229                     }
00230                 }
00231                 if ( j != c2 ) {
00232                     break;
00233                 }
00234             }
00235             if ( i != c1 ) {
00236                 // we have a connection
00237                 bordering[k*patchCount+l] =
00238                 bordering[l*patchCount+k] = 1;
00239             } else {
00240                 // no connection
00241                 bordering[k*patchCount+l] =
00242                 bordering[l*patchCount+k] = 0;
00243             }
00244 
00245         }
00246     }
00247 
00248     // build groups
00249     memset( grouped, 0, sizeof(grouped) );
00250     groupCount = 0;
00251     for ( i = 0 ; i < patchCount ; i++ ) {
00252         if ( !grouped[i] ) {
00253             groupCount++;
00254         }
00255 
00256         // recursively find all patches that belong in the same group
00257         memset( group, 0, patchCount );
00258         GrowGroup_r( i, patchCount, bordering, group );
00259 
00260         // bound them
00261         ClearBounds( bounds[0], bounds[1] );
00262         for ( j = 0 ; j < patchCount ; j++ ) {
00263             if ( group[j] ) {
00264                 grouped[j] = qtrue;
00265                 scan = meshes[j];
00266                 c1 = scan->mesh.width * scan->mesh.height;
00267                 v1 = scan->mesh.verts;
00268                 for ( k = 0 ; k < c1 ; k++, v1++ ) {
00269                     AddPointToBounds( v1->xyz, bounds[0], bounds[1] );
00270                 }
00271             }
00272         }
00273 
00274         // create drawsurf
00275         scan = meshes[i];
00276         scan->grouped = qtrue;
00277         ds = DrawSurfaceForMesh( &scan->mesh );
00278         ds->shaderInfo = scan->shaderInfo;
00279         VectorCopy( bounds[0], ds->lightmapVecs[0] );
00280         VectorCopy( bounds[1], ds->lightmapVecs[1] );
00281     }
00282 
00283     qprintf( "%5i patches\n", patchCount );
00284     qprintf( "%5i patch LOD groups\n", groupCount );
00285 }
00286 

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