@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
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ViroSpatialSound = exports.ViroSoundField = exports.ViroSound = exports.ViroAnimatedComponent = exports.ViroAmbientLight = exports.ViroAnimatedImage = exports.Viro360Video = exports.Viro360Image = exports.Viro3DObject = exports.ViroAnimations = exports.ViroSkyBox = exports.ViroSceneNavigator = exports.ViroSurface = exports.ViroScene = exports.ViroQuad = exports.ViroPortalScene = exports.ViroPortal = exports.ViroPolyline = exports.ViroPolygon = exports.ViroParticleEmitter = exports.ViroOrbitCamera = exports.ViroOmniLight = exports.ViroNode = exports.ViroCameraTexture = exports.ViroMaterialVideo = exports.ViroARCamera = exports.ViroMaterials = exports.ViroImage = exports.ViroLightingEnvironment = exports.ViroGeometry = exports.ViroFlexView = exports.ViroDirectionalLight = exports.useFixedUpdate = exports.useLateUpdate = exports.useGameLoop = exports.ViroGameLoopUtils = exports.ViroGameLoop = exports.ViroVirtualButton = exports.ViroVirtualJoystick = exports.ViroController = exports.ViroCamera = exports.ViroButton = exports.ViroBox = exports.ViroARSceneNavigator = exports.ViroARScene = exports.ViroARPlaneSelector = exports.ViroARPlane = exports.ViroARTrackingTargets = exports.ViroARObjectMarker = exports.ViroARImageMarker = void 0;
4
- exports.exitImmersiveSpace = exports.enterImmersiveSpace = exports.isVisionOS = exports.ViroVisionOSModule = exports.StudioARScene = exports.StudioSceneNavigator = exports.VIRO_VERSION = exports.ViroRotateStateTypes = exports.ViroPinchStateTypes = exports.ViroClickStateTypes = exports.gpsToArWorld = exports.latLngToMercator = exports.checkPermissions = exports.requestRequiredPermissions = exports.isARSupportedOnDevice = exports.polarToCartesianActual = exports.polarToCartesian = exports.ViroTrackingStateConstants = exports.ViroRecordingErrorConstants = exports.ViroARTrackingReasonConstants = exports.useAnySourcePressed = exports.useAnySourceHover = exports.isQuest = exports.hasOpenXRSupport = exports.StreamingAudioManager = exports.Viro3DSceneNavigator = exports.exitVRScene = exports.useVRViewTag = exports.VRModuleOpenXR = exports.VRQuestNavigatorBridge = exports.ViroQuestEntryPoint = exports.ViroXRSceneNavigator = exports.ViroVRSceneNavigator = exports.ViroVideo = exports.ViroText = exports.ViroSpotLight = exports.ViroSpinner = exports.ViroSphere = void 0;
3
+ exports.ViroSoundField = exports.ViroSound = exports.ViroAnimatedComponent = exports.ViroAmbientLight = exports.ViroAnimatedImage = exports.Viro360Video = exports.Viro360Image = exports.Viro3DObject = exports.ViroAnimations = exports.ViroSkyBox = exports.ViroSceneNavigator = exports.ViroSurface = exports.ViroScene = exports.ViroQuad = exports.ViroPortalScene = exports.ViroPortal = exports.ViroPolyline = exports.ViroPolygon = exports.ViroParticleEmitter = exports.ViroOrbitCamera = exports.ViroOmniLight = exports.ViroNode = exports.ViroObjectDetector = exports.ViroCameraTexture = exports.ViroMaterialVideo = exports.ViroARCamera = exports.ViroMaterials = exports.ViroImage = exports.ViroLightingEnvironment = exports.ViroGeometry = exports.ViroFlexView = exports.ViroDirectionalLight = exports.useFixedUpdate = exports.useLateUpdate = exports.useGameLoop = exports.ViroGameLoopUtils = exports.ViroGameLoop = exports.ViroVirtualButton = exports.ViroVirtualJoystick = exports.ViroController = exports.ViroCamera = exports.ViroButton = exports.ViroBox = exports.ViroARSceneNavigator = exports.ViroARScene = exports.ViroARPlaneSelector = exports.ViroARPlane = exports.ViroARTrackingTargets = exports.ViroARObjectMarker = exports.ViroARImageMarker = void 0;
4
+ exports.exitImmersiveSpace = exports.enterImmersiveSpace = exports.isVisionOS = exports.ViroVisionOSModule = exports.StudioARScene = exports.StudioSceneNavigator = exports.VIRO_VERSION = exports.ViroRotateStateTypes = exports.ViroPinchStateTypes = exports.ViroClickStateTypes = exports.gpsToArWorld = exports.latLngToMercator = exports.checkPermissions = exports.requestRequiredPermissions = exports.isARSupportedOnDevice = exports.polarToCartesianActual = exports.polarToCartesian = exports.ViroTrackingStateConstants = exports.ViroRecordingErrorConstants = exports.ViroARTrackingReasonConstants = exports.useAnySourcePressed = exports.useAnySourceHover = exports.isQuest = exports.hasOpenXRSupport = exports.StreamingAudioManager = exports.Viro3DSceneNavigator = exports.setPassthroughStyle = exports.exitVRScene = exports.useVRViewTag = exports.VRModuleOpenXR = exports.VRQuestNavigatorBridge = exports.ViroQuestEntryPoint = exports.ViroXRSceneNavigator = exports.ViroVRSceneNavigator = exports.ViroVideo = exports.ViroText = exports.ViroSpotLight = exports.ViroSpinner = exports.ViroSphere = exports.ViroSpatialSound = void 0;
5
5
  /**
6
6
  * Copyright (c) 2016-present, Viro Media, Inc.
7
7
  * All rights reserved.
@@ -83,6 +83,8 @@ const ViroMaterialVideo_1 = require("./components/ViroMaterialVideo");
83
83
  Object.defineProperty(exports, "ViroMaterialVideo", { enumerable: true, get: function () { return ViroMaterialVideo_1.ViroMaterialVideo; } });
84
84
  const ViroCameraTexture_1 = require("./components/ViroCameraTexture");
85
85
  Object.defineProperty(exports, "ViroCameraTexture", { enumerable: true, get: function () { return ViroCameraTexture_1.ViroCameraTexture; } });
86
+ const ViroObjectDetector_1 = require("./components/ViroObjectDetector");
87
+ Object.defineProperty(exports, "ViroObjectDetector", { enumerable: true, get: function () { return ViroObjectDetector_1.ViroObjectDetector; } });
86
88
  const ViroNode_1 = require("./components/ViroNode");
87
89
  Object.defineProperty(exports, "ViroNode", { enumerable: true, get: function () { return ViroNode_1.ViroNode; } });
88
90
  const ViroOmniLight_1 = require("./components/ViroOmniLight");
@@ -162,6 +164,7 @@ const VRModuleOpenXR_1 = require("./components/Utilities/VRModuleOpenXR");
162
164
  Object.defineProperty(exports, "VRModuleOpenXR", { enumerable: true, get: function () { return VRModuleOpenXR_1.VRModuleOpenXR; } });
163
165
  Object.defineProperty(exports, "useVRViewTag", { enumerable: true, get: function () { return VRModuleOpenXR_1.useVRViewTag; } });
164
166
  Object.defineProperty(exports, "exitVRScene", { enumerable: true, get: function () { return VRModuleOpenXR_1.exitVRScene; } });
167
+ Object.defineProperty(exports, "setPassthroughStyle", { enumerable: true, get: function () { return VRModuleOpenXR_1.setPassthroughStyle; } });
165
168
  const StreamingAudioManager_1 = require("./components/Utilities/StreamingAudioManager");
166
169
  Object.defineProperty(exports, "StreamingAudioManager", { enumerable: true, get: function () { return StreamingAudioManager_1.StreamingAudioManager; } });
167
170
  const react_native_1 = require("react-native");
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DEFAULTS = void 0;
4
- const config_plugins_1 = require("@expo/config-plugins");
5
4
  const withViroAndroid_1 = require("./withViroAndroid");
6
5
  const withViroIos_1 = require("./withViroIos");
7
6
  const CAMERA_USAGE = "Allow $(PRODUCT_NAME) to use your camera";
@@ -34,20 +33,8 @@ exports.DEFAULTS = {
34
33
  * @returns expo configuration
35
34
  */
