pmndrs / react-three-rapier

🀺 Rapier physics in React
https://react-three-rapier.pmnd.rs
MIT License
1.07k stars 59 forks source link

Does react-three-rapier support RN app? #383

Open lsxBread opened 1 year ago

lsxBread commented 1 year ago

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

isaac-mason commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

CodyJasonBennett commented 1 year ago

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.

PaulThiberville commented 11 months ago

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

itsyoboieltr commented 7 months ago

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

itsyoboieltr commented 7 months ago

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 πŸ˜„

isaac-mason commented 7 months ago

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

itsyoboieltr commented 7 months ago

@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

isaac-mason commented 7 months ago

@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

PaulThiberville commented 3 months ago

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```
DennisSmolek commented 1 month ago

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.