Example #1
0
// returns surfID
SurfaceHandle_t RecursiveLightPoint (mnode_t *node, float start, float end,
	Vector& c, LightVecState_t& state )
{
	// didn't hit anything
	if (node->contents >= 0)
	{
		// FIXME: Should we always do this? It could get expensive...
		// Check all the faces at the leaves
		return FindIntersectionSurfaceAtLeaf( (mleaf_t*)node, start, end, c, state );
	}
	
	// Determine which side of the node plane our points are on
	// FIXME: optimize for axial
	cplane_t* plane = node->plane;

	float startDotN = DotProduct( state.m_Ray.m_Start, plane->normal );
	float deltaDotN = DotProduct( state.m_Ray.m_Delta, plane->normal );

	float front = startDotN + start * deltaDotN - plane->dist;
	float back = startDotN + end * deltaDotN - plane->dist;
	int side = front < 0;
	
	// If they're both on the same side of the plane, don't bother to split
	// just check the appropriate child
	SurfaceHandle_t surfID;
	if ( (back < 0) == side )
	{
		surfID = RecursiveLightPoint (node->children[side], start, end, c, state);
		return surfID;
	}
	
	// calculate mid point
	float frac = front / (front-back);
	float mid = start * (1.0f - frac) + end * frac;
	
	// go down front side	
	surfID = RecursiveLightPoint (node->children[side], start, mid, c, state );
	if ( IS_SURF_VALID( surfID ) )
		return surfID;		// hit something
				
	// check for impact on this node
	surfID = FindIntersectionSurfaceAtNode( node, mid, c, state );
	if ( IS_SURF_VALID( surfID ) )
		return surfID;

	// go down back side
	surfID = RecursiveLightPoint (node->children[!side], mid, end, c, state );
	return surfID;
}
Example #2
0
void CDispInfo::AddDynamicLights( Vector4D *blocklight )
{
#ifndef SWDS
    if( !IS_SURF_VALID( m_ParentSurfID ) )
    {
        Assert( !"CDispInfo::AddDynamicLights: no parent surface" );
        return;
    }

    for( int lnum=0 ; lnum<MAX_DLIGHTS ; lnum++ )
    {
        // If the light's not active, then continue
        if ( (r_dlightactive & (1 << lnum)) == 0 )
            continue;

        // not lit by this light
        if ( !(MSurf_DLightBits( m_ParentSurfID ) & (1<<lnum) ) )
            continue;

        // This light doesn't affect the world
        if ( cl_dlights[lnum].flags & DLIGHT_NO_WORLD_ILLUMINATION)
            continue;

        if ( (cl_dlights[lnum].flags & DLIGHT_DISPLACEMENT_MASK) == 0)
        {
            AddSingleDynamicLight( cl_dlights[lnum], blocklight );
        }
        else
        {
            AddSingleDynamicAlphaLight( cl_dlights[lnum], blocklight );
        }
    }
#endif
}
Example #3
0
// returns light in range from 0 to 1.
colorVec R_LightPoint (Vector& p)
{
	SurfaceHandle_t surfID;
	Vector		end;
	colorVec	c;
	Vector		color;
	
	end[0] = p[0];
	end[1] = p[1];
	end[2] = p[2] - 2048;

	surfID = R_LightVec( p, end, true, color );

	if( IS_SURF_VALID( surfID ) )
	{
		c.r = LinearToScreenGamma( color[0] ) * 255;
		c.g = LinearToScreenGamma( color[1] ) * 255;
		c.b = LinearToScreenGamma( color[2] ) * 255;
		c.a = 1;
	}
	else
	{
		c.r = c.g = c.b = c.a = 0;
	}
	return c;
}
Example #4
0
//-----------------------------------------------------------------------------
// returns light in range from 0 to 1.
// lightmapS/T is in [0,1] within the space of the surface.
// returns surfID
//-----------------------------------------------------------------------------
SurfaceHandle_t R_LightVec (const Vector& start, const Vector& end, bool bUseLightStyles, Vector& c, 
		float *textureS, float *textureT, float *lightmapS, float *lightmapT )
{
	VPROF_INCREMENT_COUNTER( "R_LightVec", 1 );

	SurfaceHandle_t retSurfID;
	SurfaceHandle_t dispSurfID;
	
	// We're using the vis frame here for lightvec tests
	// to make sure we test each displacement only once
	++r_surfacevisframe;

	LightVecState_t state;
	state.m_HitFrac = 1.0f;
	state.m_Ray.Init( start, end );
	state.m_pTextureS = textureS;
	state.m_pTextureT = textureT;
	state.m_pLightmapS = lightmapS;
	state.m_pLightmapT = lightmapT;
	state.m_nSkySurfID = SURFACE_HANDLE_INVALID;
	state.m_bUseLightStyles = bUseLightStyles;

	c[0] = c[1] = c[2] = 0.0f;

	model_t* model = s_pLightVecModel ? s_pLightVecModel : host_state.worldmodel; 
	retSurfID = RecursiveLightPoint(&model->brush.pShared->nodes[model->brush.firstnode],
		0.0f, 1.0f, c, state );

	// While doing recursive light point, we built a list of all
	// displacement surfaces which we need to test, so let's test them
	dispSurfID = R_LightVecDisplacementChain( state, bUseLightStyles, c );

	if( r_visualizelighttraces.GetBool() )
	{
		if( r_visualizelighttracesshowfulltrace.GetBool() )
		{
			CDebugOverlay::AddLineOverlay( start, end, 0, 255, 0, 255, true, -1.0f );
		}
		else
		{
			CDebugOverlay::AddLineOverlay( start, start + ( end - start ) * state.m_HitFrac, 0, 255, 0, 255, true, -1.0f );
		}
	}

	if ( IS_SURF_VALID( dispSurfID ) )
		retSurfID = dispSurfID;

//	ConMsg( "R_LightVec: %f %f %f\n", c[0], c[1], c[2] );

	// If we didn't hit anything else, but we hit a sky surface at
	// some point along the ray cast, return the sky id.
	if ( ( retSurfID == SURFACE_HANDLE_INVALID ) && ( state.m_nSkySurfID != SURFACE_HANDLE_INVALID ) )
		return state.m_nSkySurfID;

	return retSurfID;
}
//-----------------------------------------------------------------------------
// 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;
	}
}
//-----------------------------------------------------------------------------
// returns light in range from 0 to 1.
// lightmapS/T is in [0,1] within the space of the surface.
// returns surfID
//-----------------------------------------------------------------------------
int R_LightVec (const Vector& start, const Vector& end, bool bUseLightStyles, Vector& c, 
		float *textureS, float *textureT, float *lightmapS, float *lightmapT )
{
	int retSurfID;
	int dispSurfID;
	
	// We're using the vis frame here for lightvec tests
	// to make sure we test each displacement only once
	++r_surfacevisframe;

	LightVecState_t state;
	state.m_HitFrac = 1.0f;
	state.m_Ray.Init( start, end );
	state.m_pTextureS = textureS;
	state.m_pTextureT = textureT;
	state.m_pLightmapS = lightmapS;
	state.m_pLightmapT = lightmapT;
	state.m_nSkySurfID = -1;
	state.m_bUseLightStyles = bUseLightStyles;

	c[0] = c[1] = c[2] = 0.0f;

	model_t* model = s_pLightVecModel ? s_pLightVecModel : host_state.worldmodel; 
	retSurfID = RecursiveLightPoint(&model->brush.nodes[model->brush.firstnode],
		0.0f, 1.0f, c, state );

	// While doing recursive light point, we built a list of all
	// displacement surfaces which we need to test, so let's test them
	dispSurfID = R_LightVecDisplacementChain( state, bUseLightStyles, c );
	if ( IS_SURF_VALID( dispSurfID ) )
		retSurfID = dispSurfID;

//	Con_Printf( "R_LightVec: %f %f %f\n", c[0], c[1], c[2] );

	// If we didn't hit anything else, but we hit a sky surface at
	// some point along the ray cast, return the sky id.
	if ( ( retSurfID == -1 ) && ( state.m_nSkySurfID != -1 ) )
		return state.m_nSkySurfID;

	return retSurfID;
}