mapbox / mapbox-maps-flutter

Interactive, thoroughly customizable maps for Flutter powered by Mapbox Maps SDK
https://www.mapbox.com/mobile-maps-sdk
Other
285 stars 117 forks source link

3d Location Puck not showing on the map #621

Open gustavohexagon opened 3 months ago

gustavohexagon commented 3 months ago

Hi, I've been trying to introduce a 3d location puck, but no puck is loaded at all.

This is a code snippet of a functioning 2d puck, location, colors, pulsing, etc all work:

position = await geo.Geolocator.getCurrentPosition(desiredAccuracy: geo.LocationAccuracy.high);

    await mapboxMap.setCamera(
      CameraOptions(
        zoom: 18.8,
        center: Point(coordinates: Position(position.longitude, position.latitude)),
        pitch: 70,
      ),
    );

    await mapboxMap.location.updateSettings(LocationComponentSettings(
      pulsingColor: 16776960,
      pulsingMaxRadius: 40,
      pulsingEnabled: true,
      enabled: true,
    ));

Now, the very last part is what I've changed to work with the 3D puck, I tried both .glb and .gltf assets I downloaded from https://sketchfab.com/ and saved to assets.

    await mapboxMap.location.updateSettings(LocationComponentSettings(
      locationPuck: LocationPuck(locationPuck3D: LocationPuck3D(
        modelUri: 'assets/image/sphere.glb',
        modelRotation: [0, 0, 180],
        position: [position.latitude, position.longitude]
      )),
      pulsingColor: 16776960,
      pulsingMaxRadius: 40,
      pulsingEnabled: true,
      enabled: true,
    ));

What am I missing here? Thanks in advance!

maios commented 3 months ago

Hi @gustavohexagon, to use local 3D asset file, you need to provide a correct uri in modelUri, so in your example, assets/image/sphere.glb is not a correct path in the platform application's bundle, as implied in Sharing assets with the underlying platform The good news is, we understand that getting this absolute path might be cumbersome for our clients, we have addressed this by introducing uri with asset:// scheme in this https://github.com/mapbox/mapbox-maps-flutter/pull/608, this will be included in our v2.2.0-beta.1 which set to release this or next week :)

maios commented 3 months ago

Hi again, I'm happy to tell you that we have released MapboxMaps Flutter v2.2.0-beta.1 which addressed the issue with local assets for 3D Models, please try it out and let us know!

gustavohexagon commented 3 months ago

Hi @maios, thanks for getting back! I'm trying it out now after updating to v2.2.0-beta.1 , but it still hasn't worked.

Maybe it's a problem with how I'm dealing with the asset. It has a relative path of assets/image/sphere.glb so based on your instructions I tried something like:

'asset://assets/image/sphere.glb', and ended up with:

locationPuck: LocationPuck(
        locationPuck3D: LocationPuck3D(
          modelUri: 'asset://assets/image/sphere.glb',
          modelRotation: [0, 0, 180],
          position: [position.latitude, position.longitude],
        ),
      ),

If I comment the location puck code, I see the standard puck, at the right location, with the pulsingColor and other parameters I specified.

Should I have done anything else?

maios commented 3 months ago

It has a relative path of assets/image/sphere.glb

do you mean it is located at path assets/image/sphere.glb in your flutter project? Have you include the path to that asset in your pubspec.yaml as described here

gustavohexagon commented 3 months ago

Yes, I mean it's located in the path you mentioned above assets/image/sphere.glb.

Yes, my pubspec.yaml file looks like this:

  assets:
    - .env
    - assets/fonts/
    - assets/video/
    - assets/gif/
    - assets/splash_screen/
    - assets/image/

I generally use the "/" at the end so I don't have to specifiy every asset within that directory.

This project has 20+ assets in different formats (gif, png, mp4, svg, etc) so I think if it were some error related to identation, it would've popped up earlier.

Maybe the .glb file is broken somehow? I tried a .gltf file that's essentially the same, but it didn't work as well.

maios commented 3 months ago

Can you try with this file https://github.com/mapbox/mapbox-maps-flutter/blob/main/example/assets/sportcar.glb that we use in our example to see if it still doesn't work? Could you provide a minimal sample project so I can try debug on my side?

gustavohexagon commented 3 months ago

@maios Thank you so much! The sportcar.glb your sent worked just fine! That means if something else doesn't work then we should re-check our own .glb files.

