Skip to main content

collider_creation_and_insertion

A collider is described by a R3ColliderDesc structure, initialized by one of its constructors (e.g. r3BallColliderDesc, r3CuboidColliderDesc, r3CapsuleYColliderDesc, or r3DefaultColliderDesc) which set meaningful default values to all its fields. Its geometric shape is given by its shape field, a R3ShapeDesc whose kind (e.g. R3_SHAPE_DESC_CUBOID) selects which of its fields are actually read. Then it needs to be inserted into the physics world: with r3InsertCollider to attach it to a rigid-body, or with r3InsertColliderWithoutParent otherwise. Both return the R3ColliderHandle identifying the new collider.

The arrays referenced by a description (vertex buffers, index buffers, compound children, etc.) are only borrowed until its insertion returns: they can be freed or reused right after. This is also the case of the shared shapes (R3SharedShape) a description can point to, with the R3_SHAPE_DESC_SHARED kind. A shared shape is an immutable geometry created by one of the r3...SharedShape functions (e.g. r3BallSharedShape), which can be given to any number of colliders, and must be freed with r3FreeSharedShape. Some shapes, like convex decompositions or voxels, can only be created as shared shapes.

info

The following example shows several fields that can be set to customize the collider being described. The input values are just random so using this example as-is will not lead to a useful result.

// The world that will contain our colliders.
R2World *world = r2NewWorld();

// Description of a ball-shaped collider.
R2ColliderDesc ball = r2BallColliderDesc(0.5);
// Description of a cuboid-shaped collider.
R2ColliderDesc cuboid = r2CuboidColliderDesc(r2Vector(0.5, 0.2));
// Description of a capsule-shaped collider. The capsule principal axis is the `x` coordinate axis.
R2ColliderDesc capsule_x = r2CapsuleXColliderDesc(0.5, 0.2);
// Description of a capsule-shaped collider. The capsule principal axis is the `y` coordinate axis.
R2ColliderDesc capsule_y = r2CapsuleYColliderDesc(0.5, 0.2);
// Description of a triangle-mesh-shaped collider.
R2ColliderDesc trimesh = r2DefaultColliderDesc();
r2ShapeDesc_SetTrimesh(&trimesh.shape, (R2VectorView){vertices, 3}, (R2TriangleView){indices, 1}, 0);
// Description of a heightfield-shaped collider.
R2ColliderDesc heightfield = r2DefaultColliderDesc();
heightfield.shape.kind = R2_SHAPE_DESC_HEIGHTFIELD;
heightfield.shape.heights = (R2RealView){heights, 4};
heightfield.shape.rows = 4;
heightfield.shape.columns = 1;
heightfield.shape.scale = scale;
// Description of a collider with the given shared shape.
R2SharedShape *shape = r2BallSharedShape(0.5);
R2ColliderDesc collider = r2DefaultColliderDesc();
collider.shape.kind = R2_SHAPE_DESC_SHARED;
collider.shape.sharedShape = shape;
// The collider translation wrt. the body it is attached to.
// Default: the zero vector.
collider.position.translation = r2Vector(1.0, 2.0);
// The collider rotation wrt. the body it is attached to.
// Default: the identity rotation.
collider.position.rotation = r2Rotation(R2_PI);
// The collider position wrt. the body it is attached to.
// Default: the identity pose.
collider.position = r2Pose(r2Vector(1.0, 2.0), r2Rotation(R2_PI));
// The collider density. If non-zero the collider's mass and angular inertia will be added
// to the inertial properties of the body it is attached to.
// Default: 1.0
collider.density = 1.3;
// The friction coefficient of this collider.
// Default: 0.5
collider.friction = 0.8;
// Whether this collider is a sensor.
// Default: 0
collider.isSensor = 1;

// Insert the collider into the world, without attaching it to a rigid-body.
R2ColliderHandle collider_handle = r2InsertColliderWithoutParent(world, &collider);

R2RigidBodyDesc rigid_body = r2DynamicRigidBodyDesc();
R2RigidBodyHandle rigid_body_handle = r2InsertRigidBody(world, &rigid_body);
// Or insert the collider into the world and attach it to a rigid-body.
R2ColliderHandle handle = r2InsertCollider(rigid_body_handle, &collider);
// The descriptions only borrow the shared shape: free it once it is no longer needed.
r2FreeSharedShape(shape);

A collider can also be disabled, by setting the enabled field of its description to 0 or, after its creation, with r3Collider_SetEnabled. A disabled collider is excluded from all the collision-detection and physics until it is enabled again, which is useful to "turn off" a collider temporarily without removing it (a collider is removed from the world with r3RemoveCollider).