Project Swan + OS 6
Project Swan + OS 6

HCI Design and Developer Support

Project Swan and PICO OS 6 represent the next-generation PICO XR flagship experience, launching globally in 2026. The video below is a developer tutorial for UI/UX and Interaction Design that showcases my core contributions to the HCI design of this new ecosystem. My work primarily focused on pioneering Eye-Hand Interaction and establishing a robust multi-modal interaction framework.

Demonstration of Project Swan and OS 6 features.

A New 3D Interaction Paradigm for Spatial Applications

PICO OS 6 3D Object Interaction

PICO OS 6 introduces a more unified set of foundational "3D Object Interaction" capabilities at the interaction level: from interaction conditions (making objects hittable by the interaction system) to interaction actions (Tap/Drag/Scale/Rotate/Pointer), and finally to interaction effects (highlighting, moving, scaling, rotating, momentum poking). It provides a unified input paradigm to cover eye tracking, hand gestures, and controllers. Under the same SpatialView + Compose input framework, it simultaneously supports hand gestures, gaze coordination, controller rays, and pointer-based inputs. Furthermore, it uses a finer-grained interaction type (InteractionKind) to distinguish how different input methods trigger the same type of interaction action.

The goal of these capabilities is clear: to enable developers to build more intuitive and natural interaction experiences with fewer branches and a more consistent input model. This is especially true for scenarios requiring frequent manipulation of 3D content (model viewing, content editing, spatial UI, display interactions), where it can significantly reduce accidental touches and fatigue, while improving overall feel and predictability.

Highlights

Interaction Conditions: Making 3D Objects "Touchable and Responsive"

In spatial applications, not all entities are directly manipulable by the user by default. To make a 3D object support basic interactions like "tapping/pinching/poking", two conditions must be met:

1) The Object has Collision Volume (Collision)

Configure a collision volume for the entity to define the spatial range where interactions can occur. Common related elements include:

Common Configuration Methods:

Box cube collider
Box cube collider
Sphere spherical collider
Sphere spherical collider
Bounding Box collider
Bounding Box
Mesh collider
Mesh

2) The Object is in an Interactable State (Interactable)

Building upon having a collision volume, the entity must also be set to an interactable state:

This setup makes it easy to centrally manage interaction capabilities across different modes (e.g., disabling interactions in viewing mode, enabling them in editing mode), ensuring the object's operability aligns with the product's interaction strategy.

Interaction Actions: The detectSpatial* Gesture System

PICO OS 6 provides a set of core interfaces starting with detectSpatial* to capture the most common actions in spatial interaction. The design focus of these interfaces is not to "provide more gestures," but to allow developers to build interactions around stable action semantics: tapping handles triggering, dragging handles manipulation, two-handed gestures handle fine-tuning, and pointer events handle extensions.

Interactive Gesture Schematic Diagram Specific Operation Interface
Click Tap gesture schematic Single hand, quickly bring two fingers together and slightly open, simulating pinching an object detectSpatialTapGesture()
Drag and Drop Drag gesture schematic Single hand, bring two fingers together, pinch a point on the object, then move within space detectSpatialDragGesture()
Zoom Scale gesture schematic Two hands, pinch two points on the object, then move hands closer or further apart detectSpatialScaleGesture()
Spin Rotate gesture schematic Two hands, pinch two points on the object, then rotate both hands clockwise or counterclockwise simultaneously detectSpatialRotateGesture()
Custom Gesture Custom gesture schematic Two hands touch the object, then freely manipulate detectSpatialPointerEvent()

These interfaces are typically mounted on the SpatialView's Modifier.pointerInput: the same input paradigm can cover eye tracking, hand gestures, and controllers.

For applications, this significantly simplifies the engineering structure of "coexisting multiple inputs": you are mostly configuring "the semantics of the same action under different inputs" rather than copy-pasting multiple sets of interaction logic.

Coexistence of Multiple Gestures: One gesture per pointerInput

When an object needs to support Drag + Scale + Rotate simultaneously, it is recommended:

This avoids mutual interference caused by the exclusivity of internal gesture recognition. From an engineering maintenance perspective, this separation is also more suitable for future expansion: you can clearly enable/disable certain interactions, and it's easier to perform A/B tuning and locate conflicts.

Accurately Specifying the Interaction Object: TargetEntity

