@reactvision/react-viro 2.53.1 → 2.55.0

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 (153) hide show
  1. package/README.md +85 -46
  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/ViroARCamera.tsx +5 -0
  5. package/components/AR/ViroARImageMarker.tsx +5 -0
  6. package/components/AR/ViroARObjectMarker.tsx +5 -0
  7. package/components/AR/ViroARPlane.tsx +5 -0
  8. package/components/AR/ViroARPlaneSelector.tsx +5 -0
  9. package/components/AR/ViroARScene.tsx +5 -0
  10. package/components/AR/ViroARSceneNavigator.tsx +84 -0
  11. package/components/AR/ViroCommonProps.ts +11 -0
  12. package/components/Material/ViroMaterials.ts +51 -0
  13. package/components/Studio/StudioARScene.tsx +368 -0
  14. package/components/Studio/StudioSceneNavigator.tsx +191 -0
  15. package/components/Studio/VRTStudioModule.ts +40 -0
  16. package/components/Studio/domain/animationRegistry.ts +86 -0
  17. package/components/Studio/domain/collisionBindingsRuntime.ts +93 -0
  18. package/components/Studio/domain/collisionPairKey.ts +15 -0
  19. package/components/Studio/domain/dragConfiguration.ts +48 -0
  20. package/components/Studio/domain/materialConfig.ts +276 -0
  21. package/components/Studio/domain/physicsConfig.ts +204 -0
  22. package/components/Studio/domain/sceneNavigationHandler.ts +150 -0
  23. package/components/Studio/domain/studioMaterials.ts +33 -0
  24. package/components/Studio/domain/triggerImageRegistry.ts +64 -0
  25. package/components/Studio/domain/useStudioShaderTimeUniforms.ts +51 -0
  26. package/components/Studio/domain/useStudioShaderViewportUniforms.ts +52 -0
  27. package/components/Studio/domain/viroNodeFactory.tsx +323 -0
  28. package/components/Studio/index.ts +18 -0
  29. package/components/Studio/types.ts +164 -0
  30. package/components/Types/ViroEvents.ts +53 -0
  31. package/components/Utilities/VRModuleOpenXR.ts +50 -0
  32. package/components/Utilities/VRQuestNavigatorBridge.ts +168 -0
  33. package/components/Utilities/ViroPlatform.ts +52 -0
  34. package/components/Utilities/ViroUtils.tsx +48 -0
  35. package/components/Utilities/ViroVersion.ts +1 -1
  36. package/components/Utilities/useAnySourceHover.ts +55 -0
  37. package/components/Utilities/useAnySourcePressed.ts +70 -0
  38. package/components/Viro360Image.tsx +7 -0
  39. package/components/ViroQuestEntryPoint.tsx +79 -0
  40. package/components/ViroVRSceneNavigator.tsx +44 -19
  41. package/components/ViroXRSceneNavigator.tsx +217 -0
  42. package/components/VisionOS/ViroVisionOSModule.ts +93 -0
  43. package/dist/components/AR/ViroARCamera.d.ts +1 -1
  44. package/dist/components/AR/ViroARCamera.js +5 -0
  45. package/dist/components/AR/ViroARImageMarker.d.ts +1 -1
  46. package/dist/components/AR/ViroARImageMarker.js +5 -0
  47. package/dist/components/AR/ViroARObjectMarker.d.ts +1 -1
  48. package/dist/components/AR/ViroARObjectMarker.js +5 -0
  49. package/dist/components/AR/ViroARPlane.d.ts +1 -1
  50. package/dist/components/AR/ViroARPlane.js +5 -0
  51. package/dist/components/AR/ViroARPlaneSelector.d.ts +1 -1
  52. package/dist/components/AR/ViroARPlaneSelector.js +5 -0
  53. package/dist/components/AR/ViroARScene.d.ts +1 -1
  54. package/dist/components/AR/ViroARScene.js +5 -0
  55. package/dist/components/AR/ViroARSceneNavigator.d.ts +36 -0
  56. package/dist/components/AR/ViroARSceneNavigator.js +41 -0
  57. package/dist/components/AR/ViroCommonProps.d.ts +11 -0
  58. package/dist/components/Material/ViroMaterials.d.ts +12 -0
  59. package/dist/components/Material/ViroMaterials.js +25 -0
  60. package/dist/components/ReactVisionClient.d.ts +25 -0
  61. package/dist/components/ReactVisionClient.js +11 -0
  62. package/dist/components/Studio/StudioARScene.d.ts +15 -0
  63. package/dist/components/Studio/StudioARScene.js +299 -0
  64. package/dist/components/Studio/StudioSceneNavigator.d.ts +31 -0
  65. package/dist/components/Studio/StudioSceneNavigator.js +174 -0
  66. package/dist/components/Studio/VRTStudioModule.d.ts +15 -0
  67. package/dist/components/Studio/VRTStudioModule.js +31 -0
  68. package/dist/components/Studio/domain/animationRegistry.d.ts +11 -0
  69. package/dist/components/Studio/domain/animationRegistry.js +67 -0
  70. package/dist/components/Studio/domain/collisionBindingsRuntime.d.ts +21 -0
  71. package/dist/components/Studio/domain/collisionBindingsRuntime.js +54 -0
  72. package/dist/components/Studio/domain/collisionPairKey.d.ts +8 -0
  73. package/dist/components/Studio/domain/collisionPairKey.js +15 -0
  74. package/dist/components/Studio/domain/dragConfiguration.d.ts +20 -0
  75. package/dist/components/Studio/domain/dragConfiguration.js +37 -0
  76. package/dist/components/Studio/domain/materialConfig.d.ts +56 -0
  77. package/dist/components/Studio/domain/materialConfig.js +239 -0
  78. package/dist/components/Studio/domain/physicsConfig.d.ts +69 -0
  79. package/dist/components/Studio/domain/physicsConfig.js +165 -0
  80. package/dist/components/Studio/domain/sceneNavigationHandler.d.ts +12 -0
  81. package/dist/components/Studio/domain/sceneNavigationHandler.js +112 -0
  82. package/dist/components/Studio/domain/studioMaterials.d.ts +6 -0
  83. package/dist/components/Studio/domain/studioMaterials.js +30 -0
  84. package/dist/components/Studio/domain/triggerImageRegistry.d.ts +13 -0
  85. package/dist/components/Studio/domain/triggerImageRegistry.js +47 -0
  86. package/dist/components/Studio/domain/useStudioShaderTimeUniforms.d.ts +6 -0
  87. package/dist/components/Studio/domain/useStudioShaderTimeUniforms.js +48 -0
  88. package/dist/components/Studio/domain/useStudioShaderViewportUniforms.d.ts +6 -0
  89. package/dist/components/Studio/domain/useStudioShaderViewportUniforms.js +48 -0
  90. package/dist/components/Studio/domain/viroNodeFactory.d.ts +28 -0
  91. package/dist/components/Studio/domain/viroNodeFactory.js +193 -0
  92. package/dist/components/Studio/index.d.ts +3 -0
  93. package/dist/components/Studio/index.js +7 -0
  94. package/dist/components/Studio/types.d.ts +149 -0
  95. package/dist/components/Studio/types.js +4 -0
  96. package/dist/components/Types/ViroEvents.d.ts +49 -1
  97. package/dist/components/Types/ViroEvents.js +1 -0
  98. package/dist/components/Utilities/VRModuleOpenXR.d.ts +32 -0
  99. package/dist/components/Utilities/VRModuleOpenXR.js +44 -0
  100. package/dist/components/Utilities/VRQuestNavigatorBridge.d.ts +85 -0
  101. package/dist/components/Utilities/VRQuestNavigatorBridge.js +124 -0
  102. package/dist/components/Utilities/ViroPlatform.d.ts +10 -0
  103. package/dist/components/Utilities/ViroPlatform.js +43 -0
  104. package/dist/components/Utilities/ViroUtils.d.ts +19 -0
  105. package/dist/components/Utilities/ViroUtils.js +34 -0
  106. package/dist/components/Utilities/ViroVersion.d.ts +1 -1
  107. package/dist/components/Utilities/ViroVersion.js +1 -1
  108. package/dist/components/Utilities/useAnySourceHover.d.ts +36 -0
  109. package/dist/components/Utilities/useAnySourceHover.js +48 -0
  110. package/dist/components/Utilities/useAnySourcePressed.d.ts +37 -0
  111. package/dist/components/Utilities/useAnySourcePressed.js +61 -0
  112. package/dist/components/Viro360Image.d.ts +7 -0
  113. package/dist/components/ViroQuestEntryPoint.d.ts +13 -0
  114. package/dist/components/ViroQuestEntryPoint.js +104 -0
  115. package/dist/components/ViroVRSceneNavigator.d.ts +24 -10
  116. package/dist/components/ViroVRSceneNavigator.js +21 -18
  117. package/dist/components/ViroXRSceneNavigator.d.ts +54 -0
  118. package/dist/components/ViroXRSceneNavigator.js +173 -0
  119. package/dist/components/VisionOS/ViroVisionOSModule.d.ts +65 -0
  120. package/dist/components/VisionOS/ViroVisionOSModule.js +91 -0
  121. package/dist/index.d.ts +16 -3
  122. package/dist/index.js +34 -2
  123. package/dist/plugins/withViro.d.ts +28 -1
  124. package/dist/plugins/withViroAndroid.js +312 -7
  125. package/dist/plugins/withViroIos.js +17 -8
  126. package/dist/plugins/withViroVisionOS.d.ts +24 -0
  127. package/dist/plugins/withViroVisionOS.js +265 -0
  128. package/index.ts +66 -0
  129. package/ios/ViroReact.podspec +15 -5
  130. package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreCoreMLSemanticsResources.bundle/Info.plist +0 -0
  131. package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreResources.bundle/Info.plist +0 -0
  132. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSession.h +30 -1
  133. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSessioniOS.h +16 -0
  134. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROGLTFLoader.h +34 -0
  135. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROInputControllerBase.h +74 -0
  136. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROInputType.h +11 -3
  137. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMaterial.h +29 -0
  138. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMorpher.h +4 -0
  139. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPlatformUtil.h +13 -0
  140. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPortal.h +17 -0
  141. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderContext.h +41 -0
  142. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderer.h +23 -0
  143. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROSemantics.h +14 -0
  144. package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROViewAR.h +11 -0
  145. package/ios/dist/ViroRenderer/ViroKit.framework/Info.plist +0 -0
  146. package/ios/dist/ViroRenderer/ViroKit.framework/Shaders.dat +1 -1
  147. package/ios/dist/ViroRenderer/ViroKit.framework/ViroKit +0 -0
  148. package/ios/dist/ViroRenderer/ViroKit.podspec +5 -0
  149. package/ios/dist/include/VRT360Image.h +1 -0
  150. package/ios/dist/include/VRTARSceneNavigator.h +7 -0
  151. package/ios/dist/include/VRTStudioModule.h +6 -0
  152. package/ios/dist/lib/libViroReact.a +0 -0
  153. package/package.json +8 -8
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * withViroVisionOS.ts
4
+ *
5
+ * Expo config plugin that adds a visionOS target to your app's Xcode project.
6
+ *
7
+ * What it does:
8
+ * 1. Writes the SwiftUI App entry point (ViroVisionApp.swift) into the target folder
9
+ * 2. Adds a visionOS pod target to the Podfile
10
+ * 3. Creates a visionOS Xcode target in the .pbxproj with correct SDK + build settings
11
+ *
12
+ * Usage in app.json:
13
+ * {
14
+ * "plugins": [
15
+ * ["@reactvision/react-viro", { ... }],
16
+ * "@reactvision/react-viro/plugins/withViroVisionOS"
17
+ * ]
18
+ * }
19
+ *
20
+ * After running `expo prebuild`, run `pod install` in ios/ then build the
21
+ * <AppName>Vision target in Xcode targeting the visionOS simulator.
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.withViroVisionOS = void 0;
28
+ const config_plugins_1 = require("@expo/config-plugins");
29
+ const fs_1 = __importDefault(require("fs"));
30
+ const path_1 = __importDefault(require("path"));
31
+ // ─── Constants ────────────────────────────────────────────────────────────────
32
+ const TARGET_SUFFIX = "Vision";
33
+ const VISIONOS_DEPLOYMENT_TARGET = "1.0";
34
+ const PODFILE_MARKER = "# viro-visionos-target";
35
+ // ─── Swift App entry point template ──────────────────────────────────────────
36
+ function viroVisionAppSwift(targetName, bundleId) {
37
+ return `// ViroVisionApp.swift
38
+ // Auto-generated by @reactvision/react-viro — DO NOT EDIT MANUALLY.
39
+ // Re-generated on every expo prebuild run.
40
+
41
+ import SwiftUI
42
+ import ViroReact
43
+
44
+ @main
45
+ struct ${targetName}App: App {
46
+ /// Current immersion style — driven by ViroVisionOSModule.enterImmersiveSpace(style).
47
+ @State private var immersionStyle: ImmersionStyle = .mixed
48
+
49
+ var body: some Scene {
50
+ // Main 2D window (hosts React Native UI if needed, or acts as launch host).
51
+ WindowGroup {
52
+ ViroVisionLaunchView()
53
+ .viroImmersiveSpaceController()
54
+ }
55
+
56
+ // The Viro immersive rendering space.
57
+ // Opened via ViroVisionOSModule.enterImmersiveSpace() from JavaScript.
58
+ ImmersiveSpace(id: ViroImmersiveSpace.id) {
59
+ ViroImmersiveSpaceView()
60
+ }
61
+ .immersionStyle(selection: $immersionStyle, in: .mixed, .full, .progressive)
62
+ }
63
+ }
64
+
65
+ /// Minimal launch view displayed in the 2D window.
66
+ /// Replace with your own SwiftUI content or a React Native root view.
67
+ struct ViroVisionLaunchView: View {
68
+ @State private var isImmersed = false
69
+
70
+ var body: some View {
71
+ VStack(spacing: 20) {
72
+ Text("ReactVision AR")
73
+ .font(.largeTitle)
74
+ .fontWeight(.bold)
75
+
76
+ Button(isImmersed ? "Exit Immersive Space" : "Enter Immersive Space") {
77
+ Task {
78
+ if isImmersed {
79
+ await ViroImmersiveCoordinator.shared.exit()
80
+ } else {
81
+ await ViroImmersiveCoordinator.shared.enter(styleString: "mixed")
82
+ }
83
+ isImmersed.toggle()
84
+ }
85
+ }
86
+ .buttonStyle(.borderedProminent)
87
+ }
88
+ .padding(40)
89
+ }
90
+ }
91
+ `;
92
+ }
93
+ // ─── 1. Write Swift files ─────────────────────────────────────────────────────
94
+ const withVisionOSSwiftFiles = (config) => {
95
+ return (0, config_plugins_1.withDangerousMod)(config, [
96
+ "ios",
97
+ async (newConfig) => {
98
+ const root = newConfig.modRequest.platformProjectRoot;
99
+ const projectName = newConfig.modRequest.projectName;
100
+ const targetName = `${projectName}${TARGET_SUFFIX}`;
101
+ const bundleId = `${newConfig.ios?.bundleIdentifier ?? "com.example"}.vision`;
102
+ const targetDir = path_1.default.join(root, targetName);
103
+ if (!fs_1.default.existsSync(targetDir)) {
104
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
105
+ }
106
+ // Always overwrite — it's auto-generated.
107
+ fs_1.default.writeFileSync(path_1.default.join(targetDir, "ViroVisionApp.swift"), viroVisionAppSwift(targetName, bundleId), "utf-8");
108
+ return newConfig;
109
+ },
110
+ ]);
111
+ };
112
+ // ─── 2. Podfile target block ──────────────────────────────────────────────────
113
+ const withVisionOSPodfile = (config) => {
114
+ return (0, config_plugins_1.withDangerousMod)(config, [
115
+ "ios",
116
+ async (newConfig) => {
117
+ const root = newConfig.modRequest.platformProjectRoot;
118
+ const projectName = newConfig.modRequest.projectName;
119
+ const targetName = `${projectName}${TARGET_SUFFIX}`;
120
+ const podfilePath = path_1.default.join(root, "Podfile");
121
+ let podfile = fs_1.default.readFileSync(podfilePath, "utf-8");
122
+ // Idempotent — skip if already present.
123
+ if (podfile.includes(PODFILE_MARKER))
124
+ return newConfig;
125
+ const podBlock = [
126
+ "",
127
+ PODFILE_MARKER,
128
+ `# ViroKit (iOS-only) and ViroReact (ObjC) are excluded until ViroKit`,
129
+ `# is compiled for xros SDK (Week 2). The POC uses Metal + CompositorServices directly.`,
130
+ `target '${targetName}' do`,
131
+ `end`,
132
+ "",
133
+ ].join("\n");
134
+ fs_1.default.writeFileSync(podfilePath, podfile + podBlock, "utf-8");
135
+ return newConfig;
136
+ },
137
+ ]);
138
+ };
139
+ // ─── 3. Xcode target ─────────────────────────────────────────────────────────
140
+ const withVisionOSXcodeTarget = (config) => {
141
+ return (0, config_plugins_1.withXcodeProject)(config, (newConfig) => {
142
+ const pbxProject = newConfig.modResults;
143
+ const projectName = newConfig.modRequest.projectName;
144
+ const targetName = `${projectName}${TARGET_SUFFIX}`;
145
+ const bundleId = `${newConfig.ios?.bundleIdentifier ?? "com.example"}.vision`;
146
+ const targetDir = targetName; // relative path inside ios/
147
+ // ── Check for existing target ────────────────────────────────────────────
148
+ const nativeTargets = pbxProject.pbxNativeTargetSection();
149
+ const alreadyExists = Object.values(nativeTargets).some((t) => t &&
150
+ typeof t === "object" &&
151
+ (t.name === targetName || t.name === `"${targetName}"`));
152
+ if (alreadyExists)
153
+ return newConfig;
154
+ // ── Add the target (creates PBX phases + config list) ────────────────────
155
+ const target = pbxProject.addTarget(targetName, "application", targetDir, bundleId);
156
+ if (!target) {
157
+ config_plugins_1.WarningAggregator.addWarningIOS("withViroVisionOS", `Failed to add visionOS target "${targetName}" to Xcode project. ` +
158
+ "Add it manually in Xcode: File → New → Target → visionOS → App.");
159
+ return newConfig;
160
+ }
161
+ // ── Set visionOS build settings on every config for this target ──────────
162
+ const configList = pbxProject.pbxXCBuildConfigurationSection();
163
+ for (const conf of Object.values(configList)) {
164
+ if (!conf || typeof conf !== "object" || !conf.buildSettings)
165
+ continue;
166
+ const name = conf.buildSettings.PRODUCT_NAME;
167
+ if (!name)
168
+ continue;
169
+ const normalized = name.replace(/^"(.*)"$/, "$1");
170
+ if (normalized !== targetName)
171
+ continue;
172
+ const bs = conf.buildSettings;
173
+ // visionOS SDK
174
+ bs.SDKROOT = "xros";
175
+ bs.SUPPORTED_PLATFORMS = '"xros xrsimulator"';
176
+ bs[`"DEPLOYMENT_TARGET[sdk=xros*]"`] = `"${VISIONOS_DEPLOYMENT_TARGET}"`;
177
+ bs.TARGETED_DEVICE_FAMILY = '"7"';
178
+ // Swift
179
+ bs.SWIFT_VERSION = '"5.0"';
180
+ bs.CLANG_ENABLE_MODULES = "YES";
181
+ // Runpath for dynamic frameworks (CocoaPods)
182
+ bs.LD_RUNPATH_SEARCH_PATHS = '"$(inherited) @executable_path/Frameworks"';
183
+ // Embed Swift standard libraries
184
+ bs.ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "YES";
185
+ // App-specific
186
+ bs.PRODUCT_BUNDLE_IDENTIFIER = `"${bundleId}"`;
187
+ bs.INFOPLIST_FILE = `"${targetDir}/Info.plist"`;
188
+ bs.GENERATE_INFOPLIST_FILE = "NO";
189
+ bs.ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon";
190
+ // Don't strip Swift symbols in debug
191
+ if (conf.name === "Debug") {
192
+ bs.SWIFT_OPTIMIZATION_LEVEL = '"-Onone"';
193
+ bs.SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG";
194
+ }
195
+ }
196
+ // ── Write Info.plist for the visionOS target ──────────────────────────────
197
+ // (written during the dangerous mod pass — cannot write files here)
198
+ // Logged as a reminder.
199
+ config_plugins_1.WarningAggregator.addWarningIOS("withViroVisionOS", `visionOS target "${targetName}" added. ` +
200
+ `Run "pod install" in ios/ then build the target in Xcode. ` +
201
+ `An Info.plist will be auto-generated by Xcode for the new target.`);
202
+ return newConfig;
203
+ });
204
+ };
205
+ // ─── 4. Info.plist for visionOS target ───────────────────────────────────────
206
+ const INFOPLIST_CONTENT = `<?xml version="1.0" encoding="UTF-8"?>
207
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
208
+ <plist version="1.0">
209
+ <dict>
210
+ <key>CFBundleDevelopmentRegion</key>
211
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
212
+ <key>CFBundleExecutable</key>
213
+ <string>$(EXECUTABLE_NAME)</string>
214
+ <key>CFBundleIdentifier</key>
215
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
216
+ <key>CFBundleInfoDictionaryVersion</key>
217
+ <string>6.0</string>
218
+ <key>CFBundleName</key>
219
+ <string>$(PRODUCT_NAME)</string>
220
+ <key>CFBundlePackageType</key>
221
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
222
+ <key>CFBundleShortVersionString</key>
223
+ <string>1.0</string>
224
+ <key>CFBundleVersion</key>
225
+ <string>1</string>
226
+ <key>UIApplicationSceneManifest</key>
227
+ <dict>
228
+ <key>UIApplicationSupportsMultipleScenes</key>
229
+ <true/>
230
+ </dict>
231
+ <key>NSHandsTrackingUsageDescription</key>
232
+ <string>Hand tracking is used for interaction in AR experiences.</string>
233
+ </dict>
234
+ </plist>
235
+ `;
236
+ const withVisionOSInfoPlist = (config) => {
237
+ return (0, config_plugins_1.withDangerousMod)(config, [
238
+ "ios",
239
+ async (newConfig) => {
240
+ const root = newConfig.modRequest.platformProjectRoot;
241
+ const projectName = newConfig.modRequest.projectName;
242
+ const targetName = `${projectName}${TARGET_SUFFIX}`;
243
+ const targetDir = path_1.default.join(root, targetName);
244
+ if (!fs_1.default.existsSync(targetDir)) {
245
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
246
+ }
247
+ const plistPath = path_1.default.join(targetDir, "Info.plist");
248
+ if (!fs_1.default.existsSync(plistPath)) {
249
+ fs_1.default.writeFileSync(plistPath, INFOPLIST_CONTENT, "utf-8");
250
+ }
251
+ return newConfig;
252
+ },
253
+ ]);
254
+ };
255
+ // ─── Main export ──────────────────────────────────────────────────────────────
256
+ const withViroVisionOS = (config) => {
257
+ return (0, config_plugins_1.withPlugins)(config, [
258
+ withVisionOSSwiftFiles,
259
+ withVisionOSInfoPlist,
260
+ withVisionOSPodfile,
261
+ withVisionOSXcodeTarget,
262
+ ]);
263
+ };
264
+ exports.withViroVisionOS = withViroVisionOS;
265
+ exports.default = exports.withViroVisionOS;
package/index.ts CHANGED
@@ -4,6 +4,8 @@
4
4
  *
