简体   繁体   English

Threebox 和 Mapbox:为什么相同 GLTF model 的连续实例上的纹理和形状会消失?

[英]Threebox and Mapbox: Why are textures and shapes disappearing on consecutive instances of the same GLTF model?

I am adding multiple instances of the same GLTF model to a scene using Mapbox-gl (2.2.0) and the excellent Threebox (2.2.3) plugin.我正在使用 Mapbox-gl (2.2.0) 和出色的 Threebox (2.2.3) 插件将相同 GLTF model 的多个实例添加到场景中。

The first model renders correctly, the second model exists in the scene, but loses textures and/or shapes.第一个 model 渲染正确,第二个 model 存在于场景中,但会丢失纹理和/或形状。

Different models can be loaded and they do not conflict with each other, however the same behaviour occurs where the second and consecutive instances of each model lose textures and/or shapes.可以加载不同的模型并且它们不会相互冲突,但是当每个 model 的第二个和连续实例丢失纹理和/或形状时,会发生相同的行为。

Two different (but similar) models, loaded twice.两个不同(但相似)的模型,加载了两次。 The first instance of each model renders correctly, the second instance does not每个 model 的第一个实例正确渲染,第二个实例没有

Pre-Mapbox 2.0 release this was working ok, so I presume it's either a bug or a feature I've misunderstood. Mapbox 2.0 之前的版本运行正常,所以我认为这要么是错误,要么是我误解的功能。 It would be great to get this working with 3D terrain on the newest version.在最新版本的 3D 地形上使用它会很棒。

Below is the relevant code, stripped right back:下面是相关的代码,直接剥离:

    let map = new mapboxgl.Map({
        style: "mapbox://styles/mapbox/satellite-v9?optimize=true",
        center: [7.059806068014609, 46.058219779837316],
        zoom: 9.848554211380023,
        pitch: 85,
        bearing: -154.1,
        container: 'map',
        antialias: true, 
        hash: true
    });

    map.on('style.load', function () {

        map.addLayer({
            id: '3D-overlay',
            type: 'custom',
            renderingMode: '3d',
            onAdd: function (map, mbxContext) {

                window.tb = new Threebox(
                    map,
                    map.getCanvas().getContext('webgl'),{});

            },

            render: function (gl, matrix) {
                tb.update();
            }
        });

        addBike(1);
        addBike(2);

    });

    function addBike(num){

        var options = {
            obj: "./gltf/cyclist/scene.gltf",
            type: 'gltf',
            scale: 10,
            units: 'meters',
            rotation: {x: 90, y:177, z:0},
            anchor: 'auto'
        }

        tb.loadObj(options, function (model) {

            tb.add(model);

            model.setCoords([6.927566+(num/10), 45.984111 + (num/10), 4000]);

            model.traverse(function (object) {
                object.frustumCulled = false;
            });

            model.playAnimation({ animation: 0, duration: 1000000000 });

            model.selected = true;

        })

    }

Here is a github repo with the files:这是带有文件的 github 存储库:

https://github.com/nickshreck/threebox-mapbox-gltf-issue.git

Run npm i , put a mapbox token into main.js and then npm run dev运行npm i ,将 mapbox 令牌放入 main.js ,然后npm run dev

Many thanks非常感谢

Thanks for reporting such a tricky issue, in a so detailed and clear way.感谢您以如此详细和清晰的方式报告如此棘手的问题。 It helped me to identify an issue in the code of Threebox.它帮助我发现了 Threebox 代码中的一个问题。 This issue has been resolved adding a new attribute to tb.loadObj that now accepts clone: false .此问题已得到解决,向tb.loadObj添加了一个新属性,该属性现在接受clone: false It's already available in the code repo, and it will be published as npm module v2.2.4 soon.它已经在代码仓库中可用,并且很快将作为 npm 模块 v2.2.4 发布。 In the meantime you can use the bundle file from github .同时,您可以使用github 中的捆绑文件

Your function addBike would look like this now:您的 function addBike现在看起来像这样:

    function addBike(num){

        var options = {
            obj: "./gltf/cyclist/scene.gltf",
            type: 'gltf',
            scale: 10,
            units: 'meters',
            rotation: {x: 90, y:177, z:0},
            anchor: 'auto',
            clone: false //objects won't be cloned
        }

        tb.loadObj(options, function (model) {

            tb.add(model);

            model.setCoords([6.927566+(num/10), 45.984111 + (num/10), 4000]);

            model.traverse(function (object) {
                object.frustumCulled = false;
            });

            model.playAnimation({ animation: 0, duration: 1000000000 });

            model.selected = true;

        })

    }

I also recommend you to declare tb object outside the addLayer method instead of inside.我还建议您在addLayer方法之外而不是在内部声明tb object。 That will fire some automatic behaviors related to real sunlight and terrain layers, and remove the duplicated lights.这将触发一些与真实阳光和地形图层相关的自动行为,并删除重复的灯光。

        window.tb = new Threebox(
            map,
            map.getCanvas().getContext('webgl'),
            {
                realSunlight: true,
                sky: true,
                terrain: true,
                enableSelectingObjects: true,
                enableTooltips: true
            }
        );

        map.on('style.load', function () {

            map.addLayer({
                id: '3D-overlay',
                type: 'custom',
                renderingMode: '3d',
                onAdd: function (map, mbxContext) {

                    addBike(3);
                    addBike(4);

                },

                render: function (gl, matrix) {
                    tb.update();
                }
            });


        });

在此处输入图像描述

Thanks again!再次感谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM