View Single Post
Re: code to get the illumination at any point on the map
Old
  (#37)
Immortal_BLG
Member
 
Status: Offline
Posts: 171
Join Date: Nov 2007
Location: Russian Federation
Default Re: code to get the illumination at any point on the map - 21-03-2012

try:
in bot_globals.h:
Code:
#ifdef _LINUX
// Linux doesn't have this function so this emulates its functionality
inline void *GetModuleHandle(const char *name)
{
	void *handle;

	if( name == NULL )
	{
		// hmm, how can this be handled under linux....
		// is it even needed?
		return NULL;
	}

    if( (handle=dlopen(name, RTLD_NOW))==NULL)
    {
            // couldn't open this file
            return NULL;
    }

	// read "man dlopen" for details
	// in short dlopen() inc a ref count
	// so dec the ref count by performing the close
	dlclose(handle);
	return handle;
}
#endif
/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
extern Color g_pointColor;

template <typename nodeType, typename surfaceType> static const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end)
{
	float front, back, frac;
	int side;
	mplane_t *plane;
	Vector mid;
	surfaceType *surf;
	int s, t, ds, dt;
	int i;
	mtexinfo_t *tex;
	color24 *lightmap;
	unsigned int scale;
	unsigned char maps;

	// Reliability check.
	assert (node != NULL);

	if (node->contents < 0)
		return false;	// didn't hit anything

	// Determine which side of the node plane our points are on
	// FIXME: optimize for axial
	plane = node->plane;
	front = DotProduct (start, plane->normal) - plane->dist;
	back = DotProduct (end, plane->normal) - plane->dist;
	side = front < 0.0f;

	// If they're both on the same side of the plane, don't bother to split just check the appropriate child
	if ((back < 0.0f) == side)
		return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, end);

	// calculate mid point
	frac = front / (front - back);
	mid = start + (end - start) * frac;

	// go down front side	
	if (RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, mid))
		return true;	// hit something

	// Blow it off if it doesn't split the plane...
	if ((back < 0.0f) == side)
		return false;	// didn't hit anything

	// check for impact on this node
//	lightspot = mid;
//	lightplane = plane;

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

		tex = surf->texinfo;

		// See where in lightmap space our intersection point is
		s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
		t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

		// Not in the bounds of our lightmap? punt...
		if (s < surf->texturemins[0] || t < surf->texturemins[1])
			continue;

		// assuming a square lightmap (FIXME: which ain't always the case),
		// lets see if it lies in that rectangle. If not, punt...
		ds = s - surf->texturemins[0];
		dt = t - surf->texturemins[1];

		if (ds > surf->extents[0] || dt > surf->extents[1])
			continue;

		if (surf->samples == NULL)
			return true;

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

		g_pointColor.Reset ();	// Reset point color.

		const int smax ((surf->extents[0] >> 4) + 1);
		const int tmax ((surf->extents[1] >> 4) + 1);
		const int size (smax * tmax);

		lightmap = surf->samples + dt * smax + ds;

		// Compute the lightmap color at a particular point
		for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
		{
			scale = d_lightstylevalue[surf->styles[maps]];

			g_pointColor.red += lightmap->r * scale;
			g_pointColor.green += lightmap->g * scale;
			g_pointColor.blue += lightmap->b * scale;

			lightmap += size;	// skip to next lightmap
		}

		g_pointColor.red >>= 8u;
		g_pointColor.green >>= 8u;
		g_pointColor.blue >>= 8u;

		return true;
	}

	// go down back side
	return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[!side]), mid, end);
}

