/*
===============
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] );
	}
}