Threebox how do I get all 3d objects on the map?

838 views Asked by At

I need to get an array or object with all 3D models that have been added to the Mapbox map, as it is on the screenshot below. How can I get these objects?

enter image description here

I was trying to do something like this code but it didn't work.

const buildings3DModels = map.tb.world.children;
console.log("buildings3DModels: ", buildings3DModels);
buildings3DModels.forEach(element => console.log(element));

I can see log an array with object with:

console.log(map.tb.world.children);

enter image description here

But for some reason I cant loop through the array with for example forEach or any other loops, it's just don't return anything.

So, my question is: How can I get these 3D objects from the map after they were added to the map? and how can I loop through each object?

2

There are 2 answers

2
jscastro On BEST ANSWER

I'm maintaining the latest threebox repo. tb.world.children is a simple array so if tb.world.children.forEach((o) => { console.log(o) }); is not logging anything is because is empty at the runtime is being executed. Could you post your full code?

If your 3D objects are being loaded through tb.loadObj which is a full async method, it's very probable you are trying to access to tb.world.children array before the objects are fully loaded. If so, then you should manage the Promise instances returned by this method and control when all of them are resolved.

Here you have a method that loads 100 models and logs the objects inside threebox.

function makeNaive(options) {
    let promises = [];
    for (var i = 0; i < 100; i++) {
        promises.push(new Promise((resolve) => {
            tb.loadObj(options, function (model) {
                let lng = origin[0] + Math.random() * 0.4 - 0.2;
                let lat = origin[1] + Math.random() * 0.4 - 0.2;
                let alt = origin[2] + Math.random() * 0.4 - 0.2;
                let obj = model.setCoords([lng, lat, alt]);
                tb.add(obj);

                if (api.animation) {
                    // play default animation, for 10 seconds
                    let opt = { animation: 0, duration: 10000 };
                    obj.playDefault(opt);
                }

                getGeometryTotalLength();
                resolve(true);

            })
        }));

    }

    Promise.all(promises).then((values) => {
        console.log("All promises finished:");
        tb.world.children.forEach((o) => { console.log(o) });
    });
    map.repaint = true;
}

enter image description here

0
mglonnro On

I'm not sure why it's not working for you, but you are using threebox, so here is a fiddle that seems to work: http://jsfiddle.net/up8j3va5/

Short snip from the fiddle:


    threebox.addAtCoordinate(
                    plane, 
                    [origin[0], origin[1], 10],
                    {preScale: 1}
                );
                
    threebox.world.children.forEach(element => 
      console.log(element.position.x, 
                  element.position.y, 
                  element.position.z));