Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

misc_model.c (12365B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 
     23 #include "qbsp.h"
     24 #include "aselib.h"
     25 #ifdef _WIN32
     26 #ifdef _TTIMOBUILD
     27 #include "pakstuff.h"
     28 #else
     29 #include "../libs/pakstuff.h"
     30 #endif
     31 #endif
     32 
     33 
     34 typedef struct {
     35 	char		modelName[1024];
     36 	md3Header_t	*header;
     37 } loadedModel_t;
     38 
     39 int		c_triangleModels;
     40 int		c_triangleSurfaces;
     41 int		c_triangleVertexes;
     42 int		c_triangleIndexes;
     43 
     44 
     45 #define	MAX_LOADED_MODELS	1024
     46 loadedModel_t		loadedModels[MAX_LOADED_MODELS];
     47 int					numLoadedModels;
     48 
     49 /*
     50 =================
     51 R_LoadMD3
     52 =================
     53 */
     54 #define	LL(x) x=LittleLong(x)
     55 md3Header_t *R_LoadMD3( const char *mod_name ) {
     56 	int					i, j;
     57 	md3Header_t			*md3;
     58     md3Frame_t			*frame;
     59 	md3Surface_t		*surf;
     60 	md3Triangle_t		*tri;
     61 	md3St_t				*st;
     62 	md3XyzNormal_t		*xyz;
     63 	int					version;
     64 	char				filename[1024];
     65 	int					len;
     66 
     67 	sprintf( filename, "%s%s", gamedir, mod_name );
     68 	len = TryLoadFile( filename, (void **)&md3 );
     69 #ifdef _WIN32
     70   if ( len <= 0 ) {
     71     len = PakLoadAnyFile(filename, (void **)&md3);
     72   }
     73 #endif
     74 	if ( len <= 0 ) {
     75 	  return NULL;
     76 	}
     77 
     78   version = LittleLong (md3->version);
     79 	if (version != MD3_VERSION) {
     80 		_printf( "R_LoadMD3: %s has wrong version (%i should be %i)\n",
     81 				 mod_name, version, MD3_VERSION);
     82 		return NULL;
     83 	}
     84 
     85     LL(md3->ident);
     86     LL(md3->version);
     87     LL(md3->numFrames);
     88     LL(md3->numTags);
     89     LL(md3->numSurfaces);
     90     LL(md3->numSkins);
     91     LL(md3->ofsFrames);
     92     LL(md3->ofsTags);
     93     LL(md3->ofsSurfaces);
     94     LL(md3->ofsEnd);
     95 
     96 	if ( md3->numFrames < 1 ) {
     97 		_printf( "R_LoadMD3: %s has no frames\n", mod_name );
     98 		return NULL;
     99 	}
    100 
    101     // we don't need to swap tags in the renderer, they aren't used
    102     
    103 	// swap all the frames
    104     frame = (md3Frame_t *) ( (byte *)md3 + md3->ofsFrames );
    105     for ( i = 0 ; i < md3->numFrames ; i++, frame++) {
    106     	frame->radius = LittleFloat( frame->radius );
    107         for ( j = 0 ; j < 3 ; j++ ) {
    108             frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
    109             frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
    110 	    	frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
    111         }
    112 	}
    113 
    114 	// swap all the surfaces
    115 	surf = (md3Surface_t *) ( (byte *)md3 + md3->ofsSurfaces );
    116 	for ( i = 0 ; i < md3->numSurfaces ; i++) {
    117 
    118         LL(surf->ident);
    119         LL(surf->flags);
    120         LL(surf->numFrames);
    121         LL(surf->numShaders);
    122         LL(surf->numTriangles);
    123         LL(surf->ofsTriangles);
    124         LL(surf->numVerts);
    125         LL(surf->ofsShaders);
    126         LL(surf->ofsSt);
    127         LL(surf->ofsXyzNormals);
    128         LL(surf->ofsEnd);
    129 		
    130 		if ( surf->numVerts > SHADER_MAX_VERTEXES ) {
    131 			Error ("R_LoadMD3: %s has more than %i verts on a surface (%i)",
    132 				mod_name, SHADER_MAX_VERTEXES, surf->numVerts );
    133 		}
    134 		if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) {
    135 			Error ("R_LoadMD3: %s has more than %i triangles on a surface (%i)",
    136 				mod_name, SHADER_MAX_INDEXES / 3, surf->numTriangles );
    137 		}
    138 
    139 		// swap all the triangles
    140 		tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
    141 		for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
    142 			LL(tri->indexes[0]);
    143 			LL(tri->indexes[1]);
    144 			LL(tri->indexes[2]);
    145 		}
    146 
    147 		// swap all the ST
    148         st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
    149         for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
    150             st->st[0] = LittleFloat( st->st[0] );
    151             st->st[1] = LittleFloat( st->st[1] );
    152         }
    153 
    154 		// swap all the XyzNormals
    155         xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
    156         for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ ) 
    157 		{
    158             xyz->xyz[0] = LittleShort( xyz->xyz[0] );
    159             xyz->xyz[1] = LittleShort( xyz->xyz[1] );
    160             xyz->xyz[2] = LittleShort( xyz->xyz[2] );
    161 
    162             xyz->normal = LittleShort( xyz->normal );
    163         }
    164 
    165 
    166 		// find the next surface
    167 		surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
    168 	}
    169 
    170 	return md3;
    171 }
    172 
    173 
    174 /*
    175 ================
    176 LoadModel
    177 ================
    178 */
    179 md3Header_t *LoadModel( const char *modelName ) {
    180 	int				i;
    181 	loadedModel_t	*lm;
    182 
    183 	// see if we already have it loaded
    184 	for ( i = 0, lm = loadedModels ; i < numLoadedModels ; i++, lm++ ) {
    185 		if ( !strcmp( modelName, lm->modelName ) ) {
    186 			return lm->header;
    187 		}
    188 	}
    189 
    190 	// load it
    191 	if ( numLoadedModels == MAX_LOADED_MODELS ) {
    192 		Error( "MAX_LOADED_MODELS" );
    193 	}
    194 	numLoadedModels++;
    195 
    196 	strcpy( lm->modelName, modelName );
    197 
    198 	lm->header = R_LoadMD3( modelName );
    199 
    200 	return lm->header;
    201 }
    202 
    203 /*
    204 ============
    205 InsertMD3Model
    206 
    207 Convert a model entity to raw geometry surfaces and insert it in the tree
    208 ============
    209 */
    210 void InsertMD3Model( const char *modelName, vec3_t origin, float angle, tree_t *tree ) {
    211 	int					i, j;
    212 	md3Header_t			*md3;
    213 	md3Surface_t		*surf;
    214 	md3Shader_t			*shader;
    215 	md3Triangle_t		*tri;
    216 	md3St_t				*st;
    217 	md3XyzNormal_t		*xyz;
    218 	drawVert_t			*outv;
    219 	float				lat, lng;
    220 	float				angleCos, angleSin;
    221 	mapDrawSurface_t	*out;
    222 	vec3_t				temp;
    223 
    224 	angle = angle / 180 * Q_PI;
    225 	angleCos = cos( angle );
    226 	angleSin = sin( angle );
    227 
    228 	// load the model
    229 	md3 = LoadModel( modelName );
    230 	if ( !md3 ) {
    231 		return;
    232 	}
    233 
    234 	// each md3 surface will become a new bsp surface
    235 
    236 	c_triangleModels++;
    237 	c_triangleSurfaces += md3->numSurfaces;
    238 
    239 	// expand, translate, and rotate the vertexes
    240 	// swap all the surfaces
    241 	surf = (md3Surface_t *) ( (byte *)md3 + md3->ofsSurfaces );
    242 	for ( i = 0 ; i < md3->numSurfaces ; i++) {
    243 		// allocate a surface
    244 		out = AllocDrawSurf();
    245 		out->miscModel = qtrue;
    246 
    247         shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
    248 
    249 		out->shaderInfo = ShaderInfoForShader( shader->name );
    250 
    251 		out->numVerts = surf->numVerts;
    252 		out->verts = malloc( out->numVerts * sizeof( out->verts[0] ) );
    253 
    254 		out->numIndexes = surf->numTriangles * 3;
    255 		out->indexes = malloc( out->numIndexes * sizeof( out->indexes[0] ) );
    256 
    257 		out->lightmapNum = -1;
    258 		out->fogNum = -1;
    259 
    260 		// emit the indexes
    261 		c_triangleIndexes += surf->numTriangles * 3;
    262 		tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
    263 		for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
    264 			out->indexes[j*3+0] = tri->indexes[0];
    265 			out->indexes[j*3+1] = tri->indexes[1];
    266 			out->indexes[j*3+2] = tri->indexes[2];
    267 		}
    268 
    269 		// emit the vertexes
    270         st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
    271         xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
    272 
    273 		c_triangleVertexes += surf->numVerts;
    274 		for ( j = 0 ; j < surf->numVerts ; j++, st++, xyz++ ) {
    275 			outv = &out->verts[ j ];
    276 
    277 			outv->st[0] = st->st[0];
    278 			outv->st[1] = st->st[1];
    279 
    280 			outv->lightmap[0] = 0;
    281 			outv->lightmap[1] = 0;
    282 
    283 			// the colors will be set by the lighting pass
    284 			outv->color[0] = 255;
    285 			outv->color[1] = 255;
    286 			outv->color[2] = 255;
    287 			outv->color[3] = 255;
    288 
    289 			outv->xyz[0] = origin[0] + MD3_XYZ_SCALE * ( xyz->xyz[0] * angleCos - xyz->xyz[1] * angleSin );
    290 			outv->xyz[1] = origin[1] + MD3_XYZ_SCALE * ( xyz->xyz[0] * angleSin +  xyz->xyz[1] * angleCos );
    291 			outv->xyz[2] = origin[2] + MD3_XYZ_SCALE * ( xyz->xyz[2] );
    292 
    293 			// decode the lat/lng normal to a 3 float normal
    294 			lat = ( xyz->normal >> 8 ) & 0xff;
    295 			lng = ( xyz->normal & 0xff );
    296 			lat *= Q_PI/128;
    297 			lng *= Q_PI/128;
    298 
    299 			temp[0] = cos(lat) * sin(lng);
    300 			temp[1] = sin(lat) * sin(lng);
    301 			temp[2] = cos(lng);
    302 
    303 			// rotate the normal
    304 			outv->normal[0] = temp[0] * angleCos - temp[1] * angleSin;
    305 			outv->normal[1] = temp[0] * angleSin +  temp[1] * angleCos;
    306 			outv->normal[2] = temp[2];
    307 		}
    308 
    309 		// find the next surface
    310 		surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
    311 	}
    312 
    313 }
    314 
    315 //==============================================================================
    316 
    317 
    318 /*
    319 ============
    320 InsertASEModel
    321 
    322 Convert a model entity to raw geometry surfaces and insert it in the tree
    323 ============
    324 */
    325 void InsertASEModel( const char *modelName, vec3_t origin, float angle, tree_t *tree ) {
    326 	int					i, j;
    327 	drawVert_t			*outv;
    328 	float				angleCos, angleSin;
    329 	mapDrawSurface_t	*out;
    330 	int					numSurfaces;
    331 	const char			*name;
    332 	polyset_t			*pset;
    333 	int					numFrames;
    334 	char				filename[1024];
    335 
    336 	sprintf( filename, "%s%s", gamedir, modelName );
    337 
    338 	angle = angle / 180 * Q_PI;
    339 	angleCos = cos( angle );
    340 	angleSin = sin( angle );
    341 
    342 	// load the model
    343 	ASE_Load( filename, qfalse, qfalse );
    344 
    345 	// each ase surface will become a new bsp surface
    346 	numSurfaces = ASE_GetNumSurfaces();
    347 
    348 	c_triangleModels++;
    349 	c_triangleSurfaces += numSurfaces;
    350 
    351 	// expand, translate, and rotate the vertexes
    352 	// swap all the surfaces
    353 	for ( i = 0 ; i < numSurfaces ; i++) {
    354 		name = ASE_GetSurfaceName( i );
    355 
    356 		pset = ASE_GetSurfaceAnimation( i, &numFrames, -1, -1, -1 );
    357 		if ( !name || !pset ) {
    358 			continue;
    359 		}
    360 
    361 		// allocate a surface
    362 		out = AllocDrawSurf();
    363 		out->miscModel = qtrue;
    364 
    365 		out->shaderInfo = ShaderInfoForShader( pset->materialname );
    366 
    367 		out->numVerts = 3 * pset->numtriangles;
    368 		out->verts = malloc( out->numVerts * sizeof( out->verts[0] ) );
    369 
    370 		out->numIndexes = 3 * pset->numtriangles;
    371 		out->indexes = malloc( out->numIndexes * sizeof( out->indexes[0] ) );
    372 
    373 		out->lightmapNum = -1;
    374 		out->fogNum = -1;
    375 
    376 		// emit the indexes
    377 		c_triangleIndexes += out->numIndexes;
    378 		for ( j = 0 ; j < out->numIndexes ; j++ ) {
    379 			out->indexes[j] = j;
    380 		}
    381 
    382 		// emit the vertexes
    383 		c_triangleVertexes += out->numVerts;
    384 		for ( j = 0 ; j < out->numVerts ; j++ ) {
    385 			int		index;
    386 			triangle_t	*tri;
    387 
    388 			index = j % 3;
    389 			tri = &pset->triangles[ j / 3 ];
    390 
    391 			outv = &out->verts[ j ];
    392 
    393 			outv->st[0] = tri->texcoords[index][0];
    394 			outv->st[1] = tri->texcoords[index][1];
    395 
    396 			outv->lightmap[0] = 0;
    397 			outv->lightmap[1] = 0;
    398 
    399 			// the colors will be set by the lighting pass
    400 			outv->color[0] = 255;
    401 			outv->color[1] = 255;
    402 			outv->color[2] = 255;
    403 			outv->color[3] = 255;
    404 
    405 			outv->xyz[0] = origin[0] + tri->verts[index][0];
    406 			outv->xyz[1] = origin[1] + tri->verts[index][1];
    407 			outv->xyz[2] = origin[2] + tri->verts[index][2];
    408 
    409 			// rotate the normal
    410 			outv->normal[0] = tri->normals[index][0];
    411 			outv->normal[1] = tri->normals[index][1];
    412 			outv->normal[2] = tri->normals[index][2];
    413 		}
    414 	}
    415 
    416 }
    417 
    418 
    419 //==============================================================================
    420 
    421 
    422 
    423 /*
    424 =====================
    425 AddTriangleModels
    426 =====================
    427 */
    428 void AddTriangleModels( tree_t *tree ) {
    429 	int			entity_num;
    430 	entity_t	*entity;
    431 
    432 	qprintf("----- AddTriangleModels -----\n");
    433 
    434 	for ( entity_num=1 ; entity_num< num_entities ; entity_num++ ) {
    435 		entity = &entities[entity_num];
    436 	
    437 		// convert misc_models into raw geometry
    438 		if ( !Q_stricmp( "misc_model", ValueForKey( entity, "classname" ) ) ) {
    439 			const char	*model;
    440 			vec3_t	origin;
    441 			float	angle;
    442 
    443 			// get the angle for rotation  FIXME: support full matrix positioning
    444 			angle = FloatForKey( entity, "angle" );
    445 
    446 			GetVectorForKey( entity, "origin", origin );
    447 
    448 			model = ValueForKey( entity, "model" );
    449 			if ( !model[0] ) {
    450 				_printf("WARNING: misc_model at %i %i %i without a model key\n", (int)origin[0],
    451 					(int)origin[1], (int)origin[2] );
    452 				continue;
    453 			}
    454 			if ( strstr( model, ".md3" ) || strstr( model, ".MD3" ) ) {
    455 				InsertMD3Model( model, origin, angle, tree );
    456 				continue;
    457 			}
    458 			if ( strstr( model, ".ase" ) || strstr( model, ".ASE" ) ) {
    459 				InsertASEModel( model, origin, angle, tree );
    460 				continue;
    461 			}
    462 			_printf( "Unknown misc_model type: %s\n", model );
    463 			continue;
    464 		}
    465 	}
    466 
    467 	qprintf( "%5i triangle models\n", c_triangleModels );
    468 	qprintf( "%5i triangle surfaces\n", c_triangleSurfaces );
    469 	qprintf( "%5i triangle vertexes\n", c_triangleVertexes );
    470 	qprintf( "%5i triangle indexes\n", c_triangleIndexes );
    471 }
    472