Chapter 12: Physics 
The IWSDK provides a comprehensive physics system powered by the @babylonjs/havok physics engine. This chapter covers everything you need to know about implementing realistic physics in your IWSDK applications.
What You'll Build 
By the end of this chapter, you'll be able to:
- Set up the Havok physics engine with customized gravity settings
 - Create falling objects with realistic collision shapes and material properties
 - Build static environments with floors, walls, and other immovable objects
 - Implement grabbable objects with proper physics interactions
 - Apply forces and manipulate object velocities for dynamic interactions
 - Optimize physics performance for complex scenes
 
Overview 
The physics system is built using an Entity Component System (ECS) architecture and consists of three main components:
PhysicsSystem- The core system that manages the Havok physics worldPhysicsShape- Defines collision shapes and physics material properties (density, restition, friction)PhysicsBody- Defines the motion behavior of entities (Static, Dynamic, Kinematic)PhysicsManipulation- Applies one-time force and velocity changes
Quick Start 
Here's a minimal example to get physics working in your scene:
import {
  World,
  PhysicsSystem,
  PhysicsBody,
  PhysicsShape,
  PhysicsState,
  PhysicsShapeType,
  Mesh,
  SphereGeometry,
  MeshStandardMaterial,
} from '@iwsdk/core';
// 1. Register the physics system with customized gravity
world
  .registerSystem(PhysicsSystem, { configData: { gravity: [0, -10, 0] } })
  .registerComponent(PhysicsBody)
  .registerComponent(PhysicsShape);
// 2. Create a mesh
const sphere = new Mesh(
  new SphereGeometry(0.5),
  new MeshStandardMaterial({ color: 0xff0000 }),
);
sphere.position.set(0, 5, 0);
scene.add(sphere);
// 3. Create entity and add physics components
const entity = world.createTransformEntity(sphere);
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Auto, // Automatically detects sphere
});
entity.addComponent(PhysicsBody, {
  state: PhysicsState.Dynamic, // Falls due to gravity
});System Setup 
Step 1: Register the Physics System 
The PhysicsSystem must be registered with your world to enable physics simulation:
world
  .registerSystem(PhysicsSystem)
  .registerComponent(PhysicsBody)
  .registerComponent(PhysicsShape);Step 2: Physics World Configuration 
The physics system automatically creates a Havok physics world with:
- Gravity: Default value 
[0, -9.81, 0](configurable in physics system) (Earth-like gravity) - Step Rate: Synchronized with your application's frame rate
 - Automatic Cleanup: Physics resources are cleaned up when entities are removed
 
Understanding the Components 
PhysicsShape 
Defines the collision shape and material properties of an entity.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [2, 1, 1],
  density: 1.0,
  friction: 0.5,
  restitution: 0.0,
});Required Properties 
shape- The collision shape type (see Shape Types)
Optional Properties 
dimensions- Shape-specific dimensions array. Not applicable whenPhysicsShapeType.Autois used.density- Mass density (default: 1.0)friction- Surface friction coefficient (default: 0.5)restitution- Bounciness factor (default: 0.0)
Shape Types 
Auto Detection 
The most convenient option that automatically detects the best shape from your Three.js geometry. When this type is selected, the dimensions field in PhysicsShape will be overridden by the size of the Three.js geometry.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Auto,
});Mapping Rules:
SphereGeometry→SphereBoxGeometry→BoxPlaneGeometry→Box(thin)CylinderGeometry→Cylinder- Other geometries → 
ConvexHull 
Sphere 
Most efficient for round objects.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.5, 0, 0], // [radius, unused, unused]
});Box 
Perfect for rectangular objects.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [2, 1, 1], // [width, height, depth]
});Cylinder 
For cylindrical objects.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Cylinder,
  dimensions: [0.5, 2, 0], // [radius, height, unused]
});ConvexHull 
A convex hull is the smallest convex shape containing points. It has good balance between accuracy and performance for complex shapes.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.ConvexHull,
  // dimensions automatically calculated from geometry
});TriMesh 
Using tri mesh to fit the geometry. Most accurate but computationally expensive. Best for static objects.
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.TriMesh,
  // dimensions automatically calculated from geometry
});Physics Material Properties 
Density 
Controls the mass of the object. Higher density = heavier object.
// Light object (foam ball)
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.5, 0, 0],
  density: 0.1,
});
// Heavy object (metal ball)
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.5, 0, 0],
  density: 10.0,
});Friction 
Controls sliding behavior on surfaces (0 = no friction, 1 = high friction).
// Slippery ice surface
iceEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [10, 0.1, 10],
  friction: 0.1,
});
// Grippy rubber surface
rubberEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [10, 0.1, 10],
  friction: 0.9,
});Restitution 
Controls bounciness (0 = no bounce, 1 = perfect bounce).
// Dead ball (no bounce)
deadBallEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.5, 0, 0],
  restitution: 0.0,
});
// Super bouncy ball
bouncyBallEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.5, 0, 0],
  restitution: 0.95,
});PhysicsBody 
Defines the motion behavior of an entity in the physics simulation.
entity.addComponent(PhysicsBody, {
  state: PhysicsState.Dynamic, // Required: motion type
});Motion Types 
PhysicsState.Static- Immovable objects like walls and floors- Never moves, but affects other bodies
 - Ideal for environment geometry
 
PhysicsState.Dynamic- Responds to forces and gravity- Affected by collisions, gravity, and applied forces
 - Most common for interactive objects
 
PhysicsState.Kinematic- Programmatically controlled- Can be moved by code but not affected by other bodies
 - Useful for moving platforms or player-controlled objects
 
