Physics

Castle Game Engine is integrated with Kraft Physics Engine made by Benjamin 'BeRo' Rosseaux. Read on to learn how to add rigid-body physics to your own games.

Note: Physics integration is only implemented in Castle Game Engine >= 6.3. For now (until we release the CGE 6.4) you need to use the CGE version from GitHub to have this feature.

Usage

You can turn any T3DTransform instance into a rigid body, which means that it will be affected by gravity and collisions with other rigid bodies. A T3DTransform is typically a parent for one or more TCastleScene, which actually show the 3D objects.

To make a rigid body you need to:

  1. Create a T3DTransform and TCastleScene, this is described in the manual chapter about transforming scene.

  2. Create and configure an instance of TRigidBody.

  3. Create and configure an instance of some TCollider descendant, like TPlaneCollider, TBoxCollider, TSphereCollider, TMeshCollider. It will be connected to the parent rigid body at construction (the TRigidBody.Collider property will be automatically set when creating the collider).

  4. Link to your rigid body from the T3DTransform.RigidBody property.

This is a sample code:

var
  Scene: TCastleScene;
  Transform: T3DTransform;
  RigidBody: TRigidBody;
  Collider: TBoxCollider;
begin
  // Create TCastleScene
  Scene := TCastleScene.Create(Application);
  Scene.Load(URL);
  Scene.Spatial := [ssRendering, ssDynamicCollisions];
  Scene.ProcessEvents := true;
 
  // Create T3DTransform
  Transform := T3DTransform.Create(Application);
  // Transform.Translation := Vector3(1, 2, 3); // set initial position
  Transform.Add(Scene);
 
  // Create TRigidBody
  RigidBody := TRigidBody.Create(Application);
  // RigidBody.Dynamic := ?; // boolean, default true
  // RigidBody.Gravity := ?; // boolean, default true
  // RigidBody.InitialLinearVelocity := Vector3(10, 0, 0);
 
  // Create TCollider (a TBoxCollider, to be more precise, in this case).
  // Note that TBoxCollider assumes that box is centered around (0,0,0) for now
  Collider := TBoxCollider.Create(RigidBody);
  Collider.Size := Scene.BoundingBox.Size;
  // Collider.Restitution := 0.3;
  // Collider.Density := 100.0;
 
  // Connect rigid body
  Transform.RigidBody := RigidBody;
 
  // Add Transform to the scene manager, to make it part of visible 3D world
  SceneManager.Items.Add(Transform);
end;

See physics_3d_demo, in particular the physics_3d_demo/game.pas source code, for a complete working example.

Notes:

  • Right now the instruction to assign T3DTransform.RigidBody should be at the very end, when you configured all the rigid body and collider parameters. Right now, this is when the rigid body is actually created on the physics engine side. Right now changing the properties of rigid body or collider later has no effect (if you need it, the temporary workaround is to set T3DTransform.RigidBody to nil and then again to your TRigidBody instance).

  • The collider shape is not synchronized with the scene shape in any way. This also applies to the TMeshCollider that has a Scene property: the mesh is created once from the scene geometry, it is not synchronized with scene changes later. (If you need it, the workaround is the same as above: set T3DTransform.RigidBody to nil and then again to your TRigidBody instance. But creating a mesh collider is a costly operation, so think twice before doing this during the game!)

2D games

Although internally Castle Game Engine and Kraft work in 3D, the physics can work just fine for 2D games too.

  • Simply position everything around Z = 0 (or any other Z = constant plane).
  • When creating colliders, make sure that they have some non-zero size in Z axis too. Even though the Z axis is not visible in 2D games, but the colliders need to have some volume in all 3 axes.
  • Constrain rotations and movement of dynamic rigid bodies to 2D by calling TRigidBody.Setup2D.

The example how to do this is in physics_2d_game_sopwith (see in particular the physics_2d_game_sopwith/game.pas source code).

Future plans (TODOs)

Current physics engine integration is just a start. Michalis wants to dedicate a whole Castle Game Engine release in the future toward extending the physics. The plans are:

  • A shape within the TCastleScene should be able to act like a rigid body, independent of the rest of the scene. Ideally, this should be configurable in Blender, and exported nicely to X3D. The X3D specification has a rigid-body component to describe such things.

  • Currently we also have an older, simpler, internal physics/collision engine in CGE, that takes care of some tasks: the collisions of player and creatures (from CastleCreatures), a simple gravity for them, and custom collision methods for you (like RayCollision, SphereCollision etc. in Castle3D unit). The new physics engine can probably replace them all, and there should be a flag to make it possible, and eventually it should even become the default, and the old collision implementation should be simply removed.

  • The current implementation doesn't expose any API for joints. Again, they could be designed in Blender and exported to X3D.

  • The current implementation doesn't allow T3DTransform with rigid body to be further transformed by parent T3DTransform. This should be fixed. Also, during CGE 6.4. release, T3DTransform will be changed to a more flexible TCastleTransform, see plans for nearest CGE 6.4 release.

  • In the past, I planned integration with other physics engines, through a layer providing a common API. However, right now, I'm extremely satisfied with Kraft. As far as rigid body simulation goes, I think that Kraft may be the physics engine for us, and we may not need anything else... But just in case, here are other options I considered:

    • Bullet. Very full-featured, e.g. there's soft body, not only rigid body.

      Full integration with Bullet will require proper translation of Bullet API to C and then to Pascal (as Bullet is in C++, it's not readily usable from anything other than C++). There is a C header for Bullet, see this old Google Code issue and this GitHub issue, but it's rather minimalistic (only rigid body), although it may be a good start.

    • ODE. A popular physics engine with simple C API. Old Pascal header here. I don't see any advantages ODE has over Kraft, for now.