inline const bool IsSoftwareDrawingMode (void)
{
	#ifdef _LINUX
		return true;	// Always software rendering mode....
	#else	// ifdef _LINUX
		static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

		return isSoftwareDrawingMode;
	#endif	// ifndef _LINUX
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
	return IsSoftwareDrawingMode () ?
		RecursiveLightPoint <mnode_t, msurface_t> (sv_worldmodel->nodes, start, end) :
		RecursiveLightPoint <GL_mnode_t, GL_msurface_t> (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}

inline const unsigned char R_LightPoint (const Vector &p)
{
	// Reliability check.
	if (sv_worldmodel == NULL)
		return 0u;

	if (sv_worldmodel->lightdata == NULL)
		return 255u;

	Vector end (p);

	end.z -= 2048.0f;

	return ActualRecursiveLightPoint (p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
}
}
or even use the method of an "axe", as we in Russia love.... (without templates)
Code:
static const bool RecursiveLightPoint (const mnode_t *const node, const Vector &start, const Vector &end)
{
	float front, back, frac;
	int side;
	mplane_t *plane;
	Vector mid;
	msurface_t *surf;
	int s, t, ds, dt;
	int i;
	mtexinfo_t *tex;
	color24 *lightmap;
	unsigned int scale;
	unsigned char maps;

	// Reliability check.
	assert (node != NULL);

	if (node->contents < 0)
		return false;	// didn't hit anything

	// Determine which side of the node plane our points are on
	// FIXME: optimize for axial
	plane = node->plane;
	front = DotProduct (start, plane->normal) - plane->dist;
	back = DotProduct (end, plane->normal) - plane->dist;
	side = front < 0.0f;

	// If they're both on the same side of the plane, don't bother to split just check the appropriate child
	if ((back < 0.0f) == side)
		return RecursiveLightPoint (node->children[side], start, end);

	// calculate mid point
	frac = front / (front - back);
	mid = start + (end - start) * frac;

	// go down front side	
	if (RecursiveLightPoint (node->children[side], start, mid))
		return true;	// hit something

	// Blow it off if it doesn't split the plane...
	if ((back < 0.0f) == side)
		return false;	// didn't hit anything

	// check for impact on this node
//	lightspot = mid;
//	lightplane = plane;

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

		tex = surf->texinfo;

		// See where in lightmap space our intersection point is
		s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
		t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

		// Not in the bounds of our lightmap? punt...
		if (s < surf->texturemins[0] || t < surf->texturemins[1])
			continue;

		// assuming a square lightmap (FIXME: which ain't always the case),
		// lets see if it lies in that rectangle. If not, punt...
		ds = s - surf->texturemins[0];
		dt = t - surf->texturemins[1];

		if (ds > surf->extents[0] || dt > surf->extents[1])
			continue;

		if (surf->samples == NULL)
			return true;

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

		g_pointColor.Reset ();	// Reset point color.

		const int smax ((surf->extents[0] >> 4) + 1);
		const int tmax ((surf->extents[1] >> 4) + 1);
		const int size (smax * tmax);

		lightmap = surf->samples + dt * smax + ds;

		// Compute the lightmap color at a particular point
		for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
		{
			scale = d_lightstylevalue[surf->styles[maps]];

			g_pointColor.red += lightmap->r * scale;
			g_pointColor.green += lightmap->g * scale;
			g_pointColor.blue += lightmap->b * scale;

			lightmap += size;	// skip to next lightmap
		}

		g_pointColor.red >>= 8u;
		g_pointColor.green >>= 8u;
		g_pointColor.blue >>= 8u;

		return true;
	}

	// go down back side
	return RecursiveLightPoint (node->children[!side], mid, end);
}
static const bool GL_RecursiveLightPoint (const GL_mnode_t *const node, const Vector &start, const Vector &end)
{
	float front, back, frac;
	int side;
	mplane_t *plane;
	Vector mid;
	GL_msurface_t *surf;
	int s, t, ds, dt;
	int i;
	mtexinfo_t *tex;
	color24 *lightmap;
	unsigned int scale;
	unsigned char maps;

	// Reliability check.
	assert (node != NULL);

	if (node->contents < 0)
		return false;	// didn't hit anything

	// Determine which side of the node plane our points are on
	// FIXME: optimize for axial
	plane = node->plane;
	front = DotProduct (start, plane->normal) - plane->dist;
	back = DotProduct (end, plane->normal) - plane->dist;
	side = front < 0.0f;

	// If they're both on the same side of the plane, don't bother to split just check the appropriate child
	if ((back < 0.0f) == side)
		return GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[side]), start, end);

	// calculate mid point
	frac = front / (front - back);
	mid = start + (end - start) * frac;

	// go down front side	
	if (GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[side]), start, mid))
		return true;	// hit something

	// Blow it off if it doesn't split the plane...
	if ((back < 0.0f) == side)
		return false;	// didn't hit anything

	// check for impact on this node
//	lightspot = mid;
//	lightplane = plane;

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

		tex = surf->texinfo;

		// See where in lightmap space our intersection point is
		s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
		t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

		// Not in the bounds of our lightmap? punt...
		if (s < surf->texturemins[0] || t < surf->texturemins[1])
			continue;

		// assuming a square lightmap (FIXME: which ain't always the case),
		// lets see if it lies in that rectangle. If not, punt...
		ds = s - surf->texturemins[0];
		dt = t - surf->texturemins[1];

		if (ds > surf->extents[0] || dt > surf->extents[1])
			continue;

		if (surf->samples == NULL)
			return true;

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

		g_pointColor.Reset ();	// Reset point color.

		const int smax ((surf->extents[0] >> 4) + 1);
		const int tmax ((surf->extents[1] >> 4) + 1);
		const int size (smax * tmax);

		lightmap = surf->samples + dt * smax + ds;

		// Compute the lightmap color at a particular point
		for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
		{
			scale = d_lightstylevalue[surf->styles[maps]];

			g_pointColor.red += lightmap->r * scale;
			g_pointColor.green += lightmap->g * scale;
			g_pointColor.blue += lightmap->b * scale;

			lightmap += size;	// skip to next lightmap
		}

		g_pointColor.red >>= 8u;
		g_pointColor.green >>= 8u;
		g_pointColor.blue >>= 8u;

		return true;
	}

	// go down back side
	return GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[!side]), mid, end);
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
	return IsSoftwareDrawingMode () ?
		RecursiveLightPoint (sv_worldmodel->nodes, start, end) :
		GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}
But don't forget to remove all definitions of function RecursiveLightPoint from .cpp files FOR BOTH CASES....
Finally in bot_globals.cpp everything should be as so:
Code:
/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//const mplane_t *lightplane (NULL);
//Vector lightspot;
Color g_pointColor;
}
  
Reply With Quote