Collision Classes
Use collision classes to filter collisions between two physical entities. A collision
class
comprises two 32-bit uints, a type
, and an ignore
.
You can use collision classes to implement scenarios such as "player only collisions," which are objects passable by AI actors but not passable by players. This feature allows you to configure filtering of the collision between physical entities independently of their collision types.
Setup
Physical entities can have one or more collision classes and can ignore one or more
collision classes. To have a physical entity ignore a collision, use the
ignore_collision
attribute of the <Physics>
element in the
<SurfaceType>
definition, as shown in the following example:
SurfaceTypes.xml
<SurfaceType name="mat_nodraw_ai_passable"> <Physics friction="0" elasticity="0" pierceability="15" ignore_collision="collision_class_ai"/> </SurfaceType>
All physical entity types such as LivingEntity
and
ParticleEntity
are supplied with default collision classes like
collision_class_living
and collision_class_particle
. Living entity
uses one additional game specific collision class: either collision_class_ai
for
AI actors, or collision_class_player
for players.
Player.lua
Player = { ... physicsParams = { collisionClass=collision_class_player, }, ... }
BasicAI.lua
BasicAI = { ... physicsParams = { collisionClass=collision_class_ai, }, ... }
Code
struct SCollisionClass { uint32 type; // collision_class flags to identify the entity uint32 ignore; // another entity will be ignored if *any* of these bits are set in its type };
The type
identifies which entity the collision classes belong to.
Some collision classes like the following are defined in CryPhysics
:
-
collision_class_terrain
-
collision_class_wheeled
-
collision_class_living
-
collision_class_articulated
-
collision_class_soft
-
collision_class_roped
-
collision_class_particle
Other collision classes are defined in GamePhysicsSettings.h
,
starting from the collision_class_game
bit:
#define GAME_COLLISION_CLASSES(f) \ f( gcc_player_capsule, collision_class_game << 0) \ f( gcc_player_body, collision_class_game << 1) \ f( gcc_pinger_capsule, collision_class_game << 2) \ f( gcc_pinger_body, collision_class_game << 3) \ f( gcc_vehicle, collision_class_game << 4) \ f( gcc_large_kickable, collision_class_game << 5) \ f( gcc_ragdoll, collision_class_game << 6) \ f( gcc_rigid, collision_class_game << 7) \ f( gcc_alien_drop_pod, collision_class_game << 8) \ f( gcc_vtol, collision_class_game << 9) \
All these classes are automatically exposed to Lua. Brushes and most objects have the collision classes available in the properties through the editor.
Types
For types, you can set many or zero bits.
In the following example, of the classes LIVING
, PLAYER
,
TEAM1
, TEAM2
, AI
, AI_1
, and
AI_2
, player1
belongs to the LIVING
entity class, the
PLAYER
class, and the TEAM1
class:
SCollisionClass player1(0,0), player2(0,0), ai1(0,0), ai7(0,0), object1(0,0); player1.type = LIVING|PLAYER|TEAM1; player2.type = LIVING|PLAYER|TEAM2; ai1.type = LIVING|AI|AI_1; ai7.type = LIVING|AI|AI_2; object1.type = 0;
Filtering the collision
Filtering occurs by checking the type
of one entity against the
ignore
of another entity.
This is done both ways, and if bits overlap, then the collision is ignored. For example:
bool ignoreCollision = (A->type & B->ignore) || (A->ignore & B->type);
If you want ai7
to ignore collisions with anything that has AI_1
set, then add AI_1
to the ignore
flags like this:
ai7.ignore = AI_1
If you want object1
to ignore all living physical entities, set its
ignore
flag like this:
object1.ignore=LIVING
Interface
-
For code, see
physinterface.h
andGamePhysicsSettings.h
. -
To access and set the collision classes on the physical entity, use
*pe_collision_class struct SCollisionClass pe_params_collision_class
. -
For helpers that set additional ignore maps, see
GamePhysicsSettings.h
. -
In Lua, see
SetupCollisionFiltering
andApplyCollisionFiltering
. Lua script-binding is done throughSetPhysicParams(PHYSICPARAM_COLLISION_CLASS)
.