void AddEmitSurfaceLights( const Vector &vStart, Vector lightBoxColor[6] )
{
	fltx4 fractionVisible;

	FourVectors vStart4, wlOrigin4;
	vStart4.DuplicateVector ( vStart );

	for ( int iLight=0; iLight < *pNumworldlights; iLight++ )
	{
		dworldlight_t *wl = &dworldlights[iLight];

		// Should this light even go in the ambient cubes?
		if ( !( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) )
			continue;

		Assert( wl->type == emit_surface );

		// Can this light see the point?
		wlOrigin4.DuplicateVector ( wl->origin );
		TestLine ( vStart4, wlOrigin4, &fractionVisible );
		if ( !TestSignSIMD ( CmpGtSIMD ( fractionVisible, Four_Zeros ) ) )
			continue;

		// Add this light's contribution.
		Vector vDelta = wl->origin - vStart;
		float flDistanceScale = Engine_WorldLightDistanceFalloff( wl, vDelta );

		Vector vDeltaNorm = vDelta;
		VectorNormalize( vDeltaNorm );
		float flAngleScale = Engine_WorldLightAngle( wl, wl->normal, vDeltaNorm, vDeltaNorm );

		float ratio = flDistanceScale * flAngleScale * SubFloat ( fractionVisible, 0 );
		if ( ratio == 0 )
			continue;

		for ( int i=0; i < 6; i++ )
		{
			float t = DotProduct( g_BoxDirections[i], vDeltaNorm );
			if ( t > 0 )
			{
				lightBoxColor[i] += wl->intensity * (t * ratio);
			}
		}
	}	
}
Exemplo n.º 2
0
void AddEmitSurfaceLights( const Vector &vStart, Vector lightBoxColor[6] )
{
	int iThread = 0;

	for ( int iLight=0; iLight < *pNumworldlights; iLight++ )
	{
		dworldlight_t *wl = &dworldlights[iLight];

		// Should this light even go in the ambient cubes?
		if ( !( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) )
			continue;

		Assert( wl->type == emit_surface );

		// Can this light see the point?
		if ( TestLine( vStart, wl->origin, 0, iThread ) != CONTENTS_EMPTY )
			continue;

		// Add this light's contribution.
		Vector vDelta = wl->origin - vStart;
		float flDistanceScale = Engine_WorldLightDistanceFalloff( wl, vDelta );

		Vector vDeltaNorm = vDelta;
		VectorNormalize( vDeltaNorm );
		float flAngleScale = Engine_WorldLightAngle( wl, wl->normal, vDeltaNorm, vDeltaNorm );

		float ratio = flDistanceScale * flAngleScale;
		if ( ratio == 0 )
			continue;

		for ( int i=0; i < 6; i++ )
		{
			float t = DotProduct( g_BoxDirections[i], vDeltaNorm );
			if ( t > 0 )
			{
				lightBoxColor[i] += wl->intensity * (t * ratio);
			}
		}
	}	
}
Exemplo n.º 3
0
//-----------------------------------------------------------------------------
// Purpose: find the brightest light source at a point
//-----------------------------------------------------------------------------
bool CWorldLights::GetBrightestLightSource(const Vector &vecPosition, Vector &vecLightPos, Vector &vecLightBrightness)
{
	if(!m_nWorldLights || !m_pWorldLights)
		return false;
 
	// Default light position and brightness to zero
	vecLightBrightness.Init();
	vecLightPos.Init();
 
	// Find the size of the PVS for our current position
	int nCluster = g_pEngineServer->GetClusterForOrigin(vecPosition);
	int nPVSSize = g_pEngineServer->GetPVSForCluster(nCluster, 0, NULL);
 
	// Get the PVS at our position
	byte *pvs = new byte[nPVSSize];
	g_pEngineServer->GetPVSForCluster(nCluster, nPVSSize, pvs);
 
	// Iterate through all the worldlights
	for(int i = 0; i < m_nWorldLights; ++i)
	{
		dworldlight_t *light = &m_pWorldLights[i];
 
		// Skip skyambient
		if(light->type == emit_skyambient)
		{
			//engine->Con_NPrintf(i, "%d: skyambient", i);
			continue;
		}
 
		// Handle sun
		if(light->type == emit_skylight)
		{
			// Calculate sun position
			Vector vecAbsStart = vecPosition + Vector(0,0,30);
			Vector vecAbsEnd = vecAbsStart - (light->normal * MAX_TRACE_LENGTH);
 
			trace_t tr;
			UTIL_TraceLine(vecPosition, vecAbsEnd, MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr);
 
			// If we didn't hit anything then we have a problem
			if(!tr.DidHit())
			{
				//engine->Con_NPrintf(i, "%d: skylight: couldn't touch sky", i);
				continue;
			}
 
			// If we did hit something, and it wasn't the skybox, then skip
			// this worldlight
			if(!(tr.surface.flags & SURF_SKY) && !(tr.surface.flags & SURF_SKY2D))
			{
				//engine->Con_NPrintf(i, "%d: skylight: no sight to sun", i);
				continue;
			}
 
			// Act like we didn't find any valid worldlights, so the shadow
			// manager uses the default shadow direction instead (should be the
			// sun direction)

			delete[] pvs;

			return false;
		}
 
		// Calculate square distance to this worldlight
		Vector vecDelta = light->origin - vecPosition;
		float flDistSqr = vecDelta.LengthSqr();
		float flRadiusSqr = light->radius * light->radius;
 
		// Skip lights that are out of our radius
		if(flRadiusSqr > 0 && flDistSqr >= flRadiusSqr)
		{
			//engine->Con_NPrintf(i, "%d: out-of-radius (dist: %d, radius: %d)", i, sqrt(flDistSqr), light->radius);
			continue;
		}
 
		// Is it out of our PVS?
		if(!g_pEngineServer->CheckOriginInPVS(light->origin, pvs, nPVSSize))
		{
			//engine->Con_NPrintf(i, "%d: out of PVS", i);
			continue;
		}
 
		// Calculate intensity at our position
		float flRatio = Engine_WorldLightDistanceFalloff(light, vecDelta);
		Vector vecIntensity = light->intensity * flRatio;
 
		// Is this light more intense than the one we already found?
		if(vecIntensity.LengthSqr() <= vecLightBrightness.LengthSqr())
		{
			//engine->Con_NPrintf(i, "%d: too dim", i);
			continue;
		}
 
		// Can we see the light?
		trace_t tr;
		Vector vecAbsStart = vecPosition + Vector(0,0,30);
		UTIL_TraceLine(vecAbsStart, light->origin, MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr);
 
		if(tr.DidHit())
		{
			//engine->Con_NPrintf(i, "%d: trace failed", i);
			continue;
		}
 
		vecLightPos = light->origin;
		vecLightBrightness = vecIntensity;
 
		//engine->Con_NPrintf(i, "%d: set (%.2f)", i, vecIntensity.Length());
	}
 
	delete[] pvs;

	//engine->Con_NPrintf(m_nWorldLights, "result: %d", !vecLightBrightness.IsZero());
	return !vecLightBrightness.IsZero();
}