@reactvision/react-viro 2.56.0 → 2.57.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +8 -0
  2. package/android/react_viro/react_viro-release.aar +0 -0
  3. package/android/viro_renderer/viro_renderer-release.aar +0 -0
  4. package/components/AR/ViroARPlane.tsx +1 -4
  5. package/components/AR/ViroARPlaneSelector.tsx +10 -5
  6. package/components/AR/ViroARScene.tsx +19 -4
  7. package/components/Studio/StudioARScene.tsx +243 -48
  8. package/components/Studio/StudioSceneNavigator.tsx +15 -0
  9. package/components/Studio/VRTStudioModule.ts +10 -0
  10. package/components/Studio/domain/StudioSounds.tsx +46 -0
  11. package/components/Studio/domain/apiRequestHelpers.ts +612 -0
  12. package/components/Studio/domain/collisionBindingsRuntime.ts +17 -2
  13. package/components/Studio/domain/defaultApiRequestExecutor.ts +61 -0
  14. package/components/Studio/domain/expressionEvaluator.ts +603 -0
  15. package/components/Studio/domain/sceneNavigationHandler.ts +770 -20
  16. package/components/Studio/domain/soundManager.ts +141 -0
  17. package/components/Studio/domain/utils.ts +50 -0
  18. package/components/Studio/domain/variableStore.ts +74 -0
  19. package/components/Studio/domain/viroNodeFactory.tsx +175 -44
  20. package/components/Studio/domain/visibilityStore.ts +66 -0
  21. package/components/Studio/index.ts +1 -0
  22. package/components/Studio/types.ts +178 -1
  23. package/components/Utilities/VRModuleOpenXR.ts +35 -0
  24. package/components/Utilities/ViroVersion.ts +1 -1
  25. package/components/ViroAnimatedImage.tsx +1 -0
  26. package/components/ViroFlexView.tsx +1 -0
  27. package/components/ViroImage.tsx +1 -0
  28. package/components/ViroObjectDetector.tsx +230 -0
  29. package/components/ViroParticleEmitter.tsx +2 -0
  30. package/components/ViroPolygon.tsx +2 -1
  31. package/components/ViroQuad.tsx +2 -1
  32. package/components/ViroSurface.tsx +1 -0
  33. package/components/ViroVideo.tsx +1 -0
  34. package/components/ViroXRSceneNavigator.tsx +8 -0
  35. package/dist/components/AR/ViroARPlane.d.ts +1 -1
  36. package/dist/components/AR/ViroARPlane.js +1 -5
  37. package/dist/components/AR/ViroARPlaneSelector.d.ts +1 -1
  38. package/dist/components/AR/ViroARPlaneSelector.js +10 -5
  39. package/dist/components/AR/ViroARScene.d.ts +13 -1
  40. package/dist/components/AR/ViroARScene.js +10 -6
  41. package/dist/components/Studio/StudioARScene.d.ts +3 -0
  42. package/dist/components/Studio/StudioARScene.js +142 -15
  43. package/dist/components/Studio/StudioSceneNavigator.js +14 -0
  44. package/dist/components/Studio/VRTStudioModule.d.ts +6 -0
  45. package/dist/components/Studio/VRTStudioModule.js +10 -0
  46. package/dist/components/Studio/domain/StudioSounds.d.ts +11 -0
  47. package/dist/components/Studio/domain/StudioSounds.js +69 -0
  48. package/dist/components/Studio/domain/apiRequestHelpers.d.ts +180 -0
  49. package/dist/components/Studio/domain/apiRequestHelpers.js +496 -0
  50. package/dist/components/Studio/domain/collisionBindingsRuntime.d.ts +3 -1
  51. package/dist/components/Studio/domain/collisionBindingsRuntime.js +4 -3
  52. package/dist/components/Studio/domain/defaultApiRequestExecutor.d.ts +14 -0
  53. package/dist/components/Studio/domain/defaultApiRequestExecutor.js +58 -0
  54. package/dist/components/Studio/domain/expressionEvaluator.d.ts +108 -0
  55. package/dist/components/Studio/domain/expressionEvaluator.js +520 -0
  56. package/dist/components/Studio/domain/sceneNavigationHandler.d.ts +35 -8
  57. package/dist/components/Studio/domain/sceneNavigationHandler.js +564 -22
  58. package/dist/components/Studio/domain/soundManager.d.ts +52 -0
  59. package/dist/components/Studio/domain/soundManager.js +118 -0
  60. package/dist/components/Studio/domain/utils.d.ts +16 -0
  61. package/dist/components/Studio/domain/utils.js +48 -0
  62. package/dist/components/Studio/domain/variableStore.d.ts +21 -0
  63. package/dist/components/Studio/domain/variableStore.js +65 -0
  64. package/dist/components/Studio/domain/viroNodeFactory.d.ts +4 -9
  65. package/dist/components/Studio/domain/viroNodeFactory.js +84 -25
  66. package/dist/components/Studio/domain/visibilityStore.d.ts +33 -0
  67. package/dist/components/Studio/domain/visibilityStore.js +66 -0
  68. package/dist/components/Studio/index.d.ts +1 -1
  69. package/dist/components/Studio/types.d.ts +150 -1
  70. package/dist/components/Utilities/VRModuleOpenXR.d.ts +19 -0
  71. package/dist/components/Utilities/VRModuleOpenXR.js +16 -0
  72. package/dist/components/Utilities/ViroVersion.d.ts +1 -1
  73. package/dist/components/Utilities/ViroVersion.js +1 -1
  74. package/dist/components/ViroAnimatedImage.js +1 -0
  75. package/dist/components/ViroFlexView.js +1 -0
  76. package/dist/components/ViroImage.js +1 -0
  77. package/dist/components/ViroObjectDetector.d.ts +146 -0
  78. package/dist/components/ViroObjectDetector.js +93 -0
  79. package/dist/components/ViroParticleEmitter.js +2 -0
  80. package/dist/components/ViroPolygon.js +1 -0
  81. package/dist/components/ViroQuad.js +1 -0
  82. package/dist/components/ViroSurface.js +1 -0
  83. package/dist/components/ViroVideo.js +1 -0
  84. package/dist/components/ViroXRSceneNavigator.d.ts +8 -0
  85. package/dist/index.d.ts +6 -4
  86. package/dist/index.js +5 -2
  87. package/dist/plugins/withViro.js +2 -15
  88. package/dist/plugins/withViroAndroid.js +18 -5
  89. package/dist/plugins/withViroIos.js +0 -6
  90. package/index.ts +7 -3
  91. package/ios/ViroReact.podspec +25 -6
  92. package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreCoreMLSemanticsResources.bundle/Info.plist +0 -0
  93. package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreResources.bundle/Info.plist +0 -0
  94. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARFrameiOS.h +9 -0
  95. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARScene.h +14 -1
  96. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSceneDelegateiOS.h +8 -0
  97. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROGLTFLoader.h +5 -1
  98. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMonocularDepthEstimator.h +10 -0
  99. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROObjectDetector.h +134 -0
  100. package/ios/dist/ViroRenderer/ViroKit.framework/Info.plist +0 -0
  101. package/ios/dist/ViroRenderer/ViroKit.framework/Shaders.dat +1 -1
  102. package/ios/dist/ViroRenderer/ViroKit.framework/ViroKit +0 -0
  103. package/ios/dist/ViroRendererVisionOS/ViroKit.podspec +27 -0
  104. package/ios/dist/include/VRTARScene.h +1 -0
  105. package/ios/dist/lib/libViroReact.a +0 -0
  106. package/package.json +17 -20
