THREE.JS / FOUNDATIONS 189

Paint in spatial strokes.

Follow the official XR painter contract: a controller pivot becomes a cursor, select events open and close a stroke, squeeze changes brush size, and TubePainter turns the sampled path into a tube mesh.

Initializing Preparing renderer

Preparing TubePainter, controller spaces, and the WebXR session entry point...

mode
-
controllers
-
strokes
-
vertices
-
brush
-
events
-
draws
-
frames
-
Desktop controller harnesssame XR listeners

Connect a virtual controller, selectstart to begin painting, move through its synthetic path, then selectend to cap the stroke.

Event sequencewaiting
No controller events yet.
active controller-
target-ray mode-
select / squeeze-
TubePainter contractidle

The event log records the last eight controller lifecycle and gesture transitions.

TubePainter contractaddon boundary
moveTo(position)start without a segment
lineTo(position)extend the tube
setColor(color)color new segments
setSize(size)size new segments
update()upload changed buffers

The official addon owns a dynamic position/normal/color buffer. Clear replaces each painter so its internal update cursor and GPU resources reset together.

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

Desktop paths verify controller events and TubePainter buffer updates; physical controller pose and immersive frame timing still require a headset.

The XR button is a real session entry point. Use ?forceWebGL=1 for the WebGL2 companion; desktop controller paths are labeled simulation.

THREE.JS FOUNDATIONS LAB