5
5
  */
6
6
  import { ViroAnimations } from "./components/Animation/ViroAnimations";
7
+ import { StudioSceneNavigator, StudioARScene } from "./components/Studio";
8
+ import { ViroVisionOSModule, isVisionOS, enterImmersiveSpace, exitImmersiveSpace } from "./components/VisionOS/ViroVisionOSModule";
7
9
  import { Viro3DObject } from "./components/Viro3DObject";
8
10
  import { Viro360Image } from "./components/Viro360Image";
9
11
  import { Viro360Video } from "./components/Viro360Video";
@@ -59,14 +61,22 @@ import { ViroSpotLight } from "./components/ViroSpotLight";
59
61
  import { ViroText } from "./components/ViroText";
60
62
  import { ViroVideo } from "./components/ViroVideo";
61
63
  import { ViroVRSceneNavigator } from "./components/ViroVRSceneNavigator";
64
+ import { ViroXRSceneNavigator } from "./components/ViroXRSceneNavigator";
62
65
  import { Viro3DSceneNavigator } from "./components/Viro3DSceneNavigator";
66
+ import { hasOpenXRSupport, isQuest } from "./components/Utilities/ViroPlatform";
67
+ import { useAnySourceHover } from "./components/Utilities/useAnySourceHover";
68
+ import { useAnySourcePressed } from "./components/Utilities/useAnySourcePressed";
63
69
  import { ViroTextStyle } from "./components/Styles/ViroTextStyle";
