logo

Babylon.js Market

Velocity6DOF

movement

Velocity6DOF

1
Unlock

Install with the CLI:

bjs download Velocity6DOF

Velocity6DOF

Six-degrees-of-freedom velocity plus the integrator that turns it into movement — the thing that actually moves a Transform6DOF each frame.

What it does

Velocity6DOFComponent is pure motion data: a linear velocity (vx, vy, vz) in world space (units/sec) and an angular velocity (wx, wy, wz) in the ship's body frame (radians/sec — wx pitch, wy yaw, wz roll). Its Movement6DOFSystem queries every entity carrying both a Transform6DOF and a Velocity6DOF and integrates them each frame: pos += vel · dt, and the orientation quaternion is advanced straight from the body-frame angular velocity via quatIntegrateBody, then the Euler mirror is re-synced. Advancing the unit quaternion directly — rather than YXZ Euler angles — is what keeps the ship free of the gimbal-lock singularity at pitch ±π/2, so it can loop, roll, and fly inverted. dt is applied linearly, so the same path results at 30, 60, or 144 Hz. It runs at priority 60 and is renderer-agnostic: zero @babylonjs/three imports, the system constructor takes (eventBus) only.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add Velocity6DOF
    bjs download Velocity6DOF

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "Player": {
    "components": {
      "Transform6DOF": { "x": 0, "y": 0, "z": 0 },
      "Velocity6DOF": { "vz": 16, "wz": 0.6 },
      "Renderable": { "shape": "spaceplane", "glbSrc": "/wingman/falconship.glb" }
    }
  }
}

Props

  • vx (number, default 0) — world-space linear velocity along X (units/sec).
  • vy (number, default 0) — world-space linear velocity along Y (units/sec).
  • vz (number, default 0) — world-space linear velocity along Z (units/sec); +Z is the ship's nose in a fresh pose.
  • wx (number, default 0) — body-frame pitch rate around local X (radians/sec).
  • wy (number, default 0) — body-frame yaw rate around local Y (radians/sec).
  • wz (number, default 0) — body-frame roll rate around local Z (radians/sec).

Events

  • Emits nothing. Movement6DOFSystem is a pure integrator — it mutates Transform6DOF in place, so there is no goal.scored-style bus traffic to subscribe to.
  • Listens for nothing. It never touches the EventBus; the velocity is set by a flight model (ShipFlight reading FlightIntent) or written directly in scene data, and the integrator just consumes it.

Dependencies

Transform6DOF — the pose the integrator writes into. An entity with a Velocity6DOF but no Transform6DOF never matches Movement6DOFSystem's query, so nothing moves. That's the only hard requirement; a bare Transform6DOF + Velocity6DOF pair already drifts and rotates on its own.

Notes

  • World-linear, body-angular. (vx,vy,vz) push the entity along fixed world axes; (wx,wy,wz) rotate it around its own axes, so a nonzero wz barrel-rolls the ship while a nonzero vz still carries it wherever its nose currently points — set both to see the quaternion integration at work.
  • Angular is short-circuited when zero. The quaternion is only advanced when at least one of wx/wy/wz is nonzero, so a purely translating body skips the rotation math (and the Euler re-sync) entirely.
  • It's an integrator, not a controller. Velocity6DOF holds how fast, not how to steer. For interactive flight, add FlightIntent + ShipFlight (and KeyboardInput + PlayerFlightInput); those write vx…wz from thrust/turn intent each frame, and Movement6DOF integrates the result. In this component's example scene the velocities are hardcoded so the ship drifts and rolls with no input.
  • Every entity with the pair moves. The integrator is generic — the player ship, an AI-piloted enemy, or a coasting projectile all use the same Velocity6DOF; give each its own values. The example's Drifter carries a different velocity purely to show it's per-entity.
  • Angular velocity is in radians per second, not degrees — wz: 0.6 is a lazy ~10-second roll, not a blur.

More like this

Transform6DOF
Animation
Bumper
CameraState6DOF
ChaseCamera6DOF
ChaseCameraTarget
FlightIntent
FreighterChain
Jump
KeyboardMover
MouseHole
Movement
Obstacle
Physics
PlayerFlightInput
Renderable
ShipFlight
SpaceDust
Spinner
WorldOriginAnchor

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search