首页 > 解决方案 > 如何在 Autodesk Forge 中动态更新 THREE.js PointCloud 覆盖

问题描述

我正在为 Autodesk forge 开发一个标记扩展。我希望能够单击一个位置,并将标记动态显示为点云。

下面是扩展的加载函数。我第一次加载点云时它可以工作,但是当我尝试向几何体添加顶点并渲染它时,新点不会出现。但是,光线投射器能够检测到该点。我知道这一点是因为当我第二次单击某个位置时,我收到一条日志,告诉我光线投射器截获了点云(即使该点未在屏幕上呈现)。

ClickableMarkup.prototype.load = function () {
    const self = this;

    /* Initizialize */
    console.log('Start loading clickableMarkup extension');
    this.camera = this.viewer.navigation.getCamera(); // Save camera instance
    console.log(this.camera);
    this.initCameraInfo(); // Populate cameraInfo array
    this.overlayManager.addScene(this.sceneName); // Add scene to overlay manager
    this.scene = this.viewer.impl.overlayScenes[this.sceneName].scene; // Save reference to the scene

    /* Create pointCloud */
    this.geometry = new THREE.Geometry();
    this.cameraInfo.forEach( function(e) {
            // console.log(`   > add ${e.position}`)
            self.geometry.vertices.push(e.position);
        }
    );
    this.geometry.computeBoundingBox();
    // const material = new THREE.PointCloudMaterial( { size: 50, color: 0Xff0000, opacity: 100, sizeAttenuation: true } );
    const texture = THREE.ImageUtils.loadTexture(this.pointCloudTextureURL);
    this.material = new THREE.ShaderMaterial({
        vertexColors: THREE.VertexColors,
        opacity: this.prefs.POINT_CLOUD_OPACITY,
        fragmentShader: this.fragmentShader,
        vertexShader: this.vertexShader,
        depthWrite: true,
        depthTest: true,
        uniforms: {
            size: {type: "f", value: self.size},
            tex: {type: "t", value: texture}
        }
    });
    this.points = new THREE.PointCloud( this.geometry, this.material );

    /* Add the pointcloud to the scene */
    this.overlayManager.addMesh(this.points, this.sceneName); /* >>> THIS WORKS  SO IT RENDERS THE POINTCLOUD AT THE BEGINNING OF LAOD <<< */

    /* Set up event listeners */
    document.addEventListener('click', event => {
        event.preventDefault();

        this.setRaycasterIntersects(event); // Fill this.intersects with pointcloud indices that are currently selected

        if (this.intersects.length > 0) {
            console.log('Raycaster hit index: ' + this.hitIndex + JSON.stringify(this.intersects[0]));
            this.setCameraView(this.hitIndex);
        } else {
            /*  >>>>  THE PROBLEM IS HERE - IT DOESN'T RENDER THE NEW POINTCLOUD POINTS <<<< */
            const mousePos = this.screenToWorld(event);
            if (mousePos) { // Only add point to scene if the user clicked on the building
                const vertexMousePos = new THREE.Vector3(mousePos.x, mousePos.y, mousePos.z);
                this.geometry.vertices.push(vertexMousePos);
                this.geometry.verticesNeedUpdate = true;
                this.geometry.computeBoundingBox();

                this.points = new THREE.PointCloud(this.geometry, this.material);
                this.overlayManager.addMesh(this.points, this.sceneName);
                this.viewer.impl.invalidate(true); // Render the scene again
            }
        }

    }, false);

    console.log('ClickableMarkup extension is loaded!');
    return true;
};

如何使新的点云顶点渲染?

标签: three.jsautodesk-forge

解决方案


看起来有问题的代码中可能有错字。

this.overlayManager.addMesh(this.points, 'this.sceneName');

应该是

this.overlayManager.addMesh(this.points, this.sceneName);

推荐阅读