/************************************************************************************************ * RE_AddMiniRefEntityToScene * * Adds a mini ref ent to the scene. If the input parameter is null, it signifies the end * * of the chain. Otherwise, if there is a valid chain parent, it will be added to that. * * If there is no parent, it will be added as a regular ref ent. * * * * Input * * ent: the mini ref ent to be added * * * * Output / Return * * none * * * ************************************************************************************************/ void RE_AddMiniRefEntityToScene( const miniRefEntity_t *ent ) { #if 0 refEntity_t *parent; #endif if ( !tr.registered ) { return; } if (!ent) { refEntParent = -1; return; } #if 1 //i hate you minirefent! refEntity_t tempEnt; memcpy(&tempEnt, ent, sizeof(*ent)); memset(((char *)&tempEnt)+sizeof(*ent), 0, sizeof(tempEnt) - sizeof(*ent)); RE_AddRefEntityToScene(&tempEnt); #else if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { Com_Error( ERR_DROP, "RE_AddMiniRefEntityToScene: bad reType %i", ent->reType ); } if (!r_numentities || refEntParent == -1 || r_numminientities >= MAX_MINI_ENTITIES) { //rww - add it as a refent also if we run out of minis // Com_Error( ERR_DROP, "RE_AddMiniRefEntityToScene: mini without parent ref ent"); refEntity_t tempEnt; memcpy(&tempEnt, ent, sizeof(*ent)); memset(((char *)&tempEnt)+sizeof(*ent), 0, sizeof(tempEnt) - sizeof(*ent)); RE_AddRefEntityToScene(&tempEnt); return; } parent = &backEndData->entities[refEntParent].e; parent->uRefEnt.uMini.miniCount++; backEndData->miniEntities[r_numminientities].e = *ent; r_numminientities++; #endif }
/************************************************************************************************ * RE_AddMiniRefEntityToScene * * Adds a mini ref ent to the scene. If the input parameter is null, it signifies the end * * of the chain. Otherwise, if there is a valid chain parent, it will be added to that. * * If there is no parent, it will be added as a regular ref ent. * * * * Input * * ent: the mini ref ent to be added * * * * Output / Return * * none * * * ************************************************************************************************/ void RE_AddMiniRefEntityToScene( const miniRefEntity_t *ent ) { refEntity_t *parent; if ( !tr.registered ) { return; } if (!ent) { refEntParent = -1; return; } if ( r_numminientities >= MAX_MINI_ENTITIES) { ri.Printf( PRINT_WARNING, S_COLOR_YELLOW "WARNING: Attempting to add too many miniRefEntity_t\n"); return; } if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { ri.Error( ERR_DROP, "RE_AddMiniRefEntityToScene: bad reType %i", ent->reType ); } if (!r_numentities || refEntParent == -1) { // ri.Error( ERR_DROP, "RE_AddMiniRefEntityToScene: mini without parent ref ent"); refEntity_t tempEnt; memcpy(&tempEnt, ent, sizeof(*ent)); memset(((char *)&tempEnt)+sizeof(*ent), 0, sizeof(tempEnt) - sizeof(*ent)); RE_AddRefEntityToScene(&tempEnt); return; } parent = &backEndData[tr.smpFrame]->entities[refEntParent].e; parent->uRefEnt.uMini.miniCount++; backEndData[tr.smpFrame]->miniEntities[r_numminientities].e = *ent; r_numminientities++; }
void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { #else static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { #endif vec3_t lightOrigin; int pos[3]; int i, j; float frac[3]; int gridStep[3]; vec3_t direction; float totalFactor; unsigned short *startGridPos; if (r_fullbright->integer || (tr.refdef.rdflags & RDF_doLAGoggles) ) { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 255.0; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 255.0; VectorCopy( tr.sunDirection, ent->lightDir ); return; } if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) { // seperate lightOrigins are needed so an object that is // sinking into the ground can still be lit, and so // multi-part models can be lit identically VectorCopy( ent->e.lightingOrigin, lightOrigin ); } else { VectorCopy( ent->e.origin, lightOrigin ); } #define ACCURATE_LIGHTGRID_SAMPLING 1 #if ACCURATE_LIGHTGRID_SAMPLING vec3_t startLightOrigin; VectorCopy( lightOrigin, startLightOrigin ); #endif VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin ); for ( i = 0 ; i < 3 ; i++ ) { float v; v = lightOrigin[i]*tr.world->lightGridInverseSize[i]; pos[i] = floor( v ); frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) { pos[i] = tr.world->lightGridBounds[i] - 1; } } VectorClear( ent->ambientLight ); VectorClear( ent->directedLight ); VectorClear( direction ); // trilerp the light value gridStep[0] = 1; gridStep[1] = tr.world->lightGridBounds[0]; gridStep[2] = tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1]; startGridPos = tr.world->lightGridArray + pos[0] * gridStep[0] + pos[1] * gridStep[1] + pos[2] * gridStep[2]; #if ACCURATE_LIGHTGRID_SAMPLING vec3_t startGridOrg; VectorCopy( tr.world->lightGridOrigin, startGridOrg ); startGridOrg[0] += pos[0] * tr.world->lightGridSize[0]; startGridOrg[1] += pos[1] * tr.world->lightGridSize[1]; startGridOrg[2] += pos[2] * tr.world->lightGridSize[2]; #endif totalFactor = 0; for ( i = 0 ; i < 8 ; i++ ) { float factor; mgrid_t *data; unsigned short *gridPos; int lat, lng; vec3_t normal; #if ACCURATE_LIGHTGRID_SAMPLING vec3_t gridOrg; VectorCopy( startGridOrg, gridOrg ); #endif factor = 1.0; gridPos = startGridPos; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1<<j) ) { factor *= frac[j]; gridPos += gridStep[j]; #if ACCURATE_LIGHTGRID_SAMPLING gridOrg[j] += tr.world->lightGridSize[j]; #endif } else { factor *= (1.0 - frac[j]); } } if (gridPos >= tr.world->lightGridArray + tr.world->numGridArrayElements) {//we've gone off the array somehow continue; } data = tr.world->lightGridData + *gridPos; if ( data->styles[0] == LS_NONE ) { continue; // ignore samples in walls } #if 0 if ( !SV_inPVS( startLightOrigin, gridOrg ) ) { continue; } #endif totalFactor += factor; for(j=0;j<MAXLIGHTMAPS;j++) { if (data->styles[j] != LS_NONE) { const byte style= data->styles[j]; ent->ambientLight[0] += factor * data->ambientLight[j][0] * styleColors[style][0] / 255.0f; ent->ambientLight[1] += factor * data->ambientLight[j][1] * styleColors[style][1] / 255.0f; ent->ambientLight[2] += factor * data->ambientLight[j][2] * styleColors[style][2] / 255.0f; ent->directedLight[0] += factor * data->directLight[j][0] * styleColors[style][0] / 255.0f; ent->directedLight[1] += factor * data->directLight[j][1] * styleColors[style][1] / 255.0f; ent->directedLight[2] += factor * data->directLight[j][2] * styleColors[style][2] / 255.0f; } else { break; } } lat = data->latLong[1]; lng = data->latLong[0]; lat *= (FUNCTABLE_SIZE/256); lng *= (FUNCTABLE_SIZE/256); // decode X as cos( lat ) * sin( long ) // decode Y as sin( lat ) * sin( long ) // decode Z as cos( long ) normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; VectorMA( direction, factor, normal, direction ); #if ACCURATE_LIGHTGRID_SAMPLING if ( r_debugLight->integer && ent->e.hModel == -1 ) { //draw refEntity_t refEnt; refEnt.hModel = 0; refEnt.ghoul2 = NULL; refEnt.renderfx = 0; VectorCopy( gridOrg, refEnt.origin ); vectoangles( normal, refEnt.angles ); AnglesToAxis( refEnt.angles, refEnt.axis ); refEnt.reType = RT_MODEL; RE_AddRefEntityToScene( &refEnt ); refEnt.renderfx = RF_DEPTHHACK; refEnt.reType = RT_SPRITE; refEnt.customShader = RE_RegisterShader( "gfx/misc/debugAmbient" ); refEnt.shaderRGBA[0] = data->ambientLight[0][0]; refEnt.shaderRGBA[1] = data->ambientLight[0][1]; refEnt.shaderRGBA[2] = data->ambientLight[0][2]; refEnt.shaderRGBA[3] = 255; refEnt.radius = factor*50+2.0f; // maybe always give it a minimum size? refEnt.rotation = 0; // don't let the sprite wobble around RE_AddRefEntityToScene( &refEnt ); refEnt.reType = RT_LINE; refEnt.customShader = RE_RegisterShader( "gfx/misc/debugArrow" ); refEnt.shaderRGBA[0] = data->directLight[0][0]; refEnt.shaderRGBA[1] = data->directLight[0][1]; refEnt.shaderRGBA[2] = data->directLight[0][2]; refEnt.shaderRGBA[3] = 255; VectorCopy( refEnt.origin, refEnt.oldorigin ); VectorMA( gridOrg, (factor*-255) - 2.0f, normal, refEnt.origin ); // maybe always give it a minimum length refEnt.radius = 1.5f; RE_AddRefEntityToScene( &refEnt ); } #endif } if ( totalFactor > 0 && totalFactor < 0.99 ) { totalFactor = 1.0 / totalFactor; VectorScale( ent->ambientLight, totalFactor, ent->ambientLight ); VectorScale( ent->directedLight, totalFactor, ent->directedLight ); } VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight ); VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight ); VectorNormalize2( direction, ent->lightDir ); }