# Babylon React Native

## Usage

This quick overview will help you understand the constructs provided by Babylon React Native and how to use them in a React Native application.

### Dependencies

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). These plugins can be disabled and by such, dependency to `react-native-permissions` is not needed anymore (see below).

### React Native minimum version

| BabylonReactNative version | iOS / Android        | Windows                       |
| -------------------------- | -------------------- | ----------------------------- |
| next / main                | react-native 0.81.6+ | react-native-windows 0.81.4+  |
| 2.0.0 - 2.0.2              | react-native 0.79.4  | react-native-windows 0.79.1   |

### Android Configuration

The minimum Android SDK version is 21. This must be set as `minSdkVersion` in the consuming project's `build.gradle` file.

### iOS Configuration

The minimum deployment target version is 16. 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`.
Make sure `pod install` is called from the ios folder after npm install.

#### Workspace
In your app workspace, add a reference to BabylonReactNative project by adding these lines:
```
<FileRef
    location = "group:../node_modules/@babylonjs/react-native/Build/iOS/ReactNativeBabylon.xcodeproj">
</FileRef>
```
to your app `xcworkspace/content.xcworkspacedata` file.

#### CMake
To disable post install CMake generation, set this variable before running `npm install`:
```
export BABYLON_NO_CMAKE_POSTINSTALL=1
```

To use the system cmake (e.g. a Homebrew or system install) instead of the cmake bundled in the npm package, set this variable before running `npm install`:
```
export BABYLON_USE_SYSTEM_CMAKE=1
```

To override the iOS deployment target used by the generated `ReactNativeBabylon.xcodeproj` (defaults to `16.0`), set this variable before running `npm install` so it matches your app's Podfile `platform :ios` value:
```
export BABYLON_IOS_DEPLOYMENT_TARGET=16.0
```
The previous default of iOS 12 caused Xcode 26's Clang to crash while compiling `DeviceImpl_iOS.mm`; the default is now `16.0` and this variable lets you raise it further (or, at your own risk, lower it) without patching the deployment target from a Podfile `post_install` hook.

### Plugins selection

Plugins can be disabled at build time. They are all enabled by default and disabling is done with environment variables:

To disable Camera plugin:
```
export BABYLON_NATIVE_PLUGIN_NATIVECAMERA=0
```

For Native XR:
```
export BABYLON_NATIVE_PLUGIN_NATIVEXR=0
```

### Platform Native Packages

Starting with BabylonReactNative NPM 2.0.0+, one single package is available for iOS, Android and Windows versus multiple packages before.

Babylon.js minimal version:

|BabylonReactNative version | Babylon.js version | BabylonNative commit |
| ----------- | ------------------------ | --- |
|2.0.2 | 9.0.0 | ce2edf0851e0c8483559832a4f8eb9d39c6b2f53
|2.0.0 | 8.3.0 | 6c25966e8f8c0f3a0c13fdf77064f1bde790391f


### `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:

```tsx
import { useEngine } from '@babylonjs/react-native';
import { Engine, Scene } from '@babylonjs/core';

const MyComponent: FunctionComponent<MyComponentProps> = (props: MyComponentProps) => {
    const engine = useEngine();

    useEffect(() => {
        if (engine) {
            const scene = new Scene(engine);
            // Setup the scene!
        }
    }, [engine]);

    return (
        <>
        </>
    );
}
```

### `EngineView`

`EngineView` is a **custom React Native view** that presents a `camera` from a Babylon `scene`. A `camera` therefore is assigned to the `EngineView`. For example:

```tsx
import { useEngine, EngineView } from '@babylonjs/react-native';
import { Engine, Scene, Camera } from '@babylonjs/core';

const MyComponent: FunctionComponent<MyComponentProps> = (props: MyComponentProps) => {
    const engine = useEngine();
    const [camera, setCamera] = useState<Camera>();

    useEffect(() => {
        if (engine) {
            const scene = new Scene(engine);
            scene.createDefaultCamera(true);
            setCamera(scene.activeCamera!);
            // Setup the scene!
        }
    }, [engine]);

    return (
        <>
            <EngineView style={{flex: 1}} camera={camera} />
        </>
    );
}
```

Also the `EngineView` has a boolean `isTransparent` flag which defines whether the background of the scene should be transparent or not.

e.g.

```tsx
<EngineView style={{flex: 1}} camera={camera} isTransparent={true} />
```
To configure anti-aliasing, a property called `antiAliasing` can be changed to a value of 0 or 1 (disable anti-aliasing, default), 2, 4, 8 or 16 (anti-aliasing samples).

e.g.

```tsx
<EngineView style={{flex: 1}} camera={camera} MSAA={4} />
```

Note: Currently only one `EngineView` can be active at any given time. Multi-view will be supported in a future release.

The Android specific `androidView` property can help set the type of the view used for rendering. Depending on user needs and performance, refer to the table below. [`TextureView`](https://developer.android.com/reference/android/view/TextureView) can be inserted anywhere in the view hierarchy, but is less efficient. [`SurfaceView`](https://developer.android.com/reference/android/view/SurfaceView) can only be fully above or fully below the rest of the UI, but is more efficient.

| isTransparent | androidView        | Description |
| ----------- | ------------------------ | ----------- |
| False       | TextureView              | Opaque TextureView.
| False       | SurfaceView              | Simple SurfaceView (default when no `androidView` set with `isTransparent=false`).
| False       | SurfaceViewZTopMost      | SurfaceView with [ZTopMost](https://developer.android.com/reference/android/view/SurfaceView#setZOrderOnTop(boolean)) set to `true`.
| False       | SurfaceViewZMediaOverlay | SurfaceView with [ZMediaOverlay](https://developer.android.com/reference/android/view/SurfaceView#setZOrderMediaOverlay(boolean)) set to `true`.
| True        | TextureView              | Transparent TextureView.
| True        | SurfaceView              | SurfaceView will stay opaque
| True        | SurfaceViewZTopMost      | SurfaceView with [ZTopMost](https://developer.android.com/reference/android/view/SurfaceView#setZOrderOnTop(boolean)) set to `true`. Transparent but topmost. (default when no `androidView` set with `isTransparent=true`)
| True        | SurfaceViewZMediaOverlay | SurfaceView with [ZMediaOverlay](https://developer.android.com/reference/android/view/SurfaceView#setZOrderMediaOverlay(boolean)) set to `true`. Only transparent on top of other SurfaceViews.

More information on TextureView vs SurfaceView performance here:
https://developer.android.com/reference/android/view/TextureView