View Single Post
Re: code to get the illumination at any point on the map
Old
  (#11)
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 - 13-03-2012

You should add or in HLSDK, or somewhere in the header file of the bot of structures with a prefix "GL_".
Generally, for your bot it is necessary to add simply all code, from my fifth post and if it is concrete:
Code:
// "bot_globals.h"
//{
#include <com_model.h>	// WARNING: Probably it is necessary to add any additional includes....

struct GL_msurface_t
{
/*off=0(0)*/	int			visframe;		// should be drawn when node is crossed
/*off=4(1)*/	mplane_t	*plane;			// pointer to shared plane
/*off=8(2)*/	int			flags;			// see SURF_* #defines

/*off=12(3)*/	int			firstedge;	// look up in model->surfedges[], negative numbers are backwards edges
/*off=16(4)*/	int			numedges;

/*off=20(5)*/	short		texturemins[2]; // smallest s/t position on the surface.
/*off=24(6)*/	short		extents[2];		// ?? s/t texture size, 1..256 for all non-sky surfaces

/*off=28(7)*/	int			light_s, light_t;	// gl lightmap coordinates
/*off=36(9)*/	struct glpoly_t	*polys;				// multiple if warped
/*off=40(10)*/	msurface_t	*texturechain;
/*off=44(11)*/	mtexinfo_t	*texinfo;

// lighting info
/*off=48(12)*/	int			dlightframe;	// last frame the surface was checked by an animated light
/*off=52(13)*/	int			dlightbits;		// dynamically generated. Indicates if the surface illumination
								// is modified by an animated light.
/*off=56(14)*/	int			lightmaptexturenum;
/*off=60(15)*/	unsigned char		styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights
									  // no one surface can be effected by more than 4
									  // animated lights.

/*off=64(16)*/	int			cached_light[MAXLIGHTMAPS];	// values currently used in lightmap
/*off=80(20)*/	BOOL	cached_dlight;				// true if dynamic light in cache

/*off=84(21)*/	color24		*samples;	// [numstyles*surfsize]

/*off=88(22)*/	decal_t		*pdecals;
};	// sizeof (GL_msurface_t) == 92 (23)
struct GL_mnode_t
{
	enum ChildrenType_t
	{
		ChildrenType_Front,
		ChildrenType_Back,

		ChildrenType_Total
	};

// common with leaf
/*! Off=0(0)*/	int			contents;		// 0, to differentiate from leafs
/*! Off=4(1)*/	int			visframe;		// node needs to be traversed if current

/*! Off=8(2)*/	Vector		mins, maxs;		// for bounding box culling

/*! Off=32(8)*/	mnode_t	*parent;

// node specific
/*! Off=36(9)*/	mplane_t	*plane;
/*! Off=40(10)*/	mnode_t	*children[ChildrenType_Total];

/*! Off=48(12)*/	unsigned short		firstsurface;
/*! Off=50(12.5)*/	unsigned short		numsurfaces;
};	// sizeof (GL_mnode_t) == 52 (13)

#define	MAX_LIGHTSTYLES	64
#define	MAX_LIGHTSTYLEVALUE	256

struct lightstyle_t
{
	int  length;
	char map[MAX_LIGHTSTYLES];
};

extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern int          d_lightstylevalue[MAX_LIGHTSTYLEVALUE];	// 8.8 fraction of base light value
extern model_t     *sv_worldmodel;	// Analog of sv.worldmodel.

struct Color
{
	int red;
	int green;
	int blue;

	inline       void         Reset  (void)       { red = green = blue = 0; }
	inline const unsigned int GetAvg (void) const { return (red + green + blue) / (sizeof (Color) / sizeof (int)); }
};

/*
=============================================================================

LIGHT SAMPLING

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

template <typename nodeType, typename surfaceType> extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);

inline const bool IsSoftwareDrawingMode (void)
{
	static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

	return isSoftwareDrawingMode;
}
inline const bool ActualRecursiveLightPoint (const Math::Vector3D &start, const Math::Vector3D &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 ());
}
}
//}

// "bot_globals.cpp"
//{
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
int          d_lightstylevalue[MAX_LIGHTSTYLEVALUE];	// 8.8 fraction of base light value
model_t     *sv_worldmodel (NULL);	// Analog of sv.worldmodel.
//}

// "dll.cpp"
//{
static inline const char *const FormatBuffer (const char *const format, ...)
{
	/// @todo REMOVE THIS SHIT

	static char string[4096u];

	va_list argumentPointer;

	// Concatenate all the arguments in one string....
	va_start (argumentPointer, format);
		vsnprintf (string, sizeof (string), format, argumentPointer);
	va_end (argumentPointer);

	return string;
}
inline void ShowMagic (void)
{
	/// @todo REMOVE THIS SHIT

	const edict_t *const hostPlayerEdict (INDEXENT (1u));

	if (hostPlayerEdict == NULL || hostPlayerEdict->free || (hostPlayerEdict->v.flags & FL_FAKECLIENT))
		return;

	CLIENT_PRINTF (hostPlayerEdict, print_chat, FormatBuffer ("ShowMagic(): \"%s\"->v.light_level=%i, R_LightPoint(hostOrg)=%i\n", STRING (hostPlayerEdict->v.netname), hostPlayerEdict->v.light_level, Light::R_LightPoint (hostPlayerEdict->v.origin)));
}

static inline void SetupLightStyles (void)
{
	// Setup lighting information....

	// reset all light styles
	for (unsigned char index (0u); index < MAX_LIGHTSTYLES; ++index)
	{
		cl_lightstyle.length = 0u;
		cl_lightstyle.map[0u] = '\0';
	}

	for (unsigned short index (0u); index < MAX_LIGHTSTYLEVALUE; ++index)
		d_lightstylevalue[index] = 264;	// normal light value
}

static inline void R_AnimateLight (void)
{
	// light animations
	// 'm' is normal light, 'a' is no light, 'z' is double bright
	const int i (static_cast <int> (gpGlobals->time * 10.0f));
	int k;

	for (unsigned char j (0u); j < MAX_LIGHTSTYLES; ++j)
	{
		if (cl_lightstyle[j].length == 0u)
		{
			d_lightstylevalue[j] = 256;

			continue;
		}

		k = cl_lightstyle[j].map[i % cl_lightstyle[j].length] - 'a';
		k *= 22;

		d_lightstylevalue[j] = k;
	}	
}

static inline void CallbackStartFrame (void)
{
	R_AnimateLight ();

	/// @todo REMOVE THIS SHIT
	{
	inline void ShowMagic (void);

	ShowMagic ();
	}
}
static inline void CallbackPM_Move (playermove_t *const playerMove, const bool server)
{
	// Reliability checks.
	assert (playerMove != NULL);
	assert (server == true);	// ALWAYS SHOULD BE TRUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	// Honestly this is need only once per changelevel, but....
	sv_worldmodel = playerMove->physents[0u].model;	// Always point at sv.worldmodel!

	// Reliability check.
	assert (sv_worldmodel != NULL);
}

/////////////////////////////////// BEGIN OF DLL API FORWARDS ///////////////////////////////////
WINAPI GiveFnptrsToDll (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals)
{
	// get the engine functions from the engine...

	memcpy (&g_engfuncs, pengfuncsFromEngine, sizeof (enginefuncs_t));
	gpGlobals = pGlobals;

	SetupLightStyles ();
}
// Called each Server frame at the very beginning
void StartFrame (void)
{
	CallbackStartFrame ();

	/// ... PART OF YOUR CODE HERE

	RETURN_META (MRES_IGNORED);
}
static void PM_Move (playermove_t *playerMove, BOOL server)	// NEW FORWARD FOR YOUR BOT!!!
{
	// this is the player movement code clients run to predict things when the server can't update
	// them often enough (or doesn't want to). The server runs exactly the same function for
	// moving players. There is normally no distinction between them, else client-side prediction
	// wouldn't work properly (and it doesn't work that well, already...)

	CallbackPM_Move (playerMove, server == TRUE);

	RETURN_META (MRES_IGNORED);
}
/////////////////////////////////// END OF DLL API FORWARDS ///////////////////////////////////

C_DLLEXPORT int GetEntityAPI2 (DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
   gFunctionTable.pfnGameInit = GameDLLInit;
   gFunctionTable.pfnSpawn = Spawn;
   gFunctionTable.pfnClientConnect = ClientConnect;
   gFunctionTable.pfnClientDisconnect = ClientDisconnect;
   gFunctionTable.pfnClientPutInServer = ClientPutInServer;
   gFunctionTable.pfnClientCommand = ClientCommand;
   gFunctionTable.pfnServerActivate = ServerActivate;
   gFunctionTable.pfnServerDeactivate = ServerDeactivate;
   gFunctionTable.pfnStartFrame = StartFrame;
   gFunctionTable.pfnKeyValue = Pfn_KeyValue;                  // KWo - 06.03.2006
   gFunctionTable.pfnPM_Move = PM_Move;	// NEW FORWARD FOR YOUR BOT!!!
   gFunctionTable.pfnUpdateClientData = Pfn_UpdateClientData;  // KWo - 02.03.2010

   memcpy (pFunctionTable, &gFunctionTable, sizeof (DLL_FUNCTIONS));
   return (TRUE);
}
//}

// "engine.cpp"
//{
static inline void CallbackLightStyle (const unsigned char style, char *const value)
{
	if (style >= MAX_LIGHTSTYLES)
	{
		g_engfuncs.ServerPrintf ("SVC_LIGHTSTYLE > MAX_LIGHTSTYLES\n");

		return;
	}

	// OCCURS!
	if (value == NULL)
	{
		cl_lightstyle[style].length = 0u;
		cl_lightstyle[style].map[0u] = '\0';

		return;
	}

	const unsigned short maximumCopyAmount (sizeof (cl_lightstyle[style].map) - sizeof ('\0'));

	strncpy (cl_lightstyle[style].map, value, maximumCopyAmount);

	cl_lightstyle[style].map[maximumCopyAmount] = '\0';

	cl_lightstyle[style].length = strlen (cl_lightstyle[style].map);
}

/////////////////////////////////// BEGIN OF ENGINE API FORWARDS ///////////////////////////////////
static void pfnLightStyle (int style, char *value)	// NEW FORWARD FOR YOUR BOT!!!
{
	// Update light style for fake clients....
	CallbackLightStyle (static_cast <const unsigned char> (style), value);

	RETURN_META (MRES_IGNORED);
}

C_DLLEXPORT int GetEngineFunctions (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion)
{
   meta_engfuncs.pfnChangeLevel = pfnChangeLevel;
   meta_engfuncs.pfnEmitSound = pfnEmitSound;
   meta_engfuncs.pfnFindEntityByString = pfnFindEntityByString;
   meta_engfuncs.pfnClientCommand = pfnClientCommand;
   meta_engfuncs.pfnLightStyle = pfnLightStyle;	// NEW FORWARD FOR YOUR BOT!!!
   meta_engfuncs.pfnMessageBegin = pfnMessageBegin;
   meta_engfuncs.pfnMessageEnd = pfnMessageEnd;
   meta_engfuncs.pfnWriteByte = pfnWriteByte;
   meta_engfuncs.pfnWriteChar = pfnWriteChar;
   meta_engfuncs.pfnWriteShort = pfnWriteShort;
   meta_engfuncs.pfnWriteLong = pfnWriteLong;
   meta_engfuncs.pfnWriteAngle = pfnWriteAngle;
   meta_engfuncs.pfnWriteCoord = pfnWriteCoord;
   meta_engfuncs.pfnWriteString = pfnWriteString;
   meta_engfuncs.pfnWriteEntity = pfnWriteEntity;
   meta_engfuncs.pfnClientPrintf = pfnClientPrintf;
   meta_engfuncs.pfnCmd_Args = pfnCmd_Args;
   meta_engfuncs.pfnCmd_Argv = pfnCmd_Argv;
   meta_engfuncs.pfnCmd_Argc = pfnCmd_Argc;
   meta_engfuncs.pfnSetClientMaxspeed = pfnSetClientMaxspeed;
   meta_engfuncs.pfnGetPlayerWONId = pfnGetPlayerWONId;
   meta_engfuncs.pfnGetPlayerAuthId = pfnGetPlayerAuthId;

   memcpy (pengfuncsFromEngine, &meta_engfuncs, sizeof (enginefuncs_t));
   return (TRUE);
}
/////////////////////////////////// END OF ENGINE API FORWARDS ///////////////////////////////////
//}

// "util.cpp"
//{
/*
=============================================================================

LIGHT SAMPLING

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

template <typename nodeType, typename surfaceType> 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 = (start | plane->normal) - plane->dist;
	back = (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> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
		t = static_cast <int> ((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);
}
}
//}
Well everything seems to be....
  
Reply With Quote