예제 #1
0
//-----------------------------------------------------------------------------
// 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;
}
예제 #2
0
//-----------------------------------------------------------------------------
// A method to get the material color + texture coordinate
//-----------------------------------------------------------------------------
IMaterial* BrushModel_GetLightingAndMaterial( const Vector &start, 
	const Vector &end, Vector &diffuseLightColor, Vector &baseColor)
{
	float textureS, textureT;
	IMaterial *material;
	int surfID = R_LightVec( start, end, true, diffuseLightColor, &textureS, &textureT );
	if( !IS_SURF_VALID( surfID ) || !MSurf_TexInfo( surfID ) )
	{
//		Con_Printf( "didn't hit anything\n" );
		return 0;
	}
	else
	{
		material = MSurf_TexInfo( surfID )->material;
		material->GetLowResColorSample( textureS, textureT, baseColor.Base() );
//		Con_Printf( "%s: diff: %f %f %f base: %f %f %f\n", material->GetName(), diffuseLightColor[0], diffuseLightColor[1], diffuseLightColor[2], baseColor[0], baseColor[1], baseColor[2] );
		return material;
	}
}
예제 #3
0
int R_TryLightMarkSurface( dlight_t *light, msurfacelighting_t *pLighting, SurfaceHandle_t surfID, int bit )
{
	// Make sure this light actually intersects the surface cache of the surfaces it hits
	mtexinfo_t	*tex;

	// FIXME: No worky for brush models

	// Find the perpendicular distance to the surface we're lighting
	// NOTE: Allow some stuff that's slightly behind it because view models can get behind walls
	// FIXME: We should figure out a better way to deal with view models
	float perpDistSq = DotProduct (light->origin, MSurf_Plane( surfID ).normal) - MSurf_Plane( surfID ).dist;
	if (perpDistSq < DLIGHT_BEHIND_PLANE_DIST)
		return 0;

	perpDistSq *= perpDistSq;

	float flInPlaneRadiusSq = light->GetRadiusSquared() - perpDistSq;
	if (flInPlaneRadiusSq <= 0)
		return 0;

	tex = MSurf_TexInfo( surfID );

	Vector2D mins, maxs;
	mins.Init( pLighting->m_LightmapMins[0], pLighting->m_LightmapMins[1] ); 
	maxs.Init( mins.x + pLighting->m_LightmapExtents[0], mins.y + pLighting->m_LightmapExtents[1] );

	// Project light center into texture coordinates
	Vector2D vecCircleCenter;
	vecCircleCenter.x = DotProduct (light->origin, tex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
		tex->lightmapVecsLuxelsPerWorldUnits[0][3];
	vecCircleCenter.y = DotProduct (light->origin, tex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
		tex->lightmapVecsLuxelsPerWorldUnits[1][3];

	// convert from world space to luxel space and convert to int
	float flInPlaneLuxelRadius = sqrtf( flInPlaneRadiusSq * tex->luxelsPerWorldUnit * tex->luxelsPerWorldUnit );

	// Does the circle intersect the square?
	if ( !IsCircleIntersectingRectangle( mins, maxs, vecCircleCenter, flInPlaneLuxelRadius ) )
		return 0;

	// Ok, mark the surface as using this light.
	R_MarkSurfaceDLight( surfID, pLighting, bit); 
	return 1;
}
예제 #4
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;
}