.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   Source-like filtered trace hull in HL1 (http://forums.bots-united.com/showthread.php?t=7657)

Immortal_BLG 14-07-2010 13:12

Source-like filtered trace hull in HL1
 
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;
        }
}


The Storm 14-07-2010 18:36

Re: Source-like filtered trace hull in HL1
 
I'm not familiar with the Source SDK, so can you explain shortly what is the difference? :)

Immortal_BLG 15-07-2010 05:08

Re: Source-like filtered trace hull in HL1
 
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...........................................

Immortal_BLG 15-07-2010 05:08

Re: Source-like filtered trace hull in HL1
 
Sorry - double post - my internet is shit! :(


All times are GMT +2. The time now is 01:27.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.