CollisionProperty: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
 
m (markup tweaks)
Line 1: Line 1:
----
All entities that are collideable have a <code>CollisionProperty</code>.  There's an accessor in CBaseEntity 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:
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.
Entities that use <code>[[vphysics]]</code> 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 (CollisionProp()->SetSolid()) determines what type of collision primitive to use for tests.  There is also
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>
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.
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.
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.
Line 21: Line 17:
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:
It can be customized by calling:
<pre>
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
</pre>


The parameter can be any of these:
CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
<pre>  
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
};
</pre>


The parameter can be any of these:


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.
  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_GAME_CODE lets a programmer customize the bounds as needed by calling a virtual defined in the entity's class:
<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.


<pre>
<code>USE_GAME_CODE</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 );
</pre>


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 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).
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 <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]]

Revision as of 12:58, 10 January 2007

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 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).