diff --git a/Apps/PackageTest/ios/PackageTest.xcodeproj/xcshareddata/xcschemes/PackageTest.xcscheme b/Apps/PackageTest/ios/PackageTest.xcodeproj/xcshareddata/xcschemes/PackageTest.xcscheme index ff341641e..43f2051a2 100644 --- a/Apps/PackageTest/ios/PackageTest.xcodeproj/xcshareddata/xcschemes/PackageTest.xcscheme +++ b/Apps/PackageTest/ios/PackageTest.xcodeproj/xcshareddata/xcschemes/PackageTest.xcscheme @@ -49,6 +49,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/Apps/PackageTest/ios/Podfile.lock b/Apps/PackageTest/ios/Podfile.lock index 8b1784c21..f53c706b6 100644 --- a/Apps/PackageTest/ios/Podfile.lock +++ b/Apps/PackageTest/ios/Podfile.lock @@ -359,7 +359,7 @@ DEPENDENCIES: - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - boost-for-react-native - CocoaAsyncSocket - CocoaLibEvent @@ -476,6 +476,6 @@ SPEC CHECKSUMS: Yoga: 7d2edc5b410474191962e6dee88ee67f9b328b6b YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: b26865836ae3178eaa7e5446020aad2493d60909 +PODFILE CHECKSUM: 62c5fe3e1509657d6d39ffc17a80798ed2216cac -COCOAPODS: 1.6.1 +COCOAPODS: 1.9.3 diff --git a/Apps/Playground/ios/Playground.xcodeproj/xcshareddata/xcschemes/Playground.xcscheme b/Apps/Playground/ios/Playground.xcodeproj/xcshareddata/xcschemes/Playground.xcscheme index 1512ca623..6347928f1 100644 --- a/Apps/Playground/ios/Playground.xcodeproj/xcshareddata/xcschemes/Playground.xcscheme +++ b/Apps/Playground/ios/Playground.xcodeproj/xcshareddata/xcschemes/Playground.xcscheme @@ -49,6 +49,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/Apps/Playground/ios/Podfile.lock b/Apps/Playground/ios/Podfile.lock index 52d3f932f..1994b826a 100644 --- a/Apps/Playground/ios/Podfile.lock +++ b/Apps/Playground/ios/Podfile.lock @@ -362,7 +362,7 @@ DEPENDENCIES: - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - boost-for-react-native - CocoaAsyncSocket - CocoaLibEvent @@ -484,4 +484,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d5b2ddada6b82d7ff2f0c4518b88942d30cc3d95 -COCOAPODS: 1.6.1 +COCOAPODS: 1.9.3 diff --git a/Apps/Playground/node_modules/@babylonjs/react-native/README.md b/Apps/Playground/node_modules/@babylonjs/react-native/README.md index 14284384a..6586636d0 100644 --- a/Apps/Playground/node_modules/@babylonjs/react-native/README.md +++ b/Apps/Playground/node_modules/@babylonjs/react-native/README.md @@ -6,7 +6,7 @@ This quick overview will help you understand the constructs provided by Babylon ### Dependencies -This package has several **peer dependencies**. If these dependencies are unmet, the `react-native` build will emit warnings. Be sure to add these dependencies to your project. +This package has several **peer dependencies**. If these dependencies are unmet, `npm install` will emit warnings. Be sure to add these dependencies to your project. The `react-native-permissions` dependency is required for XR capabilities of Babylon.js (to request camera permissions automatically). Be sure to follow the `react-native-permissions` [instructions](https://github.com/react-native-community/react-native-permissions#setup) to update your `Podfile` and `Info.plist` (iOS) and/or `AndroidManifest.xml` (Android). @@ -22,6 +22,14 @@ The minimum Android SDK version is 18. This must be set as `minSdkVersion` in th The minimum deployment target version is 12. This must be set as `iOS Deployment Target` in the consuming project's `project.pbxproj`, and must also be set as `platform` in the consuming project's `podfile`. +When running from XCode (with the debugger attached), `API Metal Validation` must be disabled: + +1. From within XCode, select from the main menu `Product -> Scheme -> Edit Scheme...` +1. Ensure the target for your app is selected in the upper left corner of the window. +1. Select `Run` from the scheme list. +1. Select the `Options` tab. +1. Change `API Metal Validation` to `Disabled`. + ### `useEngine` `useEngine` is a **custom React hook** that manages the lifecycle of a Babylon engine instance in the context of an owning React component. `useEngine` creates an engine instance **asynchronously** which is used to create and configure scenes. Typically scene initialization code should exist in a `useEffect` triggered by an `engine` state change. For example: diff --git a/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNative.cpp b/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNative.cpp index 1e4363f5c..a71ee597d 100644 --- a/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNative.cpp +++ b/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNative.cpp @@ -45,11 +45,10 @@ namespace Babylon Native::Native(facebook::jsi::Runtime* jsiRuntime, void* windowPtr, size_t width, size_t height) : m_impl{ std::make_unique(jsiRuntime) } { - // TODO: We should initialize graphics on the UI thread, but for some reason this causes the app to crash -// dispatch_sync(dispatch_get_main_queue(), ^{ -// Plugins::NativeEngine::InitializeGraphics(windowPtr, width, height); -// }); - + dispatch_sync(dispatch_get_main_queue(), ^{ + Plugins::NativeEngine::InitializeGraphics(windowPtr, width, height); + }); + auto run_loop_scheduler = std::make_shared(arcana::run_loop_scheduler::get_for_current_thread()); JsRuntime::DispatchFunctionT dispatchFunction{[env = m_impl->env, run_loop_scheduler = std::move(run_loop_scheduler)](std::function func) @@ -64,7 +63,6 @@ namespace Babylon Polyfills::Window::Initialize(m_impl->env); - Plugins::NativeEngine::InitializeGraphics(windowPtr, width, height); Plugins::NativeWindow::Initialize(m_impl->env, windowPtr, width, height); Plugins::NativeEngine::Initialize(m_impl->env); Plugins::NativeXr::Initialize(m_impl->env); @@ -84,10 +82,7 @@ namespace Babylon void Native::Resize(size_t width, size_t height) { - m_impl->runtime->Dispatch([width, height](Napi::Env env) - { - Plugins::NativeWindow::UpdateSize(env, width, height); - }); + Plugins::NativeWindow::UpdateSize(m_impl->env, width, height); } void Native::SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y) diff --git a/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm b/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm index 1ce3f3de0..56c8bdf79 100644 --- a/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm +++ b/Apps/Playground/node_modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm @@ -50,8 +50,9 @@ + (void)setView:(RCTBridge*)bridge jsRunLoop:(NSRunLoop*)jsRunLoop mktView:(MTKV [BabylonNativeInterop setCurrentView:mtkView]; currentNativeInstance->Refresh((__bridge void*)currentView, width, height); } else { - // TODO: Figure out why resizing causes the app to crash - //currentNativeInstance->Resize(width, height); + // NOTE: This will cause Metal API Validation to fail if it is enabled when the debugger is attached, which stops app execution. + // For now, be sure to disable Metal API Validation under Product->Scheme->Edit Scheme. + currentNativeInstance->Resize(width, height); } } }]; diff --git a/README.md b/README.md index 7581bda5b..830ce6571 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,23 @@ This project provides Babylon Native integration into React Native. +[![](https://github.com/BabylonJS/BabylonReactNative/workflows/Publish%20Package/badge.svg)](https://github.com/BabylonJS/BabylonReactNative/actions?query=workflow%3A%22Publish+Package%22) +[![npm version](https://badge.fury.io/js/%40babylonjs%2Freact-native.svg)](https://badge.fury.io/js/%40babylonjs%2Freact-native) + ## Current Status Babylon React Native is in the early phase of its development, and has the following limitations: -1. Android support only - support for both iOS and Windows is planned. -1. JavaScriptCore only - support for Hermes is planned, and support for other JavaScript engines used by React Native is uncertain. +1. Android and iOS support only - support for Windows is planned, but the timeline is currently unknown. +1. JavaScriptCore (JSC) only - the published @babylonjs/react-native package is configured specifically for JSC, though it is possible to rebuild it and target other JavaScript engines supported by React Native. In the future, the published package will directly support all JavaScript engines that can be used with React Native. ## Usage -See the [package usage](Apps/Playground/node_modules/@babylonjs/react-native/README.md) or the Playground app's [App.tsx](Apps/Playground/App.tsx) for example usage. +See the [package usage](Apps/Playground/node_modules/@babylonjs/react-native/README.md) for installation instructions and/or the Playground app's [App.tsx](Apps/Playground/App.tsx) for example usage. ## Contributing -This quick overview will help you get started developing in the Babylon React Native repository. We support development on Windows and macOS, but assume the use of [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell) in the instructions below. +This quick overview will help you get started developing in the Babylon React Native repository. We support development on Windows and MacOS, but assume the use of [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell) in the instructions below (unless otherwise noted). If you are interested in making contributions, be sure to also review [CONTRIBUTING.md](CONTRIBUTING.md). @@ -84,33 +87,35 @@ export JAVA_HOME=$(/usr/libexec/java_home -v 13) ### **Building and Running the Playground App** -On either Mac or Windows, NPX is used to build and run the Playground sample/test app from the command line. Open a command prompt at the root of the BabylonReactNative repo if you don't have one already open. +On either Mac or Windows, NPM is used to build and run the Playground sample/test app from the command line. Open a command prompt at the root of the BabylonReactNative repo if you don't have one already open. #### Android ``` cd Apps/Playground -npx react-native run-android +npm run android ``` After having run the above commands, you can also open `Apps/Playground/android` in Android Studio and run the app from there. #### iOS +iOS can only be built on a Mac. Additionally, `CMake` must manually be run to generate the XCode project that the [Playground XCode workspace](Apps/Playground/ios/Playground.xcworkspace/contents.xcworkspacedata) includes. + ``` pushd Apps/Playground/node_modules/@babylonjs/react-native/ios cmake -G Xcode -DCMAKE_TOOLCHAIN_FILE=../submodules/BabylonNative/Dependencies/ios-cmake/ios.toolchain.cmake -DPLATFORM=OS64COMBINED -DENABLE_ARC=0 -DENABLE_BITCODE=1 -DDEPLOYMENT_TARGET=12 -DENABLE_GLSLANG_BINARIES=OFF -DSPIRV_CROSS_CLI=OFF . popd cd Apps/Playground -npx react-native run-ios +npm run ios ``` After having run the above commands, you can also open `Apps/Playground/ios/Playground.xcworkspace` in XCode and run the app from there. ### **Building the NPM Package** -An NPM package can be built in two different ways: as source, and as binaries. Source is useful if you want to debug the Babylon React Native source in the context of the project consuming it, though configuration is a bit more involved. Binaries are useful in that they simplify configuration in the consuming app, though they cannot be debugged so easily. +An NPM package can be built in two different ways: as source, and as binaries. Source is useful if you want to debug the Babylon React Native source in the context of the project consuming it, though configuration is a bit more involved. Binaries are useful in that they simplify configuration in the consuming app, though they cannot be debugged so easily. The binary package is what is published to [npmjs.org](https://www.npmjs.com/package/@babylonjs/react-native). #### Source Package @@ -121,7 +126,7 @@ cd Apps/Playground/node_modules/@babylonjs/react-native npm pack ``` -This will produce a zipped local NPM source-based package that can be installed into a React Native application for testing purposes. +This will produce a zipped local NPM source-based package that can be installed into a React Native application for testing purposes. Note that when testing a source based package for iOS, the XCode project needs to be generated with `CMake` as described [above](#ios). #### Binary Package