36
35
  const withViro = (config, props) => {
37
- // Validate New Architecture is enabled
38
- const newArchEnabled = config.plugins?.some((plugin) => Array.isArray(plugin) &&
39
- plugin[0] === "expo-dev-client" &&
40
- plugin[1]?.newArchEnabled === true) || config.newArchEnabled === true;
41
- if (!newArchEnabled) {
42
- config_plugins_1.WarningAggregator.addWarningAndroid("withViro", "ViroReact requires React Native New Architecture (Fabric) to be enabled. " +
43
- "Please enable New Architecture in your app configuration. " +
44
- 'Add "newArchEnabled": true to your app.json/app.config.js expo configuration, ' +
45
- "or ensure your React Native project has New Architecture enabled.");
46
- config_plugins_1.WarningAggregator.addWarningIOS("withViro", "ViroReact requires React Native New Architecture (Fabric) to be enabled. " +
47
- "Please enable New Architecture in your app configuration. " +
48
- 'Add "newArchEnabled": true to your app.json/app.config.js expo configuration, ' +
49
- "or ensure your React Native project has New Architecture enabled.");
50
- }
36
+ // New Architecture is the only architecture in Expo SDK 53+ (and the React
37
+ // Native versions ViroReact supports), so there is nothing to validate here.
51
38
  // Apply platform-specific configurations
52
39
  config = (0, withViroIos_1.withViroIos)(config, props);
53
40
  config = (0, withViroAndroid_1.withViroAndroid)(config, props);
@@ -101,11 +101,6 @@ const withBranchAndroid = (config) => {
101
101
  ]);