Have a nice day!

sumocode commented 3 months ago

@maios Currently testing the new beta. I'm trying to add sportcar.glb model to unclustered layer of my cluster source using mapboxMap.style.addPersistentStyleLayer, but so far I'm not able to make the model appear. I have only successfully added the model using addLayer and on the 3d location puck with the new "asset://" internal uri. I'm assuming a user error, but can you confirm does the addPersistentStyleLayer support the new "asset://" uri as model-id yet?

final String unclusteredModelLayer = jsonEncode({
      "id": "unclustered-models-$sourceId",
      "type": "model",
      "source": sourceId,
      "filter": [
        "all",
        [
          "!",
          ["has", "point_count"]
        ],
      ],
      "model-id": "asset://lib/assets/sportcar.glb",
      "model-scale": [
        "interpolate",
        ["linear"],
        ["zoom"],
        5,
        [50.0, 50.0, 50.0],
        16,
        [10.0, 10.0, 10.0]
      ],
      "model-translation": [0, 0, 0]
    });

    // Add the layer for models
    await mapboxMap.style.addPersistentStyleLayer(unclusteredModelLayer, null);
maios commented 3 months ago

Hi @sumocode, yes unfortunately we don't support this url scheme in low level addPersistentStyle yet :(

Log-Mushun commented 3 months ago

I'm having the same issue I just followed the same steps given to gustavohexagon and this is how my function to set the puck looks

Future<void> _enableLocationComponent() async {
  geo.Position position = await geo.Geolocator.getCurrentPosition();

  _mapboxMap.location.updateSettings(LocationComponentSettings(
    enabled: true,
    locationPuck: LocationPuck(
      locationPuck3D: LocationPuck3D(
        modelUri: 'asset://assets/images/sportcar.glb',
        modelRotation: [0, 0, 180],
        position: [position.latitude, position.longitude],
      ),
    ),
  ));
}

But it isn't shown, the only way I can see a puck is by deleting the locationPuck field and it's value, leaving only enabled:true, I'm not sure if I need to configure a ModelLayer or something to be able to load the model, this also happens when I provide a real uri taken from my database

maios commented 3 months ago

Hi @Log-Mushun, I have noticed that your position values is incorrect, it should be [longitude, latitude] format, also if you are using device's location for the puck, you do not need to provide this position field at all.

Log-Mushun commented 2 months ago

Hi, Thank you! it works, now my function looks like this (and the model loads)

 Future<void> _enableLocationComponent() async {
  geo.Position position = await geo.Geolocator.getCurrentPosition();

  _mapboxMap?.location.updateSettings(LocationComponentSettings(
      locationPuck: LocationPuck(locationPuck3D: LocationPuck3D(
        modelUri: "https://raw.githubusercontent.com/Log-Mushun/TSP_models/main/Truck_pkg_1_glb.glb",
        modelScale: [8, 8, 8],
      ),
      ),
      enabled: true
  ));
  }

But if I try to load de model locally, like this

modelUri: "asset://assets/Truck_pkg_1_glb.glb",

after defining it in my pubspec this way

  assets:
    - assets/Truck_pkg_1_glb.glb

It doesn't work, also doesn't work if I try to bring my model from firebase storage. The same happens if I try it with the sportcar model

maios commented 2 months ago

@Log-Mushun, which MapboxMaps Flutter SDK version are you using?

Log-Mushun commented 2 months ago

@maios

I'm using mapbox_maps_flutter: ^2.1.0.

I’m not sure if this is relevant, but I’m testing on an Android device. However, my intention from the beginning has been to store the models remotely.

Regarding the issue I encountered while downloading the model from Firebase Storage, I discovered that the download links provided by Firebase Storage always include a ?alt=media parameter at the end(or almost), and it’s not possible to download the file without it. Here’s what my public download link looked like:

https://firebasestorage.googleapis.com/v0/b/sample-bucket/o/3d_models%2Fsample_model.glb?alt=media

While I could potentially implement some logic to handle this, I opted to generate the link using Google Cloud Storage instead, which provides a direct link without the parameter:

https://storage.googleapis.com/sample-bucket/3d_models/sample_model.glb

That way it worked.

maios commented 2 months ago

Hey @Log-Mushun , ModelLayer local asset is supported since v2.2.0-beta.1, so you need to update to use this version