Skip to content

Commit 94bfda5

Browse files
felixtrzmeta-codesync[bot]
authored andcommitted
feat(locomotion): expose config options in WorldOptions and add enableJumping
Summary: Forward initialPlayerPosition, comfortAssist, turningMethod, and a new enableJumping toggle through WorldOptions.features.locomotion so users can configure locomotion at World.create time without reaching into system internals. Reviewed By: zjm-meta Differential Revision: D94388774 fbshipit-source-id: 2e22fd5843dd7f659ba4b7e7a83acff30d06fc20
1 parent 3cd87b6 commit 94bfda5

File tree

6 files changed

+213
-20
lines changed

6 files changed

+213
-20
lines changed

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ temp/
6262
# Development tools
6363
.aider.conf.yml
6464
.claude/
65+
.codex/
66+
.cursor/
67+
.mcp.json
6568

6669
# Backup files created by build scripts
6770
**/package.json.backup
@@ -82,13 +85,13 @@ examples/**/public/glxf/
8285
examples/**/public/gltf/generated/
8386
examples/**/public/ui/
8487
examples/**/metaspatial/components/
85-
example-local-build/**/public/glxf/
86-
example-local-build/**/public/gltf/generated/
87-
example-local-build/**/public/ui/
8888

8989
# Auto generated version files
9090
**/version.ts
9191
**/version.js
9292

9393
# Meta Spatial Editor CLI (downloaded by build-examples.sh in CI)
9494
.meta-spatial-cli/
95+
96+
# Local playground (created via `node packages/create/dist/cli.js playground`)
97+
/playground/

