Api

Physics API

Rigidbody/collider components and the public PhysicsSystem facade.

Includes

#include <EngineExports.hpp>
#include <ECS/components/Rigidbody.hpp>
#include <ECS/components/CapsuleCollider.hpp>
#include <ECS/systems/builtin/PhysicsSystem.hpp>

The public physics API is:

Public::ECS::Systems::Builtin::PhysicsSystem

Do not include Internal::Physics::IPhysicsEngine from game code. That interface is engine-private.

Getting the System

auto* physics = Public::Engine::getInstance().GetPhysicsSystem();
if (!physics) {
    LOG_ERROR("Physics system is unavailable");
    return;
}

Required Components

A physics body is created for an entity that has:

  • Transform
  • Rigidbody
  • one collider: BoxCollider, SphereCollider, CapsuleCollider, or MeshCollider

Example scene fragment:

{
  "type": "Rigidbody",
  "data": {
    "type": "Dynamic",
    "mass": 1.0,
    "useGravity": true,
    "linearVelocity": [0.0, 0.0, 0.0]
  }
},
{
  "type": "CapsuleCollider",
  "data": {
    "center": [0.0, 0.0, 0.0],
    "radius": 0.35,
    "height": 1.8,
    "friction": 0.5,
    "restitution": 0.0,
    "isTrigger": false
  }
}

Body Types

TypeUse
StaticNon-moving world geometry.
DynamicSimulated bodies affected by gravity, forces, and impulses.
KinematicMoved by game logic, still participating in physics queries/collisions.

Rigidbody.type accepts enum values in C++ and strings/integers in JSON.

Simulation Control

APIPurpose
SetSimulationEnabled(bool)Enable or pause physics stepping.
IsSimulationEnabled()Query simulation state.
StepSimulation(float dt)Manually step physics.
ClearBodies()Destroy all physics bodies tracked by the system.

Normal games let the engine call update(dt).

Simulation Filters

std::unordered_set<Public::ECS::EntityID> simulated;
simulated.insert(player);

physics->SetSimulationFilter(simulated, true);
APIPurpose
SetSimulationFilter(set, includeUnfilteredStaticEnvironment)Simulate only selected entities, optionally keeping static environment bodies.
ClearSimulationFilter()Return to normal simulation.
IsSimulationFilterEnabled()Query filter state.

Filters are useful for editor previews, isolated simulations, or custom tools.

Public Entity Controls

APIReturnsPurpose
HasBody(entity)boolCheck if a physics body exists.
GetBodyHandle(entity)PhysicsBodyHandleGet public handle; IsValid() checks nonzero ID.
SetLinearVelocity(entity, velocity)boolSet world linear velocity.
GetLinearVelocity(entity, velocity)boolRead world linear velocity.
AddForce(entity, force)boolApply force.
AddImpulse(entity, impulse)boolApply impulse.
SetBodyEnabled(entity, enabled)boolEnable/disable body.
TryGetBodyEnabled(entity, enabled)boolQuery enabled state.

Example:

float velocity[3] = {0.0f, 0.0f, 0.0f};
if (physics->GetLinearVelocity(player, velocity)) {
    velocity[0] = desiredX;
    velocity[2] = desiredZ;
    physics->SetLinearVelocity(player, velocity);
}

Gravity

float gravity[3] = {0.0f, -9.81f, 0.0f};
physics->SetGravity(gravity);

float current[3];
if (physics->GetGravity(current)) {
    LOG_INFO("Gravity Y: " + std::to_string(current[1]));
}

Rigidbody.useGravity controls whether an individual body uses gravity.

Raycasts

Public::ECS::Structs::PhysicsRaycastHit hit;
float origin[3] = {0.0f, 1.0f, 0.0f};
float direction[3] = {0.0f, -1.0f, 0.0f};

if (physics->Raycast(origin, direction, 2.0f, hit) && hit.hit) {
    float distance = hit.distance;
}

PhysicsRaycastHit contains:

FieldMeaning
hitWhether anything was hit.
bodyPublic body handle.
position[3]World hit point.
normal[3]World normal.
distanceDistance from origin.

Locking Axes

Use Rigidbody.lockRotation and Rigidbody.lockMovement for axis locks:

"lockRotation": [true, true, true],
"lockMovement": [false, false, false]

The loader also accepts a single boolean or { "x": true, "y": false, "z": true }.

Practical Guidance

  • Use Static plus MeshCollider for large world geometry.
  • Use Dynamic plus primitive colliders for characters and props.
  • Use CapsuleCollider for upright characters.
  • Use Raycast for ground checks.
  • Preserve vertical velocity when setting horizontal movement velocity.
  • Prefer AddImpulse for jumps and SetLinearVelocity for direct controller-style movement.