react-three-rapier icon indicating copy to clipboard operation
react-three-rapier copied to clipboard

Does react-three-rapier support RN app?

Open lsxBread opened this issue 2 years ago • 13 comments

Hi, I am trying to use this lib together with @react-three/fiber & @react-three/drei in the Expo project "expo": "47.0.13" "react-native": "0.70.5"

That's the demo in the docs I followed:

import { Box, Torus } from "@react-three/drei/native";
import { Canvas } from "@react-three/fiber/native";
import { Physics, RigidBody, Debug } from "@react-three/rapier";

const App = () => {
  return (
    <Canvas>
      <Suspense>
        <Physics debug>
          <RigidBody colliders={"hull"} restitution={2}>
            <Torus />
          </RigidBody>

          <CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]} />
        </Physics>
      </Suspense>
    </Canvas>
  );
};

It works all good in browser but get below error when run it as the RN app in iOS: MicrosoftTeams-image

Seems it doesn't expose an native module like fiber & drei does which could support RN. I don't really find any RN related stuff in the docs, so try to confirm that does rapier support RN app OR I miss some config to make it runnable?

Thanks

lsxBread avatar Apr 18 '23 01:04 lsxBread

The issue could be that WebAssembly isn't supported in React Native?

I'm not familiar with it enough to know if that's the case though.

isaac-mason avatar Apr 18 '23 08:04 isaac-mason

From a brief search, it seems that React Native for ios and android doesn't support WASM out of the box.

Some people have found workarounds though. Some people mention using webassemblyjs (though I can't imagine performance being good), and others say they mounted a webview in the RN app (webviews would support WASM). This was referenced: https://www.npmjs.com/package/react-native-react-bridge

If you get something working, please share! 🙂

isaac-mason avatar Apr 18 '23 08:04 isaac-mason

This also looks interesting - https://github.com/cawfree/react-native-webassembly

isaac-mason avatar May 08 '23 01:05 isaac-mason

iOS does not support JIT under the browser ban (WebKit has special permissions), but pending March 2024 EU legislation this can change.

In the meantime, no such implementation exists for WebAssembly even for Android, but it should be possible if Apple cedes ground here.

CodyJasonBennett avatar Oct 17 '23 05:10 CodyJasonBennett

@lsxBread did you find a solution to make it work ? Or did you use something else ?

PaulThiberville avatar Nov 16 '23 17:11 PaulThiberville

I hit the same error quite recently. Does anyone have some tips/examples on how to use this package with React Native?

itsyoboieltr avatar Mar 28 '24 23:03 itsyoboieltr

I actually found a fix for this. This is what I did to make it work in _layout.tsx using Expo Router:

if (Platform.OS !== 'web') {
  // Polyfill WebAssembly for the Rapier physics engine
  // https://github.com/pmndrs/react-three-rapier/issues/383
  const WebAssembly = require('polywasm').WebAssembly;
  globalThis.WebAssembly = WebAssembly;
}

I couldn't believe it, but it actually worked 😄

itsyoboieltr avatar Mar 29 '24 01:03 itsyoboieltr

@itsyoboieltr thanks for sharing 🙏 would you mind sharing a demo / video? I'm curious to see what the performance is like.

isaac-mason avatar Mar 29 '24 02:03 isaac-mason

@itsyoboieltr thanks for sharing 🙏 would you mind sharing a demo / video? I'm curious to see what the performance is like.

The thing I am currently working on is not really computationally intense so I see no difference native vs browser. Do you have any ideas what/how should I benchmark? I can make a quick demo

itsyoboieltr avatar Mar 29 '24 02:03 itsyoboieltr

@itsyoboieltr I was firstly just curious whether a basic simulation with a few physics bodies runs ok. Hearing that you don't see a difference between browser and native for your scene is interesting!

Looking at polywasm I see it works by translating wasm functions to javascript - which sounds like it would be very slow.

For some potentially easy comparisons, you could grab the source code of some react-three-rapier examples, e.g. https://react-three-rapier.pmnd.rs/performance https://github.com/pmndrs/react-three-rapier/blob/c3ad82319a15c7a87a2708f83a6604da3b484245/demo/src/examples/performance/PeformanceExample.tsx#L113

isaac-mason avatar Mar 29 '24 10:03 isaac-mason

I just tried it in a bare React Native project. The polyfill trick makes the app build, but when I try the basic usage code sample from the react-three /rapier GitHub I get errors.

The basic usage code :

import { Box, Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { Physics, RigidBody, CuboidCollider } from "@react-three/rapier";
import React, { Suspense } from 'react'

const MyComponent = () => {
  return (
    <Canvas>
      <Suspense>
        <Physics debug>
          <RigidBody colliders={"hull"} restitution={2}>
            <Torus />
          </RigidBody>

          <CuboidCollider position={[0, -2, 0]} args={[20, 0.5, 20]} />
        </Physics>
      </Suspense>
    </Canvas>
  );
};

The errors :

TypeError: Cannot read property 'Physics' of undefined
TypeError: Cannot read property 'prototype' of undefined, js engine: hermes

What i'm using :

react : 18.2.0
react-native:  0.72.4
expo: ^49.0.21
expo-gl: ~130.1
three: ^0.158.0
@react-three/fiber: ^8.16.8
@react-three/drei: ^9.109.2
@react-three/rapier: ^1.4.0
polywasm : ^0.1.4```

PaulThiberville avatar Aug 04 '24 11:08 PaulThiberville

I generally wouldn't expect this to work or ever be performant. If running r3/rapier or anything using web based libraries you'll have better luck using a webview based platform like ionic/Capacitor.

I too was pulling my hair out trying to get things to work with expo/rn but besides the 3d stuff the views were just UI and that works just as good in ionic with way less nightmares.

DennisSmolek avatar Sep 26 '24 10:09 DennisSmolek