packages/core/src/init/world-initializer.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { Interactable, Hovered, Pressed } from '../grab/index.js';
2727
import { InputSystem } from '../input/index.js';
2828
import { LevelTag, LevelRoot } from '../level/index.js';
2929
import { LevelSystem } from '../level/index.js';
30-
import { LocomotionSystem } from '../locomotion/index.js';
30+
import { LocomotionSystem, TurningMethod } from '../locomotion/index.js';
3131
import { MCPRuntime } from '../mcp/index.js';
3232
import {
3333
PhysicsBody,
@@ -101,7 +101,16 @@ export type WorldOptions = {
101101
/** Opt‑in feature systems. */
102102
features?: {
103103
/** Locomotion (teleport/slide/turn). Boolean or config. @defaultValue false */
104-
locomotion?: boolean | { useWorker?: boolean };
104+
locomotion?:
105+
| boolean
106+
| {
107+
useWorker?: boolean;
108+
initialPlayerPosition?: [number, number, number];
109+
comfortAssistLevel?: number;
110+
turningMethod?: TurningMethod;
111+
/** Whether jumping is enabled. @defaultValue true */
112+
enableJumping?: boolean;
113+
};
105114
/** Grabbing (one/two‑hand, distance). @defaultValue false */
106115
grabbing?: boolean | { useHandPinchForGrab?: boolean };
107116
/** Physics simulation (Havok). @defaultValue false */
@@ -442,7 +451,13 @@ function registerFeatureSystems(
442451
) {
443452
const locomotion = config.features.locomotion as
444453
| boolean
445-
| { useWorker?: boolean };
454+
| {
455+
useWorker?: boolean;
456+
initialPlayerPosition?: [number, number, number];
457+
comfortAssistLevel?: number;
458+
turningMethod?: TurningMethod;
459+
enableJumping?: boolean;
460+
};
446461
const locomotionEnabled = !!locomotion;
447462
const grabbing = config.features.grabbing as
448463
| boolean
@@ -467,7 +482,15 @@ function registerFeatureSystems(
467482
if (locomotionEnabled) {
468483
const locOpts =
469484
typeof locomotion === 'object' && locomotion
470-
? { useWorker: locomotion.useWorker }
485+
? Object.fromEntries(
486+
Object.entries({
487+
useWorker: locomotion.useWorker,
488+
initialPlayerPosition: locomotion.initialPlayerPosition,
489+
comfortAssist: locomotion.comfortAssistLevel,
490+
turningMethod: locomotion.turningMethod,
491+
enableJumping: locomotion.enableJumping,
492+
}).filter(([, v]) => v !== undefined),
493+
)
471494
: undefined;
472495
world.registerSystem(LocomotionSystem, {
473496
priority: -5,
@@ -478,7 +501,11 @@ function registerFeatureSystems(
478501
if (grabbingEnabled) {
479502
const grabOpts =
480503
typeof grabbing === 'object' && grabbing
481-
? { useHandPinchForGrab: grabbing.useHandPinchForGrab }
504+
? Object.fromEntries(
505+
Object.entries({
506+
useHandPinchForGrab: grabbing.useHandPinchForGrab,
507+
}).filter(([, v]) => v !== undefined),
508+
)
482509
: undefined;
483510
world.registerSystem(GrabSystem, { priority: -3, configData: grabOpts });
484511
}
@@ -496,7 +523,11 @@ function registerFeatureSystems(
496523
if (sceneUnderstandingEnabled) {
497524
const sceneOpts =
498525
typeof sceneUnderstanding === 'object' && sceneUnderstanding
499-
? { showWireFrame: sceneUnderstanding.showWireFrame }
526+
? Object.fromEntries(
527+
Object.entries({
528+
showWireFrame: sceneUnderstanding.showWireFrame,
529+
}).filter(([, v]) => v !== undefined),
530+
)
500531
: undefined;
501532
world
502533
.registerComponent(XRPlane)

packages/core/src/locomotion/locomotion.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export class LocomotionSystem extends createSystem(
9090
jumpCooldown: { type: Types.Float32, default: 0.1 },
9191
/** Button used to jump in SlideSystem. */
9292
jumpButton: { type: Types.String, default: InputComponent.A_Button },
93+
/** Whether jumping is enabled. */
94+
enableJumping: { type: Types.Boolean, default: true },
9395
},
9496
) {
9597
private locomotor!: Locomotor;
@@ -150,6 +152,11 @@ export class LocomotionSystem extends createSystem(
150152
this.slideSystem.config.jumpButton.value = value;
151153
}
152154
}),
155+
this.config.enableJumping.subscribe((value) => {
156+
if (this.slideSystem) {
157+
this.slideSystem.config.enableJumping.value = value;
158+
}
159+
}),
153160
);
154161
});
155162

@@ -190,6 +197,7 @@ export class LocomotionSystem extends createSystem(
190197
maxSpeed: this.config.slidingSpeed.value,
191198
comfortAssist: this.config.comfortAssist.value,
192199
jumpButton: this.config.jumpButton.value,
200+
enableJumping: this.config.enableJumping.value,
193201
locomotor: this.locomotor,
194202
},
195203
});
@@ -204,6 +212,9 @@ export class LocomotionSystem extends createSystem(
204212
}
205213

206214
private addEnvironmentToEngine(entity: Entity): void {
215+
if (!this.locomotor?.isInitialized()) {
216+
return;
217+
}
207218
if (entity.getValue(LocomotionEnvironment, '_initialized')) {
208219
return; // Already initialized
209220
}
@@ -230,6 +241,9 @@ export class LocomotionSystem extends createSystem(
230241
}
231242

232243
private removeEnvironmentFromEngine(entity: Entity): void {
244+
if (!this.locomotor) {
245+
return;
246+
}
233247
const envHandle = entity.getValue(LocomotionEnvironment, '_envHandle');
234248
if (envHandle === 0) {
235249
return; // Not initialized or invalid handle
@@ -239,6 +253,9 @@ export class LocomotionSystem extends createSystem(
239253
}
240254

241255
update(delta: number): void {
256+
if (!this.locomotor) {
257+
return;
258+
}
242259
this.locomotor.updateKinematicEnvironments();
243260
this.locomotor.update(delta);
244261
this.player.position.copy(this.locomotor.position);
@@ -285,6 +302,5 @@ export class LocomotionSystem extends createSystem(
285302
if (this.slideSystem) {
286303
this.world.unregisterSystem(SlideSystem);
287304
}
288-
this.cleanupFuncs.forEach((fn) => fn());
289305
}
290306
}

packages/core/src/locomotion/slide.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export class SlideSystem extends createSystem(
8787
comfortAssist: { type: Types.Float32, default: 0.5 },
8888
/** Button used to trigger jump. */
8989
jumpButton: { type: Types.String, default: InputComponent.A_Button },
90+
/** Whether jumping is enabled. */
91+
enableJumping: { type: Types.Boolean, default: true },
9092
},
9193
) {
9294
private movementVector = new Vector3();
@@ -111,6 +113,7 @@ export class SlideSystem extends createSystem(
111113

112114
// Handle jump input
113115
if (
116+
this.config.enableJumping.value &&
114117
this.input.gamepads.right?.getButtonDown(
115118
this.config.jumpButton.value as InputComponent,
116119
)

0 commit comments

Comments
 (0)