Skip to content

Commit d689db4

Browse files
zjm-metameta-codesync[bot]
authored andcommitted
fix(example) Update scene understanding example README.
Summary: Updated scene understanding example README to reflect the correct information. Reviewed By: felixtrz Differential Revision: D83393541 fbshipit-source-id: 67962de52fa40ba9ba830e30250f466f138be44c
1 parent d11f8de commit d689db4

2 files changed

Lines changed: 212 additions & 81 deletions

File tree

examples/scene-understanding/README.md

Lines changed: 211 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,53 @@
1-
# WebXR Framework Boilerplate
1+
# WebXR Framework Scene Understanding Example
22

3-
This is the official boilerplate project for the WebXR Framework, designed for optimal developer, designer, and tech artist workflow.
3+
This example demonstrates WebXR scene understanding features in the Immersive Web SDK (IWSDK), showcasing real-world plane detection, mesh detection, and spatial anchors for augmented reality (AR) applications. Learn how to build AR experiences that understand and interact with the physical environment.
4+
5+
## 🎯 What You'll Learn
6+
7+
This example demonstrates:
8+
9+
- **Scene Understanding System**: Detecting and tracking real-world surfaces and objects
10+
- **Plane Detection**: Identifying horizontal and vertical surfaces (floors, walls, tables)
11+
- **Mesh Detection**: Capturing detailed 3D geometry of the environment
12+
- **Spatial Anchors**: Placing virtual objects that stay fixed in the real world
13+
- **Interactive AR**: Making detected planes and meshes interactive with pointer events
14+
- **AR Session Management**: Configuring WebXR AR sessions with required features
15+
16+
### What's in the Example
17+
18+
The example includes:
19+
20+
1. **Plane Detection System**: Automatically detects real-world surfaces and visualizes them as wireframe meshes
21+
2. **Mesh Detection System**: Captures 3D geometry of the environment with semantic labels
22+
3. **Anchored Sphere**: A grabbable sphere that stays anchored to a fixed position in the real world
23+
4. **Interactive Visualization**: Detected planes and meshes become visible when you point at them
24+
5. **Custom System**: A `SceneShowSystem` that manages visibility and interaction of detected geometry
425

526
## 📁 Project Structure
627

728
```
8-
boilerplate/
29+
scene-understanding/
930
├── src/ # Source code
10-
│ ├── index.js # Main application entry point
11-
│ ├── settings.js # Settings configuration
12-
│ ├── test-component.js # Example component
13-
│ └── settings.uikitml # UI markup
14-
├── public/ # Static assets (served at root)
15-
│ ├── gltf/ # 3D models in GLTF format
16-
│ ├── glxf/ # GLXF scene files
17-
│ ├── textures/ # Images and texture files
18-
│ ├── audio/ # Audio files
19-
│ └── models/ # Other 3D model formats
20-
├── generated/ # Auto-generated files (committed for designers)
21-
│ └── components/ # Generated component XML definitions
22-
│ ├── Transform.xml # Core transform component
23-
│ ├── LocomotionEnvironment.xml # Locomotion component
24-
│ └── ... # Other framework components
25-
├── metaspatial/ # Meta Spatial project files
26-
├── dist/ # Build output (generated)
27-
├── index.html # Main HTML file
28-
├── vite.config.js # Vite configuration
29-
└── package.json # Project dependencies
31+
│ └── index.js # Main application entry point with SceneShowSystem
32+
├── dist/ # Build output (generated)
33+
├── index.html # Main HTML file
34+
├── vite.config.js # Vite configuration
35+
└── package.json # Project dependencies
3036
```
3137

38+
**Note**: This example focuses on code-based AR scene understanding and doesn't require static assets or Meta Spatial project files.
39+
3240
## 🚀 Quick Start
3341

3442
### Prerequisites
3543

36-
- Node.js 18+ and pnpm
44+
- Node.js 20.19.0+ and pnpm
3745
- HTTPS support for WebXR development
3846

3947
### Installation
4048

4149
```bash
42-
cd boilerplate
50+
cd scene-understanding
4351
pnpm install
4452
```
4553

@@ -58,96 +66,194 @@ pnpm preview
5866