64
70
  import { ViroStyle } from "./components/Styles/ViroStyle";
65
71
  import {
66
72
  polarToCartesian,
67
73
  polarToCartesianActual,
68
74
  isARSupportedOnDevice,
75
+ requestRequiredPermissions,
76
+ checkPermissions,
69
77
  ViroARSupportResponse,
78
+ ViroPermissionsResult,
79
+ ViroPermission,
70
80
  latLngToMercator,
71
81
  gpsToArWorld,
72
82
  } from "./components/Utilities/ViroUtils";
@@ -157,10 +167,25 @@ import {
157
167
  ViroMonocularDepthSupportResult,
158
168
  ViroMonocularDepthModelAvailableResult,
159
169
  ViroMonocularDepthPreferenceResult,
170
+ // Quest / OpenXR Hand Tracking Types
171
+ ViroJoint,
172
+ ViroHandJoints,
173
+ ViroHandPinchEvent,
174
+ ViroHandUpdateEvent,
160
175
  } from "./components/Types/ViroEvents";
161
176
  import { ViroSurface } from "./components/ViroSurface";
162
177
  import { ViroSceneNavigator } from "./components/ViroSceneNavigator";
163
178
  import { VIRO_VERSION } from "./components/Utilities/ViroVersion";
179
+ import { ViroQuestEntryPoint } from "./components/ViroQuestEntryPoint";
180
+ import { VRQuestNavigatorBridge } from "./components/Utilities/VRQuestNavigatorBridge";
181
+ import { VRModuleOpenXR, useVRViewTag, exitVRScene } from "./components/Utilities/VRModuleOpenXR";
182
+ import type { VRModuleOpenXRType } from "./components/Utilities/VRModuleOpenXR";
183
+ import { AppRegistry } from "react-native";
184
+
185
+ // Auto-register the Quest VR entry point. VRActivity launches this component
186
+ // as 'VRQuestScene'. Registering here means apps need no manual setup.
187
+ // Apps that need a custom VR root can re-register after importing this package.
188
+ AppRegistry.registerComponent("VRQuestScene", () => ViroQuestEntryPoint);
164
189
 
