@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
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
#include <string>
|
|
31
31
|
#include <chrono>
|
|
32
32
|
#include <functional>
|
|
33
|
+
#include <map>
|
|
34
|
+
#include <mutex>
|
|
35
|
+
#include <cstdint>
|
|
33
36
|
#include "VROVector3f.h"
|
|
34
37
|
|
|
35
38
|
class VROARDepthMesh;
|
|
@@ -50,16 +53,36 @@ struct VROWorldMeshConfig {
|
|
|
50
53
|
float maxDepth = 5.0f; // Maximum depth in meters
|
|
51
54
|
|
|
52
55
|
// Update settings
|
|
53
|
-
double updateIntervalMs =
|
|
56
|
+
double updateIntervalMs = 500.0; // Minimum time between mesh updates
|
|
54
57
|
double meshPersistenceMs = 500.0; // Time to keep mesh after depth data lost
|
|
55
58
|
|
|
56
59
|
// Physics properties
|
|
57
60
|
float friction = 0.5f; // Surface friction coefficient
|
|
58
61
|
float restitution = 0.3f; // Bounciness (0 = no bounce, 1 = full bounce)
|
|
59
62
|
std::string collisionTag = "world"; // Tag for collision event identification
|
|
63
|
+
int physicsMaxTriangles = 0; // Stride-decimation triangle cap (0 = no limit). Leaves
|
|
64
|
+
// large gaps — prefer physicsCellSize for collision.
|
|
65
|
+
float physicsCellSize = 0.10f; // Vertex-clustering cell size in meters (0 = disabled).
|
|
66
|
+
// Groups nearby vertices into a single representative,
|
|
67
|
+
// producing a gap-free simplified mesh. Max collision gap =
|
|
68
|
+
// sqrt(3) * cellSize. 0.10m → catches objects >~8cm reliably.
|
|
69
|
+
// Applied before physicsMaxTriangles (if both set).
|
|
60
70
|
|
|
61
71
|
// Visualization
|
|
62
|
-
bool debugDrawEnabled = false;
|
|
72
|
+
bool debugDrawEnabled = false; // Enable wireframe visualization of mesh
|
|
73
|
+
bool debugDrawDepthTest = true; // Depth-test wireframe against scene (occluded by real surfaces)
|
|
74
|
+
int debugDrawMaxTriangles = 1000; // Triangle cap for wireframe debug draw
|
|
75
|
+
float debugDrawLineThickness = 0.001f; // Line thickness for wireframe (meters)
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Identifies the data source that produced a world mesh.
|
|
80
|
+
*/
|
|
81
|
+
enum class VROWorldMeshSource {
|
|
82
|
+
LiDAR, // ARKit ARMeshAnchor (LiDAR-equipped device)
|
|
83
|
+
Monocular, // Monocular depth estimation (non-LiDAR device)
|
|
84
|
+
Plane, // Triangulated AR plane anchors (fallback)
|
|
85
|
+
Unknown
|
|
63
86
|
};
|
|
64
87
|
|
|
65
88
|
/**
|
|
@@ -74,10 +97,45 @@ struct VROWorldMeshStats {
|
|
|
74
97
|
};
|
|
75
98
|
|
|
76
99
|
/**
|
|
77
|
-
*
|
|
100
|
+
* Delivered to every registered subscriber when the world mesh is updated.
|
|
101
|
+
*/
|
|
102
|
+
struct VROWorldMeshUpdate {
|
|
103
|
+
std::shared_ptr<VROARDepthMesh> mesh;
|
|
104
|
+
VROWorldMeshStats stats;
|
|
105
|
+
VROWorldMeshSource source = VROWorldMeshSource::Unknown;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Per-subscriber options controlling mesh decimation.
|
|
110
|
+
* maxTriangles = 0 means no limit (full mesh delivered as-is).
|
|
111
|
+
*/
|
|
112
|
+
struct VROWorldMeshSubscriberOptions {
|
|
113
|
+
enum class DecimationStrategy {
|
|
114
|
+
Stride, // Take every N-th triangle (O(1) per triangle, default)
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
int maxTriangles = 0; // 0 = unlimited
|
|
118
|
+
DecimationStrategy strategy = DecimationStrategy::Stride;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
using VROWorldMeshSubscriberId = uint32_t;
|
|
122
|
+
using VROWorldMeshSubscriberCallback = std::function<void(const VROWorldMeshUpdate&)>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Legacy callback — delivers only stats. Kept for back-compat; prefer subscribe().
|
|
78
126
|
*/
|
|
79
127
|
using VROWorldMeshUpdateCallback = std::function<void(const VROWorldMeshStats&)>;
|
|
80
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Custom deleter for btRigidBody.
|
|
131
|
+
* Bullet requires removing the body from the dynamics world before deletion;
|
|
132
|
+
* this deleter encapsulates that invariant so it can't be forgotten.
|
|
133
|
+
*/
|
|
134
|
+
struct BulletRigidBodyDeleter {
|
|
135
|
+
std::weak_ptr<VROPhysicsWorld> physicsWorld;
|
|
136
|
+
void operator()(btRigidBody *body) const;
|
|
137
|
+
};
|
|
138
|
+
|
|
81
139
|
/**
|
|
82
140
|
* VROARWorldMesh manages the lifecycle of a physics collision mesh generated
|
|
83
141
|
* from AR depth data. It automatically updates the mesh from incoming AR frames
|
|
@@ -144,7 +202,21 @@ public:
|
|
|
144
202
|
VROWorldMeshStats getStats() const;
|
|
145
203
|
|
|
146
204
|
/**
|
|
147
|
-
*
|
|
205
|
+
* Subscribe to mesh updates. Returns an opaque ID used to unsubscribe.
|
|
206
|
+
* The callback is invoked on the render thread after each successful mesh build.
|
|
207
|
+
* @param callback Receives the full VROWorldMeshUpdate (mesh, stats, source).
|
|
208
|
+
* @param options Per-consumer options (e.g. maxTriangles for W3 decimation).
|
|
209
|
+
*/
|
|
210
|
+
VROWorldMeshSubscriberId subscribe(VROWorldMeshSubscriberCallback callback,
|
|
211
|
+
VROWorldMeshSubscriberOptions options = {});
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Unsubscribe a previously registered callback. No-op if id is not found.
|
|
215
|
+
*/
|
|
216
|
+
void unsubscribe(VROWorldMeshSubscriberId id);
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @deprecated Prefer subscribe(). Delivers stats only, no mesh data.
|
|
148
220
|
*/
|
|
149
221
|
void setUpdateCallback(VROWorldMeshUpdateCallback callback) {
|
|
150
222
|
_updateCallback = callback;
|
|
@@ -161,9 +233,10 @@ public:
|
|
|
161
233
|
private:
|
|
162
234
|
std::weak_ptr<VROPhysicsWorld> _physicsWorld;
|
|
163
235
|
|
|
164
|
-
// Bullet physics components
|
|
165
|
-
|
|
166
|
-
|
|
236
|
+
// Bullet physics components — smart pointers for exception-safe lifecycle.
|
|
237
|
+
// BulletRigidBodyDeleter removes the body from the world before deletion.
|
|
238
|
+
std::unique_ptr<btRigidBody, BulletRigidBodyDeleter> _rigidBody;
|
|
239
|
+
std::unique_ptr<btDefaultMotionState> _motionState;
|
|
167
240
|
std::shared_ptr<VROPhysicsShape> _physicsShape;
|
|
168
241
|
|
|
169
242
|
// Current mesh data
|
|
@@ -172,14 +245,21 @@ private:
|
|
|
172
245
|
// Configuration and state
|
|
173
246
|
VROWorldMeshConfig _config;
|
|
174
247
|
bool _enabled = false;
|
|
248
|
+
bool _isAddedToPhysicsWorld = false; // guard against re-add on rapid updates
|
|
175
249
|
|
|
176
250
|
// Timing
|
|
177
251
|
double _lastUpdateTimeMs = 0.0;
|
|
178
252
|
double _lastDepthTimeMs = 0.0;
|
|
179
253
|
|
|
180
|
-
//
|
|
254
|
+
// Legacy stats-only callback
|
|
181
255
|
VROWorldMeshUpdateCallback _updateCallback;
|
|
182
256
|
|
|
257
|
+
// Subscriber registry
|
|
258
|
+
std::map<VROWorldMeshSubscriberId,
|
|
259
|
+
std::pair<VROWorldMeshSubscriberCallback, VROWorldMeshSubscriberOptions>> _subscribers;
|
|
260
|
+
VROWorldMeshSubscriberId _nextSubscriberId = 1;
|
|
261
|
+
mutable std::mutex _subscriberMutex;
|
|
262
|
+
|
|
183
263
|
/**
|
|
184
264
|
* Apply a new mesh to the physics world.
|
|
185
265
|
* Creates a new physics shape and rigid body from the mesh.
|
|
@@ -210,6 +290,29 @@ private:
|
|
|
210
290
|
* Check if the mesh is stale (depth data not received recently).
|
|
211
291
|
*/
|
|
212
292
|
bool isMeshStale() const;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Fire the legacy _updateCallback and all registered subscribers.
|
|
296
|
+
* Called on the render thread after a mesh is successfully applied.
|
|
297
|
+
*/
|
|
298
|
+
void notifySubscribers(std::shared_ptr<VROARDepthMesh> mesh);
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Return a decimated copy of mesh with at most maxTriangles triangles,
|
|
302
|
+
* using Stride strategy (every N-th triangle). Vertices are copied as-is;
|
|
303
|
+
* only the index buffer is thinned. Returns mesh unchanged if already within budget.
|
|
304
|
+
*/
|
|
305
|
+
static std::shared_ptr<VROARDepthMesh> decimateMesh(
|
|
306
|
+
std::shared_ptr<VROARDepthMesh> mesh, int maxTriangles);
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Vertex-clustering simplification. Groups all vertices within cellSize metres
|
|
310
|
+
* into a single representative, rebuilds triangles, drops degenerate ones.
|
|
311
|
+
* Produces a gap-free mesh: max gap = sqrt(3)*cellSize.
|
|
312
|
+
* 0.10m cells → catches objects wider than ~8cm reliably.
|
|
313
|
+
*/
|
|
314
|
+
static std::shared_ptr<VROARDepthMesh> clusterMesh(
|
|
315
|
+
std::shared_ptr<VROARDepthMesh> mesh, float cellSize);
|
|
213
316
|
};
|
|
214
317
|
|
|
215
318
|
#endif /* VROARWorldMesh_h */
|
|
@@ -51,6 +51,25 @@ public:
|
|
|
51
51
|
virtual void setMuted(bool muted) = 0;
|
|
52
52
|
virtual void seekToTime(float seconds) = 0;
|
|
53
53
|
|
|
54
|
+
/*
|
|
55
|
+
Streaming PCM API. Subclasses that support runtime PCM feeding override
|
|
56
|
+
these; the default no-ops preserve all existing non-streaming subclasses.
|
|
57
|
+
|
|
58
|
+
beginStreaming: configure the player for streaming mode (instead of
|
|
59
|
+
loading a file/blob). Must be called before play(). sampleRate is in
|
|
60
|
+
Hz; channels is 1 (mono) or 2 (stereo).
|
|
61
|
+
|
|
62
|
+
pushSamples: feed interleaved float PCM samples in the range [-1, 1].
|
|
63
|
+
Thread-safe — may be called from any thread (sim loop, TTS callback,
|
|
64
|
+
etc.). Returns the number of samples accepted; if the ring buffer is
|
|
65
|
+
full the excess is dropped.
|
|
66
|
+
|
|
67
|
+
isStreaming: true once beginStreaming has been called successfully.
|
|
68
|
+
*/
|
|
69
|
+
virtual void beginStreaming(int sampleRate, int channels) {}
|
|
70
|
+
virtual size_t pushSamples(const float *data, size_t count) { return 0; }
|
|
71
|
+
virtual bool isStreaming() const { return false; }
|
|
72
|
+
|
|
54
73
|
protected:
|
|
55
74
|
std::shared_ptr<VROSoundDelegateInternal> _delegate;
|
|
56
75
|
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VROAudioPlayerStreamiOS.h
|
|
3
|
+
// ViroKit
|
|
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
|
+
#ifndef VROAudioPlayerStreamiOS_h
|
|
19
|
+
#define VROAudioPlayerStreamiOS_h
|
|
20
|
+
|
|
21
|
+
#include "VROAudioPlayer.h"
|
|
22
|
+
#include "VROPCMRingBuffer.h"
|
|
23
|
+
#include <memory>
|
|
24
|
+
#include <atomic>
|
|
25
|
+
|
|
26
|
+
#ifdef __OBJC__
|
|
27
|
+
@class AVAudioEngine;
|
|
28
|
+
@class AVAudioSourceNode;
|
|
29
|
+
@class AVAudioFormat;
|
|
30
|
+
#else
|
|
31
|
+
// Forward declarations for non-ObjC translation units (Android, WASM).
|
|
32
|
+
typedef void AVAudioEngine;
|
|
33
|
+
typedef void AVAudioSourceNode;
|
|
34
|
+
typedef void AVAudioFormat;
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
Streaming PCM audio player for iOS using AVAudioEngine + AVAudioSourceNode.
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
auto player = std::make_shared<VROAudioPlayerStreamiOS>();
|
|
42
|
+
player->beginStreaming(32000, 2); // stereo @ 32 kHz
|
|
43
|
+
player->setVolume(1.0f);
|
|
44
|
+
player->play();
|
|
45
|
+
// from any thread:
|
|
46
|
+
player->pushSamples(floatBuffer, frameCount * channels);
|
|
47
|
+
|
|
48
|
+
The AVAudioSourceNode render block drains the VROPCMRingBuffer on the
|
|
49
|
+
real-time audio thread (no locks). If the ring is empty, silence is output.
|
|
50
|
+
Spatialisation (position / attenuation) is NOT applied here — this player
|
|
51
|
+
is for non-spatial streaming audio. Spatial streaming is tracked separately.
|
|
52
|
+
*/
|
|
53
|
+
class VROAudioPlayerStreamiOS : public VROAudioPlayer {
|
|
54
|
+
|
|
55
|
+
public:
|
|
56
|
+
|
|
57
|
+
VROAudioPlayerStreamiOS();
|
|
58
|
+
virtual ~VROAudioPlayerStreamiOS();
|
|
59
|
+
|
|
60
|
+
// VROAudioPlayer overrides
|
|
61
|
+
void setup() override;
|
|
62
|
+
void setLoop(bool loop) override {} // streaming is continuous; loop is a no-op
|
|
63
|
+
void play() override;
|
|
64
|
+
void pause() override;
|
|
65
|
+
void setVolume(float volume) override;
|
|
66
|
+
void setMuted(bool muted) override;
|
|
67
|
+
void seekToTime(float seconds) override {} // not meaningful for live PCM
|
|
68
|
+
|
|
69
|
+
// Streaming API
|
|
70
|
+
void beginStreaming(int sampleRate, int channels) override;
|
|
71
|
+
size_t pushSamples(const float *data, size_t count) override;
|
|
72
|
+
bool isStreaming() const override { return _streaming; }
|
|
73
|
+
|
|
74
|
+
private:
|
|
75
|
+
|
|
76
|
+
void teardown();
|
|
77
|
+
|
|
78
|
+
#ifdef __OBJC__
|
|
79
|
+
AVAudioEngine *_engine = nil;
|
|
80
|
+
AVAudioSourceNode *_sourceNode = nil;
|
|
81
|
+
AVAudioFormat *_format = nil;
|
|
82
|
+
#else
|
|
83
|
+
void *_engine = nullptr;
|
|
84
|
+
void *_sourceNode = nullptr;
|
|
85
|
+
void *_format = nullptr;
|
|
86
|
+
#endif
|
|
87
|
+
|
|
88
|
+
std::shared_ptr<VROPCMRingBuffer> _ring;
|
|
89
|
+
std::atomic<bool> _playing { false };
|
|
90
|
+
std::atomic<bool> _muted { false };
|
|
91
|
+
std::atomic<float> _volume { 1.0f };
|
|
92
|
+
bool _streaming = false;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
#endif /* VROAudioPlayerStreamiOS_h */
|
|
@@ -62,7 +62,23 @@ public:
|
|
|
62
62
|
texture.
|
|
63
63
|
*/
|
|
64
64
|
std::vector<float> getCameraIntrinsics() const;
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
Expose the underlying capture controller so that callers (e.g. VRTCameraTexture)
|
|
68
|
+
can invoke photo / video capture directly.
|
|
69
|
+
*/
|
|
70
|
+
std::shared_ptr<VROAVCaptureController> getCaptureController() const {
|
|
71
|
+
return _controller;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Convenience wrappers so callers don't need to import VROAVCaptureController.h.
|
|
75
|
+
void setUpdateListener(std::function<void(CMSampleBufferRef, std::vector<float>)> listener);
|
|
76
|
+
void capturePhoto(NSString *outputPath,
|
|
77
|
+
std::function<void(bool, NSString *, NSString *)> onCaptured);
|
|
78
|
+
void startRecording(NSString *outputPath,
|
|
79
|
+
std::function<void(bool, NSString *, NSString *)> onStarted);
|
|
80
|
+
void stopRecording(std::function<void(bool, NSString *, NSString *)> onStopped);
|
|
81
|
+
|
|
66
82
|
private:
|
|
67
83
|
|
|
68
84
|
/*
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include <vector>
|
|
31
31
|
#include "VRODefines.h"
|
|
32
32
|
#include "VROSoundData.h"
|
|
33
|
+
#include "VROVertexBuffer.h"
|
|
33
34
|
|
|
34
35
|
class VROGeometry;
|
|
35
36
|
class VROMaterial;
|
|
@@ -278,6 +279,16 @@ public:
|
|
|
278
279
|
virtual std::shared_ptr<VRORenderTarget> newRenderTarget(VRORenderTargetType type, int numAttachments, int numImages,
|
|
279
280
|
bool enableMipmaps, bool needsDepthStencil) = 0;
|
|
280
281
|
virtual std::shared_ptr<VROVertexBuffer> newVertexBuffer(std::shared_ptr<VROData> data) = 0;
|
|
282
|
+
/*
|
|
283
|
+
Create a vertex buffer with an explicit usage hint. Subclasses that don't
|
|
284
|
+
override this default get a Static buffer; subclasses that do override gain
|
|
285
|
+
mutable buffers via VROVertexBuffer::updateData(). Used by VRODynamicGeometry
|
|
286
|
+
and any other path that needs per-frame buffer updates.
|
|
287
|
+
*/
|
|
288
|
+
virtual std::shared_ptr<VROVertexBuffer> newVertexBuffer(std::shared_ptr<VROData> data,
|
|
289
|
+
VROVertexBufferUsage usage) {
|
|
290
|
+
return newVertexBuffer(data);
|
|
291
|
+
}
|
|
281
292
|
virtual std::shared_ptr<VRORenderTarget> getDisplay() = 0;
|
|
282
293
|
virtual std::shared_ptr<VROImagePostProcess> newImagePostProcess(std::shared_ptr<VROShaderProgram> shader) = 0;
|
|
283
294
|
virtual std::shared_ptr<VROVideoTextureCache> newVideoTextureCache() = 0;
|
|
@@ -285,6 +296,15 @@ public:
|
|
|
285
296
|
virtual std::shared_ptr<VROSound> newSound(std::string resource, VROResourceType resourceType, VROSoundType type) = 0;
|
|
286
297
|
virtual std::shared_ptr<VROAudioPlayer> newAudioPlayer(std::shared_ptr<VROSoundData> data) = 0;
|
|
287
298
|
virtual std::shared_ptr<VROAudioPlayer> newAudioPlayer(std::string path, bool isLocal) = 0;
|
|
299
|
+
/*
|
|
300
|
+
Create an audio player pre-configured for streaming PCM. The returned
|
|
301
|
+
player's beginStreaming(sampleRate, channels) must be called before play().
|
|
302
|
+
Default implementation falls back to a no-op stub so subclasses that
|
|
303
|
+
haven't yet implemented streaming still compile.
|
|
304
|
+
*/
|
|
305
|
+
virtual std::shared_ptr<VROAudioPlayer> newStreamingAudioPlayer() {
|
|
306
|
+
return newAudioPlayer(std::string(""), true); // stub — subclasses override
|
|
307
|
+
}
|
|
288
308
|
virtual std::shared_ptr<VROTypefaceCollection> newTypefaceCollection(std::string typefaces, int size, VROFontStyle style, VROFontWeight weight) = 0;
|
|
289
309
|
virtual void setSoundRoom(float sizeX, float sizeY, float sizeZ, std::string wallMaterial,
|
|
290
310
|
std::string ceilingMaterial, std::string floorMaterial) = 0;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VRODynamicGeometry.h
|
|
3
|
+
// ViroKit
|
|
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
|
+
#ifndef VRODynamicGeometry_h
|
|
19
|
+
#define VRODynamicGeometry_h
|
|
20
|
+
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <stdint.h>
|
|
23
|
+
#include "VROGeometry.h"
|
|
24
|
+
|
|
25
|
+
class VROVertexBuffer;
|
|
26
|
+
class VRODriver;
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
A geometry whose vertex buffers can be replaced in place every frame without
|
|
30
|
+
recreating the geometry, its sources/elements, or its underlying GPU substrate.
|
|
31
|
+
|
|
32
|
+
Use this when the data driving the mesh changes at render-loop frequency:
|
|
33
|
+
- Procedural mesh (marching cubes, voxels)
|
|
34
|
+
- External engines that emit vertex soup per tick (libsm64, soft-body sims)
|
|
35
|
+
- CPU skinning of formats ViroCore doesn't parse natively
|
|
36
|
+
- Visualisations of changing scientific data
|
|
37
|
+
|
|
38
|
+
The first iteration supports unindexed triangle soup only. The vertex buffers
|
|
39
|
+
are allocated once at construction with the supplied capacity. Subsequent
|
|
40
|
+
calls to setBuffers() that stay within capacity reuse the GPU buffers without
|
|
41
|
+
reallocation. Exceeding the capacity triggers a one-time reallocation and a
|
|
42
|
+
warning; size the initial capacity to the upper bound your producer will emit.
|
|
43
|
+
|
|
44
|
+
Attribute availability is declared at construction. Buffers passed to
|
|
45
|
+
setBuffers() for absent attributes must be null; mismatches are logged.
|
|
46
|
+
|
|
47
|
+
Typical use:
|
|
48
|
+
|
|
49
|
+
auto geom = std::make_shared<VRODynamicGeometry>(
|
|
50
|
+
driver,
|
|
51
|
+
maxVertices, // upper bound the producer will emit
|
|
52
|
+
VRODynamicGeometryFeatures::All // positions + normals + uvs + colours
|
|
53
|
+
);
|
|
54
|
+
someNode->setGeometry(geom);
|
|
55
|
+
someNode->getGeometry()->setMaterials({myMaterial});
|
|
56
|
+
|
|
57
|
+
// each frame:
|
|
58
|
+
geom->setBuffers(positions, normals, uvs, colours, triangleCount);
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
enum class VRODynamicGeometryFeatures : uint32_t {
|
|
62
|
+
None = 0,
|
|
63
|
+
Positions = 1 << 0, // always implicitly required
|
|
64
|
+
Normals = 1 << 1,
|
|
65
|
+
UVs = 1 << 2,
|
|
66
|
+
Colors = 1 << 3,
|
|
67
|
+
PosNorm = Positions | Normals,
|
|
68
|
+
PosNormUV = Positions | Normals | UVs,
|
|
69
|
+
All = Positions | Normals | UVs | Colors,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
inline VRODynamicGeometryFeatures operator|(VRODynamicGeometryFeatures a,
|
|
73
|
+
VRODynamicGeometryFeatures b) {
|
|
74
|
+
return static_cast<VRODynamicGeometryFeatures>(
|
|
75
|
+
static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
|
76
|
+
}
|
|
77
|
+
inline bool hasFeature(VRODynamicGeometryFeatures set,
|
|
78
|
+
VRODynamicGeometryFeatures probe) {
|
|
79
|
+
return (static_cast<uint32_t>(set) & static_cast<uint32_t>(probe)) != 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class VRODynamicGeometry : public VROGeometry {
|
|
83
|
+
|
|
84
|
+
public:
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
Construct a dynamic geometry sized to hold up to maxVertices and configured
|
|
88
|
+
for the given attribute set. Allocates and hydrates one VBO per declared
|
|
89
|
+
attribute up front. Positions are always allocated.
|
|
90
|
+
*/
|
|
91
|
+
VRODynamicGeometry(std::shared_ptr<VRODriver> driver,
|
|
92
|
+
int maxVertices,
|
|
93
|
+
VRODynamicGeometryFeatures features =
|
|
94
|
+
VRODynamicGeometryFeatures::PosNormUV);
|
|
95
|
+
|
|
96
|
+
virtual ~VRODynamicGeometry();
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
Replace the geometry's vertex data and triangle count.
|
|
100
|
+
|
|
101
|
+
- positions: required, vertexCount * 3 floats
|
|
102
|
+
- normals: required iff Normals feature was declared at construction,
|
|
103
|
+
else must be null
|
|
104
|
+
- uvs: required iff UVs feature was declared, vertexCount * 2 floats
|
|
105
|
+
- colors: required iff Colors feature was declared, vertexCount * 4
|
|
106
|
+
RGBA8 bytes (0..255)
|
|
107
|
+
- triangleCount: number of triangles to draw; vertexCount = triangleCount * 3
|
|
108
|
+
|
|
109
|
+
vertexCount may not exceed maxVertices declared at construction without
|
|
110
|
+
triggering a one-time VBO reallocation (logged warning).
|
|
111
|
+
|
|
112
|
+
Safe to call from the render thread. Thread-safety with any other thread
|
|
113
|
+
calling setBuffers concurrently is the caller's responsibility.
|
|
114
|
+
*/
|
|
115
|
+
void setBuffers(const float *positions,
|
|
116
|
+
const float *normals,
|
|
117
|
+
const float *uvs,
|
|
118
|
+
const uint8_t *colors,
|
|
119
|
+
int triangleCount);
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
Maximum vertex capacity declared at construction (or grown by a previous
|
|
123
|
+
overflowing setBuffers call).
|
|
124
|
+
*/
|
|
125
|
+
int getMaxVertices() const { return _maxVertices; }
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
Features (attributes) this dynamic geometry was constructed with.
|
|
129
|
+
*/
|
|
130
|
+
VRODynamicGeometryFeatures getFeatures() const { return _features; }
|
|
131
|
+
|
|
132
|
+
private:
|
|
133
|
+
|
|
134
|
+
std::weak_ptr<VRODriver> _driver;
|
|
135
|
+
VRODynamicGeometryFeatures _features;
|
|
136
|
+
int _maxVertices;
|
|
137
|
+
int _currentTriangleCount;
|
|
138
|
+
|
|
139
|
+
std::shared_ptr<VROVertexBuffer> _positionBuffer;
|
|
140
|
+
std::shared_ptr<VROVertexBuffer> _normalBuffer;
|
|
141
|
+
std::shared_ptr<VROVertexBuffer> _uvBuffer;
|
|
142
|
+
std::shared_ptr<VROVertexBuffer> _colorBuffer;
|
|
143
|
+
|
|
144
|
+
std::shared_ptr<VROGeometryElement> _triangleSoupElement;
|
|
145
|
+
|
|
146
|
+
/*
|
|
147
|
+
Allocate the per-attribute VBOs and wire up the parent VROGeometry's
|
|
148
|
+
sources/elements once. Called from the constructor.
|
|
149
|
+
*/
|
|
150
|
+
void initBuffers();
|
|
151
|
+
|
|
152
|
+
/*
|
|
153
|
+
Helper: replace a VertexBuffer's data and forward to its updateData hook.
|
|
154
|
+
*/
|
|
155
|
+
void updateBuffer(const std::shared_ptr<VROVertexBuffer> &buffer,
|
|
156
|
+
const void *data,
|
|
157
|
+
size_t byteSize);
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
Like updateBuffer but pads the VROData to totalBytes with zeros so
|
|
161
|
+
VROGeometrySource's declared vertexCount stays consistent with the buffer
|
|
162
|
+
capacity (avoids VROByteBuffer over-read during bounding-box computation).
|
|
163
|
+
*/
|
|
164
|
+
void updateBufferPadded(const std::shared_ptr<VROVertexBuffer> &buffer,
|
|
165
|
+
const void *activeData, size_t activeBytes,
|
|
166
|
+
size_t totalBytes);
|
|
167
|
+
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
#endif /* VRODynamicGeometry_h */
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VRODynamicMeshNode.h
|
|
3
|
+
// ViroKit
|
|
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
|
+
#ifndef VRODynamicMeshNode_h
|
|
19
|
+
#define VRODynamicMeshNode_h
|
|
20
|
+
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <vector>
|
|
23
|
+
#include "VRONode.h"
|
|
24
|
+
#include "VRODynamicGeometry.h"
|
|
25
|
+
#include "VROVector3f.h"
|
|
26
|
+
#include "VROVector2f.h"
|
|
27
|
+
#include "VROVector4f.h"
|
|
28
|
+
|
|
29
|
+
class VRODriver;
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
A VRONode that owns a VRODynamicGeometry and exposes a high-level typed
|
|
33
|
+
setBuffers() API, matching the output of simulation adapters (e.g. libsm64).
|
|
34
|
+
|
|
35
|
+
Typical use:
|
|
36
|
+
|
|
37
|
+
auto node = std::make_shared<VRODynamicMeshNode>();
|
|
38
|
+
scene->getRootNode()->addChildNode(node);
|
|
39
|
+
node->init(driver, maxVertices, VRODynamicGeometryFeatures::All);
|
|
40
|
+
|
|
41
|
+
// each frame, from a VROFrameListener:
|
|
42
|
+
node->setBuffers(positions, normals, uvs, colors, vertexCount);
|
|
43
|
+
|
|
44
|
+
init() must be called once with a valid driver (e.g. from sceneWillAppear)
|
|
45
|
+
before the first setBuffers() call. vertexCount = triangleCount * 3.
|
|
46
|
+
|
|
47
|
+
scratch buffers for float packing are owned by the node and reused every
|
|
48
|
+
frame to avoid per-frame heap allocation.
|
|
49
|
+
*/
|
|
50
|
+
class VRODynamicMeshNode : public VRONode {
|
|
51
|
+
public:
|
|
52
|
+
VRODynamicMeshNode() = default;
|
|
53
|
+
~VRODynamicMeshNode() override = default;
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
Allocate the underlying VRODynamicGeometry sized to hold up to maxVertices.
|
|
57
|
+
Must be called once from the render thread (e.g. sceneWillAppear) before
|
|
58
|
+
any setBuffers() call.
|
|
59
|
+
*/
|
|
60
|
+
void init(std::shared_ptr<VRODriver> driver,
|
|
61
|
+
int maxVertices,
|
|
62
|
+
VRODynamicGeometryFeatures features = VRODynamicGeometryFeatures::All);
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
Replace the mesh data for the current frame. vertexCount = triangleCount * 3.
|
|
66
|
+
colors components must be in [0, 1]; they are converted to uint8 RGBA internally.
|
|
67
|
+
Safe to call from the render thread at frame rate.
|
|
68
|
+
*/
|
|
69
|
+
void setBuffers(const std::vector<VROVector3f> &positions,
|
|
70
|
+
const std::vector<VROVector3f> &normals,
|
|
71
|
+
const std::vector<VROVector2f> &uvs,
|
|
72
|
+
const std::vector<VROVector4f> &colors,
|
|
73
|
+
int vertexCount);
|
|
74
|
+
|
|
75
|
+
std::shared_ptr<VRODynamicGeometry> getDynamicGeometry() const { return _dynGeom; }
|
|
76
|
+
|
|
77
|
+
private:
|
|
78
|
+
std::shared_ptr<VRODynamicGeometry> _dynGeom;
|
|
79
|
+
|
|
80
|
+
// Scratch buffers reused every frame to avoid heap churn
|
|
81
|
+
std::vector<float> _scratchPos;
|
|
82
|
+
std::vector<float> _scratchNorm;
|
|
83
|
+
std::vector<float> _scratchUV;
|
|
84
|
+
std::vector<uint8_t> _scratchColor;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
#endif /* VRODynamicMeshNode_h */
|
|
@@ -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
|
-
|
|
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(
|