@reactvision/react-viro 2.57.0 → 2.57.3
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.
- package/README.md +8 -0
- package/android/react_viro/react_viro-release.aar +0 -0
- package/android/viro_renderer/viro_renderer-release.aar +0 -0
- package/components/AR/ViroARPlane.tsx +1 -4
- package/components/AR/ViroARPlaneSelector.tsx +10 -5
- package/components/AR/ViroARScene.tsx +2 -4
- package/components/AR/ViroARSceneNavigator.tsx +11 -3
- package/components/Studio/StudioARScene.tsx +243 -48
- package/components/Studio/StudioSceneNavigator.tsx +15 -0
- package/components/Studio/VRTStudioModule.ts +10 -0
- package/components/Studio/domain/StudioSounds.tsx +46 -0
- package/components/Studio/domain/apiRequestHelpers.ts +612 -0
- package/components/Studio/domain/collisionBindingsRuntime.ts +17 -2
- package/components/Studio/domain/defaultApiRequestExecutor.ts +61 -0
- package/components/Studio/domain/expressionEvaluator.ts +603 -0
- package/components/Studio/domain/sceneNavigationHandler.ts +770 -20
- package/components/Studio/domain/soundManager.ts +141 -0
- package/components/Studio/domain/utils.ts +50 -0
- package/components/Studio/domain/variableStore.ts +74 -0
- package/components/Studio/domain/viroNodeFactory.tsx +175 -44
- package/components/Studio/domain/visibilityStore.ts +66 -0
- package/components/Studio/index.ts +1 -0
- package/components/Studio/types.ts +178 -1
- package/components/Utilities/VRModuleOpenXR.ts +35 -0
- package/components/Utilities/ViroVersion.ts +1 -1
- package/components/ViroAnimatedImage.tsx +1 -0
- package/components/ViroFlexView.tsx +1 -0
- package/components/ViroImage.tsx +1 -0
- package/components/ViroObjectDetector.tsx +13 -5
- package/components/ViroParticleEmitter.tsx +2 -0
- package/components/ViroPolygon.tsx +2 -1
- package/components/ViroQuad.tsx +2 -1
- package/components/ViroSurface.tsx +1 -0
- package/components/ViroVideo.tsx +1 -0
- package/components/ViroXRSceneNavigator.tsx +8 -0
- package/dist/components/AR/ViroARPlane.d.ts +1 -1
- package/dist/components/AR/ViroARPlane.js +1 -5
- package/dist/components/AR/ViroARPlaneSelector.d.ts +1 -1
- package/dist/components/AR/ViroARPlaneSelector.js +10 -5
- package/dist/components/AR/ViroARScene.d.ts +1 -1
- package/dist/components/AR/ViroARScene.js +2 -5
- package/dist/components/AR/ViroARSceneNavigator.d.ts +11 -3
- package/dist/components/Studio/StudioARScene.d.ts +3 -0
- package/dist/components/Studio/StudioARScene.js +142 -15
- package/dist/components/Studio/StudioSceneNavigator.js +14 -0
- package/dist/components/Studio/VRTStudioModule.d.ts +6 -0
- package/dist/components/Studio/VRTStudioModule.js +10 -0
- package/dist/components/Studio/domain/StudioSounds.d.ts +11 -0
- package/dist/components/Studio/domain/StudioSounds.js +69 -0
- package/dist/components/Studio/domain/apiRequestHelpers.d.ts +180 -0
- package/dist/components/Studio/domain/apiRequestHelpers.js +496 -0
- package/dist/components/Studio/domain/collisionBindingsRuntime.d.ts +3 -1
- package/dist/components/Studio/domain/collisionBindingsRuntime.js +4 -3
- package/dist/components/Studio/domain/defaultApiRequestExecutor.d.ts +14 -0
- package/dist/components/Studio/domain/defaultApiRequestExecutor.js +58 -0
- package/dist/components/Studio/domain/expressionEvaluator.d.ts +108 -0
- package/dist/components/Studio/domain/expressionEvaluator.js +520 -0
- package/dist/components/Studio/domain/sceneNavigationHandler.d.ts +35 -8
- package/dist/components/Studio/domain/sceneNavigationHandler.js +564 -22
- package/dist/components/Studio/domain/soundManager.d.ts +52 -0
- package/dist/components/Studio/domain/soundManager.js +118 -0
- package/dist/components/Studio/domain/utils.d.ts +16 -0
- package/dist/components/Studio/domain/utils.js +48 -0
- package/dist/components/Studio/domain/variableStore.d.ts +21 -0
- package/dist/components/Studio/domain/variableStore.js +65 -0
- package/dist/components/Studio/domain/viroNodeFactory.d.ts +4 -9
- package/dist/components/Studio/domain/viroNodeFactory.js +84 -25
- package/dist/components/Studio/domain/visibilityStore.d.ts +33 -0
- package/dist/components/Studio/domain/visibilityStore.js +66 -0
- package/dist/components/Studio/index.d.ts +1 -1
- package/dist/components/Studio/types.d.ts +150 -1
- package/dist/components/Utilities/VRModuleOpenXR.d.ts +19 -0
- package/dist/components/Utilities/VRModuleOpenXR.js +16 -0
- package/dist/components/Utilities/ViroVersion.d.ts +1 -1
- package/dist/components/Utilities/ViroVersion.js +1 -1
- package/dist/components/ViroAnimatedImage.js +1 -0
- package/dist/components/ViroFlexView.js +1 -0
- package/dist/components/ViroImage.js +1 -0
- package/dist/components/ViroObjectDetector.d.ts +13 -5
- package/dist/components/ViroObjectDetector.js +13 -5
- package/dist/components/ViroParticleEmitter.js +2 -0
- package/dist/components/ViroPolygon.js +1 -0
- package/dist/components/ViroQuad.js +1 -0
- package/dist/components/ViroSurface.js +1 -0
- package/dist/components/ViroVideo.js +1 -0
- package/dist/components/ViroXRSceneNavigator.d.ts +8 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -1
- package/dist/plugins/withViroAndroid.js +18 -0
- package/index.ts +4 -3
- package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreCoreMLSemanticsResources.bundle/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreResources.bundle/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARFrameiOS.h +8 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSessioniOS.h +14 -3
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROFrontCameraProvider.h +34 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROViewAR.h +3 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Shaders.dat +1 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/ViroKit +0 -0
- package/ios/dist/lib/libViroReact.a +0 -0
- package/package.json +11 -11
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { StudioAsset } from "../types";
|
|
2
|
+
import { KeyedListeners, isDev } from "./utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-scene visibility store, keyed by scene asset placement id. Seeded from
|
|
6
|
+
* each asset's author-time `hidden_on_load` default at scene load; Set
|
|
7
|
+
* Visibility actions then flip the live value. Toggle reads the current value
|
|
8
|
+
* here, never the author default.
|
|
9
|
+
*
|
|
10
|
+
* Listeners are per-asset (unlike the global variable store) so a Set
|
|
11
|
+
* Visibility on one object repaints only that node, not the whole scene. Node
|
|
12
|
+
* factories subscribe to their own asset id.
|
|
13
|
+
*/
|
|
14
|
+
export class StudioVisibilityStore {
|
|
15
|
+
private visible = new Map<string, boolean>();
|
|
16
|
+
private listeners = new KeyedListeners();
|
|
17
|
+
|
|
18
|
+
/** Current visibility; defaults to visible for assets never seeded/set. */
|
|
19
|
+
isVisible(assetId: string): boolean {
|
|
20
|
+
return this.visible.get(assetId) ?? true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Subscribe to changes for one asset; returns an unsubscribe fn. */
|
|
24
|
+
subscribe(assetId: string, listener: () => void): () => void {
|
|
25
|
+
return this.listeners.subscribe(assetId, listener);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Initialise-if-absent from author-time defaults (idempotent, strict-mode safe). */
|
|
29
|
+
seed(assets: StudioAsset[]): void {
|
|
30
|
+
for (const asset of assets) {
|
|
31
|
+
if (!asset?.id) continue;
|
|
32
|
+
if (this.visible.has(asset.id)) continue;
|
|
33
|
+
this.visible.set(asset.id, !asset.hidden_on_load);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Apply a Set Visibility action. TOGGLE flips the live value; VISIBLE/HIDDEN
|
|
39
|
+
* set it absolutely. No-op writes don't wake subscribers.
|
|
40
|
+
*/
|
|
41
|
+
apply(assetId: string, state: "VISIBLE" | "HIDDEN" | "TOGGLE"): void {
|
|
42
|
+
const next =
|
|
43
|
+
state === "TOGGLE" ? !this.isVisible(assetId) : state === "VISIBLE";
|
|
44
|
+
if (this.visible.get(assetId) === next) return;
|
|
45
|
+
this.visible.set(assetId, next);
|
|
46
|
+
if (isDev()) {
|
|
47
|
+
console.log(`[Studio] Visibility "${assetId}" =`, next);
|
|
48
|
+
}
|
|
49
|
+
this.listeners.notify(assetId);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Re-initialise for a new scene: replace all values from author-time
|
|
54
|
+
* defaults, THEN notify every subscribed asset so mounted nodes re-read.
|
|
55
|
+
* Order matters — notifying before re-seeding would briefly surface the
|
|
56
|
+
* visible default for an asset that starts hidden.
|
|
57
|
+
*/
|
|
58
|
+
reseed(assets: StudioAsset[]): void {
|
|
59
|
+
this.visible.clear();
|
|
60
|
+
for (const asset of assets) {
|
|
61
|
+
if (!asset?.id) continue;
|
|
62
|
+
this.visible.set(asset.id, !asset.hidden_on_load);
|
|
63
|
+
}
|
|
64
|
+
this.listeners.notifyAll();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -24,13 +24,159 @@ export interface StudioProjectMeta {
|
|
|
24
24
|
occlusion_mode: "NONE" | "PEOPLEONLY" | "DEPTHBASED";
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* One ordered step of a Sequence: an ACTION (runs a function), a WAIT (timed
|
|
29
|
+
* pause), or a STOP (explicit terminal — the run halts here).
|
|
30
|
+
*/
|
|
31
|
+
export interface StudioSequenceStep {
|
|
32
|
+
id: string;
|
|
33
|
+
step_order: number;
|
|
34
|
+
step_type: "ACTION" | "WAIT" | "STOP";
|
|
35
|
+
duration_ms: number | null; // set for WAIT
|
|
36
|
+
function_id: string | null; // set for ACTION
|
|
37
|
+
function: StudioSceneFunction | null; // resolved child for ACTION; null for WAIT/STOP
|
|
38
|
+
// false (default) = wait for this step's effect to finish before the next
|
|
39
|
+
// step; true = fire-and-forget. Ignored for instant/terminal kinds.
|
|
40
|
+
advance_immediately: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface StudioSequence {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string | null;
|
|
46
|
+
steps: StudioSequenceStep[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Scene-level variable declaration. Runtime state lives in StudioVariableStore. */
|
|
50
|
+
export interface StudioSceneVariable {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
type: "BOOLEAN" | "NUMBER" | "STRING";
|
|
54
|
+
initial_value: boolean | number | string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* One ordered predicate arm of a BRANCH. Variable names/types are joined from
|
|
59
|
+
* project_variables so they follow renames. The arm is an owned, headless
|
|
60
|
+
* sequence run like a nested sequence.
|
|
61
|
+
*/
|
|
62
|
+
export interface StudioBranchCondition {
|
|
63
|
+
id: string;
|
|
64
|
+
eval_order: number;
|
|
65
|
+
variable_id: string;
|
|
66
|
+
variable_name: string;
|
|
67
|
+
variable_type: "BOOLEAN" | "NUMBER" | "STRING";
|
|
68
|
+
comparison:
|
|
69
|
+
| "EQUALS"
|
|
70
|
+
| "NOT_EQUALS"
|
|
71
|
+
| "GREATER_THAN"
|
|
72
|
+
| "LESS_THAN"
|
|
73
|
+
| "GREATER_OR_EQUAL"
|
|
74
|
+
| "LESS_OR_EQUAL"
|
|
75
|
+
| "LIKE"
|
|
76
|
+
| "ILIKE";
|
|
77
|
+
compare_literal: boolean | number | string | null;
|
|
78
|
+
compare_variable_id: string | null;
|
|
79
|
+
compare_variable_name: string | null;
|
|
80
|
+
compare_variable_type: "BOOLEAN" | "NUMBER" | "STRING" | null;
|
|
81
|
+
sequence: StudioSequence;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* BRANCH payload. Conditions are evaluated in eval_order (first match wins),
|
|
86
|
+
* falling through to the optional no-match arm. Arms are owned, headless
|
|
87
|
+
* sequences run like nested sequences.
|
|
88
|
+
*/
|
|
89
|
+
export interface StudioSceneBranch {
|
|
90
|
+
id: string;
|
|
91
|
+
conditions: StudioBranchCondition[];
|
|
92
|
+
no_match_sequence: StudioSequence | null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* GROUP payload. Owns N lanes, each an owned headless sequence run like a
|
|
97
|
+
* nested sequence. Lanes run concurrently; the group completes when all lanes
|
|
98
|
+
* complete (barrier join).
|
|
99
|
+
*/
|
|
100
|
+
export interface StudioSceneGroup {
|
|
101
|
+
id: string;
|
|
102
|
+
lanes: { lane_order: number; sequence: StudioSequence }[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** One response->variable binding of an API_REQUEST function. */
|
|
106
|
+
export interface StudioApiRequestBinding {
|
|
107
|
+
id: string;
|
|
108
|
+
source: "BODY" | "STATUS" | "OK" | "ERROR_MESSAGE";
|
|
109
|
+
selector: string | null;
|
|
110
|
+
variable_id: string;
|
|
111
|
+
variable_name: string;
|
|
112
|
+
variable_type: "BOOLEAN" | "NUMBER" | "STRING";
|
|
113
|
+
bind_order: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* API_REQUEST payload. The HTTP call executes server-side through the
|
|
118
|
+
* platform egress proxy (the client only ever sends the function id plus
|
|
119
|
+
* current variable values); connection_id is an opaque server-side
|
|
120
|
+
* reference. Arms are owned, headless sequences run like nested sequences.
|
|
121
|
+
*/
|
|
122
|
+
export interface StudioSceneApiRequest {
|
|
123
|
+
id: string;
|
|
124
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
125
|
+
url_template: string;
|
|
126
|
+
headers: { key: string; value_template: string }[];
|
|
127
|
+
body_template: string | null;
|
|
128
|
+
timeout_ms: number;
|
|
129
|
+
connection_id: string | null;
|
|
130
|
+
bindings: StudioApiRequestBinding[];
|
|
131
|
+
success_sequence: StudioSequence | null;
|
|
132
|
+
failure_sequence: StudioSequence | null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Outcome envelope an API-request executor resolves with. */
|
|
136
|
+
export interface StudioApiRequestOutcome {
|
|
137
|
+
ok: boolean;
|
|
138
|
+
status: number | null;
|
|
139
|
+
body?: unknown;
|
|
140
|
+
error_code?: string | null;
|
|
141
|
+
error_message?: string | null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Host-app transport for API_REQUEST functions: StudioGo calls the
|
|
146
|
+
* scene-api-request edge function with the user JWT; production Viro apps
|
|
147
|
+
* call it with their X-API-Key. Must resolve with an outcome (reject only on
|
|
148
|
+
* transport failure).
|
|
149
|
+
*/
|
|
150
|
+
export type StudioApiRequestExecutor = (
|
|
151
|
+
functionId: string,
|
|
152
|
+
variables: Record<string, boolean | number | string>,
|
|
153
|
+
) => Promise<StudioApiRequestOutcome>;
|
|
154
|
+
|
|
27
155
|
export interface StudioSceneFunction {
|
|
28
156
|
id: string;
|
|
29
157
|
scene: string;
|
|
30
|
-
function_type:
|
|
158
|
+
function_type:
|
|
159
|
+
| "NAVIGATION"
|
|
160
|
+
| "ALERT"
|
|
161
|
+
| "ANIMATION"
|
|
162
|
+
| "SEQUENCE"
|
|
163
|
+
| "SET_VARIABLE"
|
|
164
|
+
| "BRANCH"
|
|
165
|
+
| "API_REQUEST"
|
|
166
|
+
| "SET_VISIBILITY"
|
|
167
|
+
| "SOUND"
|
|
168
|
+
| "GROUP";
|
|
31
169
|
navigation: string | null;
|
|
32
170
|
alert: string | null;
|
|
33
171
|
animation: string | null;
|
|
172
|
+
sequence: string | null;
|
|
173
|
+
set_variable: string | null;
|
|
174
|
+
branch: string | null;
|
|
175
|
+
api_request: string | null;
|
|
176
|
+
set_visibility: string | null;
|
|
177
|
+
sound: string | null;
|
|
178
|
+
// Named group_fn because `group` is a reserved SQL keyword.
|
|
179
|
+
group_fn: string | null;
|
|
34
180
|
scene_navigation: { id: string; navigate_to: string } | null;
|
|
35
181
|
scene_alert: {
|
|
36
182
|
id: string;
|
|
@@ -44,6 +190,33 @@ export interface StudioSceneFunction {
|
|
|
44
190
|
delay_ms: number | null;
|
|
45
191
|
properties: Record<string, unknown>;
|
|
46
192
|
} | null;
|
|
193
|
+
scene_sequence: StudioSequence | null;
|
|
194
|
+
/** name/type are joined from the target scene_variables row, so they follow renames. */
|
|
195
|
+
scene_set_variable: {
|
|
196
|
+
id: string;
|
|
197
|
+
variable_id: string;
|
|
198
|
+
name: string;
|
|
199
|
+
type: "BOOLEAN" | "NUMBER" | "STRING";
|
|
200
|
+
expression: string;
|
|
201
|
+
} | null;
|
|
202
|
+
scene_branch: StudioSceneBranch | null;
|
|
203
|
+
scene_api_request: StudioSceneApiRequest | null;
|
|
204
|
+
scene_set_visibility: {
|
|
205
|
+
id: string;
|
|
206
|
+
target_asset_id: string;
|
|
207
|
+
state: "VISIBLE" | "HIDDEN" | "TOGGLE";
|
|
208
|
+
} | null;
|
|
209
|
+
scene_sound: {
|
|
210
|
+
id: string;
|
|
211
|
+
action: "PLAY" | "STOP";
|
|
212
|
+
audio_asset_id: string | null;
|
|
213
|
+
audio_url: string | null;
|
|
214
|
+
target_asset_id: string | null;
|
|
215
|
+
volume: number;
|
|
216
|
+
loop: boolean;
|
|
217
|
+
stop_other_sounds: boolean;
|
|
218
|
+
} | null;
|
|
219
|
+
scene_group: StudioSceneGroup | null;
|
|
47
220
|
}
|
|
48
221
|
|
|
49
222
|
export interface StudioAsset {
|
|
@@ -63,6 +236,8 @@ export interface StudioAsset {
|
|
|
63
236
|
latitude: number | null;
|
|
64
237
|
longitude: number | null;
|
|
65
238
|
is_draggable: boolean;
|
|
239
|
+
/** Author-time "hidden on start"; the runtime seeds visibility from it. */
|
|
240
|
+
hidden_on_load: boolean | null;
|
|
66
241
|
trigger_image_url: string | null;
|
|
67
242
|
trigger_image_orientation: "Up" | "Down" | "Left" | "Right" | null;
|
|
68
243
|
trigger_image_physical_width_m: number | null;
|
|
@@ -149,6 +324,8 @@ export interface StudioSceneResponse {
|
|
|
149
324
|
collision_bindings: StudioCollisionBinding[];
|
|
150
325
|
animations: StudioAnimation[];
|
|
151
326
|
functions: StudioSceneFunction[];
|
|
327
|
+
/** Absent in responses from backends predating the Variables feature. */
|
|
328
|
+
variables?: StudioSceneVariable[];
|
|
152
329
|
meta: { request_id: string };
|
|
153
330
|
}
|
|
154
331
|
|
|
@@ -15,8 +15,43 @@ export function exitVRScene(): void {
|
|
|
15
15
|
export type VRModuleOpenXRType = {
|
|
16
16
|
recenterTracking?: (viewTag: number) => void;
|
|
17
17
|
setPassthroughEnabled?: (viewTag: number, enabled: boolean) => void;
|
|
18
|
+
setPassthroughStyle?: (
|
|
19
|
+
viewTag: number,
|
|
20
|
+
opacity: number,
|
|
21
|
+
edgeR: number,
|
|
22
|
+
edgeG: number,
|
|
23
|
+
edgeB: number,
|
|
24
|
+
edgeA: number
|
|
25
|
+
) => void;
|
|
18
26
|
};
|
|
19
27
|
|
|
28
|
+
/** Options for {@link setPassthroughStyle}. All channels are normalized [0,1]. */
|
|
29
|
+
export type ViroPassthroughStyle = {
|
|
30
|
+
/** Texture opacity factor [0,1]. Default 1 (fully opaque passthrough). */
|
|
31
|
+
opacity?: number;
|
|
32
|
+
/** Edge-highlight colour [r,g,b,a]. Alpha 0 (default) disables the edge effect. */
|
|
33
|
+
edgeColor?: [number, number, number, number];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Style the Quest passthrough layer (XR_FB_passthrough). No-op off-Quest.
|
|
38
|
+
*
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const viewTag = useVRViewTag();
|
|
41
|
+
* if (viewTag != null) {
|
|
42
|
+
* setPassthroughStyle(viewTag, { opacity: 0.8, edgeColor: [0, 1, 1, 1] });
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function setPassthroughStyle(
|
|
47
|
+
viewTag: number,
|
|
48
|
+
style: ViroPassthroughStyle
|
|
49
|
+
): void {
|
|
50
|
+
const opacity = style.opacity ?? 1;
|
|
51
|
+
const [r, g, b, a] = style.edgeColor ?? [0, 0, 0, 0];
|
|
52
|
+
VRModuleOpenXR?.setPassthroughStyle?.(viewTag, opacity, r, g, b, a);
|
|
53
|
+
}
|
|
54
|
+
|
|
20
55
|
/**
|
|
21
56
|
* Typed reference to the VRModuleOpenXR native module.
|
|
22
57
|
* undefined when not running on Meta Quest (no-op calls are safe via optional chaining).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VIRO_VERSION = "2.57.
|
|
1
|
+
export const VIRO_VERSION = "2.57.3";
|
|
@@ -170,6 +170,7 @@ export class ViroAnimatedImage extends ViroBase<Props> {
|
|
|
170
170
|
nativeProps.style = [this.props.style];
|
|
171
171
|
nativeProps.onHoverViro = this._onHover;
|
|
172
172
|
nativeProps.onClickViro = this._onClickState;
|
|
173
|
+
nativeProps.onClick = undefined;
|
|
173
174
|
nativeProps.onTouchViro = this._onTouch;
|
|
174
175
|
nativeProps.onScrollViro = this._onScroll;
|
|
175
176
|
nativeProps.onSwipeViro = this._onSwipe;
|
|
@@ -59,6 +59,7 @@ export class ViroFlexView extends ViroBase<Props> {
|
|
|
59
59
|
nativeProps.transformBehaviors = transformBehaviors;
|
|
60
60
|
nativeProps.onHoverViro = this._onHover;
|
|
61
61
|
nativeProps.onClickViro = this._onClickState;
|
|
62
|
+
nativeProps.onClick = undefined;
|
|
62
63
|
nativeProps.onTouchViro = this._onTouch;
|
|
63
64
|
nativeProps.onScrollViro = this._onScroll;
|
|
64
65
|
nativeProps.onSwipeViro = this._onSwipe;
|
package/components/ViroImage.tsx
CHANGED
|
@@ -142,6 +142,7 @@ export class ViroImage extends ViroBase<Props> {
|
|
|
142
142
|
nativeProps.style = [this.props.style];
|
|
143
143
|
nativeProps.onHoverViro = this._onHover;
|
|
144
144
|
nativeProps.onClickViro = this._onClickState;
|
|
145
|
+
nativeProps.onClick = undefined;
|
|
145
146
|
nativeProps.onTouchViro = this._onTouch;
|
|
146
147
|
nativeProps.onScrollViro = this._onScroll;
|
|
147
148
|
nativeProps.onSwipeViro = this._onSwipe;
|
|
@@ -146,11 +146,19 @@ const VRTObjectDetectorView = requireNativeComponent<any>("VRTObjectDetectorView
|
|
|
146
146
|
/**
|
|
147
147
|
* ViroObjectDetector — on-device open-vocabulary object detection powered by YOLOE.
|
|
148
148
|
*
|
|
149
|
-
* Runs
|
|
150
|
-
*
|
|
151
|
-
* fires `onDetection` with labels, normalized
|
|
152
|
-
* `screenBoundingBox` (dp) at up to `maxFPS`.
|
|
153
|
-
*
|
|
149
|
+
* Runs in AR and on Meta Quest:
|
|
150
|
+
* - **Phone AR**: shares the camera feed of the enclosing `ViroARSceneNavigator`
|
|
151
|
+
* (no separate camera session) and fires `onDetection` with labels, normalized
|
|
152
|
+
* bounding boxes, and an on-screen `screenBoundingBox` (dp) at up to `maxFPS`.
|
|
153
|
+
* - **Meta Quest 3 / 3S** (Horizon OS v74+): when mounted in a Quest MR scene
|
|
154
|
+
* (under `ViroXRSceneNavigator`), it captures the headset camera via the Meta
|
|
155
|
+
* Passthrough Camera API and runs the same YOLOE pipeline. Requires the
|
|
156
|
+
* `horizonos.permission.HEADSET_CAMERA` runtime permission. v1 emits `label` +
|
|
157
|
+
* normalized `boundingBox` only — `screenBoundingBox` and `worldPosition` are
|
|
158
|
+
* not provided on Quest yet (they need camera extrinsics).
|
|
159
|
+
*
|
|
160
|
+
* Mount it as a child or sibling of the scene navigator; it renders nothing itself,
|
|
161
|
+
* so give it `width: 0, height: 0`.
|
|
154
162
|
*
|
|
155
163
|
* @example
|
|
156
164
|
* ```tsx
|
|
@@ -261,6 +261,7 @@ export class ViroParticleEmitter extends React.Component<Props, State> {
|
|
|
261
261
|
: undefined;
|
|
262
262
|
// Create native props object.
|
|
263
263
|
let nativeProps = Object.assign({} as any, this.props);
|
|
264
|
+
nativeProps.onClick = undefined;
|
|
264
265
|
nativeProps.position = this.state.propsPositionState;
|
|
265
266
|
nativeProps.onNativeTransformDelegateViro = transformDelegate;
|
|
266
267
|
nativeProps.hasTransformDelegate =
|
|
@@ -344,6 +345,7 @@ export class ViroParticleEmitter extends React.Component<Props, State> {
|
|
|
344
345
|
};
|
|
345
346
|
nativeProps.particleAppearance.rotation = newAppearanceRotMod;
|
|
346
347
|
}
|
|
348
|
+
nativeProps.onClick = undefined;
|
|
347
349
|
nativeProps.ref = (component: ViroNativeRef) => {
|
|
348
350
|
this._component = component;
|
|
349
351
|
};
|
|
@@ -60,7 +60,7 @@ type Props = {
|
|
|
60
60
|
* that texture partially over the entire surface.
|
|
61
61
|
*/
|
|
62
62
|
uvCoordinates?: ViroUVCoordinate;
|
|
63
|
-
arShadowReceiver?: boolean
|
|
63
|
+
arShadowReceiver?: boolean;
|
|
64
64
|
style?: ViroStyle;
|
|
65
65
|
};
|
|
66
66
|
|
|
@@ -104,6 +104,7 @@ export class ViroPolygon extends ViroBase<Props> {
|
|
|
104
104
|
nativeProps.style = [this.props.style];
|
|
105
105
|
nativeProps.onHoverViro = this._onHover;
|
|
106
106
|
nativeProps.onClickViro = this._onClickState;
|
|
107
|
+
nativeProps.onClick = undefined;
|
|
107
108
|
nativeProps.onTouchViro = this._onTouch;
|
|
108
109
|
nativeProps.onScrollViro = this._onScroll;
|
|
109
110
|
nativeProps.onSwipeViro = this._onSwipe;
|
package/components/ViroQuad.tsx
CHANGED
|
@@ -18,7 +18,7 @@ import { checkMisnamedProps } from "./Utilities/ViroProps";
|
|
|
18
18
|
import { ViroBase } from "./ViroBase";
|
|
19
19
|
|
|
20
20
|
type Props = {
|
|
21
|
-
arShadowReceiver?: boolean
|
|
21
|
+
arShadowReceiver?: boolean;
|
|
22
22
|
uvCoordinates?: ViroUVCoordinate[];
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -62,6 +62,7 @@ export class ViroQuad extends ViroBase<Props> {
|
|
|
62
62
|
nativeProps.style = [this.props.style];
|
|
63
63
|
nativeProps.onHoverViro = this._onHover;
|
|
64
64
|
nativeProps.onClickViro = this._onClickState;
|
|
65
|
+
nativeProps.onClick = undefined;
|
|
65
66
|
nativeProps.onTouchViro = this._onTouch;
|
|
66
67
|
nativeProps.onScrollViro = this._onScroll;
|
|
67
68
|
nativeProps.onSwipeViro = this._onSwipe;
|
|
@@ -65,6 +65,7 @@ export class ViroSurface extends ViroBase<Props> {
|
|
|
65
65
|
nativeProps.style = [this.props.style];
|
|
66
66
|
nativeProps.onHoverViro = this._onHover;
|
|
67
67
|
nativeProps.onClickViro = this._onClickState;
|
|
68
|
+
nativeProps.onClick = undefined;
|
|
68
69
|
nativeProps.onTouchViro = this._onTouch;
|
|
69
70
|
nativeProps.onScrollViro = this._onScroll;
|
|
70
71
|
nativeProps.onSwipeViro = this._onSwipe;
|
package/components/ViroVideo.tsx
CHANGED
|
@@ -131,6 +131,7 @@ export class ViroVideo extends ViroBase<Props> {
|
|
|
131
131
|
nativeProps.onUpdateTimeViro = this._onUpdateTime;
|
|
132
132
|
nativeProps.onHoverViro = this._onHover;
|
|
133
133
|
nativeProps.onClickViro = this._onClickState;
|
|
134
|
+
nativeProps.onClick = undefined;
|
|
134
135
|
nativeProps.onTouchViro = this._onTouch;
|
|
135
136
|
nativeProps.onScrollViro = this._onScroll;
|
|
136
137
|
nativeProps.onSwipeViro = this._onSwipe;
|
|
@@ -59,6 +59,14 @@ type Props = ViewProps & {
|
|
|
59
59
|
* On Quest, this scene is forwarded to VRActivity via VRQuestNavigatorBridge
|
|
60
60
|
* rather than rendered inline, because OpenXR exclusive display requires the
|
|
61
61
|
* VR intent category on the host Activity.
|
|
62
|
+
*
|
|
63
|
+
* The scene root may be either:
|
|
64
|
+
* - `ViroScene` → fully-virtual VR.
|
|
65
|
+
* - `ViroARScene` → mixed reality: passthrough is enabled automatically and
|
|
66
|
+
* real-time plane detection (XR_EXT_plane_detection, Quest 3 / 3S) drives
|
|
67
|
+
* `onAnchorFound` and `ViroARPlane`, exactly as on phone AR. A single
|
|
68
|
+
* AR-rooted `initialScene` therefore runs on phones (ARCore) and Quest (OpenXR)
|
|
69
|
+
* with no per-platform changes. See docs/QUEST_SETUP.md §7b.
|
|
62
70
|
*/
|
|
63
71
|
vrInitialScene?: SceneFactory;
|
|
64
72
|
|
|
@@ -25,6 +25,6 @@ export declare class ViroARPlane extends ViroBase<Props> {
|
|
|
25
25
|
_onAnchorFound: (event: NativeSyntheticEvent<ViroARAnchorFoundEvent>) => void;
|
|
26
26
|
_onAnchorUpdated: (event: NativeSyntheticEvent<ViroARAnchorUpdatedEvent>) => void;
|
|
27
27
|
_onAnchorRemoved: (_event: NativeSyntheticEvent<ViroARAnchorRemovedEvent>) => void;
|
|
28
|
-
render(): React.JSX.Element
|
|
28
|
+
render(): React.JSX.Element;
|
|
29
29
|
}
|
|
30
30
|
export {};
|
|
@@ -47,7 +47,6 @@ exports.ViroARPlane = void 0;
|
|
|
47
47
|
const ViroBase_1 = require("../ViroBase");
|
|
48
48
|
const React = __importStar(require("react"));
|
|
49
49
|
const react_native_1 = require("react-native");
|
|
50
|
-
const ViroPlatform_1 = require("../Utilities/ViroPlatform");
|
|
51
50
|
/**
|
|
52
51
|
* Container for Viro Components anchored to a detected plane.
|
|
53
52
|
*/
|
|
@@ -68,10 +67,7 @@ class ViroARPlane extends ViroBase_1.ViroBase {
|
|
|
68
67
|
}
|
|
69
68
|
};
|
|
70
69
|
render() {
|
|
71
|
-
|
|
72
|
-
console.warn("[Viro] ViroARPlane is not supported on Quest and will not render.");
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
70
|
+
// Supported on Quest via XR_FB_scene plane anchors (room model). No longer gated.
|
|
75
71
|
// Uncomment this line to check for misnamed props
|
|
76
72
|
//checkMisnamedProps("ViroARPlane", this.props);
|
|
77
73
|
let timeToFuse = undefined;
|
|
@@ -293,7 +293,7 @@ export declare class ViroARPlaneSelector extends React.Component<Props, State> {
|
|
|
293
293
|
*/
|
|
294
294
|
_worldToLocal: (world: [number, number, number], anchorPosition: [number, number, number], rotationDeg: [number, number, number]) => [number, number, number];
|
|
295
295
|
_passesAlignmentFilter: (anchor: ViroAnchor) => boolean;
|
|
296
|
-
render(): React.JSX.Element
|
|
296
|
+
render(): React.JSX.Element;
|
|
297
297
|
_renderPlanes(): React.JSX.Element[];
|
|
298
298
|
}
|
|
299
299
|
export {};
|
|
@@ -285,10 +285,7 @@ class ViroARPlaneSelector extends React.Component {
|
|
|
285
285
|
// Render
|
|
286
286
|
// ---------------------------------------------------------------------------
|
|
287
287
|
render() {
|
|
288
|
-
|
|
289
|
-
console.warn("[Viro] ViroARPlaneSelector is not supported on Quest and will not render.");
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
288
|
+
// Supported on Quest via XR_FB_scene plane anchors (room model). No longer gated.
|
|
292
289
|
return <ViroNode_1.ViroNode>{this._renderPlanes()}</ViroNode_1.ViroNode>;
|
|
293
290
|
}
|
|
294
291
|
_renderPlanes() {
|
|
@@ -351,6 +348,14 @@ ViroMaterials_1.ViroMaterials.createMaterials({
|
|
|
351
348
|
diffuseColor: "rgba(0, 122, 255, 0.5)",
|
|
352
349
|
blendMode: "Alpha",
|
|
353
350
|
cullMode: "None",
|
|
354
|
-
|
|
351
|
+
// Phone: don't write depth, so overlapping/coplanar overlays blend cleanly.
|
|
352
|
+
// Quest: WRITE depth. On Quest's tiled GPU, many non-depth-writing transparent
|
|
353
|
+
// draws break the second (right) eye's render entirely — the whole eye goes
|
|
354
|
+
// black/garbage. Writing depth avoids that path and renders correctly in both
|
|
355
|
+
// eyes (device-confirmed). The plane overlays don't overlap, so depth-writing
|
|
356
|
+
// has no visible downside here. (Engine-level bug — non-depth-writing
|
|
357
|
+
// transparency at quantity breaking stereo — tracked in virocore
|
|
358
|
+
// VROGeometry::updateSubstrate notes / QUEST_SETUP.md.)
|
|
359
|
+
writesToDepthBuffer: ViroPlatform_1.isQuest,
|
|
355
360
|
},
|
|
356
361
|
});
|
|
@@ -52,7 +52,6 @@ const react_native_1 = require("react-native");
|
|
|
52
52
|
const resolveAssetSource_1 = __importDefault(require("react-native/Libraries/Image/resolveAssetSource"));
|
|
53
53
|
const ViroBase_1 = require("../ViroBase");
|
|
54
54
|
const ViroConstants_1 = require("../ViroConstants");
|
|
55
|
-
const ViroPlatform_1 = require("../Utilities/ViroPlatform");
|
|
56
55
|
const ViroCameraModule = react_native_1.NativeModules.ViroCameraModule;
|
|
57
56
|
class ViroARScene extends ViroBase_1.ViroBase {
|
|
58
57
|
onTrackingFirstInitialized = false;
|
|
@@ -290,10 +289,8 @@ class ViroARScene extends ViroBase_1.ViroBase {
|
|
|
290
289
|
return await ViroCameraModule.getCameraPosition((0, react_native_1.findNodeHandle)(this));
|
|
291
290
|
};
|
|
292
291
|
render() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
292
|
+
// On Meta Quest, ViroARScene renders as a mixed-reality scene through the
|
|
293
|
+
// OpenXR renderer (passthrough + XR_FB_scene plane anchors). No longer gated.
|
|
297
294
|
// Uncomment this line to check for misnamed props
|
|
298
295
|
//checkMisnamedProps("ViroARScene", this.props);
|
|
299
296
|
// Since anchorDetectionTypes can be either a string or an array, convert the string to a 1-element array.
|
|
@@ -149,9 +149,17 @@ type Props = ViewProps & {
|
|
|
149
149
|
monocularDepthTargetFPS?: number;
|
|
150
150
|
/**
|
|
151
151
|
* Use the front (selfie) camera as the AR session background.
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
152
|
+
*
|
|
153
|
+
* Requires the optional `@reactvision/react-viro-face-tracking` package to be
|
|
154
|
+
* installed — it provides the native front-camera AR configuration and, on
|
|
155
|
+
* iOS, declares TrueDepth usage. Without it, this prop has no effect.
|
|
156
|
+
*
|
|
157
|
+
* On iOS the package uses the front TrueDepth camera; on Android it uses
|
|
158
|
+
* ARCore Augmented Faces mode. World tracking, plane detection, and LiDAR are
|
|
159
|
+
* unavailable in this mode.
|
|
160
|
+
*
|
|
161
|
+
* For a plain selfie feed without face tracking (no TrueDepth), use
|
|
162
|
+
* `ViroCameraTexture` with `cameraPosition="front"` instead.
|
|
155
163
|
*
|
|
156
164
|
* @default false
|
|
157
165
|
* @platform ios, android
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { StudioVariableStore } from "./domain/variableStore";
|
|
2
3
|
import { StudioSceneResponse } from "./types";
|
|
3
4
|
interface StudioARSceneProps {
|
|
4
5
|
sceneNavigator?: any;
|
|
@@ -6,6 +7,8 @@ interface StudioARSceneProps {
|
|
|
6
7
|
onReady?: () => void;
|
|
7
8
|
onError?: (err: Error) => void;
|
|
8
9
|
onSceneChange?: (sceneId: string, sceneName: string) => void;
|
|
10
|
+
/** Session-scoped store owned by the navigator; survives scene pushes. */
|
|
11
|
+
variableStore?: StudioVariableStore;
|
|
9
12
|
}
|
|
10
13
|
/**
|
|
11
14
|
* Outer gate: keeps the hooks-bearing inner component out of the tree until
|