.:: Bots United ::.  
filebase forums discord server github wiki web
cubebot epodbot fritzbot gravebot grogbot hpbbot ivpbot jkbotti joebot
meanmod podbotmm racc rcbot realbot sandbot shrikebot soulfathermaps yapb

Go Back   .:: Bots United ::. > Developer's Farm > General Bot Coding
General Bot Coding See what a pain it is to get those little mechs shooting around

Reply
 
Thread Tools
Source-like filtered trace hull in HL1
Old
  (#1)
Immortal_BLG
Member
 
Status: Offline
Posts: 171
Join Date: Nov 2007
Location: Russian Federation
Smile Source-like filtered trace hull in HL1 - 14-07-2010

WARNING THIS CODE IS VERY SLOW!!! (Profiling(in microseconds): provided function ~= 0.044809, UTIL_TraceLine() ~= 0.001445)

Code:
class ITraceFilter
{
	public:
		virtual inline const bool ShouldHitEntity (edict_t *const edict) = 0;

	//
	// Group: Private operators.
	//
	private:
		inline ITraceFilter &operator = (const ITraceFilter &/*right*/);	// Avoid "warning C4512: 'ITraceFilter' : assignment operator could not be generated".
};

//-----------------------------------------------------------------------------
// Classes need not inherit from these
//-----------------------------------------------------------------------------
class TraceFilter_HitWorldOnly : public ITraceFilter
{
	public:
		inline const bool ShouldHitEntity (edict_t *const edict)
		{
			return ENTINDEX (edict) == 0u;
		}
};

class TraceFilter_HitAll : public ITraceFilter
{
	public:
		virtual inline const bool ShouldHitEntity (edict_t *const edict)
		{
			return true;
		}
};

class TraceFilter_PassEntity : public ITraceFilter
{
	private:
		const edict_t *m_passEdict;

	public:
		inline TraceFilter_PassEntity (const edict_t *const passEdict) :
			m_passEdict (passEdict)
		{ /* VOID */ }

	public:
		inline const bool ShouldHitEntity (edict_t *const edict)
		{
			return m_passEdict != edict;
		}
};

//-----------------------------------------------------------------------------
// Trace filter that can take a list of entities to ignore
//-----------------------------------------------------------------------------
class TraceFilter_SimpleList : public ITraceFilter
{
	protected:
		vector <edict_t *> m_passEntities;

	public:
		inline TraceFilter_SimpleList (void) { /* VOID */ }

	public:
		virtual inline const bool ShouldHitEntity (edict_t *const edict)
		{
			for (unsigned int index (0u); index < m_passEntities.size (); ++index)
				if (edict == m_passEntities[index])
					return false;

			return true;
		}

		//-----------------------------------------------------------------------------
		// Purpose: Add an entity to my list of entities to ignore in the trace
		//-----------------------------------------------------------------------------
		inline void AddEntityToIgnore (edict_t *const edict)
		{
			m_passEntities.push_back (edict);
		}
};

//-----------------------------------------------------------------------------
// Trace filter that can take a classname to ignore
//-----------------------------------------------------------------------------
class TraceFilter_SkipClassName : public ITraceFilter
{
	private:
		const char *const m_className;

	public:
		inline TraceFilter_SkipClassName (const char *const className) :
			m_className (className)
		{ /* VOID */ }

	public:
		virtual inline const bool ShouldHitEntity (SDK::Classes::Edict *const edict)
		{
			return !FClassnameIs (edict, m_className);
		}
};

//-----------------------------------------------------------------------------
// Trace filter that can take a list of entities to ignore
//-----------------------------------------------------------------------------
class TraceFilter_SimpleClassNameList : public ITraceFilter
{
	private:
		vector <const char *> m_passClassNames;

	public:
		virtual inline const bool ShouldHitEntity (SDK::Classes::Edict *const edict)
		{
			for (unsigned int index (0u); index < m_passClassNames.size (); ++index)
				if (FClassnameIs (edict, m_passClassNames[index]))
					return false;

			return true;
		}

		//-----------------------------------------------------------------------------
		// Purpose: Add an entity to my list of entities to ignore in the trace
		//-----------------------------------------------------------------------------
		inline void AddClassnameToIgnore (const char *const className)
		{
			m_passClassNames.push_back (className);
		}
};

class TraceFilter_Chain : public ITraceFilter
{
	private:
		ITraceFilter &m_traceFilter1;
		ITraceFilter &m_traceFilter2;

	public:
		inline TraceFilter_Chain (ITraceFilter &traceFilter1, ITraceFilter &traceFilter2) :
			m_traceFilter1 (traceFilter1),
			m_traceFilter2 (traceFilter2)
		{ /* VOID */ }

	public:
		virtual inline const bool ShouldHitEntity (edict_t *const edict)
		{
			return m_traceFilter1.ShouldHitEntity (edict) && m_traceFilter2.ShouldHitEntity (edict);
		}
};

void TraceHull (const Vector &source, const Vector &destination, const int hullNumber, ITraceFilter &traceFilter, TraceResult &traceResult)
{
	TraceResult tempTraceResult;
	edict_t *entity (INDEXENT (0u));	// worldspawn

	if (traceFilter.ShouldHitEntity (entity))
		g_engfuncs.pfnTraceModel (source, destination, hullNumber, entity, &traceResult);
	else
	{
		// Fill in a default trace result
		memset (&traceResult, 0, sizeof (traceResult));

		traceResult.flFraction = 1.0f;
		traceResult.fAllSolid = true;
		traceResult.vecEndPos = destination;
	}

	// For each entity....
	for (unsigned short index (1u/* Skip worldspawn entity.... */); index < gpGlobals->maxEntities; ++index)
	{
		++entity;

		if (FNullEnt (entity) || entity->v.mins == vec3_origin || entity->v.maxs == vec3_origin)
			continue;

		// Reliability check.
		assert (entity->v.classname > 0);	// MAY HAPPEN?!?!?!?!?!?

		if (!traceFilter.ShouldHitEntity (entity))
			continue;

		g_engfuncs.pfnTraceModel (source, destination, hullNumber, entity, &tempTraceResult);

		if (tempTraceResult.flFraction < traceResult.flFraction)
			traceResult = tempTraceResult;
	}
}
  
Reply With Quote
Re: Source-like filtered trace hull in HL1
Old
  (#2)
The Storm
Council Member / E[POD]bot developer
 
The Storm's Avatar
 
Status: Offline
Posts: 1,618
Join Date: Jul 2004
Location: Bulgaria
Default Re: Source-like filtered trace hull in HL1 - 14-07-2010

I'm not familiar with the Source SDK, so can you explain shortly what is the difference?
  
Reply With Quote
Re: Source-like filtered trace hull in HL1
Old
  (#3)
Immortal_BLG
Member
 
Status: Offline
Posts: 171
Join Date: Nov 2007
Location: Russian Federation
Default Re: Source-like filtered trace hull in HL1 - 15-07-2010

HL1 Trace hull/line doesn't hit's entities with solid type SOLID_NOT or SOLID_TRIGGER ("func_ladder", "func_illusionary", ....), but the given function can hit all the entities, to filter them you should made your's filter or use given one, to check - is this entity should be checked for collision or not.

Example: The code below will pass only player entities.
Code:
TraceFilter_SkipClassName traceFilter ("player");

TraceHull (source, destination, point_hull, traceFilter, traceResult);
Sorry for bad english...........................................
  
Reply With Quote
Re: Source-like filtered trace hull in HL1
Old
  (#4)
Immortal_BLG
Member
 
Status: Offline
Posts: 171
Join Date: Nov 2007
Location: Russian Federation
Default Re: Source-like filtered trace hull in HL1 - 15-07-2010

Sorry - double post - my internet is shit!
  
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
vBulletin Skin developed by: vBStyles.com