5967
The development server will start at `https://localhost:8081` with automatic HTTPS certificates.
6068

61-
## 📦 Asset Organization
69+
**Important**: Scene understanding features require an AR-capable device (e.g., Meta Quest 3, Quest Pro) with plane detection, mesh detection, and anchor support.
70+
71+
## 🔍 Scene Understanding System Overview
72+
73+
### Enabling Scene Understanding
74+
75+
Configure your WebXR AR session with scene understanding features:
76+
77+
```javascript
78+
World.create(document.getElementById('scene-container'), {
79+
xr: {
80+
sessionMode: SessionMode.ImmersiveAR,
81+
features: {
82+
hitTest: true,
83+
planeDetection: { required: true }, // Enable plane detection
84+
meshDetection: { required: true }, // Enable mesh detection
85+
anchors: { required: true }, // Enable spatial anchors
86+
},
87+
},
88+
features: {
89+
grabbing: true,
90+
sceneUnderstanding: true, // Enable IWSDK scene understanding system
91+
},
92+
});
93+
```
94+
95+
### Scene Understanding Components
96+
97+
The scene understanding system uses three main ECS components:
98+
99+
#### 1. XRPlane
100+
101+
Represents a detected real-world surface (floor, wall, table, etc.). See `immersive-web-sdk/packages/core/src/scene-understanding/plane.ts:32-42`
102+
103+
Planes are automatically created and updated by the `SceneUnderstandingSystem` and has an Object3D representing the Plane's geometry associated.
62104

63-
### WebXR-Optimized Asset Handling
105+
#### 2. XRMesh
64106

65-
This boilerplate uses Vite's `public/` directory for WebXR assets since they are:
107+
Represents detected 3D geometry in the environment. See `immersive-web-sdk/packages/core/src/scene-understanding/mesh.ts:43-55`
66108

67-
- Loaded at runtime via URLs (not imported as modules)
68-
- Large files that shouldn't be bundled or processed
69-
- Need direct URL access for asset loaders
109+
**Properties**:
110+
- `isBounded3D`: Whether this is a bounded object (true) or global mesh (false)
111+
- `semanticLabel`: Semantic label from the device (e.g., "wall", "couch", "global mesh")
112+
- `min`: Minimum bounding box corner `[x, y, z]`
113+
- `max`: Maximum bounding box corner `[x, y, z]`
114+
- `dimensions`: Size of the bounding box `[width, height, depth]`
70115

71-
### Assets Directory Structure
116+
Meshes are automatically created and updated by the `SceneUnderstandingSystem` has an Object3D representing the Mesh's geometry associated.
72117

73-
- **`public/gltf/`** - 3D models in GLTF/GLB format
74-
- **`public/glxf/`** - GLXF scene files containing component data
75-
- **`public/textures/`** - Images, textures, and visual assets (.png, .jpg, etc.)
76-
- **`public/audio/`** - Sound effects and music files
77-
- **`public/models/`** - Other 3D model formats
118+
#### 3. XRAnchor
78119

79-
### Asset Usage
120+
Marks an entity to be anchored at a fixed position in the real world (will not move after recentering the view). See `immersive-web-sdk/packages/core/src/scene-understanding/anchor.ts:35-45`
80121

122+
**Properties**:
123+
- `attached`: Boolean indicating if the entity is attached to the anchor group, default `false`
124+
125+
**Usage**:
81126
```javascript
82-
// Reference assets using root-relative paths (Vite serves public/ at root)
83-
const assets = {
84-
scene: { url: '/glxf/my-scene.glxf', type: AssetType.GLXF },
85-
model: { url: '/gltf/my-model.gltf', type: AssetType.GLTF },
86-
texture: { url: '/textures/my-texture.png', type: AssetType.Texture },
87-
};
127+
// Create an entity that stays fixed in the real world
128+
const entity = world.createTransformEntity(mesh);
129+
entity.addComponent(XRAnchor);
88130
```
89131

