CollisionProperty: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
 
No edit summary
 
(8 intermediate revisions by 6 users not shown)
Line 1: Line 1:
----
{{LanguageBar}}
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:
{{Underlinked|date=January 2024}}


Entities that use vphysics also have a IPhysicsObject which provides additional collision properties related to vphysics simulation.
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:


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
Entities that use [[VPhysics]] also have a <code>IPhysicsObject</code> which provides additional collision properties related to vphysics simulation.
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.
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.


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.
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 Bounds
== 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. So a player's surrounding bounds need to be configured so that they always enclose any hitboxes that should be checked.
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.
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:
<pre>  
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
</pre>  
</syntaxhighlight>


The parameter can be any of these:
The parameter can be any of these:<syntaxhighlight lang="cpp">
<pre>  
enum SurroundingBoundsType_t
enum SurroundingBoundsType_t
{
{
Line 39: Line 34:
SURROUNDING_TYPE_BIT_COUNT = 3
SURROUNDING_TYPE_BIT_COUNT = 3
};
};
</pre>
</syntaxhighlight>
 
 
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:


<pre>
<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.
virtual void ComputeWorldSpaceSurroundingBox( Vector *pWorldMins, Vector *pWorldMaxs );
</pre>


<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. As a tradeoff, 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).
<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

English (en)中文 (zh)Translate (Translate)
Underlinked - Logo.png
This article needs more Wikipedia icon links to other articles to help Wikipedia icon integrate it into the encyclopedia. Please help improve this article by adding links Wikipedia icon that are relevant to the context within the existing text.
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).