// Static floor
floorEntity.addComponent(PhysicsBody, { state: PhysicsState.Static });
// Dynamic ball that falls and bounces
ballEntity.addComponent(PhysicsBody, { state: PhysicsState.Dynamic });
// Kinematic elevator platform
elevatorEntity.addComponent(PhysicsBody, { state: PhysicsState.Kinematic });PhysicsManipulation 
The PhysicsManipulation component allows you to apply one-time forces and set velocities. The component is automatically removed after application.
Applying Forces 
Forces are applied as impulses at the entity's center of mass:
// Make object jump
entity.addComponent(PhysicsManipulation, {
  force: [0, 10, 0], // Upward force
});
// Throw object forward
entity.addComponent(PhysicsManipulation, {
  force: [5, 2, 0], // Forward and up
});Setting Velocities 
Directly set linear and angular velocities:
// Set specific movement
entity.addComponent(PhysicsManipulation, {
  linearVelocity: [3, 0, 0], // Move right at 3 m/s
  angularVelocity: [0, 2, 0], // Spin around Y-axis
});Combined Manipulation 
You can combine forces and velocities in a single manipulation:
entity.addComponent(PhysicsManipulation, {
  force: [0, 5, 0], // Push up
  linearVelocity: [2, 0, 0], // Set rightward velocity
  angularVelocity: [0, 1, 0], // Add spin
});Common Patterns 
Creating a Falling Object 
const box = new Mesh(new BoxGeometry(1, 1, 1), new MeshStandardMaterial());
box.position.set(0, 10, 0);
scene.add(box);
const entity = world.createTransformEntity(box);
entity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Auto,
});
entity.addComponent(PhysicsBody, {
  state: PhysicsState.Dynamic,
});Creating a Static Environment 
const floor = new Mesh(new PlaneGeometry(20, 20), new MeshStandardMaterial());
floor.position.set(0, 0, 0);
scene.add(floor);
const floorEntity = world.createTransformEntity(floor);
floorEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Auto,
});
floorEntity.addComponent(PhysicsBody, {
  state: PhysicsState.Static,
});Interactive Grabbable Objects 
// Create a grabbable ball
const ball = new Mesh(
  new SphereGeometry(0.2),
  new MeshStandardMaterial({ color: 0x00ff00 }),
);
ball.position.set(0, 2, 0);
scene.add(ball);
const ballEntity = world.createTransformEntity(ball);
ballEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Sphere,
  dimensions: [0.2],
  density: 0.5,
  restitution: 0.6,
});
ballEntity.addComponent(PhysicsBody, {
  state: PhysicsState.Dynamic,
});
// Add grabbing capability (requires GrabSystem)
ballEntity.addComponent(Interactable);
ballEntity.addComponent(OneHandGrabbable);Kinematic Moving Platforms 
const platform = new Mesh(
  new BoxGeometry(3, 0.2, 3),
  new MeshStandardMaterial({ color: 0x0000ff }),
);
scene.add(platform);
const platformEntity = world.createTransformEntity(platform);
platformEntity.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [3, 0.2, 3],
  friction: 0.8,
});
platformEntity.addComponent(PhysicsBody, {
  state: PhysicsState.Kinematic,
});
// Animate the platform (in your update loop)
function animatePlatform(time) {
  platform.position.y = Math.sin(time * 0.001) * 2 + 2;
}Performance Optimization 
Use appropriate shape types:
- Primitives (Sphere, Box) are fastest
 - ConvexHull for moderate complexity
 - TriMesh only for static, highly detailed objects
 
Optimize shape complexity:
- Simplify meshes when possible. Use ConvexHull over TriMesh when possble.
 - Use fewer vertices for ConvexHull and TriMesh shapes
 
Manage entity count:
- Remove physics components from distant objects
 - Use object pooling for frequently created/destroyed objects
 
Troubleshooting 
Common Issues 
Physics objects fall through the floor:
- Ensure your floor has a 
PhysicsShapecomponent - Make sure floor has a 
PhysicsBodycomponent withPhysicsState.Static - Check that floor dimensions match visual geometry
 
Objects don't collide:
- Verify both objects have 
PhysicsShapecomponents - Check that shapes have appropriate dimensions
 - Ensure objects are not starting inside each other
 - Make sure floor has a 
PhysicsBodycomponent withPhysicsState.Dynamic 
Poor performance:
- Use simpler shape types when possible
 - Reduce the number of physics entities
 - Consider using TriMesh only for static objects
 
Objects behave unexpectedly:
- Check density values (very high/low values can cause issues)
 - Verify friction and restitution are in reasonable ranges (0-1)
 - Ensure forces aren't too large
 
Debug Tips 
- Log component values to verify they're set correctly
 - Test with simple primitive shapes before using complex geometry
 - Check console for warnings from the physics system
 
MetaSpatial Integration 
The physics components are also available in MetaSpatial projects through XML component definitions:
<!-- PhysicsBody component -->
<IWSDKPhysicsBody state="DYNAMIC" />
<!-- PhysicsShape component -->
<IWSDKPhysicsShape
  shape="Box"
  dimensions="2f, 1f, 1f"
  density="1f"
  friction="0.5f"
  restitution="0f" />
<!-- PhysicsManipulation component -->
<IWSDKPhysicsManipulation
  force="0f, 10f, 0f"
  linearVelocity="0f, 0f, 0f"
  angularVelocity="0f, 0f, 0f" />Example Projects 
Check out the examples/physics project in the SDK for a complete working example that demonstrates:
- Basic physics setup
 - Dynamic sphere creation
 - Force application
 - Integration with XR interactions
 
The example creates a bouncing sphere with applied forces and can be run with:
cd examples/physics
pnpm install
pnpm dev