Skip to content

@web-engine-dev/physics3d

Reference 3D physics implementation and API surface for web-engine-dev.

Production: Use @web-engine-dev/physics3d-rapier for full collision response, joints, and robust simulation.

Features

  • Rigid Body Dynamics: Semi-implicit Euler integration with damping and sleep
  • Collision Detection: Sweep-and-prune broadphase + SAT + GJK/EPA narrowphase
  • Collision Response: Sequential impulse solver with warm starting
  • Constraints: Fixed, spring, hinge, and slider joints with motors/limits
  • Raycasting: AABB-based ray queries
  • Continuous Detection: Experimental per-body CCD flag (full CCD via Rapier)

Installation

bash
npm install @web-engine-dev/physics3d
# or
pnpm add @web-engine-dev/physics3d

Quick Start

typescript
import { PhysicsWorld3D, RigidBody, BoxCollider, SphereCollider } from '@web-engine-dev/physics3d';

// Create physics world
const world = new PhysicsWorld3D({
  gravity: { x: 0, y: -9.81, z: 0 },
});

// Add ground
const ground = world.createBody({
  type: 'static',
  position: { x: 0, y: 0, z: 0 },
  collider: new BoxCollider({ x: 50, y: 0.5, z: 50 }),
});

// Add dynamic sphere
const ball = world.createBody({
  type: 'dynamic',
  position: { x: 0, y: 10, z: 0 },
  collider: new SphereCollider(1),
  mass: 1,
  restitution: 0.7,
});

// Step simulation
world.step(1 / 60);

API Overview

Collider Types

typescript
// Box
new BoxCollider({ x: 1, y: 1, z: 1 }); // Half-extents

// Sphere
new SphereCollider(radius);

// Capsule
new CapsuleCollider(radius, height);

// Convex hull
new ConvexHullCollider(vertices);

// Triangle mesh (static only)
new MeshCollider(vertices, indices);

Forces and Impulses

typescript
// Apply force at center
body.applyForce({ x: 100, y: 0, z: 0 });

// Apply force at point
body.applyForceAtPoint(force, worldPoint);

// Apply impulse
body.applyImpulse({ x: 10, y: 5, z: 0 });

// Apply torque
body.applyTorque({ x: 0, y: 5, z: 0 });

Constraints

typescript
// Fixed joint
world.createJoint({
  type: 'fixed',
  bodyA,
  bodyB,
});

// Hinge joint
world.createJoint({
  type: 'hinge',
  bodyA,
  bodyB,
  anchor: { x: 0, y: 0, z: 0 },
  axis: { x: 0, y: 1, z: 0 },
  limits: { min: -Math.PI / 2, max: Math.PI / 2 },
});

// Spring joint
world.createJoint({
  type: 'spring',
  bodyA,
  bodyB,
  stiffness: 100,
  damping: 10,
});

Raycasting

typescript
const result = world.raycast(origin, direction, maxDistance);

if (result.hit) {
  console.log('Hit body:', result.body);
  console.log('Point:', result.point);
  console.log('Normal:', result.normal);
}

Collision Events

typescript
world.on('collision-start', (bodyA, bodyB, contact) => {
  console.log('Contact point:', contact.point);
  console.log('Normal:', contact.normal);
  console.log('Impulse:', contact.impulse);
});

Peer Dependencies

  • @web-engine-dev/math - Vector/quaternion math

Proprietary software. All rights reserved.