Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
- **Android: a failure while a recording is being stopped no longer leaves `getRecordingStatus()` at IOError (`ARSessionRecorder`).** `encoder.stop()` and `muxer.stop()` failures reported it to the scene after the stop had already set the status back to None, so the status read IOError with nothing recording. Such a failure is now reported in the stop's result only. `ARScene.stopRecording()` may be called off the UI thread.
- **Android hit tests always deliver their results (`VRORendererARCore_JNI`, `VRORenderer_JNI`).** The AR point, ray and position hit tests, the Quest OpenXR hit tests and the scene hit test kept the caller's one-shot listener only as a weak global reference, so the garbage collector could take it before the renderer thread answered, and the results never arrived. It is now a global reference, deleted once the callback has run.
- **iOS downloads from a signed URL are saved (`VROPlatformDownloadURLToFile`, `VROPlatformDownloadURLToFileAsync`).** The temporary file was named after the URL's last path component with its query, and a signed URL's token pushed the name past the 255-byte file name limit, so the write failed and the download still reported success with a file that did not exist. `VROPlatformLastPathComponent` drops the query and fragment, and a failed write now fails the download.
- **Android: a camera added before the renderer no longer crashes (`VROPlatformUtil`, #597).** `libviro_renderer.so` now sets the `JavaVM` in `JNI_OnLoad`. It was set only when a renderer or loader started, and under Fabric `ViroARCamera`'s view is built first, so adding its node reached `getJNIEnv` with no VM.
- **A GLB whose skins share joints animates every skin (`VROGLTFLoader`, #599).** Resampling runs once per skin and rewrote a shared joint's channels in place; the next skin's pass kept only the translation of the merged channel, so those joints lost their rotation and scale. Every property of a channel is now copied.

### Removed

Expand Down
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
- **Co-location:** `VROColocationSession::deviceId()`, sent as `x-rv-device`, so the relay bills a device once.
- **A click goes to the node drawn on top,** and a click in open space reaches the controller's own delegates again.
- **Text sits where its vertical alignment puts it,** and a back-culled draw after a front-culled one culls back faces again.
- **GLB characters with one skin per mesh animate every part,** not only the first skin's.
- **Android: a `ViroARCamera` no longer crashes the scene as it mounts.**
- **Video:** a paused iOS video stays paused and its late callbacks no longer reach a freed texture; Android play and pause keep their order.
- **iOS:** ViroKit targets iOS 15.1, and builds for the iOS Simulator (arm64 and x86_64) as well as the device. The copy into viro now makes `ViroKit.xcframework`, replacing only the slice just built. `ios/build_ios_simulator_libs.sh` adds the simulator builds of LinearMath, protobuf-lite and GVR Audio that ViroKit links.
- **Removed:** the macOS target, which no longer linked and nothing built, and dead code (an unused metrics client, the API key validator, the OpenCV headers, an old OpenXR loader).
Expand Down
12 changes: 9 additions & 3 deletions ViroRenderer/VROGLTFLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1516,19 +1516,25 @@ void VROGLTFLoader::resampleSkeletalChannelsToCommonGrid(std::map<int, std::pair
const VROKeyframeAnimationFrame *fB = frames[kB].get();

// STEP samplers hold the left key; LINEAR (and pre-baked CUBICSPLINE) interpolate.
// Every property the channel has is copied, not only the first: a raw glTF
// channel carries one, but a joint shared by several skins comes back here
// already merged by an earlier skin's pass, with all of them.
if (chan->_hasTranslation) {
hasTrans = true;
mergedFrames[gi]->translation = step ? fA->translation
: fA->translation.interpolate(fB->translation, alpha);
} else if (chan->_hasScale) {
}
if (chan->_hasScale) {
hasScale = true;
mergedFrames[gi]->scale = step ? fA->scale
: fA->scale.interpolate(fB->scale, alpha);
} else if (chan->_hasRotation) {
}
if (chan->_hasRotation) {
hasRotation = true;
mergedFrames[gi]->rotation = step ? fA->rotation
: VROQuaternion::slerp(fA->rotation, fB->rotation, alpha);
} else if (chan->_hasMorphWeights) {
}
if (chan->_hasMorphWeights) {
hasMorph = true;
std::map<std::string, float> weights;
for (const auto &kv : fA->morphWeights) {
Expand Down
9 changes: 9 additions & 0 deletions ViroRenderer/VROPlatformUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,15 @@ static jobject sJavaAssetMgr = nullptr;
static jobject sPlatformUtil = nullptr;
static AAssetManager *sAssetMgr = nullptr;

// The JavaVM is known from the moment System.loadLibrary("viro_renderer") loads this library, so
// a JNI call that reaches getJNIEnv() before any renderer or loader has called VROPlatformSetEnv
// still finds it. Under Fabric a view such as VRTCamera is built before the scene's renderer, and
// adding its node already calls back into Java.
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
sVM = vm;
return JNI_VERSION_1_6;
}

// Map (and mutex) holding native tasks waiting to be dispatched. On Android the threading
// functionality is handled on the Java layer, so we need some mechanism for mapping IDs
// to corresponding tasks. Both the ID generator and the map itself are protected by the
Expand Down
Loading