CollisionProperty: Difference between revisions
Jay Stelly (talk | contribs) No edit summary |
No edit summary |
||
(8 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{{LanguageBar}} | |||
{{Underlinked|date=January 2024}} | |||
All entities that are collideable have a '''<code>CollisionProperty</code>'''. There's an accessor in <code>[[CBaseEntity]]</code> called <code>CollisionProp()</code> that lets you access/interact with collision functionality. Here is an overview of some of the functionality contained in the collision property: | |||
Entities that use [[VPhysics]] also have a <code>IPhysicsObject</code> which provides additional collision properties related to vphysics simulation. | |||
For the entity's motion, the collision property's solid type (<code>CollisionProp()->SetSolid()</code>) determines what type of collision primitive to use for tests. | |||
There is also <code>unsigned int CBaseEntity::PhysicsSolidMaskForEntity( void ) const</code> which determines what types of contents are solid for the entity. Most things are <code>[[CONTENTS_SOLID]]</code>, but [[Contents flags|there are a set of flags]] (mostly used by the BSP compiler) that can specialize contents to be filtered by certain traces or movement types. An example of this is <code>[[CONTENTS_GRATE]]</code> which is applied to brushes textured with textures that should be solid for movement, but not for bullets or line of sight tests. | |||
Otherwise <code>CBaseEntity::m_CollisionGroup</code> determines which other entities will collide with this one. The rules for which collision groups collide are in <code>CGameRules::ShouldCollide()</code> and can be customized to suit the needs of a particular mod. | |||
Surrounding | == Surrounding bounds == | ||
Surrounding bounds are used as a coarse test for many queries like collision and visibility. | Surrounding bounds are used as a coarse test for many queries like collision and visibility. | ||
For example, ray/box traces are first checked against the collision property's surrounding bounds to determine whether to then check for intersections with hitboxes on players. | For example, ray/box traces are first checked against the collision property's surrounding bounds to determine whether to then check for intersections with hitboxes on players. So a player's surrounding bounds need to be configured so that they always enclose any hitboxes that should be checked. | ||
By default the surrounding bounds are computed as a box that surrounds the collision hull. | By default the surrounding bounds are computed as a box that surrounds the collision hull. If the collision hull is smaller than the hitboxes, the surrounding bounds must be enlarged to guarantee a proper hitbox test. It can be customized by calling:<syntaxhighlight lang="cpp"> | ||
It can be customized by calling: | |||
< | |||
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE ); | CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE ); | ||
</ | </syntaxhighlight> | ||
The parameter can be any of these: | The parameter can be any of these:<syntaxhighlight lang="cpp"> | ||
< | |||
enum SurroundingBoundsType_t | enum SurroundingBoundsType_t | ||
{ | { | ||
Line 39: | Line 34: | ||
SURROUNDING_TYPE_BIT_COUNT = 3 | SURROUNDING_TYPE_BIT_COUNT = 3 | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
< | <code>USE_HITBOXES</code> will simply transform all hitboxes and build a surrounding box around those. This can be expensive to do every frame (players generally move every frame), but may be the simplest way to solve any hitbox problems. | ||
</ | |||
<code>USE_GAME_CODE</code> lets a programmer customize the bounds as needed by calling a virtual defined in the entity's class:<syntaxhighlight lang="cpp"> | |||
virtual void ComputeWorldSpaceSurroundingBox( Vector *pWorldMins, Vector *pWorldMaxs ); | |||
</syntaxhighlight> | |||
USE_SPECIFIED_BOUNDS could also be used to solve this problem by specifying a constant box that is always larger than the space occupied by hitboxes in any animation. | <code>USE_SPECIFIED_BOUNDS</code> could also be used to solve this problem by specifying a constant box that is always larger than the space occupied by hitboxes in any animation. As a trade off, this will be cheaper than <code>USE_HITBOXES</code> as the player animates and moves, but more a conservative boundary resulting in more hitbox queries happening against ray tests that miss. The highest performance method will depend on the mod's number of players moving vs. number of ray/box traces computed against players (and how many of those queries actually miss). | ||
[[Category:Tutorials]][[Category:Programming]] | [[Category:Tutorials]] | ||
[[Category:Programming]] |
Latest revision as of 09:09, 27 June 2025




January 2024
All entities that are collideable have a CollisionProperty
. There's an accessor in CBaseEntity
called CollisionProp()
that lets you access/interact with collision functionality. Here is an overview of some of the functionality contained in the collision property:
Entities that use VPhysics also have a IPhysicsObject
which provides additional collision properties related to vphysics simulation.
For the entity's motion, the collision property's solid type (CollisionProp()->SetSolid()
) determines what type of collision primitive to use for tests.
There is also unsigned int CBaseEntity::PhysicsSolidMaskForEntity( void ) const
which determines what types of contents are solid for the entity. Most things are CONTENTS_SOLID
, but there are a set of flags (mostly used by the BSP compiler) that can specialize contents to be filtered by certain traces or movement types. An example of this is CONTENTS_GRATE
which is applied to brushes textured with textures that should be solid for movement, but not for bullets or line of sight tests.
Otherwise CBaseEntity::m_CollisionGroup
determines which other entities will collide with this one. The rules for which collision groups collide are in CGameRules::ShouldCollide()
and can be customized to suit the needs of a particular mod.
Surrounding bounds
Surrounding bounds are used as a coarse test for many queries like collision and visibility.
For example, ray/box traces are first checked against the collision property's surrounding bounds to determine whether to then check for intersections with hitboxes on players. So a player's surrounding bounds need to be configured so that they always enclose any hitboxes that should be checked.
By default the surrounding bounds are computed as a box that surrounds the collision hull. If the collision hull is smaller than the hitboxes, the surrounding bounds must be enlarged to guarantee a proper hitbox test. It can be customized by calling:
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
The parameter can be any of these:
enum SurroundingBoundsType_t
{
USE_OBB_COLLISION_BOUNDS = 0,
USE_BEST_COLLISION_BOUNDS, // Always use the best bounds (most expensive)
USE_HITBOXES,
USE_SPECIFIED_BOUNDS,
USE_GAME_CODE,
USE_ROTATION_EXPANDED_BOUNDS,
USE_COLLISION_BOUNDS_NEVER_VPHYSICS,
SURROUNDING_TYPE_BIT_COUNT = 3
};
USE_HITBOXES
will simply transform all hitboxes and build a surrounding box around those. This can be expensive to do every frame (players generally move every frame), but may be the simplest way to solve any hitbox problems.
USE_GAME_CODE
lets a programmer customize the bounds as needed by calling a virtual defined in the entity's class:
virtual void ComputeWorldSpaceSurroundingBox( Vector *pWorldMins, Vector *pWorldMaxs );
USE_SPECIFIED_BOUNDS
could also be used to solve this problem by specifying a constant box that is always larger than the space occupied by hitboxes in any animation. As a trade off, this will be cheaper than USE_HITBOXES
as the player animates and moves, but more a conservative boundary resulting in more hitbox queries happening against ray tests that miss. The highest performance method will depend on the mod's number of players moving vs. number of ray/box traces computed against players (and how many of those queries actually miss).