@@ -18,13 +18,131 @@ export interface StudioProjectMeta {
18
18
  id: string;
19
19
  occlusion_mode: "NONE" | "PEOPLEONLY" | "DEPTHBASED";
20
20
  }
21
+ /**
22
+ * One ordered step of a Sequence: an ACTION (runs a function), a WAIT (timed
23
+ * pause), or a STOP (explicit terminal — the run halts here).
24
+ */
25
+ export interface StudioSequenceStep {
26
+ id: string;
27
+ step_order: number;
28
+ step_type: "ACTION" | "WAIT" | "STOP";
29
+ duration_ms: number | null;
30
+ function_id: string | null;
31
+ function: StudioSceneFunction | null;
32
+ advance_immediately: boolean;
33
+ }
34
+ export interface StudioSequence {
35
+ id: string;
36
+ name: string | null;
37
+ steps: StudioSequenceStep[];
38
+ }
39
+ /** Scene-level variable declaration. Runtime state lives in StudioVariableStore. */
40
+ export interface StudioSceneVariable {
41
+ id: string;
42
+ name: string;
43
+ type: "BOOLEAN" | "NUMBER" | "STRING";
44
+ initial_value: boolean | number | string;
45
+ }
46
+ /**
47
+ * One ordered predicate arm of a BRANCH. Variable names/types are joined from
48
+ * project_variables so they follow renames. The arm is an owned, headless
49
+ * sequence run like a nested sequence.
50
+ */
51
+ export interface StudioBranchCondition {
52
+ id: string;
53
+ eval_order: number;
54
+ variable_id: string;
55
+ variable_name: string;
56
+ variable_type: "BOOLEAN" | "NUMBER" | "STRING";
57
+ comparison: "EQUALS" | "NOT_EQUALS" | "GREATER_THAN" | "LESS_THAN" | "GREATER_OR_EQUAL" | "LESS_OR_EQUAL" | "LIKE" | "ILIKE";
58
+ compare_literal: boolean | number | string | null;
59
+ compare_variable_id: string | null;
60
+ compare_variable_name: string | null;
61
+ compare_variable_type: "BOOLEAN" | "NUMBER" | "STRING" | null;
62
+ sequence: StudioSequence;
63
+ }
64
+ /**
65
+ * BRANCH payload. Conditions are evaluated in eval_order (first match wins),
66
+ * falling through to the optional no-match arm. Arms are owned, headless
67
+ * sequences run like nested sequences.
68
+ */
69
+ export interface StudioSceneBranch {
70
+ id: string;
71
+ conditions: StudioBranchCondition[];
72
+ no_match_sequence: StudioSequence | null;
73
+ }
74
+ /**
75
+ * GROUP payload. Owns N lanes, each an owned headless sequence run like a
76
+ * nested sequence. Lanes run concurrently; the group completes when all lanes
77
+ * complete (barrier join).
78
+ */
79
+ export interface StudioSceneGroup {
80
+ id: string;
81
+ lanes: {
82
+ lane_order: number;
83
+ sequence: StudioSequence;
84
+ }[];
85
+ }
86
+ /** One response->variable binding of an API_REQUEST function. */
87
+ export interface StudioApiRequestBinding {
88
+ id: string;
89
+ source: "BODY" | "STATUS" | "OK" | "ERROR_MESSAGE";
90
+ selector: string | null;
91
+ variable_id: string;
92
+ variable_name: string;
93
+ variable_type: "BOOLEAN" | "NUMBER" | "STRING";
94
+ bind_order: number;
95
+ }
96
+ /**
97
+ * API_REQUEST payload. The HTTP call executes server-side through the
98
+ * platform egress proxy (the client only ever sends the function id plus
99
+ * current variable values); connection_id is an opaque server-side
100
+ * reference. Arms are owned, headless sequences run like nested sequences.
101
+ */
102
+ export interface StudioSceneApiRequest {
103
+ id: string;
104
+ method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
105
+ url_template: string;
106
+ headers: {
107
+ key: string;
108
+ value_template: string;
109
+ }[];
110
+ body_template: string | null;
111
+ timeout_ms: number;
112
+ connection_id: string | null;
113
+ bindings: StudioApiRequestBinding[];
114
+ success_sequence: StudioSequence | null;
115
+ failure_sequence: StudioSequence | null;
116
+ }
117
+ /** Outcome envelope an API-request executor resolves with. */
118
+ export interface StudioApiRequestOutcome {
119
+ ok: boolean;
120
+ status: number | null;
121
+ body?: unknown;
122
+ error_code?: string | null;
123
+ error_message?: string | null;
124
+ }
125
+ /**
126
+ * Host-app transport for API_REQUEST functions: StudioGo calls the
127
+ * scene-api-request edge function with the user JWT; production Viro apps
128
+ * call it with their X-API-Key. Must resolve with an outcome (reject only on
129
+ * transport failure).
130
+ */
131
+ export type StudioApiRequestExecutor = (functionId: string, variables: Record<string, boolean | number | string>) => Promise<StudioApiRequestOutcome>;
21
132
  export interface StudioSceneFunction {
22
133
  id: string;
23
134
  scene: string;
24
- function_type: "NAVIGATION" | "ALERT" | "ANIMATION";
135
+ function_type: "NAVIGATION" | "ALERT" | "ANIMATION" | "SEQUENCE" | "SET_VARIABLE" | "BRANCH" | "API_REQUEST" | "SET_VISIBILITY" | "SOUND" | "GROUP";
25
136
  navigation: string | null;
26
137
  alert: string | null;
27
138
  animation: string | null;
139
+ sequence: string | null;
140
+ set_variable: string | null;
141
+ branch: string | null;
142
+ api_request: string | null;
143
+ set_visibility: string | null;
144
+ sound: string | null;
145
+ group_fn: string | null;
28
146
  scene_navigation: {
29
147
  id: string;
30
148
  navigate_to: string;
@@ -41,6 +159,33 @@ export interface StudioSceneFunction {
41
159
  delay_ms: number | null;
42
160
  properties: Record<string, unknown>;
43
161
  } | null;
162
+ scene_sequence: StudioSequence | null;
163
+ /** name/type are joined from the target scene_variables row, so they follow renames. */
164
+ scene_set_variable: {
165
+ id: string;
166
+ variable_id: string;
167
+ name: string;
168
+ type: "BOOLEAN" | "NUMBER" | "STRING";
169
+ expression: string;
170
+ } | null;
171
+ scene_branch: StudioSceneBranch | null;
172
+ scene_api_request: StudioSceneApiRequest | null;
173
+ scene_set_visibility: {
174
+ id: string;
175
+ target_asset_id: string;
176
+ state: "VISIBLE" | "HIDDEN" | "TOGGLE";
177
+ } | null;
178
+ scene_sound: {
179
+ id: string;
180
+ action: "PLAY" | "STOP";
181
+ audio_asset_id: string | null;
182
+ audio_url: string | null;
183
+ target_asset_id: string | null;
184
+ volume: number;
185
+ loop: boolean;
186
+ stop_other_sounds: boolean;
187
+ } | null;
188
+ scene_group: StudioSceneGroup | null;
44
189
  }
45
190
  export interface StudioAsset {
46
191
  id: string;
@@ -59,6 +204,8 @@ export interface StudioAsset {
59
204
  latitude: number | null;
60
205
  longitude: number | null;
61
206
  is_draggable: boolean;
207
+ /** Author-time "hidden on start"; the runtime seeds visibility from it. */
208
+ hidden_on_load: boolean | null;
62
209
  trigger_image_url: string | null;
63
210
  trigger_image_orientation: "Up" | "Down" | "Left" | "Right" | null;
64
211
  trigger_image_physical_width_m: number | null;
@@ -133,6 +280,8 @@ export interface StudioSceneResponse {
133
280
  collision_bindings: StudioCollisionBinding[];
134
281
  animations: StudioAnimation[];
135
282
  functions: StudioSceneFunction[];
283
+ /** Absent in responses from backends predating the Variables feature. */
284
+ variables?: StudioSceneVariable[];
136
285
  meta: {
137
286
  request_id: string;
138
287
  };
@@ -6,7 +6,26 @@ export declare function exitVRScene(): void;
6
6
  export type VRModuleOpenXRType = {
7
7
  recenterTracking?: (viewTag: number) => void;
8
8
  setPassthroughEnabled?: (viewTag: number, enabled: boolean) => void;
9
+ setPassthroughStyle?: (viewTag: number, opacity: number, edgeR: number, edgeG: number, edgeB: number, edgeA: number) => void;
9
10
  };
11
+ /** Options for {@link setPassthroughStyle}. All channels are normalized [0,1]. */
12
+ export type ViroPassthroughStyle = {
13
+ /** Texture opacity factor [0,1]. Default 1 (fully opaque passthrough). */
14
+ opacity?: number;
15
+ /** Edge-highlight colour [r,g,b,a]. Alpha 0 (default) disables the edge effect. */
16
+ edgeColor?: [number, number, number, number];
17
+ };
18
+ /**
19
+ * Style the Quest passthrough layer (XR_FB_passthrough). No-op off-Quest.
20
+ *
21
+ * ```tsx
22
+ * const viewTag = useVRViewTag();
23
+ * if (viewTag != null) {
24
+ * setPassthroughStyle(viewTag, { opacity: 0.8, edgeColor: [0, 1, 1, 1] });
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function setPassthroughStyle(viewTag: number, style: ViroPassthroughStyle): void;
10
29
  /**
11
30
  * Typed reference to the VRModuleOpenXR native module.
12
31
  * undefined when not running on Meta Quest (no-op calls are safe via optional chaining).
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VRModuleOpenXR = void 0;
4
4
  exports.exitVRScene = exitVRScene;
5
+ exports.setPassthroughStyle = setPassthroughStyle;
5
6
  exports.useVRViewTag = useVRViewTag;
6
7
  const react_1 = require("react");
7
8
  const react_native_1 = require("react-native");
@@ -15,6 +16,21 @@ function exitVRScene() {
15
16
  react_native_1.NativeModules.VRLauncher
16
17
  ?.exitVRScene?.();
17
18
  }
19
+ /**
20
+ * Style the Quest passthrough layer (XR_FB_passthrough). No-op off-Quest.
21
+ *
22
+ * ```tsx
23
+ * const viewTag = useVRViewTag();
24
+ * if (viewTag != null) {
25
+ * setPassthroughStyle(viewTag, { opacity: 0.8, edgeColor: [0, 1, 1, 1] });
26
+ * }
27
+ * ```
28
+ */
29
+ function setPassthroughStyle(viewTag, style) {
30
+ const opacity = style.opacity ?? 1;
31
+ const [r, g, b, a] = style.edgeColor ?? [0, 0, 0, 0];
32
+ exports.VRModuleOpenXR?.setPassthroughStyle?.(viewTag, opacity, r, g, b, a);
33
+ }
18
34
  /**
19
35
  * Typed reference to the VRModuleOpenXR native module.
20
36
  * undefined when not running on Meta Quest (no-op calls are safe via optional chaining).
@@ -1 +1 @@
1
- export declare const VIRO_VERSION = "2.56.0";
1
+ export declare const VIRO_VERSION = "2.57.2";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VIRO_VERSION = void 0;
4
- exports.VIRO_VERSION = "2.56.0";
4
+ exports.VIRO_VERSION = "2.57.2";
@@ -110,6 +110,7 @@ class ViroAnimatedImage extends ViroBase_1.ViroBase {
110
110
  nativeProps.style = [this.props.style];
111
111
  nativeProps.onHoverViro = this._onHover;
112
112
  nativeProps.onClickViro = this._onClickState;
113
+ nativeProps.onClick = undefined;
113
114
  nativeProps.onTouchViro = this._onTouch;
114
115
  nativeProps.onScrollViro = this._onScroll;
115
116
  nativeProps.onSwipeViro = this._onSwipe;
@@ -78,6 +78,7 @@ class ViroFlexView extends ViroBase_1.ViroBase {
78
78
  nativeProps.transformBehaviors = transformBehaviors;
79
79
  nativeProps.onHoverViro = this._onHover;
80
80
  nativeProps.onClickViro = this._onClickState;
81
+ nativeProps.onClick = undefined;
81
82
  nativeProps.onTouchViro = this._onTouch;
82
83
  nativeProps.onScrollViro = this._onScroll;
83
84
  nativeProps.onSwipeViro = this._onSwipe;
@@ -117,6 +117,7 @@ class ViroImage extends ViroBase_1.ViroBase {
117
117
  nativeProps.style = [this.props.style];
118
118
  nativeProps.onHoverViro = this._onHover;
119
119
  nativeProps.onClickViro = this._onClickState;
120
+ nativeProps.onClick = undefined;
120
121
  nativeProps.onTouchViro = this._onTouch;
121
122
  nativeProps.onScrollViro = this._onScroll;
122
123
  nativeProps.onSwipeViro = this._onSwipe;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Copyright (c) 2026-present, ReactVision, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import * as React from "react";
9
+ import { ViewProps } from "react-native";
10
+ export type ViroDetectorMode = "prompt-free" | "text" | "visual";
11
+ export type ViroDetectionBoundingBox = {
12
+ /** Left edge, normalized [0, 1] */
13
+ x: number;
14
+ /** Top edge, normalized [0, 1] */
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ };
19
+ export type ViroDetectedObject = {
20
+ label: string;
21
+ confidence: number;
22
+ boundingBox: ViroDetectionBoundingBox;
23
+ /** 3D world position (metres), from raycasting the bbox centre. Present when `projectToWorld` is true (iOS only). */
24
+ worldPosition?: {
25
+ x: number;
26
+ y: number;
27
+ z: number;
28
+ };
29
+ /**
30
+ * Bounding box in density-independent points (dp), aligned to the on-screen AR
31
+ * camera preview. Use directly as { left, top, width, height } in an
32
+ * absolute-positioned View. Present on iOS and Android.
33
+ */
34
+ screenBoundingBox?: {
35
+ x: number;
36
+ y: number;
37
+ width: number;
38
+ height: number;
39
+ };
40
+ };
41
+ export type ViroDetectionEvent = {
42
+ detections: ViroDetectedObject[];
43
+ };
44
+ export type ViroDetectorReadyEvent = Record<string, never>;
45
+ export type ViroDetectorErrorEvent = {
46
+ error: string;
47
+ };
48
+ type Props = ViewProps & {
49
+ /**
50
+ * The YOLOE model to run. Either a bundled model **name** (resolved natively as
51
+ * `<name>.onnx` in the app bundle / Android assets), or an absolute `/`-path or
52
+ * `file://` URL to an `.onnx` file. Defaults to "yoloe-26s".
53
+ */
54
+ model?: string;
55
+ /**
56
+ * Inference mode:
57
+ * - "prompt-free": YOLOE LRPC — detects 4,585 categories with no extra prompt.
58
+ * - "text": YOLOE RepRTA — detect only the classes listed in `categories`.
59
+ * - "visual": YOLOE SAVPE — detect objects similar to a reference crop
60
+ * (reference image API to be added in a future release).
61
+ * Defaults to "prompt-free".
62
+ */
63
+ mode?: ViroDetectorMode;
64
+ /**
65
+ * Text categories for "text" mode, e.g. ["chair", "person", "laptop"].
66
+ * Ignored in other modes.
67
+ */
68
+ categories?: string[];
69
+ /**
70
+ * Minimum confidence score [0, 1] for a detection to be reported.
71
+ * Defaults to 0.4.
72
+ */
73
+ confidenceThreshold?: number;
74
+ /**
75
+ * IoU threshold used by NMS post-processing.
76
+ * Defaults to 0.45.
77
+ */
78
+ iouThreshold?: number;
79
+ /**
80
+ * Maximum number of inference calls per second. The camera runs at the
81
+ * device's native frame rate; this throttle prevents the inference thread
82
+ * from saturating the CPU/NPU while the AR renderer runs in parallel.
83
+ * Defaults to 15.
84
+ */
85
+ maxFPS?: number;
86
+ /**
87
+ * Maximum number of detections reported per frame, kept as the top-N by
88
+ * confidence (after NMS). Lower this to reduce clutter, raise it to surface
89
+ * more objects.
90
+ * Defaults to 20.
91
+ */
92
+ maxDetections?: number;
93
+ /**
94
+ * When true, each detection includes a `worldPosition` {x, y, z} obtained by
95
+ * raycasting the bbox centre against the AR scene. iOS only (Android emits
96
+ * `screenBoundingBox` but not yet `worldPosition`).
97
+ * Defaults to true.
98
+ */
99
+ projectToWorld?: boolean;
100
+ /**
101
+ * Called every time the detector produces a new set of detections.
102
+ * May be called with an empty array if nothing is detected in a frame.
103
+ */
104
+ onDetection?: (event: ViroDetectionEvent) => void;
105
+ /**
106
+ * Called once the model has been loaded and the camera pipeline is running.
107
+ */
108
+ onReady?: (event: ViroDetectorReadyEvent) => void;
109
+ /**
110
+ * Called if the model fails to load or the camera cannot be opened.
111
+ */
112
+ onError?: (event: ViroDetectorErrorEvent) => void;
113
+ };
114
+ /**
115
+ * ViroObjectDetector — on-device open-vocabulary object detection powered by YOLOE.
116
+ *
117
+ * Runs in AR and on Meta Quest:
118
+ * - **Phone AR**: shares the camera feed of the enclosing `ViroARSceneNavigator`
119
+ * (no separate camera session) and fires `onDetection` with labels, normalized
120
+ * bounding boxes, and an on-screen `screenBoundingBox` (dp) at up to `maxFPS`.
121
+ * - **Meta Quest 3 / 3S** (Horizon OS v74+): when mounted in a Quest MR scene
122
+ * (under `ViroXRSceneNavigator`), it captures the headset camera via the Meta
123
+ * Passthrough Camera API and runs the same YOLOE pipeline. Requires the
124
+ * `horizonos.permission.HEADSET_CAMERA` runtime permission. v1 emits `label` +
125
+ * normalized `boundingBox` only — `screenBoundingBox` and `worldPosition` are
126
+ * not provided on Quest yet (they need camera extrinsics).
127
+ *
128
+ * Mount it as a child or sibling of the scene navigator; it renders nothing itself,
129
+ * so give it `width: 0, height: 0`.
130
+ *
131
+ * @example
132
+ * ```tsx
133
+ * <ViroARSceneNavigator initialScene={{ scene: MyScene }} />
134
+ * <ViroObjectDetector
135
+ * style={{ position: "absolute", width: 0, height: 0 }}
136
+ * mode="prompt-free"
137
+ * confidenceThreshold={0.4}
138
+ * maxFPS={15}
139
+ * onDetection={({ detections }) => {
140
+ * detections.forEach(d => console.log(d.label, d.confidence, d.screenBoundingBox));
141
+ * }}
142
+ * />
143
+ * ```
144
+ */
145
+ export declare const ViroObjectDetector: React.FC<Props>;
146
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026-present, ReactVision, Inc.
4
+ * All rights reserved.
5
+ *
6
+ * This source code is licensed under the BSD-style license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.ViroObjectDetector = void 0;
44
+ const React = __importStar(require("react"));
45
+ const react_native_1 = require("react-native");
46
+ // ---------------------------------------------------------------------------
47
+ // Component
48
+ // ---------------------------------------------------------------------------
49
+ const VRTObjectDetectorView = (0, react_native_1.requireNativeComponent)("VRTObjectDetectorView");
50
+ /**
51
+ * ViroObjectDetector — on-device open-vocabulary object detection powered by YOLOE.
52
+ *
53
+ * Runs in AR and on Meta Quest:
54
+ * - **Phone AR**: shares the camera feed of the enclosing `ViroARSceneNavigator`
55
+ * (no separate camera session) and fires `onDetection` with labels, normalized
56
+ * bounding boxes, and an on-screen `screenBoundingBox` (dp) at up to `maxFPS`.
57
+ * - **Meta Quest 3 / 3S** (Horizon OS v74+): when mounted in a Quest MR scene
58
+ * (under `ViroXRSceneNavigator`), it captures the headset camera via the Meta
59
+ * Passthrough Camera API and runs the same YOLOE pipeline. Requires the
60
+ * `horizonos.permission.HEADSET_CAMERA` runtime permission. v1 emits `label` +
61
+ * normalized `boundingBox` only — `screenBoundingBox` and `worldPosition` are
62
+ * not provided on Quest yet (they need camera extrinsics).
63
+ *
64
+ * Mount it as a child or sibling of the scene navigator; it renders nothing itself,
65
+ * so give it `width: 0, height: 0`.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * <ViroARSceneNavigator initialScene={{ scene: MyScene }} />
70
+ * <ViroObjectDetector
71
+ * style={{ position: "absolute", width: 0, height: 0 }}
72
+ * mode="prompt-free"
73
+ * confidenceThreshold={0.4}
74
+ * maxFPS={15}
75
+ * onDetection={({ detections }) => {
76
+ * detections.forEach(d => console.log(d.label, d.confidence, d.screenBoundingBox));
77
+ * }}
78
+ * />
79
+ * ```
80
+ */
81
+ const ViroObjectDetector = ({ model = "yoloe-26s", mode = "prompt-free", categories = [], confidenceThreshold = 0.4, iouThreshold = 0.45, maxFPS = 15, maxDetections = 20, projectToWorld = true, onDetection, onReady, onError, style, ...rest }) => {
82
+ const handleDetection = React.useCallback((event) => {
83
+ onDetection?.(event.nativeEvent);
84
+ }, [onDetection]);
85
+ const handleReady = React.useCallback((event) => {
86
+ onReady?.(event.nativeEvent);
87
+ }, [onReady]);
88
+ const handleError = React.useCallback((event) => {
89
+ onError?.(event.nativeEvent);
90
+ }, [onError]);
91
+ return (<VRTObjectDetectorView {...rest} style={style} model={model} mode={mode} categories={categories} confidenceThreshold={confidenceThreshold} iouThreshold={iouThreshold} maxFPS={maxFPS} maxDetections={maxDetections} projectToWorld={projectToWorld} onDetectionViro={onDetection ? handleDetection : undefined} onReadyViro={onReady ? handleReady : undefined} onErrorViro={onError ? handleError : undefined}/>);
92
+ };
93
+ exports.ViroObjectDetector = ViroObjectDetector;
@@ -102,6 +102,7 @@ class ViroParticleEmitter extends React.Component {
102
102
  : undefined;
103
103
  // Create native props object.
104
104
  let nativeProps = Object.assign({}, this.props);
105
+ nativeProps.onClick = undefined;
105
106
  nativeProps.position = this.state.propsPositionState;
106
107
  nativeProps.onNativeTransformDelegateViro = transformDelegate;
107
108
  nativeProps.hasTransformDelegate =
@@ -175,6 +176,7 @@ class ViroParticleEmitter extends React.Component {
175
176
  };
176
177
  nativeProps.particleAppearance.rotation = newAppearanceRotMod;
177
178
  }
179
+ nativeProps.onClick = undefined;
178
180
  nativeProps.ref = (component) => {
179
181
  this._component = component;
180
182
  };
@@ -80,6 +80,7 @@ class ViroPolygon extends ViroBase_1.ViroBase {
80
80
  nativeProps.style = [this.props.style];
81
81
  nativeProps.onHoverViro = this._onHover;
82
82
  nativeProps.onClickViro = this._onClickState;
83
+ nativeProps.onClick = undefined;
83
84
  nativeProps.onTouchViro = this._onTouch;
84
85
  nativeProps.onScrollViro = this._onScroll;
85
86
  nativeProps.onSwipeViro = this._onSwipe;
@@ -80,6 +80,7 @@ class ViroQuad extends ViroBase_1.ViroBase {
80
80
  nativeProps.style = [this.props.style];
81
81
  nativeProps.onHoverViro = this._onHover;
82
82
  nativeProps.onClickViro = this._onClickState;
83
+ nativeProps.onClick = undefined;
83
84
  nativeProps.onTouchViro = this._onTouch;
84
85
  nativeProps.onScrollViro = this._onScroll;
85
86
  nativeProps.onSwipeViro = this._onSwipe;
@@ -81,6 +81,7 @@ class ViroSurface extends ViroBase_1.ViroBase {
81
81
  nativeProps.style = [this.props.style];
82
82
  nativeProps.onHoverViro = this._onHover;
83
83
  nativeProps.onClickViro = this._onClickState;
84
+ nativeProps.onClick = undefined;
84
85
  nativeProps.onTouchViro = this._onTouch;
85
86
  nativeProps.onScrollViro = this._onScroll;
86
87
  nativeProps.onSwipeViro = this._onSwipe;
@@ -98,6 +98,7 @@ class ViroVideo extends ViroBase_1.ViroBase {
98
98
  nativeProps.onUpdateTimeViro = this._onUpdateTime;
99
99
  nativeProps.onHoverViro = this._onHover;
100
100
  nativeProps.onClickViro = this._onClickState;
101
+ nativeProps.onClick = undefined;
101
102
  nativeProps.onTouchViro = this._onTouch;
102
103
  nativeProps.onScrollViro = this._onScroll;
103
104
  nativeProps.onSwipeViro = this._onSwipe;
@@ -33,6 +33,14 @@ export declare const ViroXRSceneNavigator: React.ForwardRefExoticComponent<ViewP
33
33
  * On Quest, this scene is forwarded to VRActivity via VRQuestNavigatorBridge
34
34
  * rather than rendered inline, because OpenXR exclusive display requires the
35
35
  * VR intent category on the host Activity.
36
+ *
37
+ * The scene root may be either:
38
+ * - `ViroScene` → fully-virtual VR.
39
+ * - `ViroARScene` → mixed reality: passthrough is enabled automatically and
40
+ * real-time plane detection (XR_EXT_plane_detection, Quest 3 / 3S) drives
41
+ * `onAnchorFound` and `ViroARPlane`, exactly as on phone AR. A single
42
+ * AR-rooted `initialScene` therefore runs on phones (ARCore) and Quest (OpenXR)
43
+ * with no per-platform changes. See docs/QUEST_SETUP.md §7b.
36
44
  */
37
45
  vrInitialScene?: SceneFactory;
38
46
  worldAlignment?: "Gravity" | "GravityAndHeading" | "Camera";
package/dist/index.d.ts CHANGED
@@ -38,6 +38,8 @@ import { ViroMaterials, ViroMaterial, ViroShaderModifiers, ViroShaderUniform, Vi
38
38
  import { ViroMaterialVideo } from "./components/ViroMaterialVideo";
39
39
  import { ViroCameraTexture } from "./components/ViroCameraTexture";
40
40
  export type { ViroCameraPosition, ViroCameraReadyEvent } from "./components/ViroCameraTexture";
41
+ import { ViroObjectDetector } from "./components/ViroObjectDetector";
42
+ export type { ViroDetectorMode, ViroDetectedObject, ViroDetectionBoundingBox, ViroDetectionEvent, ViroDetectorReadyEvent, ViroDetectorErrorEvent } from "./components/ViroObjectDetector";
41
43
  import { ViroNode } from "./components/ViroNode";
42
44
  import { ViroOmniLight } from "./components/ViroOmniLight";
43
45
  import { ViroOrbitCamera } from "./components/ViroOrbitCamera";
@@ -73,10 +75,10 @@ import { ViroSceneNavigator } from "./components/ViroSceneNavigator";
73
75
  import { VIRO_VERSION } from "./components/Utilities/ViroVersion";
74
76
  import { ViroQuestEntryPoint } from "./components/ViroQuestEntryPoint";
75
77
  import { VRQuestNavigatorBridge } from "./components/Utilities/VRQuestNavigatorBridge";
76
- import { VRModuleOpenXR, useVRViewTag, exitVRScene } from "./components/Utilities/VRModuleOpenXR";
77
- import type { VRModuleOpenXRType } from "./components/Utilities/VRModuleOpenXR";
78
+ import { VRModuleOpenXR, useVRViewTag, exitVRScene, setPassthroughStyle } from "./components/Utilities/VRModuleOpenXR";
79
+ import type { VRModuleOpenXRType, ViroPassthroughStyle } from "./components/Utilities/VRModuleOpenXR";
78
80
  import { StreamingAudioManager } from "./components/Utilities/StreamingAudioManager";
79
- export { ViroARImageMarker, ViroARObjectMarker, ViroARTrackingTargets, ViroARPlane, ViroARPlaneSelector, ViroARScene, ViroARSceneNavigator, ViroBox, ViroButton, ViroCamera, ViroController, ViroVirtualJoystick, ViroVirtualButton, ViroGameLoop, ViroGameLoopUtils, useGameLoop, useLateUpdate, useFixedUpdate, ViroDirectionalLight, ViroFlexView, ViroGeometry, ViroLightingEnvironment, ViroImage, ViroMaterials, ViroARCamera, ViroMaterialVideo, ViroCameraTexture, ViroNode, ViroOmniLight, ViroOrbitCamera, ViroParticleEmitter, ViroPolygon, ViroPolyline, ViroPortal, ViroPortalScene, ViroQuad, ViroScene, ViroSurface, ViroSceneNavigator, ViroSkyBox, ViroAnimations, Viro3DObject, Viro360Image, Viro360Video, ViroAnimatedImage, ViroAmbientLight, ViroAnimatedComponent, ViroSound, ViroSoundField, ViroSpatialSound, ViroSphere, ViroSpinner, ViroSpotLight, ViroText, ViroVideo, ViroVRSceneNavigator, ViroXRSceneNavigator, ViroQuestEntryPoint, VRQuestNavigatorBridge, VRModuleOpenXR, useVRViewTag, exitVRScene, Viro3DSceneNavigator, StreamingAudioManager, hasOpenXRSupport, isQuest, useAnySourceHover, useAnySourcePressed, ViroARTrackingReasonConstants, ViroRecordingErrorConstants, ViroTrackingStateConstants, polarToCartesian, polarToCartesianActual, isARSupportedOnDevice, requestRequiredPermissions, checkPermissions, latLngToMercator, gpsToArWorld, ViroARSupportResponse, ViroPermissionsResult, ViroPermission, ViroHoverEvent, ViroClickEvent, ViroClickStateEvent, ViroClickStateTypes, ViroTouchEvent, ViroScrollEvent, ViroSwipeEvent, ViroFuseEvent, ViroPinchEvent, ViroPinchStateTypes, ViroRotateEvent, ViroRotateStateTypes, ViroDragEvent, ViroPlatformEvent, ViroCollisionEvent, ViroPlatformInfo, ViroCameraTransformEvent, ViroPlatformUpdateEvent, ViroCameraTransform, ViroExitViroEvent, ViroErrorEvent, ViroAnimationStartEvent, ViroAnimationFinishEvent, ViroLoadStartEvent, ViroLoadEndEvent, ViroLoadErrorEvent, ViroVideoBufferStartEvent, ViroVideoBufferEndEvent, ViroVideoUpdateTimeEvent, ViroVideoErrorEvent, ViroVideoFinishEvent, ViroAnimatedComponentStartEvent, ViroAnimatedComponentFinishEvent, ViroARAnchorRemovedEvent, ViroARAnchorUpdatedEvent, ViroARAnchorFoundEvent, ViroAnchor, ViroAnchorFoundMap, ViroAnchorUpdatedMap, ViroPlaneUpdatedMap, ViroPlaneUpdatedEvent, ViroARPlaneSizes, ViroCameraARHitTestEvent, ViroCameraARHitTest, ViroARHitTestResult, ViroARPointCloudUpdateEvent, ViroARPointCloud, ViroTrackingUpdatedEvent, ViroTrackingState, ViroTrackingReason, ViroAmbientLightUpdateEvent, ViroAmbientLightInfo, ViroWorldOrigin, ViroNativeTransformUpdateEvent, ViroControllerStatusEvent, ViroControllerStatus, ViroPortalEnterEvent, ViroPortalExitEvent, ViroSoundFinishEvent, ViroTextStyle, ViroStyle, ViroMaterial, ViroShaderModifiers, ViroShaderUniform, ViroShaderModifier, VIRO_VERSION, ViroProvider, ViroCloudAnchorState, ViroCloudAnchorProvider, ViroCloudAnchor, ViroHostCloudAnchorResult, ViroResolveCloudAnchorResult, ViroCloudAnchorStateChangeEvent, ViroGeospatialAnchorProvider, ViroEarthTrackingState, ViroVPSAvailability, ViroGeospatialAnchorType, ViroQuaternion, ViroGeospatialPose, ViroGeospatialAnchor, ViroGeospatialSupportResult, ViroEarthTrackingStateResult, ViroGeospatialPoseResult, ViroVPSAvailabilityResult, ViroCreateGeospatialAnchorResult, ViroMonocularDepthSupportResult, ViroMonocularDepthModelAvailableResult, ViroMonocularDepthPreferenceResult, ViroJoint, ViroHandJoints, ViroHandPinchEvent, ViroHandUpdateEvent, StudioSceneNavigator, StudioARScene, ViroVisionOSModule, isVisionOS, enterImmersiveSpace, exitImmersiveSpace, };
80
- export type { VRModuleOpenXRType };
81
+ export { ViroARImageMarker, ViroARObjectMarker, ViroARTrackingTargets, ViroARPlane, ViroARPlaneSelector, ViroARScene, ViroARSceneNavigator, ViroBox, ViroButton, ViroCamera, ViroController, ViroVirtualJoystick, ViroVirtualButton, ViroGameLoop, ViroGameLoopUtils, useGameLoop, useLateUpdate, useFixedUpdate, ViroDirectionalLight, ViroFlexView, ViroGeometry, ViroLightingEnvironment, ViroImage, ViroMaterials, ViroARCamera, ViroMaterialVideo, ViroCameraTexture, ViroObjectDetector, ViroNode, ViroOmniLight, ViroOrbitCamera, ViroParticleEmitter, ViroPolygon, ViroPolyline, ViroPortal, ViroPortalScene, ViroQuad, ViroScene, ViroSurface, ViroSceneNavigator, ViroSkyBox, ViroAnimations, Viro3DObject, Viro360Image, Viro360Video, ViroAnimatedImage, ViroAmbientLight, ViroAnimatedComponent, ViroSound, ViroSoundField, ViroSpatialSound, ViroSphere, ViroSpinner, ViroSpotLight, ViroText, ViroVideo, ViroVRSceneNavigator, ViroXRSceneNavigator, ViroQuestEntryPoint, VRQuestNavigatorBridge, VRModuleOpenXR, useVRViewTag, exitVRScene, setPassthroughStyle, Viro3DSceneNavigator, StreamingAudioManager, hasOpenXRSupport, isQuest, useAnySourceHover, useAnySourcePressed, ViroARTrackingReasonConstants, ViroRecordingErrorConstants, ViroTrackingStateConstants, polarToCartesian, polarToCartesianActual, isARSupportedOnDevice, requestRequiredPermissions, checkPermissions, latLngToMercator, gpsToArWorld, ViroARSupportResponse, ViroPermissionsResult, ViroPermission, ViroHoverEvent, ViroClickEvent, ViroClickStateEvent, ViroClickStateTypes, ViroTouchEvent, ViroScrollEvent, ViroSwipeEvent, ViroFuseEvent, ViroPinchEvent, ViroPinchStateTypes, ViroRotateEvent, ViroRotateStateTypes, ViroDragEvent, ViroPlatformEvent, ViroCollisionEvent, ViroPlatformInfo, ViroCameraTransformEvent, ViroPlatformUpdateEvent, ViroCameraTransform, ViroExitViroEvent, ViroErrorEvent, ViroAnimationStartEvent, ViroAnimationFinishEvent, ViroLoadStartEvent, ViroLoadEndEvent, ViroLoadErrorEvent, ViroVideoBufferStartEvent, ViroVideoBufferEndEvent, ViroVideoUpdateTimeEvent, ViroVideoErrorEvent, ViroVideoFinishEvent, ViroAnimatedComponentStartEvent, ViroAnimatedComponentFinishEvent, ViroARAnchorRemovedEvent, ViroARAnchorUpdatedEvent, ViroARAnchorFoundEvent, ViroAnchor, ViroAnchorFoundMap, ViroAnchorUpdatedMap, ViroPlaneUpdatedMap, ViroPlaneUpdatedEvent, ViroARPlaneSizes, ViroCameraARHitTestEvent, ViroCameraARHitTest, ViroARHitTestResult, ViroARPointCloudUpdateEvent, ViroARPointCloud, ViroTrackingUpdatedEvent, ViroTrackingState, ViroTrackingReason, ViroAmbientLightUpdateEvent, ViroAmbientLightInfo, ViroWorldOrigin, ViroNativeTransformUpdateEvent, ViroControllerStatusEvent, ViroControllerStatus, ViroPortalEnterEvent, ViroPortalExitEvent, ViroSoundFinishEvent, ViroTextStyle, ViroStyle, ViroMaterial, ViroShaderModifiers, ViroShaderUniform, ViroShaderModifier, VIRO_VERSION, ViroProvider, ViroCloudAnchorState, ViroCloudAnchorProvider, ViroCloudAnchor, ViroHostCloudAnchorResult, ViroResolveCloudAnchorResult, ViroCloudAnchorStateChangeEvent, ViroGeospatialAnchorProvider, ViroEarthTrackingState, ViroVPSAvailability, ViroGeospatialAnchorType, ViroQuaternion, ViroGeospatialPose, ViroGeospatialAnchor, ViroGeospatialSupportResult, ViroEarthTrackingStateResult, ViroGeospatialPoseResult, ViroVPSAvailabilityResult, ViroCreateGeospatialAnchorResult, ViroMonocularDepthSupportResult, ViroMonocularDepthModelAvailableResult, ViroMonocularDepthPreferenceResult, ViroJoint, ViroHandJoints, ViroHandPinchEvent, ViroHandUpdateEvent, StudioSceneNavigator, StudioARScene, ViroVisionOSModule, isVisionOS, enterImmersiveSpace, exitImmersiveSpace, };
82
+ export type { VRModuleOpenXRType, ViroPassthroughStyle };
81
83
  export type { ImmersiveSpaceStyle } from "./components/VisionOS/ViroVisionOSModule";
82
84
  export type { StudioSceneResponse, StudioAsset, StudioAnimation, StudioCollisionBinding, StudioSceneFunction, StudioSceneMeta, StudioProjectMeta, } from "./components/Studio";