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