102
102
  };
103
103
  const withViroProjectBuildGradle = (config) => (0, config_plugins_1.withProjectBuildGradle)(config, async (newConfig) => {
104
- // Enforce New Architecture requirement
105
- if (!newConfig.modResults.contents.includes("newArchEnabled=true")) {
106
- config_plugins_1.WarningAggregator.addWarningAndroid("withViroAndroid", "ViroReact requires New Architecture to be enabled. " +
107
- 'Please add "newArchEnabled=true" to your android/gradle.properties file.');
108
- }
109
104
  newConfig.modResults.contents = newConfig.modResults.contents.replace(/minSdkVersion.*/, `minSdkVersion = 24`);
110
105
  // Ensure New Architecture is enabled
111
106
  //if (!newConfig.modResults.contents.includes("newArchEnabled=true")) {
@@ -348,6 +343,24 @@ const withViroManifest = (config) => (0, config_plugins_1.withAndroidManifest)(c
348
343
  $: { "android:name": "com.oculus.permission.EYE_TRACKING" },
349
344
  });
350
345
  }
346
+ // Spatial Data / Scene permissions — required for the Meta OpenXR runtime
347
+ // to expose the scene & spatial-entity extensions (XR_FB_scene,
348
+ // XR_FB_spatial_entity*, XR_FB_scene_capture). Without USE_ANCHOR_API the
349
+ // runtime skips those extensions, so plane / anchor data is unavailable on
350
+ // Quest. These are runtime permissions — also require a grant at runtime.
351
+ const sceneAnchorPerms = [
352
+ "horizonos.permission.USE_ANCHOR_API", // gates XR_FB_scene / XR_FB_spatial_entity on current Horizon OS
353
+ "com.oculus.permission.USE_SCENE", // legacy Scene permission (older OS)
354
+ // Meta Passthrough Camera API (Quest 3 / 3S, Horizon OS v74+): grants the
355
+ // app the headset RGB cameras via Camera2, used by ViroObjectDetector to
356
+ // run on-device object detection over passthrough. Runtime-granted.
357
+ "horizonos.permission.HEADSET_CAMERA",
358
+ ];
359
+ for (const perm of sceneAnchorPerms) {
360
+ if (!existingPermissions.includes(perm)) {
361
+ contents.manifest["uses-permission"].push({ $: { "android:name": perm } });
362
+ }
363
+ }
351
364
  }
352
365
  return newConfig;
353
366
  });
@@ -35,12 +35,6 @@ const withViroPods = (config) => {
35
35
  }
36
36
  }
