logo

Install with the CLI:

bjs download MeshPrimitive

MeshPrimitive

Create a primitive 3D mesh (box, sphere, cylinder, capsule, plane, ground, torus, disc) with an optional material.

What it does

MeshPrimitive is the shared visual substrate most other components build on — its renderer handle is what Movement, Physics, Shadow, camera targeting and pooling all read. The MeshPrimitiveSystem is renderer-agnostic: it never touches BabylonJS or Three directly, but drives the active this.world.renderer adapter to create, position, recolor, show/hide, and dispose the underlying 3D object. By default it auto-creates the mesh when the entity is added, and it also responds to imperative input events for runtime changes. It emits meshprimitive.created (and meshprimitive.material.applied / meshprimitive.disposed) so other systems can react once a mesh exists.

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.

Fastest path

bjs download scene MeshPrimitive

Pulls this exact scene into your project and runs it — no copy-paste. Add --all to grab the components and assets it needs too.

Or 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 MeshPrimitive
    bjs download MeshPrimitive

    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
{
  "entities": {
    "Box": {
      "components": {
        "MeshPrimitive": {
          "primitive": "box",
          "width": 2,
          "height": 1,
          "depth": 2,
          "position": [0, 0.5, 0],
          "material": { "diffuseColor": [0.4, 0.6, 0.9] }
        }
      }
    }
  }
}

Props

  • primitive ('box' | 'sphere' | 'cylinder' | 'capsule' | 'plane' | 'ground' | 'torus' | 'disc', default 'box') — which primitive shape to build.
  • autoCreate (boolean, default true) — create the mesh automatically when the entity is added; set false to defer until a meshprimitive.create event.
  • position ([x, y, z], default [0, 0, 0]) — world position. A {x, y, z} object is also accepted for legacy callers.
  • rotation ([x, y, z], default [0, 0, 0]) — world rotation in radians.
  • width / height / depth (number, default 1) — box dimensions.
  • diameter (number, default 1) — sphere/torus diameter.
  • segments (number, default 32) — sphere tessellation.
  • diameterTop / diameterBottom (number, optional) — cylinder end diameters.
  • tessellation (number, default 24) — cylinder/disc tessellation.
  • radius (number, default 0.5) — capsule/torus radius.
  • pivotAtBottom (boolean, default false) — place the pivot at the base of the mesh.
  • size (number, default 10) — ground/plane size.
  • subdivisions (number, default 1) — ground subdivisions.
  • thickness (number, default 0.3) — torus tube thickness.
  • color ([r, g, b]) — shorthand for a diffuse-color material.
  • material (object) — full material config: diffuseColor, specularColor, emissiveColor, alpha (each [r, g, b] / number). Legacy ambientColor is ignored (ambient is driven by scene lights).
  • visible (boolean, default true) — initial visibility.

Events

  • Emits meshprimitive.created ({ entityId, primitive, handle, mesh }) once the mesh is created, meshprimitive.material.applied ({ entityId }) when a material was set, and meshprimitive.disposed ({ entityId }) on disposal.
  • Listens for meshprimitive.create, meshprimitive.position.set, meshprimitive.scale.set, meshprimitive.color.set, meshprimitive.visible.set, and meshprimitive.dispose (each carries entityId plus the relevant params).

Notes

  • The System reaches the renderer only through the this.world.renderer adapter, so the same component works under the Babylon or Three backend. Without a renderer attached, the component still constructs and serializes (handy for tests); mesh creation is deferred until one is present.
  • The live renderer handle is runtime-only state kept in a module-level WeakMap (comp.handle is a getter/setter over it), not a serialized field — so it survives a serialize → JSON round-trip cleanly and is preserved across pool park/unpark of reused component instances.
  • Pooling-aware: when a pooled entity is removed it is hidden (not disposed) to avoid re-churning GPU work, and re-shown/repositioned on reactivation; a truly destroyed entity disposes the mesh for real.
  • meshprimitive.scale.set is currently a no-op — scale is not yet part of the renderer adapter.

More like this

AIKick
AIZone
ArcCamera
BallPossession
BallReset
CameraFollow
Goal
Shadow
AiPilot
Animation
Asteroid
Bullet
DirectionalLight
EnemySpawner
EnvironmentTexture
Flash
FreighterCar
FreighterChain
FreighterHead
GameConfig
Health
HemisphericLight
Jump
KeyboardInput
KeyboardMover
LensFlare
Lifetime
LineOfSight
MachineGun
Mesh
Missile
MissileLauncher
MissionDirector
MouseInput
Movement
NebulaSky
Obstacle
ObstacleField
OilBlob
Parts
Physics
PlayerInput
PlayerWalkAnimator
Renderable
RespawnTimer
RoadTreadmill
RoundReset
Score
ShipDamageFX
ShipLoadout
SkeletonAnimator
Skybox
SmokeScreen
SpaceDust
SpaceShooterBullet
SpaceShooterFX
SpaceShooterHealth
SpaceShooterScore
ToneMapping
Transform6DOF
TwinStickEnemy
WaveDirector
Waypoint
WaypointTrack

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search