void idRenderEntityLocal::ReadFromDemoFile( class idDemoFile* f ) { int i; renderEntity_t ent; /* Initialize Pointers */ decals = NULL; overlays = NULL; dynamicModel = NULL; ent.referenceShader = NULL; ent.referenceSound = NULL; ent.hModel = NULL; ent.customSkin = NULL; ent.customShader = NULL; ent.joints = NULL; ent.callback = NULL; ent.callbackData = NULL; ent.remoteRenderView = NULL; f->ReadInt( index ); f->ReadInt( dynamicModelFrameCount ); f->ReadInt( ent.entityNum ); f->ReadInt( ent.bodyId ); f->ReadVec3( ent.bounds[ 0 ] ); f->ReadVec3( ent.bounds[ 1 ] ); f->ReadInt( ent.suppressSurfaceInViewID ); f->ReadInt( ent.suppressShadowInViewID ); f->ReadInt( ent.suppressShadowInLightID ); f->ReadInt( ent.allowSurfaceInViewID ); f->ReadVec3( ent.origin ); f->ReadMat3( ent.axis ); for ( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { f->ReadFloat( ent.shaderParms[ i ] ); } for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { f->ReadInt( (int&)ent.gui[ i ] ); ent.gui[ i ] = NULL; } f->ReadInt( i ); //( int& )ent.remoteRenderView f->ReadInt( ent.numJoints ); f->ReadFloat( ent.modelDepthHack ); f->ReadBool( ent.noSelfShadow ); f->ReadBool( ent.noShadow ); f->ReadBool( ent.noOverlays ); f->ReadBool( ent.noDynamicInteractions ); f->ReadBool( ent.weaponDepthHack ); f->ReadInt( ent.forceUpdate ); const char * declName = NULL; declName = f->ReadHashString(); ent.customShader = ( declName[ 0 ] != 0 ) ? declManager->FindMaterial( declName ) : NULL; declName = f->ReadHashString(); ent.referenceShader = ( declName[ 0 ] != 0 ) ? declManager->FindMaterial( declName ) : NULL; declName = f->ReadHashString(); ent.customSkin = ( declName[ 0 ] != 0 ) ? declManager->FindSkin( declName ) : NULL; int soundIndex = -1; f->ReadInt( soundIndex ); ent.referenceSound = soundIndex != -1 ? common->SW()->EmitterForIndex( soundIndex ) : NULL; const char * mdlName = f->ReadHashString(); ent.hModel = ( mdlName[ 0 ] != 0 ) ? renderModelManager->FindModel( mdlName ) : NULL; if ( ent.hModel != NULL ) { bool dynamicModel = false; f->ReadBool( dynamicModel ); if ( dynamicModel ) { ent.hModel->ReadFromDemoFile( f ); } } if ( ent.numJoints > 0 ) { ent.joints = (idJointMat*)Mem_Alloc16( SIMD_ROUND_JOINTS( ent.numJoints ) * sizeof( ent.joints[ 0 ] ), TAG_JOINTMAT ); for ( int i = 0; i < ent.numJoints; i++ ) { float* data = ent.joints[ i ].ToFloatPtr(); for ( int j = 0; j < 12; ++j ) { f->ReadFloat( data[ j ] ); } } SIMD_INIT_LAST_JOINT( ent.joints, ent.numJoints ); } f->ReadInt( ent.timeGroup ); f->ReadInt( ent.xrayIndex ); /* f->ReadInt( i ); if( i ) { ent.overlays = idRenderModelOverlay::Alloc(); ent.overlays->ReadFromDemoFile( f->Read ); } */ world->UpdateEntityDef( index, &ent ); for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { if ( parms.gui[ i ] ) { parms.gui[ i ] = uiManager->Alloc(); #ifdef WRITE_GUIS parms.gui[ i ]->ReadFromDemoFile( f->Read ); #endif } } if ( r_showDemo.GetBool() ) { common->Printf( "DC_UPDATE_ENTITYDEF: %i = %s\n", index, parms.hModel ? parms.hModel->Name() : "NULL" ); } }
/* ==================== idRenderModelMD5::LoadModel used for initial loads, reloadModel, and reloading the data of purged models Upon exit, the model will absolutely be valid, but possibly as a default model ==================== */ void idRenderModelMD5::LoadModel() { int version; int num; int parentNum; idToken token; idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS ); if( !purged ) { PurgeModel(); } purged = false; if( !parser.LoadFile( name ) ) { MakeDefaultModel(); return; } parser.ExpectTokenString( MD5_VERSION_STRING ); version = parser.ParseInt(); if( version != MD5_VERSION ) { parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION ); } // // skip commandline // parser.ExpectTokenString( "commandline" ); parser.ReadToken( &token ); // parse num joints parser.ExpectTokenString( "numJoints" ); num = parser.ParseInt(); joints.SetGranularity( 1 ); joints.SetNum( num ); defaultPose.SetGranularity( 1 ); defaultPose.SetNum( num ); // parse num meshes parser.ExpectTokenString( "numMeshes" ); num = parser.ParseInt(); if( num < 0 ) { parser.Error( "Invalid size: %d", num ); } meshes.SetGranularity( 1 ); meshes.SetNum( num ); // // parse joints // parser.ExpectTokenString( "joints" ); parser.ExpectTokenString( "{" ); idJointMat* poseMat = ( idJointMat* )_alloca16( joints.Num() * sizeof( poseMat[0] ) ); for( int i = 0; i < joints.Num(); i++ ) { idMD5Joint* joint = &joints[i]; idJointQuat* pose = &defaultPose[i]; ParseJoint( parser, joint, pose ); poseMat[ i ].SetRotation( pose->q.ToMat3() ); poseMat[ i ].SetTranslation( pose->t ); if( joint->parent ) { parentNum = joint->parent - joints.Ptr(); pose->q = ( poseMat[ i ].ToMat3() * poseMat[ parentNum ].ToMat3().Transpose() ).ToQuat(); pose->t = ( poseMat[ i ].ToVec3() - poseMat[ parentNum ].ToVec3() ) * poseMat[ parentNum ].ToMat3().Transpose(); } } parser.ExpectTokenString( "}" ); //----------------------------------------- // create the inverse of the base pose joints to support tech6 style deformation // of base pose vertexes, normals, and tangents. // // vertex * joints * inverseJoints == vertex when joints is the base pose // When the joints are in another pose, it gives the animated vertex position //----------------------------------------- invertedDefaultPose.SetNum( SIMD_ROUND_JOINTS( joints.Num() ) ); for( int i = 0; i < joints.Num(); i++ ) { invertedDefaultPose[i] = poseMat[i]; invertedDefaultPose[i].Invert(); } SIMD_INIT_LAST_JOINT( invertedDefaultPose.Ptr(), joints.Num() ); for( int i = 0; i < meshes.Num(); i++ ) { parser.ExpectTokenString( "mesh" ); meshes[i].ParseMesh( parser, defaultPose.Num(), poseMat ); } // calculate the bounds of the model bounds.Clear(); for( int i = 0; i < meshes.Num(); i++ ) { idBounds meshBounds; meshes[i].CalculateBounds( poseMat, meshBounds ); bounds.AddBounds( meshBounds ); } // set the timestamp for reloadmodels fileSystem->ReadFile( name, NULL, &timeStamp ); common->UpdateLevelLoadPacifier(true); }
/* ================ ReadRenderEntity ================ */ void idRenderWorldLocal::ReadRenderEntity() { renderEntity_t ent; int index, i; common->ReadDemo()->ReadInt( index ); if( index < 0 ) { common->Error( "ReadRenderEntity: index < 0" ); } common->ReadDemo()->ReadInt( ( int& )ent.hModel ); common->ReadDemo()->ReadInt( ent.entityNum ); common->ReadDemo()->ReadInt( ent.bodyId ); common->ReadDemo()->ReadVec3( ent.bounds[0] ); common->ReadDemo()->ReadVec3( ent.bounds[1] ); common->ReadDemo()->ReadInt( ( int& )ent.callback ); common->ReadDemo()->ReadInt( ( int& )ent.callbackData ); common->ReadDemo()->ReadInt( ent.suppressSurfaceInViewID ); common->ReadDemo()->ReadInt( ent.suppressShadowInViewID ); common->ReadDemo()->ReadInt( ent.suppressShadowInLightID ); common->ReadDemo()->ReadInt( ent.allowSurfaceInViewID ); common->ReadDemo()->ReadVec3( ent.origin ); common->ReadDemo()->ReadMat3( ent.axis ); common->ReadDemo()->ReadInt( ( int& )ent.customShader ); common->ReadDemo()->ReadInt( ( int& )ent.referenceShader ); common->ReadDemo()->ReadInt( ( int& )ent.customSkin ); common->ReadDemo()->ReadInt( ( int& )ent.referenceSound ); for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { common->ReadDemo()->ReadFloat( ent.shaderParms[i] ); } for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { common->ReadDemo()->ReadInt( ( int& )ent.gui[i] ); } common->ReadDemo()->ReadInt( ( int& )ent.remoteRenderView ); common->ReadDemo()->ReadInt( ent.numJoints ); common->ReadDemo()->ReadInt( ( int& )ent.joints ); common->ReadDemo()->ReadFloat( ent.modelDepthHack ); common->ReadDemo()->ReadBool( ent.noSelfShadow ); common->ReadDemo()->ReadBool( ent.noShadow ); common->ReadDemo()->ReadBool( ent.noDynamicInteractions ); common->ReadDemo()->ReadBool( ent.weaponDepthHack ); common->ReadDemo()->ReadInt( ent.forceUpdate ); ent.callback = NULL; if( ent.customShader ) { ent.customShader = declManager->FindMaterial( common->ReadDemo()->ReadHashString() ); } if( ent.customSkin ) { ent.customSkin = declManager->FindSkin( common->ReadDemo()->ReadHashString() ); } if( ent.hModel ) { ent.hModel = renderModelManager->FindModel( common->ReadDemo()->ReadHashString() ); } if( ent.referenceShader ) { ent.referenceShader = declManager->FindMaterial( common->ReadDemo()->ReadHashString() ); } if( ent.referenceSound ) { int index; common->ReadDemo()->ReadInt( index ); ent.referenceSound = common->SW()->EmitterForIndex( index ); } if( ent.numJoints ) { ent.joints = ( idJointMat* )Mem_Alloc16( SIMD_ROUND_JOINTS( ent.numJoints ) * sizeof( ent.joints[0] ), TAG_JOINTMAT ); for( int i = 0; i < ent.numJoints; i++ ) { float* data = ent.joints[i].ToFloatPtr(); for( int j = 0; j < 12; ++j ) { common->ReadDemo()->ReadFloat( data[j] ); } } SIMD_INIT_LAST_JOINT( ent.joints, ent.numJoints ); } ent.callbackData = NULL; /* if ( ent.decals ) { ent.decals = idRenderModelDecal::Alloc(); ent.decals->ReadFromDemoFile( common->ReadDemo() ); } if ( ent.overlays ) { ent.overlays = idRenderModelOverlay::Alloc(); ent.overlays->ReadFromDemoFile( common->ReadDemo() ); } */ for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { if( ent.gui[ i ] ) { ent.gui[ i ] = uiManager->Alloc(); #ifdef WRITE_GUIS ent.gui[ i ]->ReadFromDemoFile( common->ReadDemo() ); #endif } } common->ReadDemo()->ReadInt( ent.timeGroup ); common->ReadDemo()->ReadInt( ent.xrayIndex ); UpdateEntityDef( index, &ent ); if( r_showDemo.GetBool() ) { common->Printf( "DC_UPDATE_ENTITYDEF: %i = %s\n", index, ent.hModel ? ent.hModel->Name() : "NULL" ); } }