37
37
  fs_1.default.readFile(`${root}/Podfile`, "utf-8", (err, data) => {
38
- // Check for New Architecture environment variable
39
- if (!data.includes('ENV["RCT_NEW_ARCH_ENABLED"]') &&
40
- !data.includes("RCT_NEW_ARCH_ENABLED=1")) {
41
- config_plugins_1.WarningAggregator.addWarningIOS("withViroIos", "ViroReact requires New Architecture to be enabled. " +
42
- "Please set RCT_NEW_ARCH_ENABLED=1 in your ios/.xcode.env file.");
43
- }
44
38
  // ViroReact with integrated Fabric support
45
39
  let viroPods = ` # ViroReact with integrated New Architecture (Fabric) support\n` +
46
40
  ` # Automatically includes Fabric components when RCT_NEW_ARCH_ENABLED=1\n` +
package/index.ts CHANGED
@@ -48,6 +48,8 @@ import {
48
48
  import { ViroMaterialVideo } from "./components/ViroMaterialVideo";
49
49
  import { ViroCameraTexture } from "./components/ViroCameraTexture";
50
50
  export type { ViroCameraPosition, ViroCameraReadyEvent } from "./components/ViroCameraTexture";
51
+ import { ViroObjectDetector } from "./components/ViroObjectDetector";
52
+ export type { ViroDetectorMode, ViroDetectedObject, ViroDetectionBoundingBox, ViroDetectionEvent, ViroDetectorReadyEvent, ViroDetectorErrorEvent } from "./components/ViroObjectDetector";
51
53
  import { ViroNode } from "./components/ViroNode";
52
54
  import { ViroOmniLight } from "./components/ViroOmniLight";
53
55
  import { ViroOrbitCamera } from "./components/ViroOrbitCamera";
@@ -185,8 +187,8 @@ import { ViroSceneNavigator } from "./components/ViroSceneNavigator";
185
187
  import { VIRO_VERSION } from "./components/Utilities/ViroVersion";
186
188
  import { ViroQuestEntryPoint } from "./components/ViroQuestEntryPoint";
187
189
  import { VRQuestNavigatorBridge } from "./components/Utilities/VRQuestNavigatorBridge";
188
- import { VRModuleOpenXR, useVRViewTag, exitVRScene } from "./components/Utilities/VRModuleOpenXR";
189
- import type { VRModuleOpenXRType } from "./components/Utilities/VRModuleOpenXR";
190
+ import { VRModuleOpenXR, useVRViewTag, exitVRScene, setPassthroughStyle } from "./components/Utilities/VRModuleOpenXR";
191
+ import type { VRModuleOpenXRType, ViroPassthroughStyle } from "./components/Utilities/VRModuleOpenXR";
190
192
  import { StreamingAudioManager } from "./components/Utilities/StreamingAudioManager";
191
193
  import { AppRegistry } from "react-native";
192
194
 
@@ -223,6 +225,7 @@ export {
223
225
  ViroARCamera,
224
226
  ViroMaterialVideo,
225
227
  ViroCameraTexture,
228
+ ViroObjectDetector,
226
229
  ViroNode,
227
230
  ViroOmniLight,
228
231
  ViroOrbitCamera,
@@ -259,6 +262,7 @@ export {
259
262
  VRModuleOpenXR,
260
263
  useVRViewTag,
261
264
  exitVRScene,
265
+ setPassthroughStyle,
262
266
  Viro3DSceneNavigator,
263
267
  // Streaming audio
264
268
  StreamingAudioManager,
@@ -388,7 +392,7 @@ export {
388
392
  exitImmersiveSpace,
389
393
  };
390
394
 
391
- export type { VRModuleOpenXRType };
395
+ export type { VRModuleOpenXRType, ViroPassthroughStyle };
392
396
  export type { ImmersiveSpaceStyle } from "./components/VisionOS/ViroVisionOSModule";
393
397
 
394
398
  export type {
@@ -18,16 +18,20 @@ Pod::Spec.new do |s|
18
18
  # visionOS: CompositorServices drives the immersive render loop.
19
19
  s.visionos.frameworks = ['Metal', 'MetalKit', 'CompositorServices', 'ARKit']
20
20
 
21
+ # iOS: frameworks required by source files compiled from the pod
22
+ # (VRTObjectDetectorView uses AVFoundation + Accelerate; CoreVideo for CVPixelBuffer)
23
+ s.ios.frameworks = ['AVFoundation', 'Accelerate', 'CoreVideo']
24
+
21
25
  # Base source files (always included)
22
26
  source_files_array = ['ViroReact/**/*.{h,m,mm,swift}']
23
27
  header_files_array = ['ViroReact/**/*.h']
24
-
28
+
25
29
  # Include dist files if they exist (for release builds)
26
30
  if File.exist?(File.join(__dir__, 'dist/include'))
27
31
  source_files_array << 'dist/include/**/*.{h,m,mm}'
28
32
  header_files_array << 'dist/include/*.h'
29
33
  end
30
-
34
+
31
35
  s.source_files = source_files_array
32
36
  s.public_header_files = header_files_array
33
37
 
@@ -39,15 +43,30 @@ Pod::Spec.new do |s|
39
43
  if File.exist?(File.join(__dir__, 'dist/lib/libViroReact.a'))
40
44
  s.vendored_libraries = 'dist/lib/libViroReact.a'
41
45
  end
42
-
46
+
43
47
  # React Native dependencies
44
48
  s.dependency 'React-Core'
45
-
49
+
50
+ # ONNX Runtime is distributed as a vendored dynamic xcframework (onnxruntime.xcframework).
51
+ # When the xcframework is present in ios/dist/Frameworks/, enable inference by setting:
52
+ # GCC_PREPROCESSOR_DEFINITIONS = $(inherited) VIRO_ONNXRUNTIME_AVAILABLE=1
53
+ # Until then, VRTObjectDetectorView compiles with the camera pipeline active
54
+ # and inference returning empty results.
55
+ if File.exist?(File.join(__dir__, 'dist/Frameworks/onnxruntime.xcframework'))
56
+ s.vendored_frameworks = [
57
+ 'dist/ViroRenderer/ViroKit.framework',
58
+ 'dist/Frameworks/onnxruntime.xcframework'
59
+ ]
60
+ s.pod_target_xcconfig = {
61
+ 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) RCT_NEW_ARCH_ENABLED=1 VIRO_ONNXRUNTIME_AVAILABLE=1'
62
+ }
63
+ end
64
+
46
65
  # Fabric dependencies
47
66
  s.dependency 'React-RCTFabric'
48
67
  s.dependency 'React-Fabric'
49
68
  s.dependency 'React-FabricComponents'
50
-
69
+
51
70
  # Fabric-specific build configuration
52
71
  s.pod_target_xcconfig = {
53
72
  'SWIFT_VERSION' => '5.0',
@@ -63,5 +82,5 @@ Pod::Spec.new do |s|
63
82
  'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) RCT_NEW_ARCH_ENABLED=1',
64
83
  'OTHER_CPLUSPLUSFLAGS' => '$(inherited) -std=c++17'
65
84
  }
66
-
85
+
67
86
  end
@@ -144,6 +144,15 @@ private:
144
144
  */
145
145
  float sampleDepthTextureAtUV(std::shared_ptr<VROTexture> texture, float u, float v) const;
146
146
 
147
+ /*
148
+ Unproject a camera-image-space point (normalized [0,1] in ARKit's landscape image
149
+ space, the same space used for [ARFrame hitTest:]) at a given metric depth (meters
150
+ along the optical axis) to a world-space position. Returns false if camera
151
+ intrinsics are unavailable. Used to build a depth-derived DepthPoint hit result.
152
+ */
153
+ bool unprojectToWorld(VROVector3f cameraImagePoint, float depthMeters,
154
+ VROVector3f &outWorld) const;
155
+
147
156
  };
148
157
 
149
158
  #endif
@@ -44,6 +44,12 @@ public:
44
44
  virtual void onTrackingUpdated(VROARTrackingState state, VROARTrackingStateReason reason) = 0;
45
45
  virtual void onAmbientLightUpdate(float ambientLightIntensity, VROVector3f ambientLightColor) = 0;
46
46
  virtual void onWorldMeshUpdated(const VROWorldMeshStats& stats) {}
47
+
48
+ /*
49
+ Called once when depth data (LiDAR or monocular) first becomes available for the
50
+ session, i.e. hit tests can now return DepthPoints. Optional.
51
+ */
52
+ virtual void onDepthReady() {}
47
53
  };
48
54
 
49
55
  class VROARScene : public VROScene {
@@ -113,6 +119,12 @@ public:
113
119
  void setDelegate(std::shared_ptr<VROARSceneDelegate> delegate);
114
120
  void setTrackingState(VROARTrackingState state, VROARTrackingStateReason reason, bool force);
115
121
 
122
+ /*
123
+ Notify the delegate that depth data is now available. Fires the delegate's
124
+ onDepthReady() exactly once per scene; subsequent calls are no-ops.
125
+ */
126
+ void notifyDepthReady();
127
+
116
128
  /*
117
129
  Get the ambient light estimate of the scene.
118
130
  */
@@ -180,7 +192,8 @@ private:
180
192
  std::shared_ptr<VRONode> _pointCloudNode;
181
193
  std::shared_ptr<VROFixedParticleEmitter> _pointCloudEmitter;
182
194
  std::weak_ptr<VROARSceneDelegate> _delegate;
183
-
195
+ bool _depthReadyNotified = false;
196
+
184
197
  /*
185
198
  Ambient light estimation. The intensity is in lumens and the color is in linear space.
186
199
  */
@@ -38,6 +38,8 @@
38
38
  - (void)onAnchorFound:(std::shared_ptr<VROARAnchor>)anchor;
39
39
  - (void)onAnchorUpdated:(std::shared_ptr<VROARAnchor>)anchor;
40
40
  - (void)onAnchorRemoved:(std::shared_ptr<VROARAnchor>)anchor;
41
+ @optional
42
+ - (void)onDepthReady;
41
43
  @end
42
44
 
43
45
  class VROARSceneDelegateiOS : public VROARSceneDelegate, public VROARDeclarativeSessionDelegate {
@@ -71,6 +73,12 @@ public:
71
73
  [_delegate onAmbientLightUpdate:intensity color:color];
72
74
  }
73
75
 
76
+ virtual void onDepthReady() {
77
+ if ([_delegate respondsToSelector:@selector(onDepthReady)]) {
78
+ [_delegate onDepthReady];
79
+ }
80
+ }
81
+
74
82
  private:
75
83
  __weak id<VROARSceneDelegateProtocol> _delegate;
76
84
  };
@@ -188,7 +188,11 @@ private:
188
188
  static bool processAnimations(const tinygltf::Model &gModel);
189
189
  static bool processKeyFrameAnimations(const tinygltf::Model &gModel,
190
190
  std::map<int, std::map<int, std::vector<int>>> &gltfAnimatedNodes);
191
- static void flattenSkeletalKeyframeAnimations(
191
+ // Resample all of a skin's animation channels onto a single common time-grid and merge each
192
+ // joint's per-property channels into one index-aligned VROKeyframeAnimation. Replaces the old
193
+ // drop-mismatched-channels flatten (VIRO-5741) so mixed STEP/LINEAR, multi-time-grid glTF
194
+ // animations (e.g. Blender exports) play fully instead of freezing.
195
+ static void resampleSkeletalChannelsToCommonGrid(
192
196
  std::map<int, std::pair<int, std::vector<int>>> &skeletalAnimToNodeSkinPair,
193
197
  int skinIndex);
194
198
  static std::shared_ptr<VROKeyframeAnimation> convertChannelToKeyFrameAnimation(
@@ -135,6 +135,16 @@ public:
135
135
  */
136
136
  void update(const VROARFrame *frame);
137
137
 
138
+ /**
139
+ * Run a single throwaway inference on a blank image to force CoreML / Neural Engine
140
+ * model specialization up front. Without this, the FIRST real inference pays the
141
+ * full ANE compile cost (many seconds on A-series chips) — the dominant cause of the
142
+ * long delay before the first depth frame appears. Safe to call once right after
143
+ * initWithModel(); runs asynchronously on the depth queue and does not touch the
144
+ * live depth buffers (it uses a private throwaway request).
145
+ */
146
+ void warmup();
147
+
138
148
  #pragma mark - Depth Output
139
149
 
140
150
  /**
@@ -0,0 +1,134 @@
1
+ //
2
+ // VROObjectDetector.h
3
+ // ViroRenderer
4
+ //
5
+ // Copyright © 2026 ReactVision. All rights reserved.
6
+ //
7
+ // Permission is hereby granted, free of charge, to any person obtaining
8
+ // a copy of this software and associated documentation files (the
9
+ // "Software"), to deal in the Software without restriction, including
10
+ // without limitation the rights to use, copy, modify, merge, publish,
11
+ // distribute, sublicense, and/or sell copies of the Software, and to
12
+ // permit persons to whom the Software is furnished to do so, subject to
13
+ // the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included
16
+ // in all copies or substantial portions of the Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
+ // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22
+ // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
+ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
+ // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ #ifndef VROObjectDetector_h
27
+ #define VROObjectDetector_h
28
+
29
+ #include <string>
30
+ #include <vector>
31
+ #include <functional>
32
+ #include <memory>
33
+
34
+ /*
35
+ Bounding box in normalized image space [0, 1].
36
+ Origin is top-left corner of the image.
37
+ */
38
+ struct VRODetectionBoundingBox {
39
+ float x; // left edge
40
+ float y; // top edge
41
+ float width;
42
+ float height;
43
+ };
44
+
45
+ struct VRODetectedObject {
46
+ std::string label;
47
+ float confidence;
48
+ VRODetectionBoundingBox boundingBox;
49
+ };
50
+
51
+ /*
52
+ Inference mode matching YOLOE's three prompting strategies:
53
+ - PromptFree: LRPC head, 4,585 built-in RAM++ categories, no runtime prompt needed.
54
+ - Text: RepRTA, detect arbitrary categories given a list of text labels.
55
+ - Visual: SAVPE, detect objects similar to a reference image crop.
56
+ */
57
+ enum class VRODetectorMode {
58
+ PromptFree,
59
+ Text,
60
+ Visual,
61
+ };
62
+
63
+ using VRODetectionCallback = std::function<void(const std::vector<VRODetectedObject> &)>;
64
+
65
+ /*
66
+ Abstract base class for on-device object detectors.
67
+
68
+ Platform implementations (iOS: CoreML / ONNX Runtime, Android: ONNX Runtime)
69
+ subclass this and implement loadModel() and detectInBuffer(). The bridge layer
70
+ owns the camera pipeline and calls detectInBuffer() on each sampled frame.
71
+ */
72
+ class VROObjectDetector {
73
+ public:
74
+ virtual ~VROObjectDetector() {}
75
+
76
+ /*
77
+ Load the model from the given path.
78
+ On iOS: path to a .mlpackage (CoreML) or .onnx file.
79
+ On Android: path to a .onnx file inside the app's assets or files dir.
80
+ Returns true on success.
81
+ */
82
+ virtual bool loadModel(const std::string &modelPath) = 0;
83
+
84
+ /*
85
+ Run detection on a raw RGB pixel buffer.
86
+ - pixels: pointer to contiguous RGB888 data (row-major)
87
+ - width / height: image dimensions in pixels
88
+ Results are delivered asynchronously via the detection callback.
89
+ */
90
+ virtual void detectInBuffer(const uint8_t *pixels, int width, int height) = 0;
91
+
92
+ // --- configuration (call before loadModel or between frames) ---
93
+
94
+ void setMode(VRODetectorMode mode) {
95
+ _mode = mode;
96
+ }
97
+
98
+ /*
99
+ Text categories for Text mode (e.g. {"chair", "person", "laptop"}).
100
+ Ignored in PromptFree and Visual modes.
101
+ */
102
+ void setCategories(const std::vector<std::string> &categories) {
103
+ _categories = categories;
104
+ }
105
+
106
+ void setConfidenceThreshold(float threshold) {
107
+ _confidenceThreshold = threshold;
108
+ }
109
+
110
+ /*
111
+ NMS IoU threshold used during post-processing.
112
+ */
113
+ void setIouThreshold(float threshold) {
114
+ _iouThreshold = threshold;
115
+ }
116
+
117
+ void setCallback(VRODetectionCallback callback) {
118
+ _callback = callback;
119
+ }
120
+
121
+ VRODetectorMode getMode() const { return _mode; }
122
+ float getConfidenceThreshold() const { return _confidenceThreshold; }
123
+ float getIouThreshold() const { return _iouThreshold; }
124
+ const std::vector<std::string> &getCategories() const { return _categories; }
125
+
126
+ protected:
127
+ VRODetectorMode _mode = VRODetectorMode::PromptFree;
128
+ std::vector<std::string> _categories;
129
+ float _confidenceThreshold = 0.4f;
130
+ float _iouThreshold = 0.45f;
131
+ VRODetectionCallback _callback;
132
+ };
133
+
134
+ #endif /* VROObjectDetector_h */
@@ -1,5 +1,5 @@
1
1
  dependencies: \
2
2
  /Users/dorantes/Documents/ViroWorkspace/virocore/ViroRenderer/Shaders.metal \
3
- /private/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.6.42.0.AHiUEg/Metal.xctoolchain/usr/metal/32023/lib/clang/32023.883/include/metal/module.modulemap \
3
+ /private/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.6.109.0.hR8Z6P/Metal.xctoolchain/usr/metal/32023/lib/clang/32023.883/include/metal/module.modulemap \
4
4
  /Users/dorantes/Documents/ViroWorkspace/virocore/ViroRenderer/VROSharedStructures.h \
5
5
  /Users/dorantes/Documents/ViroWorkspace/virocore/ViroRenderer/VRODefines.h
@@ -0,0 +1,27 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'ViroKit'
3
+ s.version = '1.0'
4
+ s.summary = 'Framework containing the ViroRenderer (visionOS / xros)'
5
+ s.description = <<-DESC
6
+ ViroKit is the core rendering framework for ViroReact.
7
+
8
+ This is the visionOS (xros) distribution: a Metal-only build of the
9
+ ViroRenderer packaged as an xcframework with both the device (xros-arm64)
10
+ and simulator (xros-arm64_x86_64-simulator) slices. It plugs into the
11
+ CompositorServices immersive render loop via VRORendererBridge.
12
+ DESC
13
+ s.source = { :path => '.' } # source is required, but path is defined in the user's Podfile (this value is ignored).
14
+ s.vendored_frameworks = 'ViroKit.xcframework'
15
+ s.homepage = 'https://reactvision.xyz'
16
+ s.license = {:type => 'Copyright', :text => "Copyright 2025 ReactVision" }
17
+ s.author = 'ReactVision'
18
+ s.requires_arc = true
19
+ s.platform = :visionos, '1.0'
20
+ s.visionos.deployment_target = '1.0'
21
+ s.dependency 'React'
22
+
23
+ # visionOS requires CompositorServices for the immersive render loop.
24
+ # Metal and MetalKit are available on both iOS and visionOS; ARKit provides
25
+ # world / hand tracking.
26
+ s.visionos.frameworks = ['Metal', 'MetalKit', 'CompositorServices', 'ARKit']
27
+ end
@@ -36,6 +36,7 @@
36
36
  @property (nonatomic, copy, nullable) NSArray<NSString *> *anchorDetectionTypes;
37
37
  @property (nonatomic, copy, nullable) RCTDirectEventBlock onTrackingUpdatedViro;
38
38
  @property (nonatomic, copy, nullable) RCTDirectEventBlock onAmbientLightUpdateViro;
39
+ @property (nonatomic, copy, nullable) RCTDirectEventBlock onDepthReadyViro;
39
40
 
40
41
  @property (nonatomic, copy, nullable) RCTDirectEventBlock onAnchorFoundViro;
41
42
  @property (nonatomic, copy, nullable) RCTDirectEventBlock onAnchorUpdatedViro;
Binary file
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "dist/index.js",
4
4
  "module": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
- "version": "2.56.0",
6
+ "version": "2.57.2",
7
7
  "license": "MIT",
8
8
  "publishConfig": {
9
9
  "registry": "https://registry.npmjs.org/"
@@ -27,11 +27,12 @@
27
27
  "prepare": "npm run build"
28
28
  },
29
29
  "peerDependencies": {
30
- "expo": ">=54.0.0 <56.0.0",
31
- "react-native": ">=0.81.0 <0.84.0"
30
+ "expo": ">=55.0.0 <57.0.0",
31
+ "react": ">=18.0.0",
32
+ "react-native": ">=0.83.0 <0.86.0"
32
33
  },
33
34
  "engines": {
34
- "react-native": ">=0.81.0 <0.84.0"
35
+ "react-native": ">=0.83.0 <0.86.0"
35
36
  },
36
37
  "peerDependenciesMeta": {
37
38
  "expo": {
@@ -56,31 +57,27 @@
56
57
  "bin",
57
58
  "LICENSE"
58
59
  ],
59
- "dependencies": {
60
- "@expo/config-plugins": "^9.0.14",
61
- "react": "~19.2.0",
62
- "react-native-gradle-plugin": "^0.71.19"
63
- },
64
60
  "devDependencies": {
65
61
  "@babel/core": "^7.25.2",
66
62
  "@babel/preset-env": "^7.25.3",
67
63
  "@babel/preset-typescript": "^7.26.0",
64
+ "@expo/config-plugins": "~56.0.8",
68
65
  "@jest/globals": "^29.7.0",
69
- "@react-native-community/cli": "^15.0.1",
70
- "@react-native-community/cli-platform-android": "^15.0.1",
71
- "@react-native-community/cli-platform-ios": "^15.0.1",
72
- "@react-native/babel-preset": "^0.77.0",
73
- "@react-native/eslint-config": "^0.77.0",
74
- "@react-native/metro-config": "^0.77.0",
75
- "@react-native/typescript-config": "^0.77.0",
66
+ "@react-native-community/cli": "^20.1.3",
67
+ "@react-native-community/cli-platform-android": "^20.1.3",
68
+ "@react-native-community/cli-platform-ios": "^20.1.3",
69
+ "@react-native/babel-preset": "^0.85.3",
70
+ "@react-native/eslint-config": "^0.85.3",
71
+ "@react-native/metro-config": "^0.85.3",
72
+ "@react-native/typescript-config": "^0.85.3",
76
73
  "@types/babel__core": "^7.20.5",
77
74
  "@types/node": "^22.13.1",
78
- "@types/react": "~19.2.10",
79
- "@types/react-native": "^0.73.0",
75
+ "@types/react": "~19.2.17",
80
76
  "babel-jest": "^29.7.0",
81
- "expo": "~55.0.8",
77
+ "expo": "~56.0.9",
82
78
  "jest": "^29.7.0",
83
- "react-native": "~0.83.2",
79
+ "react": "~19.2.3",
80
+ "react-native": "~0.85.3",
84
81
  "release-it": "^17.1.1",
85
82
  "ts-node": "^10.9.2",
86
83
  "typescript": "^5.3.0"