Esempio n. 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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
void
R_ShadowLight(vec3_t pos, vec3_t lightAdd)
{
	vec3_t		end;
	float		r;
	int		lnum;
	dlight_t       *dl;
	float		len;
	vec3_t		dist, angle;
	float		add;

	if (!r_worldmodel->lightdata)	/* keep old lame shadow */
		return;

	end[0] = pos[0];
	end[1] = pos[1];
	end[2] = pos[2] - 2048;

	r = RecursiveLightPoint(r_worldmodel->nodes, pos, end);

	VectorClear(lightAdd);
	//
	/* add dynamic light shadow angles */
	    //
	    dl = r_refdef.dlights;
	for (lnum = 0; lnum < r_refdef.num_dlights; lnum++, dl++) {
		if (dl->spotlight)	/* spotlights */
			continue;

		VectorSubtract(dl->origin, pos, dist);
		add = sqrt(dl->intensity - VectorLength(dist));
		VectorNormalize(dist);
		if (add > 0) {
			VectorScale(dist, add, dist);
			VectorAdd(lightAdd, dist, lightAdd);
		}
	}

	len = VectorNormalize(lightAdd);
	if (len > 2048)
		len = 2048;
	if (len <= 0)
		return;

	/* now rotate according to model yaw */
	vectoangles(lightAdd, angle);

	/* e->angles */
	angle[YAW] = -(currententity->angles[YAW] - angle[YAW]);

	AngleVectors(angle, dist, NULL, NULL);
	VectorScale(dist, len, lightAdd);
}
Esempio n. 4
0
int R_LightPoint (vec3_t &p, vec3_t &outcolor)
{
	vec3_t		end;
//	int			r;

	model_t* world = gEngfuncs.GetEntityByIndex(0)->model; 
	
	if (!world->lightdata)
	{
		outcolor[0] = outcolor[1] = outcolor[2] = 1; 
		return 255;
	}
	
	end[0] = p[0];
	end[1] = p[1];
	end[2] = p[2] - 2048;
	
	return RecursiveLightPoint (world->nodes, p, end, outcolor);
}
Esempio n. 5
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 6
0
// 0  - success
// -1 - failed
int RecursiveLightPoint (mnode_t *node, const vec3_t &start, const vec3_t &end, vec3_t &outcolor)
{
	int			r;
	float		front, back, frac;
	int			side;
	mplane_t	*plane;
	vec3_t		mid;
	msurface_t	*surf;
	int			s, t, ds, dt;
	int			i;
	mtexinfo_t	*tex;
//	byte		*lightmap;
	color24		*lightmap; 
//	unsigned	scale;
//	int			maps;

	if (node->contents < 0)
		return -1;		// didn't hit anything
	
// calculate mid point

// FIXME: optimize for axial
	plane = node->plane;
	front = DotProduct (start, plane->normal) - plane->dist;
	back = DotProduct (end, plane->normal) - plane->dist;
	side = front < 0;
	
	if ( (back < 0) == side)
		return RecursiveLightPoint (node->children[side], start, end, outcolor);
	
	frac = front / (front-back);
	mid[0] = start[0] + (end[0] - start[0])*frac;
	mid[1] = start[1] + (end[1] - start[1])*frac;
	mid[2] = start[2] + (end[2] - start[2])*frac;
	
// go down front side	
	r = RecursiveLightPoint (node->children[side], start, mid, outcolor);
	if (r >= 0)
		return r;		// hit something
		
	if ( (back < 0) == side )
		return -1;		// didn't hit anuthing
		
// check for impact on this node
	model_t* world = gEngfuncs.GetEntityByIndex(0)->model; 

	surf = world->surfaces + node->firstsurface;
	for (i=0 ; i<node->numsurfaces ; i++, surf++)
	{
		if (surf->flags & SURF_DRAWTILED)
			continue;	// no lightmaps

		tex = surf->texinfo;
		
		s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
		t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;

		if (s < surf->texturemins[0] ||
		t < surf->texturemins[1])
			continue;
		
		ds = s - surf->texturemins[0];
		dt = t - surf->texturemins[1];
		
		if ( ds > surf->extents[0] || dt > surf->extents[1] )
			continue;

		if (!surf->samples)
			return 0;

		ds >>= 4;
		dt >>= 4;

		lightmap = surf->samples;
		r = 0;
		if (lightmap)
		{
			lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
			
			outcolor[0] = (float)lightmap->r / 255.0f;
			outcolor[1] = (float)lightmap->g / 255.0f;
			outcolor[2] = (float)lightmap->b / 255.0f;

			/*	for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
					maps++)
			{
				scale = d_lightstylevalue[surf->styles[maps]];
				r += *lightmap * scale;
				lightmap += ((surf->extents[0]>>4)+1) *
						((surf->extents[1]>>4)+1);
			}			
			r >>= 8;*/
		}		
		return r;
	}

// go down back side
	return RecursiveLightPoint (node->children[!side], mid, end, outcolor);
}