90-
## 🔧 Component System
132+
Objects with the `XRAnchor` component are automatically attached to a stable anchor point by the `SceneUnderstandingSystem`.
133+
134+
135+
### How Scene Understanding Works
136+
137+
The `SceneUnderstandingSystem` (see `src/scene-understanding/scene-understanding-system.ts:72-408`) handles:
138+
139+
1. **Feature Detection**: Checks which scene understanding features are enabled
140+
2. **Plane Tracking**: Updates detected planes each frame from `XRFrame.detectedPlanes`
141+
3. **Mesh Tracking**: Updates detected meshes each frame from `XRFrame.detectedMeshes`
142+
4. **Geometry Generation**: Creates Three.js geometry from plane polygons and mesh vertices
143+
5. **Anchor Management**: Creates and maintains spatial anchors for marked entities
144+
6. **Lifecycle Management**: Destroys entities when planes/meshes are no longer tracked
145+
146+
## 💡 Best Practices & Tips
91147

92-
### Generated Components
148+
### Device Requirements
93149

94-
The `generated/components/` directory contains XML definitions for all framework components. These files are:
150+
Scene understanding features require specific hardware capabilities. Always check `session.enabledFeatures` to verify which features are available.
95151

96-
- **Generated automatically** during development
97-
- **Committed to version control** for designer/artist accessibility
98-
- **Used by Meta Spatial** for component integration
152+
### Working with Meshes
99153

100-
### Generated Files Organization
154+
**Mesh Types**:
155+
- **Bounded meshes** (`isBounded3D: true`): Individual objects like furniture, walls
156+
- **Global mesh** (`isBounded3D: false`): Environment-wide mesh without semantic meaning
101157

102-
The `generated/` folder organizes all auto-generated files:
158+
**Best Practices**:
159+
- Use `semanticLabel` to identify what the mesh represents (e.g., "couch", "wall", "table")
160+
- Bounded meshes include useful bounding box data (`min`, `max`, `dimensions`)
161+
- Global meshes are useful for physics or collision but not for semantic understanding
162+
- Filter by `isBounded3D` to work with specific objects vs. the entire environment
103163

104-
- **`generated/components/`** - Component XML definitions
105-
- **Future**: Schema files, type definitions, documentation, etc.
164+
**Example: Finding Furniture**:
165+
```javascript
166+
this.queries.meshEntities.entities.forEach((meshEntity) => {
167+
const label = meshEntity.getValue(XRMesh, 'semanticLabel');
168+
const isBounded = meshEntity.getValue(XRMesh, 'isBounded3D');
169+
170+
if (isBounded && (label === 'couch' || label === 'table')) {
171+
// This is a piece of furniture
172+
const dimensions = meshEntity.getVectorView(XRMesh, 'dimensions');
173+
console.log(`Found ${label} with size:`, dimensions);
174+
}
175+
});
176+
```
177+
178+
### Working with Anchors
179+
180+
**Anchor Behavior**:
181+
- Anchors keep objects fixed in the real world even as the device tracking shifts
182+
- Perfect for persistent AR content that should stay in one place
183+
- The system maintains anchor stability by updating transforms automatically
184+
185+
**Tips**:
186+
- Use anchors for important objects that must stay in a specific location
187+
- Can be combine with `DistanceGrabbable` to let users position objects precisely
188+
189+
**Example: User-Placed Anchored Object**:
190+
```javascript
191+
// Let user grab and position an anchored object
192+
const entity = world.createTransformEntity(mesh);
193+
entity.addComponent(DistanceGrabbable);
194+
entity.addComponent(Interactable);
195+
entity.addComponent(XRAnchor);
196+
```
106197

107-
### Important Notes
198+
### Performance Tips
108199

109-
- All generated files should be committed to ensure the project works out-of-the-box
110-
- Designers and tech artists can use these without running build commands
111-
- Files are regenerated when components change during development
200+
1. **Limit Mesh Rendering**: Only make meshes visible when needed (like on pointer hover or for development only)
201+
2. **Filter Bounded Meshes**: Use `where: [eq(XRMesh, 'isBounded3D', true)]` to ignore the global mesh
202+
3. **Simplify Geometry**: Consider creating simplified collision shapes instead of using full mesh geometry
112203

113204
## 🌐 WebXR Development
114205

115206
### HTTPS Requirements
116207

117-
WebXR requires HTTPS for all features to work properly. This boilerplate includes:
208+
WebXR requires HTTPS for all features to work properly. This example includes:
118209

