Cesium introduces Three sync camera

Original post: https://blog.csdn.net/zhishiqu/article/details/79077883

Source code: cesium-threejs-experiment

This post describes how to introduce Three in Cesium. To summarize the principle,

  1. Two containers are set up in HTML to hold Cesium and Three, and the Three container is under the Cesium container, so that the scene generated by Three can be overlaid on Cesium, and the mouse events of the Three container are disabled, and Three is synchronized through Cesium.
  2. Initialize Ceiusm, initialize Three (the renderer sets the background to be transparent to achieve the superimposition effect ), initialize the objects and add them to their respective scenes
  3. Get the coordinates of the specified location, set the coordinates of the Three scene to the coordinates of the specified location, and set the orientation and top direction
  4. Turn off the automatic update of the Three camera, copy the fov and matrix of the Cesium camera and assign them to the Three camera, update the Three camera, and Cesium+Three synchronization

important point

1. The Three source code used in the original post is the r87 version. Based on the original version, it can run normally. If you switch to the version after r87, you will find that there is no error but the Cesium displays normally but the Three model does not display the problem

Solution: The formal parameter of the lookAt method of the object3D function in the r87 version is vector3. The formal parameter of the lookAt method of the subsequent version is to split vector3 into three parameters and pass in, so changing to the subsequent version requires the lookat method in the source code. The actual parameters can be changed to display correctly.

2. After Cesium and Three are loaded normally, the Cesium map flashes

Solution: This problem may be caused by the out-of-sync of Ceiusm and Three. After updating the Cesium version in the project, no flickering phenomenon was found, so it is speculated that updating the Cesium version can solve it.

Core code

        // 核心方法
        function renderThreeObj() {
            // register Three.js scene with Cesium
            three.camera.fov = Cesium.Math.toDegrees(cesium.viewer.camera.frustum.fovy) // 获取cesium相机角度并赋值给Three
            three.camera.updateProjectionMatrix();
            // 笛卡尔转矢量
            var cartToVec = function (cart) {
                return new THREE.Vector3(cart.x, cart.y, cart.z);
            };
            // 物体位置调整
            for (var id in _3Dobjects) {
                minWGS84 = _3Dobjects[id].minWGS84;
                maxWGS84 = _3Dobjects[id].maxWGS84;
                // 物体中心点坐标
                var center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2);
                // 物体顶部朝向坐标
                var centerHigh = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2, 1);
                // y轴朝向
                var bottomLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], minWGS84[1])); // 指定平面左下角
                var topLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], maxWGS84[1])); // 指定平面左上角
                var latDir = new THREE.Vector3().subVectors(bottomLeft, topLeft).normalize(); // 指定平面左边向量
                // 物体位置调整
                _3Dobjects[id].threeMesh.position.copy(center); // 物体position更正
                _3Dobjects[id].threeMesh.lookAt(centerHigh.x, centerHigh.y, centerHigh.z); // z轴方向,即上方向,lookAt改传三个参数
                _3Dobjects[id].threeMesh.up.copy(latDir);   //指定y轴的朝向与平面左边平行,即模型朝向与平面左边朝向相同
            }
            //关闭相机自动更新
            three.camera.matrixAutoUpdate = false;
            // cesium相机位置
            var cvm = cesium.viewer.camera.viewMatrix;
            var civm = cesium.viewer.camera.inverseViewMatrix;
            // 同步Three相机位置设置
            three.camera.matrixWorld.set(
                civm[0], civm[4], civm[8], civm[12],
                civm[1], civm[5], civm[9], civm[13],
                civm[2], civm[6], civm[10], civm[14],
                civm[3], civm[7], civm[11], civm[15]
            );
            three.camera.matrixWorldInverse.set(
                cvm[0], cvm[4], cvm[8], cvm[12],
                cvm[1], cvm[5], cvm[9], cvm[13],
                cvm[2], cvm[6], cvm[10], cvm[14],
                cvm[3], cvm[7], cvm[11], cvm[15]
            );
            // 相机设置参数
            var width = ThreeContainer.clientWidth;
            var height = ThreeContainer.clientHeight;
            var aspect = width / height;
            three.camera.aspect = aspect;
            three.camera.updateProjectionMatrix(); // 相机参数更新
            // 渲染尺寸
            three.renderer.setSize(window.innerWidth, window.innerHeight);
            three.renderer.render(three.scene, three.camera); // 更新渲染
        }

 

Guess you like

Origin blog.csdn.net/oneKnow/article/details/100118580