bool idRenderModelBSP29NonMap::Load( idList<byte>& buffer, idSkinTranslation* skinTranslation ) { type = MOD_BRUSH29_NON_MAP; tr.currentModel = this; bsp29_dheader_t* header = ( bsp29_dheader_t* )buffer.Ptr(); int version = LittleLong( header->version ); if ( version != BSP29_VERSION ) { common->FatalError( "Mod_LoadBrush29Model: %s has wrong version number (%i should be %i)", name, version, BSP29_VERSION ); } // swap all the lumps byte* mod_base = ( byte* )header; for ( int i = 0; i < ( int )sizeof ( bsp29_dheader_t ) / 4; i++ ) { ( ( int* )header )[ i ] = LittleLong( ( ( int* )header )[ i ] ); } // load into heap idBsp29LoadHelper loader( name, mod_base ); loader.LoadVertexes( &header->lumps[ BSP29LUMP_VERTEXES ] ); loader.LoadEdges( &header->lumps[ BSP29LUMP_EDGES ] ); loader.LoadSurfedges( &header->lumps[ BSP29LUMP_SURFEDGES ] ); loader.LoadPlanes( &header->lumps[ BSP29LUMP_PLANES ] ); loader.LoadLighting( &header->lumps[ BSP29LUMP_LIGHTING ] ); loader.LoadTextures( &header->lumps[ BSP29LUMP_TEXTURES ] ); loader.LoadTexinfo( &header->lumps[ BSP29LUMP_TEXINFO ] ); loader.LoadFaces( &header->lumps[ BSP29LUMP_FACES ] ); delete[] loader.planes; brush29nm_lightdata = loader.lightdata; brush29nm_numtextures = loader.numtextures; brush29nm_textures = loader.textures; brush29nm_numtexinfo = loader.numtexinfo; brush29nm_texinfo = loader.texinfo; brush29nm_textureInfos = loader.textureInfos; brush29nm_numsurfaces = loader.numsurfaces; brush29nm_surfaces = loader.surfaces; if ( GGameType & GAME_Hexen2 ) { loader.LoadSubmodelsH2( &header->lumps[ BSP29LUMP_MODELS ] ); } else { loader.LoadSubmodelsQ1( &header->lumps[ BSP29LUMP_MODELS ] ); } q1_numframes = 2; // regular and alternate animation // // set up the submodels // mbrush29_submodel_t* bm = loader.submodels; brush29nm_firstmodelsurface = bm->firstface; brush29nm_nummodelsurfaces = bm->numfaces; VectorCopy( bm->maxs, q1_maxs ); VectorCopy( bm->mins, q1_mins ); q1_radius = RadiusFromBounds( q1_mins, q1_maxs ); delete[] loader.submodels; return true; }
void QClipMapNonMap::LoadMap( const char* name, const idList<quint8>& Buffer ) { this->Name = name; // call the apropriate loader switch ( LittleLong( *( unsigned* )Buffer.Ptr() ) ) { case RAPOLYHEADER: LoadAliasModelNew( Buffer.Ptr() ); break; case IDPOLYHEADER: LoadAliasModel( Buffer.Ptr() ); break; case IDSPRITE1HEADER: LoadSpriteModel( Buffer.Ptr() ); break; default: ModelMins[ 0 ] = ModelMins[ 1 ] = ModelMins[ 2 ] = -16; ModelMaxs[ 0 ] = ModelMaxs[ 1 ] = ModelMaxs[ 2 ] = 16; break; } }
bool idRenderModelMD3::Load( idList<byte>& buffer, idSkinTranslation* skinTranslation ) { q3_numLods = 0; // // load the files // int numLoaded = 0; int lod = MD3_MAX_LODS - 1; for (; lod >= 0; lod-- ) { char filename[ 1024 ]; String::Cpy( filename, name ); void* buf; if ( lod == 0 ) { buf = buffer.Ptr(); } else { char namebuf[ 80 ]; if ( String::RChr( filename, '.' ) ) { *String::RChr( filename, '.' ) = 0; } sprintf( namebuf, "_%d.md3", lod ); String::Cat( filename, sizeof ( filename ), namebuf ); FS_ReadFile( filename, ( void** )&buf ); if ( !buf ) { continue; } } int ident = LittleLong( *( unsigned* )buf ); if ( ident != MD3_IDENT ) { common->Printf( S_COLOR_YELLOW "R_LoadMd3: unknown fileid for %s\n", filename ); return false; } bool loaded = R_LoadMd3Lod( this, lod, buf, filename ); if ( lod != 0 ) { FS_FreeFile( buf ); } if ( !loaded ) { if ( lod == 0 ) { return false; } else { break; } } else { q3_numLods++; numLoaded++; // if we have a valid model and are biased // so that we won't see any higher detail ones, // stop loading them // if ( lod <= r_lodbias->integer ) { // break; // } } } if ( !numLoaded ) { return false; } // duplicate into higher lod spots that weren't // loaded, in case the user changes r_lodbias on the fly for ( lod--; lod >= 0; lod-- ) { q3_numLods++; q3_md3[ lod ] = q3_md3[ lod + 1 ]; } return true; }
bool idRenderModelMD4::Load( idList<byte>& buffer, idSkinTranslation* skinTranslation ) { md4Header_t* pinmodel = ( md4Header_t* )buffer.Ptr(); int version = LittleLong( pinmodel->version ); if ( version != MD4_VERSION ) { common->Printf( S_COLOR_YELLOW "R_LoadMD4: %s has wrong version (%i should be %i)\n", name, version, MD4_VERSION ); return false; } type = MOD_MD4; int size = LittleLong( pinmodel->ofsEnd ); q3_dataSize += size; md4Header_t* md4 = q3_md4 = ( md4Header_t* )Mem_Alloc( size ); Com_Memcpy( md4, buffer.Ptr(), LittleLong( pinmodel->ofsEnd ) ); LL( md4->ident ); LL( md4->version ); LL( md4->numFrames ); LL( md4->numBones ); LL( md4->numLODs ); LL( md4->ofsFrames ); LL( md4->ofsLODs ); LL( md4->ofsEnd ); if ( md4->numFrames < 1 ) { common->Printf( S_COLOR_YELLOW "R_LoadMD4: %s has no frames\n", name ); return false; } // we don't need to swap tags in the renderer, they aren't used // swap all the frames int frameSize = ( qintptr )( &( ( md4Frame_t* )0 )->bones[ md4->numBones ] ); for ( int i = 0; i < md4->numFrames; i++ ) { md4Frame_t* frame = ( md4Frame_t* )( ( byte* )md4 + md4->ofsFrames + i * frameSize ); frame->radius = LittleFloat( frame->radius ); for ( int j = 0; j < 3; j++ ) { frame->bounds[ 0 ][ j ] = LittleFloat( frame->bounds[ 0 ][ j ] ); frame->bounds[ 1 ][ j ] = LittleFloat( frame->bounds[ 1 ][ j ] ); frame->localOrigin[ j ] = LittleFloat( frame->localOrigin[ j ] ); } for ( int j = 0; j < md4->numBones * ( int )sizeof ( md4Bone_t ) / 4; j++ ) { ( ( float* )frame->bones )[ j ] = LittleFloat( ( ( float* )frame->bones )[ j ] ); } } // swap all the LOD's q3_md4Lods = new mmd4Lod_t[ md4->numLODs ]; md4LOD_t* lod = ( md4LOD_t* )( ( byte* )md4 + md4->ofsLODs ); for ( int lodindex = 0; lodindex < md4->numLODs; lodindex++ ) { // swap all the surfaces q3_md4Lods[ lodindex ].numSurfaces = lod->numSurfaces; q3_md4Lods[ lodindex ].surfaces = new idSurfaceMD4[ lod->numSurfaces ]; md4Surface_t* surf = ( md4Surface_t* )( ( byte* )lod + lod->ofsSurfaces ); for ( int i = 0; i < lod->numSurfaces; i++ ) { q3_md4Lods[ lodindex ].surfaces[ i ].SetMd4Data( surf ); LL( surf->ident ); LL( surf->numTriangles ); LL( surf->ofsTriangles ); LL( surf->numVerts ); LL( surf->ofsVerts ); LL( surf->ofsEnd ); if ( surf->numVerts > SHADER_MAX_VERTEXES ) { common->Error( "R_LoadMD3: %s has more than %i verts on a surface (%i)", name, SHADER_MAX_VERTEXES, surf->numVerts ); } if ( surf->numTriangles * 3 > SHADER_MAX_INDEXES ) { common->Error( "R_LoadMD3: %s has more than %i triangles on a surface (%i)", name, SHADER_MAX_INDEXES / 3, surf->numTriangles ); } // lowercase the surface name so skin compares are faster String::ToLower( surf->name ); // register the shaders shader_t* sh = R_FindShader( surf->shader, LIGHTMAP_NONE, true ); if ( sh->defaultShader ) { surf->shaderIndex = 0; } else { surf->shaderIndex = sh->index; } // swap all the triangles md4Triangle_t* tri = ( md4Triangle_t* )( ( byte* )surf + surf->ofsTriangles ); for ( int j = 0; j < surf->numTriangles; j++, tri++ ) { LL( tri->indexes[ 0 ] ); LL( tri->indexes[ 1 ] ); LL( tri->indexes[ 2 ] ); } // swap all the vertexes // FIXME // This makes TFC's skeletons work. Shouldn't be necessary anymore, but left // in for reference. //v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12); md4Vertex_t* v = ( md4Vertex_t* )( ( byte* )surf + surf->ofsVerts ); for ( int j = 0; j < surf->numVerts; j++ ) { v->normal[ 0 ] = LittleFloat( v->normal[ 0 ] ); v->normal[ 1 ] = LittleFloat( v->normal[ 1 ] ); v->normal[ 2 ] = LittleFloat( v->normal[ 2 ] ); v->texCoords[ 0 ] = LittleFloat( v->texCoords[ 0 ] ); v->texCoords[ 1 ] = LittleFloat( v->texCoords[ 1 ] ); v->numWeights = LittleLong( v->numWeights ); for ( int k = 0; k < v->numWeights; k++ ) { v->weights[ k ].boneIndex = LittleLong( v->weights[ k ].boneIndex ); v->weights[ k ].boneWeight = LittleFloat( v->weights[ k ].boneWeight ); v->weights[ k ].offset[ 0 ] = LittleFloat( v->weights[ k ].offset[ 0 ] ); v->weights[ k ].offset[ 1 ] = LittleFloat( v->weights[ k ].offset[ 1 ] ); v->weights[ k ].offset[ 2 ] = LittleFloat( v->weights[ k ].offset[ 2 ] ); } // FIXME // This makes TFC's skeletons work. Shouldn't be necessary anymore, but left // in for reference. //v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 ); v = ( md4Vertex_t* )( ( byte* )&v->weights[ v->numWeights ] ); } // find the next surface surf = ( md4Surface_t* )( ( byte* )surf + surf->ofsEnd ); } // find the next LOD lod = ( md4LOD_t* )( ( byte* )lod + lod->ofsEnd ); } return true; }
bool idRenderModelMDL::Load( idList<byte>& buffer, idSkinTranslation* skinTranslation ) { mdl_t* pinmodel = ( mdl_t* )buffer.Ptr(); int version = LittleLong( pinmodel->version ); if ( version != MESH1_VERSION ) { common->FatalError( "%s has wrong version number (%i should be %i)", name, version, MESH1_VERSION ); } // // allocate space for a working header, plus all the data except the frames, // skin and group info // mdl_pheader = new idSurfaceMDL; q1_flags = LittleLong( pinmodel->flags ); // // endian-adjust and copy the data, starting with the alias model header // mdl_pheader->header.boundingradius = LittleFloat( pinmodel->boundingradius ); mdl_pheader->header.numskins = LittleLong( pinmodel->numskins ); mdl_pheader->header.skinwidth = LittleLong( pinmodel->skinwidth ); mdl_pheader->header.skinheight = LittleLong( pinmodel->skinheight ); if ( mdl_pheader->header.skinheight > MAX_LBM_HEIGHT ) { common->FatalError( "model %s has a skin taller than %d", name, MAX_LBM_HEIGHT ); } mdl_pheader->header.numverts = LittleLong( pinmodel->numverts ); if ( mdl_pheader->header.numverts <= 0 ) { common->FatalError( "model %s has no vertices", name ); } if ( mdl_pheader->header.numverts > MAXALIASVERTS ) { common->FatalError( "model %s has too many vertices", name ); } mdl_pheader->header.numtris = LittleLong( pinmodel->numtris ); if ( mdl_pheader->header.numtris <= 0 ) { common->FatalError( "model %s has no mdl_triangles", name ); } mdl_pheader->header.numframes = LittleLong( pinmodel->numframes ); mdl_pheader->header.frames = new mmesh1framedesc_t[ mdl_pheader->header.numframes ]; int numframes = mdl_pheader->header.numframes; if ( numframes < 1 ) { common->FatalError( "Mod_LoadMdlModel: Invalid # of frames: %d\n", numframes ); } mdl_pheader->header.size = LittleFloat( pinmodel->size ) * ALIAS_BASE_SIZE_RATIO; q1_synctype = ( synctype_t )LittleLong( pinmodel->synctype ); q1_numframes = mdl_pheader->header.numframes; for ( int i = 0; i < 3; i++ ) { mdl_pheader->header.scale[ i ] = LittleFloat( pinmodel->scale[ i ] ); mdl_pheader->header.scale_origin[ i ] = LittleFloat( pinmodel->scale_origin[ i ] ); mdl_pheader->header.eyeposition[ i ] = LittleFloat( pinmodel->eyeposition[ i ] ); } // // load the skins // dmdl_skintype_t* pskintype = ( dmdl_skintype_t* )&pinmodel[ 1 ]; pskintype = ( dmdl_skintype_t* )Mod_LoadAllSkins( mdl_pheader->header.numskins, pskintype, q1_flags, skinTranslation ); // // load base s and t vertices // dmdl_stvert_t* pinstverts = ( dmdl_stvert_t* )pskintype; for ( int i = 0; i < mdl_pheader->header.numverts; i++ ) { mdl_stverts[ i ].onseam = LittleLong( pinstverts[ i ].onseam ); mdl_stverts[ i ].s = LittleLong( pinstverts[ i ].s ); mdl_stverts[ i ].t = LittleLong( pinstverts[ i ].t ); } // // load triangle lists // dmdl_triangle_t* pintriangles = ( dmdl_triangle_t* )&pinstverts[ mdl_pheader->header.numverts ]; for ( int i = 0; i < mdl_pheader->header.numtris; i++ ) { mdl_triangles[ i ].facesfront = LittleLong( pintriangles[ i ].facesfront ); for ( int j = 0; j < 3; j++ ) { mdl_triangles[ i ].vertindex[ j ] = LittleLong( pintriangles[ i ].vertindex[ j ] ); mdl_triangles[ i ].stindex[ j ] = mdl_triangles[ i ].vertindex[ j ]; } } // // load the frames // mdl_posenum = 0; dmdl_frametype_t* pframetype = ( dmdl_frametype_t* )&pintriangles[ mdl_pheader->header.numtris ]; mdl_mins[ 0 ] = mdl_mins[ 1 ] = mdl_mins[ 2 ] = 32768; mdl_maxs[ 0 ] = mdl_maxs[ 1 ] = mdl_maxs[ 2 ] = -32768; for ( int i = 0; i < numframes; i++ ) { mdl_frametype_t frametype = ( mdl_frametype_t )LittleLong( pframetype->type ); if ( frametype == ALIAS_SINGLE ) { pframetype = ( dmdl_frametype_t* )Mod_LoadAliasFrame( pframetype + 1, &mdl_pheader->header.frames[ i ] ); } else { pframetype = ( dmdl_frametype_t* )Mod_LoadAliasGroup( pframetype + 1, &mdl_pheader->header.frames[ i ] ); } } mdl_pheader->header.numposes = mdl_posenum; type = MOD_MESH1; // FIXME: do this right if ( GGameType & GAME_Hexen2 ) { q1_mins[ 0 ] = mdl_mins[ 0 ] - 10; q1_mins[ 1 ] = mdl_mins[ 1 ] - 10; q1_mins[ 2 ] = mdl_mins[ 2 ] - 10; q1_maxs[ 0 ] = mdl_maxs[ 0 ] + 10; q1_maxs[ 1 ] = mdl_maxs[ 1 ] + 10; q1_maxs[ 2 ] = mdl_maxs[ 2 ] + 10; } else { q1_mins[ 0 ] = q1_mins[ 1 ] = q1_mins[ 2 ] = -16; q1_maxs[ 0 ] = q1_maxs[ 1 ] = q1_maxs[ 2 ] = 16; } // // build the draw lists // GL_MakeAliasModelDisplayLists( this, mdl_pheader ); q1_mdl = mdl_pheader; return true; }