119210
- Automatic HTTPS certificate generation via `vite-plugin-mkcert`
120211
- Self-signed certificates for local development
121212
- Proper CORS configuration for asset loading
122213

123214
### Testing on Devices
124215

216+
**For Meta Quest Devices**:
217+
218+
1. Start the dev server:
125219
```bash
126-
# Find your local IP
127-
ipconfig getifaddr en0 # macOS
128-
# or
129-
hostname -I # Linux
220+
pnpm dev
221+
```
130222

131-
# Access from VR headset
223+
2. On your Quest device, open the browser and navigate to:
224+
```
132225
https://YOUR_LOCAL_IP:8081
133226
```
134227

135-
## 🛠 Customization
228+
3. Accept the self-signed certificate warning
229+
230+
4. Enter VR/AR mode to test scene understanding features
231+
232+
**Important**: Scene understanding works best in well-lit environments with distinct surfaces. Walk around slowly to allow the device to scan your environment.
136233

137-
### Vite Configuration
234+
## 🛠 Customization
138235

139-
The `vite.config.js` file includes:
140236

141-
- HTTPS development server setup
142-
- Static asset copying configuration
143-
- Build optimization settings
144-
- Asset handling rules
237+
### Enabling Wireframe Toggle
145238

146-
### Adding New Assets
239+
The `SceneUnderstandingSystem` has a built-in `showWireFrame` config option:
147240

148-
1. Place assets in the appropriate `public/` subdirectory
149-
2. Reference them in your code using root-relative paths (e.g., `/gltf/model.gltf`)
150-
3. Assets are automatically served by Vite during development and copied to build output
241+
```javascript
242+
World.create(document.getElementById('scene-container'), {
243+
xr: {
244+
sessionMode: SessionMode.ImmersiveAR,
245+
features: {
246+
hitTest: true,
247+
planeDetection: { required: true }, // Enable plane detection
248+
meshDetection: { required: true }, // Enable mesh detection
249+
anchors: { required: true }, // Enable spatial anchors
250+
},
251+
},
252+
features: {
253+
sceneUnderstanding: { showWireFrame: true }, // Enable IWSDK scene understanding system with wireframe enabled
254+
},
255+
});
256+
```
151257

152258
## 📋 Scripts
153259

@@ -157,12 +263,37 @@ The `vite.config.js` file includes:
157263

158264
## 🔗 Integration
159265

160-
This boilerplate is designed to work seamlessly with:
266+
This example demonstrates integration with:
267+
268+
- **IWSDK Scene Understanding System** - Automatic tracking and entity management
269+
- **IWSDK Grabbing System** - Interactive manipulation of anchored objects
270+
- **Meta Quest AR capabilities** - Real-world environment understanding
271+
272+
### Related Examples
273+
274+
- **Locomotion Example** - Learn about AR/VR navigation
275+
- **Physics Example** - Combine scene understanding with physics for realistic interactions
276+
- **Hit Test Example** - Place objects on detected surfaces using hit testing
277+
278+
### Use Cases for Scene Understanding
279+
280+
**Plane Detection**:
281+
- Furniture placement apps
282+
- AR games that need floor/table surfaces
283+
- Virtual interior design
284+
- Educational AR overlays on walls
285+
286+
**Mesh Detection**:
287+
- Obstacle avoidance for AR navigation
288+
- Environment-aware lighting and shadows
289+
- Physics interactions with real objects
290+
- Semantic understanding for context-aware apps
161291

162-
- **Meta Spatial SDK** for component definitions
163-
- **WebXR browsers** for VR/AR development
164-
- **Framework tools** for component generation
165-
- **Asset pipelines** for 3D content creation
292+
**Spatial Anchors**:
293+
- Persistent AR content that stays in place
294+
- Multi-user AR experiences with shared reference points
295+
- AR annotations on real-world objects
296+
- Virtual markers for navigation
166297

167298
## 📝 License
168299

examples/scene-understanding/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@iwsdk/physics",
2+
"name": "@iwsdk/scene-understanding",
33
"version": "0.1.0",
44
"private": true,
55
"type": "module",

0 commit comments

Comments
 (0)