165
190
  export {
166
191
  ViroARImageMarker,
@@ -211,18 +236,33 @@ export {
211
236
  ViroText,
212
237
  ViroVideo,
213
238
  ViroVRSceneNavigator,
239
+ ViroXRSceneNavigator,
240
+ ViroQuestEntryPoint,
241
+ // Quest bridge — for custom VR roots and VRModuleOpenXR viewTag access
242
+ VRQuestNavigatorBridge,
243
+ VRModuleOpenXR,
244
+ useVRViewTag,
245
+ exitVRScene,
214
246
  Viro3DSceneNavigator,
215
247
  // Utilities
248
+ hasOpenXRSupport,
249
+ isQuest,
250
+ useAnySourceHover,
251
+ useAnySourcePressed,
216
252
  ViroARTrackingReasonConstants,
217
253
  ViroRecordingErrorConstants,
218
254
  ViroTrackingStateConstants,
219
255
  polarToCartesian,
220
256
  polarToCartesianActual,
221
257
  isARSupportedOnDevice,
258
+ requestRequiredPermissions,
259
+ checkPermissions,
222
260
  latLngToMercator,
223
261
  gpsToArWorld,
224
262
  // Types
225
263
  ViroARSupportResponse,
264
+ ViroPermissionsResult,
265
+ ViroPermission,
226
266
  ViroHoverEvent,
227
267
  ViroClickEvent,
228
268
  ViroClickStateEvent,
@@ -315,4 +355,30 @@ export {
315
355
  ViroMonocularDepthSupportResult,
316
356
  ViroMonocularDepthModelAvailableResult,
317
357
  ViroMonocularDepthPreferenceResult,
358
+ // Quest / OpenXR Hand Tracking Types
359
+ ViroJoint,
360
+ ViroHandJoints,
361
+ ViroHandPinchEvent,
362
+ ViroHandUpdateEvent,
363
+ // Studio Integration
364
+ StudioSceneNavigator,
365
+ StudioARScene,
366
+ // VisionOS
367
+ ViroVisionOSModule,
368
+ isVisionOS,
369
+ enterImmersiveSpace,
370
+ exitImmersiveSpace,
318
371
  };
372
+
373
+ export type { VRModuleOpenXRType };
374
+ export type { ImmersiveSpaceStyle } from "./components/VisionOS/ViroVisionOSModule";
375
+
376
+ export type {
377
+ StudioSceneResponse,
378
+ StudioAsset,
379
+ StudioAnimation,
380
+ StudioCollisionBinding,
381
+ StudioSceneFunction,
382
+ StudioSceneMeta,
383
+ StudioProjectMeta,
384
+ } from "./components/Studio";
@@ -12,10 +12,14 @@ Pod::Spec.new do |s|
12
12
  s.author = 'ReactVision'
13
13
  s.requires_arc = true
14
14
  s.platform = :ios, '12.0'
15
- s.ios.deployment_target = '12.0'
16
-
15
+ s.ios.deployment_target = '12.0'
16
+ s.visionos.deployment_target = '1.0'
17
+
18
+ # visionOS: CompositorServices drives the immersive render loop.
19
+ s.visionos.frameworks = ['Metal', 'MetalKit', 'CompositorServices', 'ARKit']
20
+
17
21
  # Base source files (always included)
18
- source_files_array = ['ViroReact/**/*.{h,m,mm}']
22
+ source_files_array = ['ViroReact/**/*.{h,m,mm,swift}']
19
23
  header_files_array = ['ViroReact/**/*.h']
20
24
 
21
25
  # Include dist files if they exist (for release builds)
@@ -26,7 +30,12 @@ Pod::Spec.new do |s|
26
30
 
27
31
  s.source_files = source_files_array
28
32
  s.public_header_files = header_files_array
29
-
33
+
34
+ # visionOS-only sources: keep them out of the iOS build so consumers running
35
+ # `pod install` for iOS don't pull CompositorServices / VRODriverVisionOS.h
36
+ # into a target where those symbols don't exist.
37
+ s.ios.exclude_files = ['ViroReact/VisionOS/**/*']
38
+
30
39
  if File.exist?(File.join(__dir__, 'dist/lib/libViroReact.a'))
31
40
  s.vendored_libraries = 'dist/lib/libViroReact.a'
32
41
  end
@@ -40,7 +49,8 @@ Pod::Spec.new do |s|
40
49
  s.dependency 'React-FabricComponents'
41
50
 
42
51
  # Fabric-specific build configuration
43
- s.pod_target_xcconfig = {
52
+ s.pod_target_xcconfig = {
53
+ 'SWIFT_VERSION' => '5.0',
44
54
  'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
45
55
  'HEADER_SEARCH_PATHS' => [
46
56
  '"$(PODS_TARGET_SRCROOT)/ViroReact"',
@@ -319,7 +319,21 @@ public:
319
319
  texture are updated after each call to updateFrame().
320
320
  */
321
321
  virtual std::shared_ptr<VROTexture> getCameraBackgroundTexture() = 0;
322
-
322
+
323
+ /*
324
+ Get the semantic texture for the current frame. Each pixel is a VROSemanticLabel
325
+ value (0-11, R8 format). Returns nullptr if semantic mode is not enabled or
326
+ the platform does not support it.
327
+ */
328
+ virtual std::shared_ptr<VROTexture> getSemanticTexture() { return nullptr; }
329
+
330
+ /*
331
+ Get the confidence texture for the current frame. Each pixel is a confidence value
332
+ (R8, 0=uncertain, 255=certain) corresponding to the label in getSemanticTexture().
333
+ Returns nullptr if not supported; callers should substitute a 1×1 white texture.
334
+ */
335
+ virtual std::shared_ptr<VROTexture> getSemanticConfidenceTexture() { return nullptr; }
336
+
323
337
  /*
324
338
  Invoke when the viewport changes. The AR engine may adjust its camera
325
339
  background and projection matrices in response to a viewport change.
@@ -557,6 +571,21 @@ public:
557
571
  std::function<void(bool success, std::string error)> callback) {
558
572
  if (callback) callback(false, "Not supported");
559
573
  }
574
+ virtual void rvGetScene(
575
+ const std::string& sceneId,
576
+ std::function<void(bool success, std::string jsonData, std::string error)> callback) {
577
+ if (callback) callback(false, "", "Not supported");
578
+ }
579
+ virtual void rvGetSceneAssets(
580
+ const std::string& sceneId,
581
+ std::function<void(bool success, std::string jsonData, std::string error)> callback) {
582
+ if (callback) callback(false, "", "Not supported");
583
+ }
584
+ virtual void rvGetProject(
585
+ const std::string& projectId,
586
+ std::function<void(bool success, std::string jsonData, std::string error)> callback) {
587
+ if (callback) callback(false, "", "Not supported");
588
+ }
560
589
 
561
590
  // ========================================================================
562
591
  // ReactVision Geospatial CRUD API
@@ -90,6 +90,8 @@ public:
90
90
  std::unique_ptr<VROARFrame> &updateFrame();
91
91
  std::unique_ptr<VROARFrame> &getLastFrame();
92
92
  std::shared_ptr<VROTexture> getCameraBackgroundTexture();
93
+ std::shared_ptr<VROTexture> getSemanticTexture() override;
94
+ std::shared_ptr<VROTexture> getSemanticConfidenceTexture() override;
93
95
 
94
96
  void setViewport(VROViewport viewport);
95
97
  void setOrientation(VROCameraOrientation orientation);
@@ -195,6 +197,12 @@ public:
195
197
  double confidence, int matchCount, int inlierCount, int processingTimeMs,
196
198
  const std::string& platform, const std::string& externalUserId,
197
199
  std::function<void(bool, std::string)> callback) override;
200
+ void rvGetProject(const std::string& projectId,
201
+ std::function<void(bool, std::string, std::string)> callback) override;
202
+ void rvGetScene(const std::string& sceneId,
203
+ std::function<void(bool, std::string, std::string)> callback) override;
204
+ void rvGetSceneAssets(const std::string& sceneId,
205
+ std::function<void(bool, std::string, std::string)> callback) override;
198
206
 
199
207
  // Scene Semantics API
200
208
  bool isSemanticModeSupported() const override;
@@ -326,6 +334,14 @@ private:
326
334
  Video texture cache used for transferring camera content to OpenGL.
327
335
  */
328
336
  std::shared_ptr<VROVideoTextureCacheOpenGL> _videoTextureCache;
337
+
338
+ /*
339
+ Fallback 1×1 all-white confidence texture (conf=1.0 everywhere).
340
+ Returned by getSemanticConfidenceTexture() because the ARCore iOS SDK does not
341
+ expose a per-pixel confidence image. The result is hard alpha edges (no soft blend)
342
+ on iOS, identical to the previous discard behaviour.
343
+ */
344
+ std::shared_ptr<VROTexture> _defaultConfidenceTexture;
329
345
 
330
346
  /*
331
347
  Update the VROARAnchor with the transforms in the given ARAnchor.
@@ -37,6 +37,8 @@
37
37
  #include "VROMaterial.h"
38
38
  #include "VROModelIOUtil.h"
39
39
  #include "VROByteBuffer.h"
40
+ #include "VROVector3f.h"
41
+ #include "VROQuaternion.h"
40
42
 
41
43
  class VROMorpher;
42
44
  class VRONode;
@@ -143,6 +145,7 @@ private:
143
145
  std::map<int, std::shared_ptr<VROMorpher>> &morphers,
144
146
  std::shared_ptr<VRODriver> driver);
145
147
  static std::string getMorphTargetName(const tinygltf::Model &gModel,
148
+ const tinygltf::Mesh &gMesh,
146
149
  const tinygltf::Primitive &gPrimtive, int targetIndex);
147
150
 
148
151
  static void injectGLTF(std::shared_ptr<VRONode> gltfNode, std::shared_ptr<VRONode> rootNode,
@@ -213,6 +216,7 @@ private:
213
216
  const tinygltf::Skin &skin,
214
217
  std::vector<VROMatrix4f> &invBindTransformsOut);
215
218
  static void clearCachedData();
219
+ static void injectBindPoseAnimations();
216
220
 
217
221
  /*
218
222
  As multiple mesh attributes may point to the same texture or data arrays when loading a
@@ -240,6 +244,24 @@ private:
240
244
  static std::map<int, std::shared_ptr<VROGeometrySource>> _meshBoneIndices;
241
245
  static std::map<int, std::shared_ptr<VROGeometrySource>> _meshBoneWeights;
242
246
 
247
+ /*
248
+ Maps each glTF node index to its parent node index. Needed to walk up the scene graph
249
+ for multi-skin models where a skin's root joint has non-joint ancestors (e.g. a visor
250
+ skin whose root is the Neck joint, whose ancestors Hips/Spine are only in the body skin).
251
+ Populated in processSkinner(), cleared in clearCachedData().
252
+ */
253
+ static std::map<int, int> _nodeParentMap;
254
+
255
+ /*
256
+ Maps each skin index to the set of node indices that are ancestors of that skin's mesh
257
+ node (the glTF node that has gNode.skin == skinIndex). These ancestors are already applied
258
+ by Viro's renderer as the mesh node's modelMatrix, so the ancestor walk in
259
+ processSkeletalTransformsForFrame must stop before including them to avoid double-applying
260
+ transforms (e.g. Character's scale=0.01 being applied twice → model becomes invisible).
261
+ Populated in processSkinner(), cleared in clearCachedData().
262
+ */
263
+ static std::map<int, std::set<int>> _skinMeshAncestors;
264
+
243
265
  /*
244
266
  Cached maps of nodeIndexes to it's corresponding animations. These caches are cleared
245
267
  out after the parsing of a single gLTF model. Note that _nodeKeyFrameAnims is of the form:
@@ -248,6 +270,18 @@ private:
248
270
  static std::map<int, std::map<int, std::vector<std::shared_ptr<VROKeyframeAnimation>>>> _nodeKeyFrameAnims;
249
271
  static std::map<int, std::vector<std::shared_ptr<VROSkeletalAnimation>>> _skinSkeletalAnims;
250
272
 
273
+ /*
274
+ Per-node VRONode references and bind-pose TRS, populated during processNode for any node
275
+ that has keyframe animations. Used by injectBindPoseAnimations() to create single-frame
276
+ bind-pose reset animations for animation names a node doesn't participate in.
277
+ Without these, switching animations leaves non-driven nodes at the previous animation's
278
+ final pose, causing visible mesh disassembly.
279
+ */
280
+ static std::map<int, std::shared_ptr<VRONode>> _nodeGLTFMap;
281
+ static std::map<int, VROVector3f> _nodeBindPos;
282
+ static std::map<int, VROVector3f> _nodeBindScale;
283
+ static std::map<int, VROQuaternion> _nodeBindRot;
284
+
251
285
  /*
252
286
  Returns the local transform of the node index retried from the gltf model.
253
287
  */