@reactvision/react-viro 2.55.0 → 2.57.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.
- package/README.md +27 -0
- package/android/react_viro/react_viro-release.aar +0 -0
- package/android/viro_renderer/viro_renderer-release.aar +0 -0
- package/components/AR/ViroARScene.tsx +17 -0
- package/components/AR/ViroARSceneNavigator.tsx +33 -0
- package/components/Utilities/StreamingAudioManager.ts +73 -0
- package/components/Utilities/ViroVersion.ts +1 -1
- package/components/ViroCameraTexture.tsx +230 -0
- package/components/ViroGameLoop.tsx +74 -0
- package/components/ViroGameLoopUtils.ts +52 -0
- package/components/ViroObjectDetector.tsx +222 -0
- package/components/ViroVirtualButton.tsx +101 -0
- package/components/ViroVirtualJoystick.tsx +126 -0
- package/components/hooks/useGameLoop.ts +78 -0
- package/dist/components/AR/ViroARScene.d.ts +12 -0
- package/dist/components/AR/ViroARScene.js +8 -1
- package/dist/components/AR/ViroARSceneNavigator.d.ts +30 -0
- package/dist/components/Utilities/StreamingAudioManager.d.ts +22 -0
- package/dist/components/Utilities/StreamingAudioManager.js +45 -0
- package/dist/components/Utilities/ViroVersion.d.ts +1 -1
- package/dist/components/Utilities/ViroVersion.js +1 -1
- package/dist/components/ViroCameraTexture.d.ts +137 -0
- package/dist/components/ViroCameraTexture.js +170 -0
- package/dist/components/ViroGameLoop.d.ts +31 -0
- package/dist/components/ViroGameLoop.js +31 -0
- package/dist/components/ViroGameLoopUtils.d.ts +26 -0
- package/dist/components/ViroGameLoopUtils.js +44 -0
- package/dist/components/ViroObjectDetector.d.ts +138 -0
- package/dist/components/ViroObjectDetector.js +85 -0
- package/dist/components/ViroVirtualButton.d.ts +76 -0
- package/dist/components/ViroVirtualButton.js +62 -0
- package/dist/components/ViroVirtualJoystick.d.ts +85 -0
- package/dist/components/ViroVirtualJoystick.js +72 -0
- package/dist/components/hooks/useGameLoop.d.ts +34 -0
- package/dist/components/hooks/useGameLoop.js +63 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +20 -2
- package/dist/plugins/withViro.js +2 -15
- package/dist/plugins/withViroAndroid.js +52 -15
- package/dist/plugins/withViroIos.js +0 -6
- package/index.ts +21 -0
- package/ios/ViroReact.podspec +25 -6
- 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/VROARDepthMesh.h +9 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARFrame.h +33 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARFrameiOS.h +26 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARScene.h +15 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSceneDelegateiOS.h +8 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSession.h +7 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSessioniOS.h +18 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARWorldMesh.h +111 -8
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROAudioPlayer.h +19 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROAudioPlayerStreamiOS.h +95 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROCameraTextureiOS.h +17 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRODriver.h +20 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRODynamicGeometry.h +170 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRODynamicMeshNode.h +87 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROGLTFLoader.h +5 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROGameLoopListener.h +125 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROInputState.h +133 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMonocularDepthEstimator.h +73 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROObjectDetector.h +134 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPCMRingBuffer.h +143 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPencil.h +9 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderContext.h +4 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderer.h +1 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROVertexBuffer.h +102 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROViewAR.h +9 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROVirtualControllerRegistry.h +106 -0
- 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/ViroRenderer/ViroKit.framework/constant_fsh.glsl +1 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/constant_fsh_adreno.glsl +1 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/standard_fsh.glsl +1 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/standard_vsh.glsl +4 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/standard_vsh_adreno.glsl +4 -0
- package/ios/dist/ViroRendererVisionOS/ViroKit.podspec +27 -0
- package/ios/dist/include/VRTARScene.h +1 -0
- package/ios/dist/include/VRTARSceneNavigator.h +3 -0
- package/ios/dist/include/VRTCameraTexture.h +62 -0
- package/ios/dist/include/VRTCameraTextureManager.h +30 -0
- package/ios/dist/include/VRTCameraTextureModule.h +38 -0
- package/ios/dist/include/VRTGameLoopView.h +19 -0
- package/ios/dist/include/VRTGameLoopViewManager.h +8 -0
- package/ios/dist/include/VRTManagedAnimation.h +67 -0
- package/ios/dist/include/VRTStreamingAudioModule.h +21 -0
- package/ios/dist/include/VRTVirtualButtonView.h +47 -0
- package/ios/dist/include/VRTVirtualButtonViewManager.h +21 -0
- package/ios/dist/include/VRTVirtualJoystickView.h +59 -0
- package/ios/dist/include/VRTVirtualJoystickViewManager.h +26 -0
- package/ios/dist/lib/libViroReact.a +0 -0
- package/package.json +17 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VIRO_VERSION = "2.
|
|
1
|
+
export declare const VIRO_VERSION = "2.57.0";
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, ReactVision, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { NativeSyntheticEvent, ViewProps } from "react-native";
|
|
10
|
+
import { ViroErrorEvent } from "./Types/ViroEvents";
|
|
11
|
+
import { ViroNativeRef } from "./Types/ViroUtils";
|
|
12
|
+
export type ViroCameraPosition = "front" | "back";
|
|
13
|
+
export type ViroCameraReadyEvent = Record<string, never>;
|
|
14
|
+
/**
|
|
15
|
+
* Result returned by capturePhoto / startRecording / stopRecording.
|
|
16
|
+
* Mirrors the response shape from both iOS and Android NativeModules.
|
|
17
|
+
*/
|
|
18
|
+
export type ViroCaptureResult = {
|
|
19
|
+
success: true;
|
|
20
|
+
url: string;
|
|
21
|
+
} | {
|
|
22
|
+
success: false;
|
|
23
|
+
error: string;
|
|
24
|
+
};
|
|
25
|
+
export type ViroCapturePhotoOptions = {
|
|
26
|
+
/** Absolute file path for the JPEG. Defaults to a cache-dir path. */
|
|
27
|
+
outputPath?: string;
|
|
28
|
+
};
|
|
29
|
+
export type ViroCaptureVideoOptions = {
|
|
30
|
+
/** Absolute file path for the MP4. Defaults to a cache-dir path. */
|
|
31
|
+
outputPath?: string;
|
|
32
|
+
};
|
|
33
|
+
type Props = ViewProps & {
|
|
34
|
+
/**
|
|
35
|
+
* Name of the material (created via ViroMaterials.createMaterials) to bind
|
|
36
|
+
* the live camera feed to as its diffuse texture. Unlike ViroMaterialVideo,
|
|
37
|
+
* this component creates the camera texture internally and sets it on the
|
|
38
|
+
* named material — the material only needs a lightingModel defined.
|
|
39
|
+
*/
|
|
40
|
+
material: string;
|
|
41
|
+
/**
|
|
42
|
+
* Which device camera to use. Front camera feed is automatically mirrored
|
|
43
|
+
* for a natural selfie effect. Defaults to "front".
|
|
44
|
+
*/
|
|
45
|
+
cameraPosition?: ViroCameraPosition;
|
|
46
|
+
/**
|
|
47
|
+
* Whether camera capture is paused. When true the last captured frame is
|
|
48
|
+
* held and battery usage drops to near zero. Defaults to false.
|
|
49
|
+
*/
|
|
50
|
+
paused?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Called once when the first camera frame is available and the texture is
|
|
53
|
+
* ready to be rendered. Fires from the native AVFoundation / Camera2 callback,
|
|
54
|
+
* not immediately on mount.
|
|
55
|
+
*/
|
|
56
|
+
onCameraReady?: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Called when the camera fails to initialise (permission denied, hardware
|
|
59
|
+
* error, invalid material name, etc.).
|
|
60
|
+
*/
|
|
61
|
+
onError?: (event: NativeSyntheticEvent<ViroErrorEvent>) => void;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* ViroCameraTexture binds a live device camera feed to a named material texture.
|
|
65
|
+
*
|
|
66
|
+
* The component creates the camera texture internally and sets it on the material,
|
|
67
|
+
* so the material only needs a lightingModel. The texture is updated every frame.
|
|
68
|
+
*
|
|
69
|
+
* **Usage:**
|
|
70
|
+
* ```tsx
|
|
71
|
+
* import { ViroMaterials, ViroQuad, ViroCameraTexture } from '@reactvision/react-viro';
|
|
72
|
+
*
|
|
73
|
+
* ViroMaterials.createMaterials({
|
|
74
|
+
* selfieMat: { lightingModel: 'Constant' },
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* <ViroARScene>
|
|
78
|
+
* <ViroQuad position={[0, 0, -2]} width={1.6} height={2.4} materials={["selfieMat"]} />
|
|
79
|
+
* <ViroCameraTexture
|
|
80
|
+
* material="selfieMat"
|
|
81
|
+
* cameraPosition="front"
|
|
82
|
+
* onCameraReady={() => console.log('Camera ready')}
|
|
83
|
+
* onError={(e) => console.error(e.nativeEvent.error)}
|
|
84
|
+
* />
|
|
85
|
+
* </ViroARScene>
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare class ViroCameraTexture extends React.Component<Props> {
|
|
89
|
+
_component: ViroNativeRef;
|
|
90
|
+
_onCameraReady: () => void;
|
|
91
|
+
_onError: (event: NativeSyntheticEvent<ViroErrorEvent>) => void;
|
|
92
|
+
/**
|
|
93
|
+
* Capture a single JPEG still from the camera feed.
|
|
94
|
+
*
|
|
95
|
+
* @param options.outputPath Absolute path for the output JPEG.
|
|
96
|
+
* Omit to let the native layer choose a default
|
|
97
|
+
* cache-directory path.
|
|
98
|
+
* @returns Promise resolving to `{ success: true, url }` on success or
|
|
99
|
+
* `{ success: false, error }` on failure.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* const result = await cameraRef.current?.capturePhoto();
|
|
104
|
+
* if (result?.success) console.log('Saved to', result.url);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
capturePhoto(options?: ViroCapturePhotoOptions): Promise<ViroCaptureResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Start recording the camera feed to an MP4 file.
|
|
110
|
+
*
|
|
111
|
+
* The promise resolves once the recording session has successfully started.
|
|
112
|
+
* Call {@link stopRecording} to finalise the file.
|
|
113
|
+
*
|
|
114
|
+
* @param options.outputPath Absolute path for the output MP4.
|
|
115
|
+
* Omit to let the native layer choose a default.
|
|
116
|
+
* @returns Promise resolving to `{ success: true, url }` (the path that
|
|
117
|
+
* will be written) or `{ success: false, error }`.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* await cameraRef.current?.startRecording();
|
|
122
|
+
* // … some time later …
|
|
123
|
+
* const result = await cameraRef.current?.stopRecording();
|
|
124
|
+
* if (result?.success) console.log('Video saved to', result.url);
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
startRecording(options?: ViroCaptureVideoOptions): Promise<ViroCaptureResult>;
|
|
128
|
+
/**
|
|
129
|
+
* Stop an in-progress recording and finalise the MP4 file.
|
|
130
|
+
*
|
|
131
|
+
* @returns Promise resolving to `{ success: true, url }` with the path of
|
|
132
|
+
* the written file, or `{ success: false, error }`.
|
|
133
|
+
*/
|
|
134
|
+
stopRecording(): Promise<ViroCaptureResult>;
|
|
135
|
+
render(): React.JSX.Element;
|
|
136
|
+
}
|
|
137
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026-present, ReactVision, Inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the BSD-style license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.ViroCameraTexture = void 0;
|
|
44
|
+
const React = __importStar(require("react"));
|
|
45
|
+
const react_native_1 = require("react-native");
|
|
46
|
+
const { VRTCameraTextureModule } = react_native_1.NativeModules;
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Component
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* ViroCameraTexture binds a live device camera feed to a named material texture.
|
|
52
|
+
*
|
|
53
|
+
* The component creates the camera texture internally and sets it on the material,
|
|
54
|
+
* so the material only needs a lightingModel. The texture is updated every frame.
|
|
55
|
+
*
|
|
56
|
+
* **Usage:**
|
|
57
|
+
* ```tsx
|
|
58
|
+
* import { ViroMaterials, ViroQuad, ViroCameraTexture } from '@reactvision/react-viro';
|
|
59
|
+
*
|
|
60
|
+
* ViroMaterials.createMaterials({
|
|
61
|
+
* selfieMat: { lightingModel: 'Constant' },
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* <ViroARScene>
|
|
65
|
+
* <ViroQuad position={[0, 0, -2]} width={1.6} height={2.4} materials={["selfieMat"]} />
|
|
66
|
+
* <ViroCameraTexture
|
|
67
|
+
* material="selfieMat"
|
|
68
|
+
* cameraPosition="front"
|
|
69
|
+
* onCameraReady={() => console.log('Camera ready')}
|
|
70
|
+
* onError={(e) => console.error(e.nativeEvent.error)}
|
|
71
|
+
* />
|
|
72
|
+
* </ViroARScene>
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
class ViroCameraTexture extends React.Component {
|
|
76
|
+
_component = null;
|
|
77
|
+
_onCameraReady = () => {
|
|
78
|
+
this.props.onCameraReady && this.props.onCameraReady();
|
|
79
|
+
};
|
|
80
|
+
_onError = (event) => {
|
|
81
|
+
this.props.onError && this.props.onError(event);
|
|
82
|
+
};
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Capture API
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
/**
|
|
87
|
+
* Capture a single JPEG still from the camera feed.
|
|
88
|
+
*
|
|
89
|
+
* @param options.outputPath Absolute path for the output JPEG.
|
|
90
|
+
* Omit to let the native layer choose a default
|
|
91
|
+
* cache-directory path.
|
|
92
|
+
* @returns Promise resolving to `{ success: true, url }` on success or
|
|
93
|
+
* `{ success: false, error }` on failure.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const result = await cameraRef.current?.capturePhoto();
|
|
98
|
+
* if (result?.success) console.log('Saved to', result.url);
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
async capturePhoto(options = {}) {
|
|
102
|
+
const tag = (0, react_native_1.findNodeHandle)(this._component);
|
|
103
|
+
if (tag == null) {
|
|
104
|
+
return { success: false, error: "ViroCameraTexture is not mounted" };
|
|
105
|
+
}
|
|
106
|
+
return VRTCameraTextureModule.capturePhoto(tag, options.outputPath ?? null);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Start recording the camera feed to an MP4 file.
|
|
110
|
+
*
|
|
111
|
+
* The promise resolves once the recording session has successfully started.
|
|
112
|
+
* Call {@link stopRecording} to finalise the file.
|
|
113
|
+
*
|
|
114
|
+
* @param options.outputPath Absolute path for the output MP4.
|
|
115
|
+
* Omit to let the native layer choose a default.
|
|
116
|
+
* @returns Promise resolving to `{ success: true, url }` (the path that
|
|
117
|
+
* will be written) or `{ success: false, error }`.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* await cameraRef.current?.startRecording();
|
|
122
|
+
* // … some time later …
|
|
123
|
+
* const result = await cameraRef.current?.stopRecording();
|
|
124
|
+
* if (result?.success) console.log('Video saved to', result.url);
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
async startRecording(options = {}) {
|
|
128
|
+
const tag = (0, react_native_1.findNodeHandle)(this._component);
|
|
129
|
+
if (tag == null) {
|
|
130
|
+
return { success: false, error: "ViroCameraTexture is not mounted" };
|
|
131
|
+
}
|
|
132
|
+
return VRTCameraTextureModule.startRecording(tag, options.outputPath ?? null);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Stop an in-progress recording and finalise the MP4 file.
|
|
136
|
+
*
|
|
137
|
+
* @returns Promise resolving to `{ success: true, url }` with the path of
|
|
138
|
+
* the written file, or `{ success: false, error }`.
|
|
139
|
+
*/
|
|
140
|
+
async stopRecording() {
|
|
141
|
+
const tag = (0, react_native_1.findNodeHandle)(this._component);
|
|
142
|
+
if (tag == null) {
|
|
143
|
+
return { success: false, error: "ViroCameraTexture is not mounted" };
|
|
144
|
+
}
|
|
145
|
+
return VRTCameraTextureModule.stopRecording(tag);
|
|
146
|
+
}
|
|
147
|
+
render() {
|
|
148
|
+
const nativeProps = Object.assign({}, this.props);
|
|
149
|
+
nativeProps.cameraPosition = this.props.cameraPosition ?? "front";
|
|
150
|
+
nativeProps.paused = this.props.paused ?? false;
|
|
151
|
+
nativeProps.onCameraReadyViro = this._onCameraReady;
|
|
152
|
+
nativeProps.onErrorViro = this._onError;
|
|
153
|
+
nativeProps.ref = (component) => {
|
|
154
|
+
this._component = component;
|
|
155
|
+
};
|
|
156
|
+
return <VRTCameraTexture {...nativeProps}/>;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.ViroCameraTexture = ViroCameraTexture;
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
// Native component binding
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
const VRTCameraTexture = (0, react_native_1.requireNativeComponent)("VRTCameraTexture",
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
ViroCameraTexture, {
|
|
166
|
+
nativeOnly: {
|
|
167
|
+
onCameraReadyViro: true,
|
|
168
|
+
onErrorViro: true,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViroGameLoop.tsx — headless component that fires per-frame JS callbacks.
|
|
3
|
+
*
|
|
4
|
+
* Mount anywhere inside a ViroARScene or ViroScene to start the loop.
|
|
5
|
+
* The loop automatically stops when the component unmounts.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* <ViroGameLoop onUpdate={(dt, elapsed) => { ... }} />
|
|
9
|
+
* <ViroGameLoop fixedHz={30} onFixedUpdate={(dt) => { ... }} />
|
|
10
|
+
*
|
|
11
|
+
* Copyright © 2026 ReactVision. All rights reserved.
|
|
12
|
+
*/
|
|
13
|
+
import React from "react";
|
|
14
|
+
export type ViroGameLoopUpdateEvent = {
|
|
15
|
+
dt: number;
|
|
16
|
+
elapsed: number;
|
|
17
|
+
};
|
|
18
|
+
export type ViroGameLoopFixedEvent = {
|
|
19
|
+
dt: number;
|
|
20
|
+
};
|
|
21
|
+
export type ViroGameLoopProps = {
|
|
22
|
+
/** Called every rendered frame. dt = seconds since last frame. */
|
|
23
|
+
onUpdate?: (event: ViroGameLoopUpdateEvent) => void;
|
|
24
|
+
/** Called after physics + rendering each frame (useLateUpdate equivalent). */
|
|
25
|
+
onLateUpdate?: (event: ViroGameLoopUpdateEvent) => void;
|
|
26
|
+
/** Fixed simulation frequency in Hz. When set, onFixedUpdate fires at this rate. */
|
|
27
|
+
fixedHz?: number;
|
|
28
|
+
/** Called at a fixed rate determined by fixedHz. */
|
|
29
|
+
onFixedUpdate?: (event: ViroGameLoopFixedEvent) => void;
|
|
30
|
+
};
|
|
31
|
+
export declare function ViroGameLoop({ onUpdate, onLateUpdate, onFixedUpdate, fixedHz, }: ViroGameLoopProps): React.JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ViroGameLoop.tsx — headless component that fires per-frame JS callbacks.
|
|
4
|
+
*
|
|
5
|
+
* Mount anywhere inside a ViroARScene or ViroScene to start the loop.
|
|
6
|
+
* The loop automatically stops when the component unmounts.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <ViroGameLoop onUpdate={(dt, elapsed) => { ... }} />
|
|
10
|
+
* <ViroGameLoop fixedHz={30} onFixedUpdate={(dt) => { ... }} />
|
|
11
|
+
*
|
|
12
|
+
* Copyright © 2026 ReactVision. All rights reserved.
|
|
13
|
+
*/
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ViroGameLoop = ViroGameLoop;
|
|
19
|
+
const react_1 = __importDefault(require("react"));
|
|
20
|
+
const react_native_1 = require("react-native");
|
|
21
|
+
const VRTGameLoopView = (0, react_native_1.requireNativeComponent)("VRTGameLoopView");
|
|
22
|
+
// ── Component ─────────────────────────────────────────────────────────────────
|
|
23
|
+
function ViroGameLoop({ onUpdate, onLateUpdate, onFixedUpdate, fixedHz, }) {
|
|
24
|
+
// Native sends dt/elapsed as strings to avoid Fabric conversions.h type-check spam.
|
|
25
|
+
const parse = (e) => ({
|
|
26
|
+
dt: parseFloat(e.nativeEvent.dt),
|
|
27
|
+
elapsed: parseFloat(e.nativeEvent.elapsed ?? "0"),
|
|
28
|
+
});
|
|
29
|
+
const parseFixed = (e) => ({ dt: parseFloat(e.nativeEvent.dt) });
|
|
30
|
+
return (<VRTGameLoopView onUpdate={onUpdate ? (e) => onUpdate(parse(e)) : undefined} onLateUpdate={onLateUpdate ? (e) => onLateUpdate(parse(e)) : undefined} onFixedUpdate={onFixedUpdate ? (e) => onFixedUpdate(parseFixed(e)) : undefined} fixedHz={fixedHz}/>);
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViroGameLoopUtils — direct node manipulation that bypasses the React reconciler.
|
|
3
|
+
*
|
|
4
|
+
* Call these from inside useGameLoop / onUpdate callbacks for zero-setState
|
|
5
|
+
* positional updates. The native NodeModule methods dispatch directly to the
|
|
6
|
+
* render thread via the existing VRONode::setPositionAtomic() infrastructure.
|
|
7
|
+
*
|
|
8
|
+
* Copyright © 2026 ReactVision. All rights reserved.
|
|
9
|
+
*/
|
|
10
|
+
import type React from "react";
|
|
11
|
+
export declare const ViroGameLoopUtils: {
|
|
12
|
+
/**
|
|
13
|
+
* Set the node's position without going through React state.
|
|
14
|
+
* Equivalent to <ViroNode position={[x,y,z]} /> but synchronous
|
|
15
|
+
* and reconciler-free — safe to call every frame.
|
|
16
|
+
*/
|
|
17
|
+
setPosition(nodeRef: React.RefObject<any>, position: [number, number, number]): void;
|
|
18
|
+
/**
|
|
19
|
+
* Set Euler rotation (degrees) without going through React state.
|
|
20
|
+
*/
|
|
21
|
+
setRotation(nodeRef: React.RefObject<any>, rotation: [number, number, number]): void;
|
|
22
|
+
/**
|
|
23
|
+
* Set uniform or non-uniform scale without going through React state.
|
|
24
|
+
*/
|
|
25
|
+
setScale(nodeRef: React.RefObject<any>, scale: [number, number, number]): void;
|
|
26
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ViroGameLoopUtils — direct node manipulation that bypasses the React reconciler.
|
|
4
|
+
*
|
|
5
|
+
* Call these from inside useGameLoop / onUpdate callbacks for zero-setState
|
|
6
|
+
* positional updates. The native NodeModule methods dispatch directly to the
|
|
7
|
+
* render thread via the existing VRONode::setPositionAtomic() infrastructure.
|
|
8
|
+
*
|
|
9
|
+
* Copyright © 2026 ReactVision. All rights reserved.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ViroGameLoopUtils = void 0;
|
|
13
|
+
const react_native_1 = require("react-native");
|
|
14
|
+
exports.ViroGameLoopUtils = {
|
|
15
|
+
/**
|
|
16
|
+
* Set the node's position without going through React state.
|
|
17
|
+
* Equivalent to <ViroNode position={[x,y,z]} /> but synchronous
|
|
18
|
+
* and reconciler-free — safe to call every frame.
|
|
19
|
+
*/
|
|
20
|
+
setPosition(nodeRef, position) {
|
|
21
|
+
const handle = (0, react_native_1.findNodeHandle)(nodeRef.current);
|
|
22
|
+
if (handle == null)
|
|
23
|
+
return;
|
|
24
|
+
react_native_1.UIManager.dispatchViewManagerCommand(handle, "setPosition", position);
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Set Euler rotation (degrees) without going through React state.
|
|
28
|
+
*/
|
|
29
|
+
setRotation(nodeRef, rotation) {
|
|
30
|
+
const handle = (0, react_native_1.findNodeHandle)(nodeRef.current);
|
|
31
|
+
if (handle == null)
|
|
32
|
+
return;
|
|
33
|
+
react_native_1.UIManager.dispatchViewManagerCommand(handle, "setRotationEuler", rotation);
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Set uniform or non-uniform scale without going through React state.
|
|
37
|
+
*/
|
|
38
|
+
setScale(nodeRef, scale) {
|
|
39
|
+
const handle = (0, react_native_1.findNodeHandle)(nodeRef.current);
|
|
40
|
+
if (handle == null)
|
|
41
|
+
return;
|
|
42
|
+
react_native_1.UIManager.dispatchViewManagerCommand(handle, "setScale", scale);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, ReactVision, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { ViewProps } from "react-native";
|
|
10
|
+
export type ViroDetectorMode = "prompt-free" | "text" | "visual";
|
|
11
|
+
export type ViroDetectionBoundingBox = {
|
|
12
|
+
/** Left edge, normalized [0, 1] */
|
|
13
|
+
x: number;
|
|
14
|
+
/** Top edge, normalized [0, 1] */
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
};
|
|
19
|
+
export type ViroDetectedObject = {
|
|
20
|
+
label: string;
|
|
21
|
+
confidence: number;
|
|
22
|
+
boundingBox: ViroDetectionBoundingBox;
|
|
23
|
+
/** 3D world position (metres), from raycasting the bbox centre. Present when `projectToWorld` is true (iOS only). */
|
|
24
|
+
worldPosition?: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
z: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Bounding box in density-independent points (dp), aligned to the on-screen AR
|
|
31
|
+
* camera preview. Use directly as { left, top, width, height } in an
|
|
32
|
+
* absolute-positioned View. Present on iOS and Android.
|
|
33
|
+
*/
|
|
34
|
+
screenBoundingBox?: {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type ViroDetectionEvent = {
|
|
42
|
+
detections: ViroDetectedObject[];
|
|
43
|
+
};
|
|
44
|
+
export type ViroDetectorReadyEvent = Record<string, never>;
|
|
45
|
+
export type ViroDetectorErrorEvent = {
|
|
46
|
+
error: string;
|
|
47
|
+
};
|
|
48
|
+
type Props = ViewProps & {
|
|
49
|
+
/**
|
|
50
|
+
* The YOLOE model to run. Either a bundled model **name** (resolved natively as
|
|
51
|
+
* `<name>.onnx` in the app bundle / Android assets), or an absolute `/`-path or
|
|
52
|
+
* `file://` URL to an `.onnx` file. Defaults to "yoloe-26s".
|
|
53
|
+
*/
|
|
54
|
+
model?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Inference mode:
|
|
57
|
+
* - "prompt-free": YOLOE LRPC — detects 4,585 categories with no extra prompt.
|
|
58
|
+
* - "text": YOLOE RepRTA — detect only the classes listed in `categories`.
|
|
59
|
+
* - "visual": YOLOE SAVPE — detect objects similar to a reference crop
|
|
60
|
+
* (reference image API to be added in a future release).
|
|
61
|
+
* Defaults to "prompt-free".
|
|
62
|
+
*/
|
|
63
|
+
mode?: ViroDetectorMode;
|
|
64
|
+
/**
|
|
65
|
+
* Text categories for "text" mode, e.g. ["chair", "person", "laptop"].
|
|
66
|
+
* Ignored in other modes.
|
|
67
|
+
*/
|
|
68
|
+
categories?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Minimum confidence score [0, 1] for a detection to be reported.
|
|
71
|
+
* Defaults to 0.4.
|
|
72
|
+
*/
|
|
73
|
+
confidenceThreshold?: number;
|
|
74
|
+
/**
|
|
75
|
+
* IoU threshold used by NMS post-processing.
|
|
76
|
+
* Defaults to 0.45.
|
|
77
|
+
*/
|
|
78
|
+
iouThreshold?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Maximum number of inference calls per second. The camera runs at the
|
|
81
|
+
* device's native frame rate; this throttle prevents the inference thread
|
|
82
|
+
* from saturating the CPU/NPU while the AR renderer runs in parallel.
|
|
83
|
+
* Defaults to 15.
|
|
84
|
+
*/
|
|
85
|
+
maxFPS?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Maximum number of detections reported per frame, kept as the top-N by
|
|
88
|
+
* confidence (after NMS). Lower this to reduce clutter, raise it to surface
|
|
89
|
+
* more objects.
|
|
90
|
+
* Defaults to 20.
|
|
91
|
+
*/
|
|
92
|
+
maxDetections?: number;
|
|
93
|
+
/**
|
|
94
|
+
* When true, each detection includes a `worldPosition` {x, y, z} obtained by
|
|
95
|
+
* raycasting the bbox centre against the AR scene. iOS only (Android emits
|
|
96
|
+
* `screenBoundingBox` but not yet `worldPosition`).
|
|
97
|
+
* Defaults to true.
|
|
98
|
+
*/
|
|
99
|
+
projectToWorld?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Called every time the detector produces a new set of detections.
|
|
102
|
+
* May be called with an empty array if nothing is detected in a frame.
|
|
103
|
+
*/
|
|
104
|
+
onDetection?: (event: ViroDetectionEvent) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Called once the model has been loaded and the camera pipeline is running.
|
|
107
|
+
*/
|
|
108
|
+
onReady?: (event: ViroDetectorReadyEvent) => void;
|
|
109
|
+
/**
|
|
110
|
+
* Called if the model fails to load or the camera cannot be opened.
|
|
111
|
+
*/
|
|
112
|
+
onError?: (event: ViroDetectorErrorEvent) => void;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* ViroObjectDetector — on-device open-vocabulary object detection powered by YOLOE.
|
|
116
|
+
*
|
|
117
|
+
* Runs **only in AR**: it shares the camera feed of the enclosing
|
|
118
|
+
* `ViroARSceneNavigator` (no separate camera session, no preview of its own) and
|
|
119
|
+
* fires `onDetection` with labels, normalized bounding boxes, and an on-screen
|
|
120
|
+
* `screenBoundingBox` (dp) at up to `maxFPS`. Mount it as a child or sibling of a
|
|
121
|
+
* `ViroARSceneNavigator`; it renders nothing itself, so give it `width: 0, height: 0`.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <ViroARSceneNavigator initialScene={{ scene: MyScene }} />
|
|
126
|
+
* <ViroObjectDetector
|
|
127
|
+
* style={{ position: "absolute", width: 0, height: 0 }}
|
|
128
|
+
* mode="prompt-free"
|
|
129
|
+
* confidenceThreshold={0.4}
|
|
130
|
+
* maxFPS={15}
|
|
131
|
+
* onDetection={({ detections }) => {
|
|
132
|
+
* detections.forEach(d => console.log(d.label, d.confidence, d.screenBoundingBox));
|
|
133
|
+
* }}
|
|
134
|
+
* />
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export declare const ViroObjectDetector: React.FC<Props>;
|
|
138
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026-present, ReactVision, Inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the BSD-style license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.ViroObjectDetector = void 0;
|
|
44
|
+
const React = __importStar(require("react"));
|
|
45
|
+
const react_native_1 = require("react-native");
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Component
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
const VRTObjectDetectorView = (0, react_native_1.requireNativeComponent)("VRTObjectDetectorView");
|
|
50
|
+
/**
|
|
51
|
+
* ViroObjectDetector — on-device open-vocabulary object detection powered by YOLOE.
|
|
52
|
+
*
|
|
53
|
+
* Runs **only in AR**: it shares the camera feed of the enclosing
|
|
54
|
+
* `ViroARSceneNavigator` (no separate camera session, no preview of its own) and
|
|
55
|
+
* fires `onDetection` with labels, normalized bounding boxes, and an on-screen
|
|
56
|
+
* `screenBoundingBox` (dp) at up to `maxFPS`. Mount it as a child or sibling of a
|
|
57
|
+
* `ViroARSceneNavigator`; it renders nothing itself, so give it `width: 0, height: 0`.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```tsx
|
|
61
|
+
* <ViroARSceneNavigator initialScene={{ scene: MyScene }} />
|
|
62
|
+
* <ViroObjectDetector
|
|
63
|
+
* style={{ position: "absolute", width: 0, height: 0 }}
|
|
64
|
+
* mode="prompt-free"
|
|
65
|
+
* confidenceThreshold={0.4}
|
|
66
|
+
* maxFPS={15}
|
|
67
|
+
* onDetection={({ detections }) => {
|
|
68
|
+
* detections.forEach(d => console.log(d.label, d.confidence, d.screenBoundingBox));
|
|
69
|
+
* }}
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
const ViroObjectDetector = ({ model = "yoloe-26s", mode = "prompt-free", categories = [], confidenceThreshold = 0.4, iouThreshold = 0.45, maxFPS = 15, maxDetections = 20, projectToWorld = true, onDetection, onReady, onError, style, ...rest }) => {
|
|
74
|
+
const handleDetection = React.useCallback((event) => {
|
|
75
|
+
onDetection?.(event.nativeEvent);
|
|
76
|
+
}, [onDetection]);
|
|
77
|
+
const handleReady = React.useCallback((event) => {
|
|
78
|
+
onReady?.(event.nativeEvent);
|
|
79
|
+
}, [onReady]);
|
|
80
|
+
const handleError = React.useCallback((event) => {
|
|
81
|
+
onError?.(event.nativeEvent);
|
|
82
|
+
}, [onError]);
|
|
83
|
+
return (<VRTObjectDetectorView {...rest} style={style} model={model} mode={mode} categories={categories} confidenceThreshold={confidenceThreshold} iouThreshold={iouThreshold} maxFPS={maxFPS} maxDetections={maxDetections} projectToWorld={projectToWorld} onDetectionViro={onDetection ? handleDetection : undefined} onReadyViro={onReady ? handleReady : undefined} onErrorViro={onError ? handleError : undefined}/>);
|
|
84
|
+
};
|
|
85
|
+
exports.ViroObjectDetector = ViroObjectDetector;
|