[Bug]: RNMBXModels.models.getter not implemented (Expo Project)
Mapbox Implementation
Mapbox
Mapbox Version
11.1.0
React Native Version
0.73.4
Platform
iOS
@rnmapbox/maps version
10.1.17
Standalone component to reproduce
metro.config.js:
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
config.resolver.assetExts.push("gltf", "glb");
module.exports = config;
app.json:
{
"expo": {
"name": "my-app",
"plugins": [
[
"@rnmapbox/maps",
{
"RNMapboxMapsVersion": "11.1.0",
"RNMapboxMapsDownloadToken": "token..."
}
]
]
}
}
package.json
{
"dependencies": {
"@rnmapbox/maps": "^10.1.17",
"expo": "~50.0.6",
"expo-asset": "~9.0.2",
"expo-gl": "^13.6.0",
"expo-three": "^7.0.0",
"react": "18.2.0",
"react-native": "0.73.4",
"three": "^0.162.0"
}
}
src/screens/explore/Main/Main.tsx
import React from 'react';
import {View} from 'react-native';
import MapboxGL from '@rnmapbox/maps';
import {FeatureCollection, GeoJsonProperties, Geometry} from 'geojson';
MapboxGL.setAccessToken(
'token...',
);
const features = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
id: 'a-feature',
properties: {
icon: 'example',
text: 'example-icon-and-label',
},
geometry: {
type: 'Point',
coordinates: [-74.00597, 40.71427],
},
},
{
type: 'Feature',
id: 'b-feature',
properties: {
text: 'just-label',
},
geometry: {
type: 'Point',
coordinates: [-74.001097, 40.71527],
},
},
{
type: 'Feature',
id: 'c-feature',
properties: {
shown: 'visible',
icon: 'example',
},
geometry: {
type: 'Point',
coordinates: [-74.00697, 40.72427],
},
},
],
} as FeatureCollection<Geometry, GeoJsonProperties>;
const models = {
car: require('./model.glb'),
};
const MainContainer = () => {
return (
<View style={{flex: 1}}>
<MapboxGL.MapView
projection="globe"
style={{flex: 1}}
logoEnabled={false}
compassEnabled
compassFadeWhenNorth
scaleBarEnabled={false}
pitchEnabled>
<MapboxGL.Models models={models} />
<MapboxGL.Camera
zoomLevel={14}
centerCoordinate={[-74.00597, 40.71427]}
/>
<MapboxGL.ShapeSource id={'shape-source-id-0'} shape={features}>
<MapboxGL.ModelLayer
existing
id="model-layer-id"
style={{
modelId: 'car',
modelScale: [5, 5, 5],
}}
/>
</MapboxGL.ShapeSource>
</MapboxGL.MapView>
</View>
);
};
export default MainContainer;
Use this model to test: model.glb.zip
Observed behavior and steps to reproduce
I'm trying to use 3D models in Mapbox, and for that I'm using the new ModelLayer
I installed the packages and ran the npx expo prebuild command to generate the native code
I installed the App on my iOS phone using the expo run:ios --device command
The app loads and the map renders normally, but I get the following error
Mapbox [error] RNMBXModels.models.getter not implemented
I also tried using the Expo Asset to load the model and replace the require in the Models component with the asset uri or localUri, but I got the same error
const [assets, error] = useAssets([require("./model.glb")]);
console.log(assets)
// Log:
const log = [{
"_downloadCallbacks": [],
"downloaded": true,
"downloading": false,
"hash": "c34a01e8c2a282dc923835a1383c9e50",
"height": null,
"localUri": "file:///var/mobile/Containers/Data/Application/8100310E-954B-4F8E-B21F-058F887252C9/Library/Caches/ExponentAsset-c34a01e8c2a282dc923835a1383c9e50.glb",
"name": "model",
"type": "glb",
"uri": "http://192.168.1.244:8081/assets/?unstable_path=.%2Fsrc%2Fscreens%2Fexplore%2FMain/model.glb?platform=ios&hash=c34a01e8c2a282dc923835a1383c9e50",
"width": null
}]
Expected behavior
Render the 3D model on the map
Notes / preliminary analysis
Using the <MapboxGL.Images images={{ example: require("./image.png") }} /> with a SymbolLayer works and I can see the images on the map.
Using @react-three/fiber/native and @react-three/drei/native to render the model on the screen works normally, I used the following code for this:
import React, { Suspense } from "react";
import { View } from "react-native";
import { useFrame, Canvas } from "@react-three/fiber/native";
import { useGLTF, Environment } from "@react-three/drei/native";
import modelPath from "./model.glb";
function Model({ url, ...rest }) {
const { scene } = useGLTF(url);
useFrame(() => (scene.rotation.y += 0.01));
return <primitive {...rest} object={scene} />;
}
const MainContainer = () => {
return (
<View style={{ flex: 1, backgroundColor: "red" }}>
<Canvas gl={{ physicallyCorrectLights: true }} camera={{ position: [-6, 0, 16], fov: 36 }}>
<color attach="background" args={[0xe2f4df]} />
<ambientLight />
<directionalLight intensity={1.1} position={[0.5, 0, 0.866]} />
<directionalLight intensity={0.8} position={[-6, 2, 2]} />
<Suspense>
<Environment preset="park" />
<Model url={modelPath} />
</Suspense>
</Canvas>
</View>
);
};
I'm sorry this is not a component that I can copy&paste to try out. Pls fix that
<MapboxGL.ModelLayer
existing
id="model-layer-id"
style={{
modelId: 'car',
modelScale: [5, 5, 5],
}}
/>
the existing attribute means that the layer is expected to be in the style already. Which is don't think the case here.
Hi @mfazekas, I did the change #3406 in my project and removed the existing property, but after testing the model still don't load in my expo project, only in a CLI RN project, can you check?
@rodrigo4635 so it works in an RN project, but not in an expo project?
@mfazekas Exactly, I copied the code from this issue and placed it in an Expo project and a CLI project, with the same libraries and tokens, running on a real iOS device (iPhone 12).
@mfazekas Hello, any news about this issue? Also, I noticed that ShapeSource's onPress event does not fire when you click on a ModelLayer. Using the same component as this example, if I add an onPress to the ShapeSource it doesn't fire when I click on a model layer, but it does if I use any other type (SymbolLayer for example)
Hello @mfazekas any update about this ?
Same issue here @mfazekas . Can't seem to render the 3D model on the map with expo using ModelLayer. "expo": "~52.0.20", "react-native": "0.76.5", a bit stuck here, any help is much appreciated.