/* =============== R_CreateEntityRefs Creates all needed model references in portal areas, chaining them to both the area and the entityDef. Bumps tr.viewCount, which means viewCount can change many times each frame. =============== */ void R_CreateEntityRefs( idRenderEntityLocal *entity ) { if ( entity->parms.hModel == NULL ) { entity->parms.hModel = renderModelManager->DefaultModel(); } // if the entity hasn't been fully specified due to expensive animation calcs // for md5 and particles, use the provided conservative bounds. if ( entity->parms.callback != NULL ) { entity->localReferenceBounds = entity->parms.bounds; } else { entity->localReferenceBounds = entity->parms.hModel->Bounds( &entity->parms ); } // some models, like empty particles, may not need to be added at all if ( entity->localReferenceBounds.IsCleared() ) { return; } if ( r_showUpdates.GetBool() && ( entity->localReferenceBounds[1][0] - entity->localReferenceBounds[0][0] > 1024.0f || entity->localReferenceBounds[1][1] - entity->localReferenceBounds[0][1] > 1024.0f ) ) { common->Printf( "big entityRef: %f,%f\n", entity->localReferenceBounds[1][0] - entity->localReferenceBounds[0][0], entity->localReferenceBounds[1][1] - entity->localReferenceBounds[0][1] ); } // derive entity data R_DeriveEntityData( entity ); // bump the view count so we can tell if an // area already has a reference tr.viewCount++; // push the model frustum down the BSP tree into areas entity->world->PushFrustumIntoTree( entity, NULL, entity->inverseBaseModelProject, bounds_unitCube ); }
/* ===================== idRenderWorldLocal::AddWorldModelEntities ===================== */ void idRenderWorldLocal::AddWorldModelEntities() { // add the world model for each portal area // we can't just call AddEntityDef, because that would place the references // based on the bounding box, rather than explicitly into the correct area for( int i = 0; i < numPortalAreas; i++ ) { common->UpdateLevelLoadPacifier(); idRenderEntityLocal* def = new( TAG_RENDER_ENTITY ) idRenderEntityLocal; // try and reuse a free spot int index = entityDefs.FindNull(); if( index == -1 ) { index = entityDefs.Append( def ); } else { entityDefs[index] = def; } def->index = index; def->world = this; def->parms.hModel = renderModelManager->FindModel( va( "_area%i", i ) ); if( def->parms.hModel->IsDefaultModel() || !def->parms.hModel->IsStaticWorldModel() ) { common->Error( "idRenderWorldLocal::InitFromMap: bad area model lookup" ); } idRenderModel* hModel = def->parms.hModel; for( int j = 0; j < hModel->NumSurfaces(); j++ ) { const modelSurface_t* surf = hModel->Surface( j ); if( surf->shader->GetName() == idStr( "textures/smf/portal_sky" ) ) { def->needsPortalSky = true; } } // the local and global reference bounds are the same for area models def->localReferenceBounds = def->parms.hModel->Bounds(); def->globalReferenceBounds = def->parms.hModel->Bounds(); def->parms.axis[0][0] = 1.0f; def->parms.axis[1][1] = 1.0f; def->parms.axis[2][2] = 1.0f; // in case an explicit shader is used on the world, we don't // want it to have a 0 alpha or color def->parms.shaderParms[0] = 1.0f; def->parms.shaderParms[1] = 1.0f; def->parms.shaderParms[2] = 1.0f; def->parms.shaderParms[3] = 1.0f; R_DeriveEntityData( def ); AddEntityRefToArea( def, &portalAreas[i] ); } }