Latest version:
Tramway SDK 0.0.9
Github
Quick links
Home
Get Started

Physics


The physics system provides rigidbody physics simulation services.

Currently a single backed is implemented, which is the Bullet physics library backed, but more will be added in the future.

If you want to add rigidbodies to your entities, consider using the PhysicsComponent. For triggers, the TriggerComponent is available.

Key concepts


Rigidbody

An object in the physics simlation. Rigidbodies have some kind of a shape or volume. This is determined by their CollisionModel or CollisionShape.

Trigger

Triggers are special shapes or volumes that can detect if a rigidbody enters its volume.

Collision Group

Collision groups are groups that the rigidbody, trigger or other physics construct is a part of. The object can be a part of several groups. They are represented by bits in a bitmask.

It is more efficient for an object to belong to only a single group, or very few groups.

Collision Mask

Collision masks are groups with which the rigidbody, trigger or other physics construct can collide with. The object can be set to collide with several groups. Allowed collision groups are represented by bits in a bitmask.

To determine if an object should collide with another object, each objects group bitmask and the other object's mask bitmask are logically ANDed together. If the resulting value is not zero, the objects are allowed to collide.

Raycast

Useful for poking things, selecting objects. A raycast constructs a ray between two points and check whether it intersects any rigidbody between these points. If an intersection is found, it is returned.

Shapecast

Similar to raycast, but instead of a checking an intersection with an infinitely thin line, a shape is used.

Collisions: how do they work?


Like this.


This is how the bitmask ANDing works.

Programming in C++


#include <physics/physics.h>
API documentation page.

Physics::Init();

// main loop
while (true) {
    Physics::Update();
}

Here's how we do raycasts. Let's do one from the render view.

auto pos = Render::GetViewPositon();
auto rot = Render::GetViewRotation();

// convert rotation to normal vector
vec3 dir = rot * DIRECTION_FORWARD;

// set end point to ne 5 meters in
// front of the view
vec3 end = pos + dir * 5.0f;

// collision mask -1 means all bits, aka
// collide with all collision groups
auto coll = Physics::Raycast(pos, end, -1);


// skip collision if no entity attached
if (!coll.collider || !coll.collider->GetParent())
return;

auto entity = coll.collider->GetParent();

// send a SELECTED message to the collided
Message msg;

msg.sender = 0;
msg.receiver = entity->GetID();
msg.type = Message::SELECTED;
msg.data = nullptr;

Message::Send(msg);

This is how interactable object highlighting is usually done for a first-person view. We check if there is an object withing 5 meters right in front of the view, and if there is an object, we send the it a Selected message.

Shapecasts work the same way, except that you also need to pass in the shape, which will be used for the collision.