In complex scenarios (multiple interactable entities), you can limit the effective range of a gesture using the targetedToEntity parameter. This is especially crucial in apps with "multi-object editing / multi-level models / coexistence of UI and 3D", because accidental touches are highly destructive to the experience.

This makes the behavior more aligned with user expectations (I only affect the object I'm operating on).

Interaction Types: InteractionKind

In some complex scenarios, the gesture action alone is not enough to distinguish the user's actual operation method; this is where we need to further determine the interaction type. Except for detectSpatialPointerEvent(), all interfaces starting with detectSpatial provide an InteractionKind in the callback to identify how the current operation was triggered.

Common types include:

Direct Pinch Fingertip Touch/Poke Gaze + Pinch Controller Ray Click Pointer Input
Direct Pinch Fingertip Touch / Poke Gaze + Pinch Controller Ray Click Pointer Input
DirectPinch Poke GazePinch RayBasedPinch Pointer

In practical development, the same gesture interface often needs to carry multiple operations. For example:

Both of these operations can be implemented via detectSpatialDragGesture(). The key is to determine the current interaction method through InteractionKind, and thereby execute different logic. For example:

DirectPinch dragging the object GazePinch dragging the object
DirectPinch and GazePinch implement dragging the object.
Poke rotating the object Poke rotating the object continued
Poke implements rotating the object.

Through this method, you can reuse the same gesture interface while allowing different operation methods to correspond to different effects, making the interaction more intuitive for the user.

Interaction Effects: Hover, Move, Scale, Rotate, and Momentum Poke

Interaction effects dictate the user's "feel": APIs can often make things move, but whether users find it easy to use depends on whether the feedback is clear, whether the behavior aligns with their expectations, and whether continuous operations are effortless.

Highlight Prompts: HoverEffectComponent (Crucial Feedback for Remote Interaction)

For remote interaction to work, it must solve the confirmation problem of "what am I operating right now?". Highlighting/hover is not merely decorative; it is the lowest-cost prompt layer for remote interaction. It makes users more confident to act, reduces hesitation and accidental touches, and significantly elevates the credibility of the overall interaction.

Move: Drag → Transform Position Update

The most common experience issue with moving interactions is "sensitivity": too fast feels floaty, too slow feels tiring. It is recommended to design your movement mapping logic as adjustable parameters (e.g., speed coefficients, axis constraints, snapping strategies), so that different scenarios (showcase vs. editing) can have a different feel.

Scale: Scale → Transform Scale Update

Scaling affects not only visual size but also the "perceived sensitivity" of subsequent interactions (the same hand displacement feels different on large versus small objects). Therefore, when building fine-tuning editing experiences, scaling and control sensitivity usually need to be considered in tandem rather than implemented independently.

Rotate: Two Routes (Choose based on experience)

A. Single-hand Drag Rotation (Reusing Drag)

The advantage of single-hand rotation is "motion saving": the user doesn't need to use both hands, making it suitable for mobile-style quick browsing and lightweight control. It is also more suitable to combine with intent distribution (e.g., pinch-to-move vs. poke-to-rotate).

B. Two-hand Rotation (Dedicated RotateGesture)

Two-hand rotation is better suited for scenarios requiring precise posture adjustments (e.g., placing, aligning, content editing). Users' expectations of it are also more akin to real-world operations: stable, controllable, and with fewer accidental touches.

Poke Rotation: Delayed Rotation / Momentum Rotation (More like a real globe)

For Poke (poking/flicking), if you continue to make it "rotate instantly following the hand," users will often feel it is "laggy/hard to turn." A more natural approach is:

Common Components/Parameters:

Implementation Notes:

The value of momentum rotation is that it not only "looks cooler" but, more importantly, it makes large-angle rotations less effortful and more intuitive for the user. Additionally, for showcase-type content (models/products/globes/planets), it can significantly elevate the "realism" and premium feel of the product.

Conclusion: Tailored Interactions for Every Application

The core philosophy behind PICO OS 6 is that spatial interaction should never be one-size-fits-all. By providing a diverse and unified toolkit, we ensure that every type of application has the ideal interaction support it deserves:

PICO OS 6 is more than just a set of APIs; it is a commitment to a consistent, intuitive, and high-quality spatial ecosystem. By unifying eye tracking, hand gestures, and controllers into a single input paradigm, we are empowering developers to build applications where the interaction always feels exactly right, no matter the use case.

Learn more: Implement basic interactions for 3D objects