THREE.JS / FOUNDATIONS 193

Fire into the room.

Follow the official XR ball-shooter loop: controller select events mark the firing gesture, an instanced ball receives position and velocity, and Rapier advances the shared room simulation.

Initializing Preparing renderer

Preparing WebGLRenderer, RapierPhysics, instanced balls, and XR session entry point...

mode
-
physics
-
controllers
-
active balls
-
shots
-
capacity
-
physics ticks
-
events
-
draws
-
frames
-
Desktop controller harnesssame XR gestures

Connect a virtual controller, hold selectstart to fire, and selectend to stop the firing loop.

Event sequencewaiting
No controller events yet.
left / right firingidle
target-ray mode-
physics adapterloading

The event log records controller lifecycle, firing gestures, and room reset actions.

Ball-shooter contractphysics + instancing
await RapierPhysics()create a gravity world
physics.addScene(scene)register userData.physics
setMeshPosition(spheres, ...)place an instance body
setMeshVelocity(spheres, ...)launch the ball
instanceMatrix.needsUpdateupload simulated transforms

The official addon maps BoxGeometry, IcosahedronGeometry, and InstancedMesh bodies into Rapier colliders. The local harness uses the same firing and physics ownership boundary, with a labeled kinematic fallback if the external addon cannot load.

Capability boundaryprobing
WebXR API-
immersive VR-
XRButton-
reference space-

Desktop controls verify event-to-velocity mapping and the instanced room simulation; physical controller pose, Rapier CDN availability, and immersive frame timing still require a headset-capable session.

This study follows the official WebGLRenderer ball-shooter example. The XR button is a real session entry point; desktop controller paths are explicitly simulated.

THREE.JS FOUNDATIONS LAB