Example #1
0
int R_MarkLightsLeaf( dlight_t *light, int bit, mleaf_t *pLeaf )
{
	int countMarked = 0;
	for ( int i = 0; i < pLeaf->dispCount; i++ )
	{
		IDispInfo *pDispInfo = MLeaf_Disaplcement( pLeaf, i );

		SurfaceHandle_t parentSurfID = pDispInfo->GetParent();
		if ( parentSurfID )
		{
			// Don't redo all this work if we already hit this surface and decided it's lit by this light.
			msurfacelighting_t *pLighting = SurfaceLighting( parentSurfID );
			if( !R_IsDLightAlreadyMarked( pLighting, bit) )
			{
				// Do a different test for displacement surfaces.
				Vector bmin, bmax;
				MSurf_DispInfo( parentSurfID )->GetBoundingBox( bmin, bmax );
				if ( IsBoxIntersectingSphere(bmin, bmax, light->origin, light->GetRadius()) )
				{
					R_MarkSurfaceDLight( parentSurfID, pLighting, bit );
					countMarked++;
				}
			}
		}
	}

	SurfaceHandle_t *pHandle = &host_state.worldbrush->marksurfaces[pLeaf->firstmarksurface];
	for ( int i = 0; i < pLeaf->nummarksurfaces; i++ )
	{
		SurfaceHandle_t surfID = pHandle[i];
		ASSERT_SURF_VALID( surfID );
		
		// only process leaf surfaces
		if ( MSurf_Flags( surfID ) & SURFDRAW_NODE )
			continue;

		// Don't redo all this work if we already hit this surface and decided it's lit by this light.
		msurfacelighting_t *pLighting = SurfaceLighting( surfID );
		if(R_IsDLightAlreadyMarked(pLighting, bit))
			continue;

		float dist = DotProduct( light->origin, MSurf_Plane( surfID ).normal) - MSurf_Plane( surfID ).dist;
		
		if ( dist > light->GetRadius() || dist < -light->GetRadius() )
			continue;

		countMarked += R_TryLightMarkSurface( light, pLighting, surfID, bit );
	}
	return countMarked;
}
void R_MarkLightsLeaf( dlight_t *light, int bit, mleaf_t *pLeaf )
{
	for( CDispIterator it=pLeaf->GetDispIterator(); it.IsValid(); )
	{
		CDispLeafLink *pCur = it.Inc();

		// get current displacement surface info
		IDispInfo *pDispInfo = static_cast<IDispInfo*>( pCur->m_pDispInfo );

		int parentSurfID = pDispInfo->GetParent();
		if ( parentSurfID )
		{
			// Don't redo all this work if we already hit this surface and decided it's lit by this light.
			msurfacelighting_t *pLighting = SurfaceLighting( parentSurfID );
			if( !R_IsDLightAlreadyMarked( pLighting, bit) )
			{
				// Do a different test for displacement surfaces.
				Vector bmin, bmax;
				MSurf_DispInfo( parentSurfID )->GetBoundingBox( bmin, bmax );
				if ( SphereToAABBIntersection( light->origin, light->radius, bmin, bmax ) )
				{
					R_MarkSurfaceDLight( pLighting, bit ); 
				}
			}
		}
	}

	for ( int i = 0; i < pLeaf->nummarksurfaces; i++ )
	{
		int surfID = host_state.worldmodel->brush.marksurfaces[pLeaf->firstmarksurface + i];
		ASSERT_SURF_VALID( surfID );
		
		// only process leaf surfaces
		if ( MSurf_Flags( surfID ) & SURFDRAW_NODE )
			continue;

		// Don't redo all this work if we already hit this surface and decided it's lit by this light.
		msurfacelighting_t *pLighting = SurfaceLighting( surfID );
		if(R_IsDLightAlreadyMarked(pLighting, bit))
			continue;

		float dist = DotProduct( light->origin, MSurf_Plane( surfID ).normal) - MSurf_Plane( surfID ).dist;
		
		if ( dist > light->radius || dist < -light->radius )
			continue;

		R_TryLightMarkSurface( light, pLighting, surfID, bit );
	}
}
Example #3
0
// returns surfID
static SurfaceHandle_t R_LightVecDisplacementChain( LightVecState_t& state, bool bUseLightStyles, Vector& c )
{
	// test the ray against displacements
	SurfaceHandle_t surfID = SURFACE_HANDLE_INVALID;

	for ( int i = 0; i < state.m_LightTestDisps.Count(); i++ )
	{
	
		float dist;
		Vector2D luv, tuv;
		IDispInfo *pDispInfo = state.m_LightTestDisps[i];
		if (pDispInfo->TestRay( state.m_Ray, 0.0f, state.m_HitFrac, dist, &luv, &tuv ))
		{
			// It hit it, and at a point closer than the previously computed
			// nearest intersection point
			state.m_HitFrac = dist;
			surfID = pDispInfo->GetParent();
			ComputeLightmapColor( surfID, (int)luv.x, (int)luv.y, bUseLightStyles, c );

			if (state.m_pLightmapS && state.m_pLightmapT)
			{
				ComputeLightmapCoordsAtIntersection( SurfaceLighting(surfID), (int)luv.x, (int)luv.y, state.m_pLightmapS, state.m_pLightmapT );
			}

			if (state.m_pTextureS && state.m_pTextureT)
			{
				*state.m_pTextureS = tuv.x;
				*state.m_pTextureT = tuv.y;
			}
		}
	}

	return surfID;
}
// returns surfID
static int R_LightVecDisplacementChain( LightVecState_t& state, bool bUseLightStyles, Vector& c )
{
	// test the ray against displacements
	int surfID = -1;

	IDispInfo *pDispInfo = state.m_LightTestChain.GetHead();
	for( ; pDispInfo; pDispInfo = pDispInfo->GetNextInRayCastChain() )
	{
		float dist;
		Vector2D luv, tuv;
		if (pDispInfo->TestRay( state.m_Ray, 0.0f, state.m_HitFrac, dist, &luv, &tuv ))
		{
			// It hit it, and at a point closer than the previously computed
			// nearest intersection point
			state.m_HitFrac = dist;
			surfID = pDispInfo->GetParent();

			ComputeLightmapColor( surfID, (int)luv.x, (int)luv.y, bUseLightStyles, c );

			if (state.m_pLightmapS && state.m_pLightmapT)
			{
				ComputeLightmapCoordsAtIntersection( SurfaceLighting(surfID), (int)luv.x, (int)luv.y, state.m_pLightmapS, state.m_pLightmapT );
			}

			if (state.m_pTextureS && state.m_pTextureT)
			{
				*state.m_pTextureS = tuv.x;
				*state.m_pTextureT = tuv.y;
			}
		}
	}

	return surfID;
}
//-----------------------------------------------------------------------------
// Tests a particular surface
//-----------------------------------------------------------------------------
static bool FASTCALL FindIntersectionAtSurface( int surfID, float f, 
	Vector& c, LightVecState_t& state )
{
	// no lightmaps on this surface? punt...
	// FIXME: should be water surface?
	if (MSurf_Flags( surfID ) & SURFDRAW_NOLIGHT)
		return false;	

	// Compute the actual point
	Vector pt;
	VectorMA( state.m_Ray.m_Start, f, state.m_Ray.m_Delta, pt );

	mtexinfo_t* pTex = MSurf_TexInfo( surfID );
	
	// See where in lightmap space our intersection point is 
	float s, t;
	s = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[0][3];
	t = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[1][3];

	// Not in the bounds of our lightmap? punt...
	msurfacelighting_t *pLighting = SurfaceLighting( surfID );
	if( s < pLighting->m_pLightmapMins[0] || 
		t < pLighting->m_pLightmapMins[1] )
		return false;	
	
	// assuming a square lightmap (FIXME: which ain't always the case),
	// lets see if it lies in that rectangle. If not, punt...
	float ds = s - pLighting->m_pLightmapMins[0];
	float dt = t - pLighting->m_pLightmapMins[1];
	if( ds > pLighting->m_pLightmapExtents[0] || dt > pLighting->m_pLightmapExtents[1] )
		return false;	

	// Store off the hit distance...
	state.m_HitFrac = f;

	// You heard the man!
	ComputeTextureCoordsAtIntersection( pTex, pt, state.m_pTextureS, state.m_pTextureT );

#ifdef USE_CONVARS
	if( 1 )
#else
	if (r_avglight.GetInt())
#endif
	{
		// This is the faster path; it looks slightly different though
		ComputeLightmapColorFromAverage( pLighting, state.m_bUseLightStyles, c );
	}
	else
	{
		// Compute lightmap coords
		ComputeLightmapCoordsAtIntersection( pLighting, ds, dt, state.m_pLightmapS, state.m_pLightmapT );
		
		// Check out the value of the lightmap at the intersection point
		ComputeLightmapColor( surfID, (int)ds, (int)dt, state.m_bUseLightStyles, c );
	}

	return true;
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
{
	cplane_t	*splitplane;
	float		dist;
	int			i;
	
	if (node->contents >= 0)
	{
		// This is a leaf, so check displacement surfaces and leaf faces
		R_MarkLightsLeaf( light, bit, (mleaf_t*)node );
		return;
	}
	
	splitplane = node->plane;
	dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
	
	if (dist > light->radius)
	{
		R_MarkLights (light, bit, node->children[0]);
		return;
	}
	if (dist < -light->radius)
	{
		R_MarkLights (light, bit, node->children[1]);
		return;
	}
		
	// mark the polygons
	int surfID = node->firstsurface;
	for (i=0 ; i<node->numsurfaces ; i++, surfID++)
	{
		// Don't redo all this work if we already hit this surface and decided it's lit by this light.
		msurfacelighting_t *pLighting = SurfaceLighting( surfID );
		if(R_IsDLightAlreadyMarked( pLighting, bit))
			continue;

		R_TryLightMarkSurface( light, pLighting, surfID, bit );
	}

	R_MarkLights( light, bit, node->children[0] );
	R_MarkLights( light, bit, node->children[1] );
}
Example #7
0
//-----------------------------------------------------------------------------
// Computes the lightmap color at a particular point
//-----------------------------------------------------------------------------
static void ComputeLightmapColor( SurfaceHandle_t surfID, int ds, int dt, bool bUseLightStyles, Vector& c )
{
	msurfacelighting_t *pLighting = SurfaceLighting( surfID );

	ColorRGBExp32* pLightmap = pLighting->m_pSamples;
	if( !pLightmap )
	{
		static int messagecount = 0;
		if ( ++messagecount < 10 )
		{
			// Stop spamming. I heard you already!!!
			ConMsg( "hit surface has no samples\n" );
		}
		return;
	}

	int smax = ( pLighting->m_LightmapExtents[0] ) + 1;
	int tmax = ( pLighting->m_LightmapExtents[1] ) + 1;
	int offset = smax * tmax;
	if ( SurfHasBumpedLightmaps( surfID ) )
	{
		offset *= ( NUM_BUMP_VECTS + 1 );
	}

	pLightmap += dt * smax + ds;
	int nMaxMaps = bUseLightStyles ? MAXLIGHTMAPS : 1; 
	for (int maps = 0 ; maps < nMaxMaps && pLighting->m_nStyles[maps] != 255 ; ++maps)
	{
		float scale = LightStyleValue( pLighting->m_nStyles[maps] );

		c[0] += TexLightToLinear( pLightmap->r, pLightmap->exponent ) * scale;
		c[1] += TexLightToLinear( pLightmap->g, pLightmap->exponent ) * scale;
		c[2] += TexLightToLinear( pLightmap->b, pLightmap->exponent ) * scale;

		// Check version 32 in source safe for some debugging crap
		pLightmap += offset;
	}
}
Example #8
0
//-----------------------------------------------------------------------------
// Tests a particular surface
//-----------------------------------------------------------------------------
static bool FASTCALL FindIntersectionAtSurface( SurfaceHandle_t surfID, float f, 
	Vector& c, LightVecState_t& state )
{
	// no lightmaps on this surface? punt...
	// FIXME: should be water surface?
	if (MSurf_Flags( surfID ) & SURFDRAW_NOLIGHT)
		return false;	

	// Compute the actual point
	Vector pt;
	VectorMA( state.m_Ray.m_Start, f, state.m_Ray.m_Delta, pt );

	mtexinfo_t* pTex = MSurf_TexInfo( surfID );
	
	// See where in lightmap space our intersection point is 
	float s, t;
	s = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[0][3];
	t = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[1][3];

	// Not in the bounds of our lightmap? punt...
	msurfacelighting_t *pLighting = SurfaceLighting( surfID );
	if( s < pLighting->m_LightmapMins[0] || 
		t < pLighting->m_LightmapMins[1] )
		return false;	
	
	// assuming a square lightmap (FIXME: which ain't always the case),
	// lets see if it lies in that rectangle. If not, punt...
	float ds = s - pLighting->m_LightmapMins[0];
	float dt = t - pLighting->m_LightmapMins[1];
	if ( !pLighting->m_LightmapExtents[0] && !pLighting->m_LightmapExtents[1] )
	{
		worldbrushdata_t *pBrushData = host_state.worldbrush;

		// 
		float	lightMaxs[2];
		lightMaxs[ 0 ] = pLighting->m_LightmapMins[0];
		lightMaxs[ 1 ] = pLighting->m_LightmapMins[1];
		int i;
		for (i=0 ; i<MSurf_VertCount( surfID ); i++)
		{
			int e = pBrushData->vertindices[MSurf_FirstVertIndex( surfID )+i];
			mvertex_t *v = &pBrushData->vertexes[e];
			
			int j;
			for ( j=0 ; j<2 ; j++)
			{
				float sextent, textent;
				sextent = DotProduct (v->position, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
					pTex->lightmapVecsLuxelsPerWorldUnits[0][3] - pLighting->m_LightmapMins[0];
				textent = DotProduct (v->position, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
					pTex->lightmapVecsLuxelsPerWorldUnits[1][3] - pLighting->m_LightmapMins[1];

				if ( sextent > lightMaxs[ 0 ] )
				{
					lightMaxs[ 0 ] = sextent;
				}
				if ( textent > lightMaxs[ 1 ] )
				{
					lightMaxs[ 1 ] = textent;
				}
			}
		}
		if( ds > lightMaxs[0] || dt > lightMaxs[1] )
			return false;	
	}
	else
	{
		if( ds > pLighting->m_LightmapExtents[0] || dt > pLighting->m_LightmapExtents[1] )
			return false;	
	}

	// Store off the hit distance...
	state.m_HitFrac = f;

	// You heard the man!
	ComputeTextureCoordsAtIntersection( pTex, pt, state.m_pTextureS, state.m_pTextureT );

#ifdef USE_CONVARS
	if ( r_avglight.GetInt() )
#else
	if ( 1 )
#endif
	{
		// This is the faster path; it looks slightly different though
		ComputeLightmapColorFromAverage( pLighting, state.m_bUseLightStyles, c );
	}
	else
	{
		// Compute lightmap coords
		ComputeLightmapCoordsAtIntersection( pLighting, ds, dt, state.m_pLightmapS, state.m_pLightmapT );
		
		// Check out the value of the lightmap at the intersection point
		ComputeLightmapColor( surfID, (int)ds, (int)dt, state.m_bUseLightStyles, c );
	}

	return true;
}