Selection Issue with GLB Model Organized by Tileset.json

Hello!I can use the following code to highlight a glb model that contains multiple individual buildings. This will highlight the entire glb model, as shown in the picture. However, I want to highlight only a part of this glb model. The glb model is a combination of multiple OBJ files imported into Blender and exported. How can I achieve this? By the way, how can I implement clicking on a model and displaying a property box? Should I add extra information during the model construction?

Cesium.Ion.defaultAccessToken = ***
       
      
        var viewer = new Cesium.Viewer('cesiumContainer',{
            infoBox: true, 
        });
       
    
        var tileset;
        async function loadTileset() {
           
            tileset = await Cesium.Cesium3DTileset.fromUrl('./root_0330_2_glb_notileset/root/tileset.json',{allowPicking: true});
            tileset.preferFlatPrimitives = true;
            viewer.scene.primitives.add(tileset);
            
       
        }

        loadTileset().then(() => {
            console.log('Tileset success');
            viewer.zoomTo(tileset);
        }).catch((error) => {
            console.error('Tileset failed', error);
        });


        var highlighted = {
            feature: undefined,
            originalColor: new Cesium.Color()
        };

        viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(
            movement
            ) {
          if (Cesium.defined(highlighted.feature)) {
            const content = highlighted.feature.content;
            if (Cesium.defined(content) && content instanceof Cesium.Model3DTileContent) {
        
                console.log('get origin color');
                const style = new Cesium.Cesium3DTileStyle({
                    color: "color('rgba(255,255,255,1)')"
          });
          content.applyStyle(style);
            
            }
            highlighted.feature = undefined;
        }
        const pickedObject = viewer.scene.pick(movement.position);
        console.log('pickedObject:');
        console.log(pickedObject);
  
        if (Cesium.defined(pickedObject)) {
          highlighted.feature = pickedObject;
          const content = pickedObject.content;
          if (!Cesium.defined(content)) {
            return;
          }
          if (!(content instanceof Cesium.Model3DTileContent)) {
            return;
          }
        
          const style = new Cesium.Cesium3DTileStyle({
            color: "color('yellow')"
          });
          content.applyStyle(style);
          //return;
        }

      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

(Just a short backlink to this issue: Selection Issue with GLB Model Organized by Tileset.json · Issue #760 · CesiumGS/3d-tiles · GitHub )

There are different ways of how this could be accomplished. The goal is, roughly speaking, to know that a certain set of vertices/triangles “belong together” or “belong to the same object”. And this information has to be encoded in one form or another. And on a very low technical level, this is the goal of the EXT_mesh_features extension. Someone wrote a short summary about how such IDs can be assigned in Blender a while ago, but I have to admit that I did not yet follow that thoroughly. And in any case, it will involve a few manual steps, and you’ll have to process these feature IDs accordingly, on the rendering side (i.e. in CesiumJS).

Referring to your case: Combining multiple OBJs into a single GLB will raise this question about how to distinguish the formerly individual buildings. And even though this is possible, it will involve some low-level technical efforts.

So one should probably ask: Why do you combine multiple OBJs into a single GLB?

There can be good reasons for that. It might be that you want to share textures, or use instancing, or perform some form of compression, or reduce the number of network requests.

But unless there is a strong reason to combine these OBJs, you could consider to just export each OBJ as its own GLB. This way, distinguishing the buildings would be relatively easy - that’s what’s already done in the sandcastle that you posted.

1 Like
  1. You can only highlight a specific triangle (model) if you have attributes table assigned to it.
  2. attribute numbers should start from 0.
  3. You can add the attribute table in blender. Step by step:
  1. Export model:
  1. You can attach any random metadata to the attribute table and get random textur in UE. My buildings use this method.
1 Like

Thank you very much!

@m.kwiatkowski Thanks again for the description! I already mentioned in the previous thread (that I linked to, and where you described this process) that we could consider to write this up in form of a small tutorial. It may have to include some additional information. (For example: I think that it will be necessary to edit or post-process the glTF, to actually include the extension, and not only the additional attribute). I’ll try to keep this on the radar. If this question comes up more frequently, then it would probably be helpful to summarize that in one place.

An aside: I just opened Consider a function to automatically assign IDs to mesh primitives · Issue #125 · CesiumGS/3d-tiles-tools · GitHub , because I think that this could already go a long way here: I assume that Blender will export all these meshes as actual, individual mesh objects within glTF, so automatically assigning distinct IDs could be enough for many use-cases.

  1. Unfortunately, Blender does not have tools for adding metadata. In blender you can only add an attribute table, but the metadata must be added in notepad++ or injected with another tool.
  2. I wrote my own script for testing and I have currently generated the entire Poland with random metadata. My buldings have a faw metadata heght, material and type bulding.
    My Warsaw Poland in UE5:

You can use geojson or OSM to generate them. Geojson has no metadata, but is already properly set to WGS84. OSM has metadata but no height above the ellipsoid. Heights can be retrieved and assigned from TIFF files, but need GIS tool, There is no quick method :stuck_out_tongue: . .