• Cesium学习笔记(七):Demo学习(自由控制飞行的飞机)[转]


    https://blog.csdn.net/umgsoil/article/details/74923013#

    这是官方的教程Demo,名字叫Use HeadingPitchRoll,顾名思义,就是教你用HeadingPitchRoll这个方法的,下面我们就来看一看这个Demo
    首先先说一下,这个Demo是沙盒里面的,所以如果你想在本地运行的话需要改一下html
    这里是html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport"
              content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
        <title>Hello World!</title>
        <script src="../Build/Cesium/Cesium.js"></script>
        <!-- 如果要用沙盒里的东西的话加上这个 -->
        <script src="../Apps/Sandcastle/Sandcastle-header.js"></script>
        <!-- 一定要加上这个css样式 -->
        <link rel="stylesheet" href="Sandcastle/templates/bucket.css">
        <style>
            @import url(../Build/Cesium/Widgets/widgets.css);
        </style>
    </head>
    <body>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="toolbar">
        <!-- 这是Demo需要的侧边栏 -->
        <table class="infoPanel">
            <tbody>
            <tr>
                <td>Click on the 3D window then use the keyboard to change settings.</td>
            </tr>
            <tr>
                <td>Heading: <span id="heading"></span>°</td>
            </tr>
            <tr>
                <td>← to left/→ to right</td>
            </tr>
            <tr>
                <td>Pitch: <span id="pitch"></span>°</td>
            </tr>
            <tr>
                <td>↑ to up/↓ to down</td>
            </tr>
            <tr>
                <td>roll: <span id="roll"></span>°</td>
            </tr>
            <tr>
                <td>← + ⇧ left/→ + ⇧ right</td>
            </tr>
            <tr>
                <td>Speed: <span id="speed"></span>m/s</td>
            </tr>
            <tr>
                <td>↑ + ⇧ to speed up/↓ + ⇧ to speed down</td>
            </tr>
            <tr>
                <td>following aircraft
                    <input id="fromBehind" type="checkbox">
                </td>
            </tr>

            </tbody>
        </table>
    </div>

    <script src="你的js文件"></script>

    </body>
    </html>

    这是js代码

    //飞机飞行
    var canvas = viewer.canvas;
    canvas.setAttribute('tabindex', '0'); // 将焦点放在画布上
    //如果点击就获取画布焦点
    canvas.addEventListener('click', function() {
        canvas.focus();
    });
    canvas.focus();

    //飞行路径的位置
    var pathPosition = new Cesium.SampledPositionProperty();
    //添加飞机飞行路径
    var entityPath = viewer.entities.add({
        position : pathPosition,
        name : 'path',
        path : {
            show : true,
            leadTime : 0,
            trailTime : 60,
            width : 10,
            resolution : 1,
            material : new Cesium.PolylineGlowMaterialProperty({
                glowPower : 0.3,
                color : Cesium.Color.PALEGOLDENROD
            })
        }
    });

    var camera = viewer.camera;
    var controller = scene.screenSpaceCameraController;
    var r = 0;
    //中心点
    var center = new Cesium.Cartesian3();

    //机身模型的偏移参数
    var hpRoll = new Cesium.HeadingPitchRoll();
    //相机模型的偏移参数
    var hpRange = new Cesium.HeadingPitchRange();

    var speed = 10;
    //默认按一下偏移3度
    var deltaRadians = Cesium.Math.toRadians(3.0);

    //飞机位置
    var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 5000.0);
    //速度向量
    var speedVector = new Cesium.Cartesian3();
    //生成一个由两个参考系生成的矩阵
    var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west');

    //添加模型
    var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({
        //这里需要把模型路径改下(如果你用的还是HelloWord.html的话就用这个,不是的话请自行修改)
        url : '../Apps/SampleData/models/CesiumAir/Cesium_Air.glb',
        modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform),
        minimumPixelSize : 128
    }));

    //动画播放
    planePrimitive.readyPromise.then(function(model) {
        // 以半速循环动画
        model.activeAnimations.addAll({
            speedup : 0.5,
            loop : Cesium.ModelAnimationLoop.REPEAT
        });

        //r=2*max(模型的半径,相机的最近距离)
        r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
        //镜头最近距离
        controller.minimumZoomDistance = r * 0.5;
        //计算center位置(也为下面的镜头跟随提供了center位置)
        Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, center);
        //相机偏移角度
        var heading = Cesium.Math.toRadians(230.0);
        var pitch = Cesium.Math.toRadians(-20.0);
        hpRange.heading = heading;
        hpRange.pitch = pitch;
        hpRange.range = r * 50.0;
        //固定相机
        camera.lookAt(center, hpRange);
    });

    //键盘监听
    document.addEventListener('keydown', function(e) {
        switch (e.keyCode) {
            case 40:
                if (e.shiftKey) {
                    // 按住shift加下箭头减速
                    speed = Math.max(--speed, 1);
                } else {
                    // 直接按下箭头降低角度
                    hpRoll.pitch -= deltaRadians;
                    if (hpRoll.pitch < -Cesium.Math.TWO_PI) {
                        hpRoll.pitch += Cesium.Math.TWO_PI;
                    }
                }
                break;
            case 38:
                if (e.shiftKey) {
                    // 按住shift加上箭头加速
                    speed = Math.min(++speed, 100);
                } else {
                    // 直接按上箭头抬高角度
                    hpRoll.pitch += deltaRadians;
                    if (hpRoll.pitch > Cesium.Math.TWO_PI) {
                        hpRoll.pitch -= Cesium.Math.TWO_PI;
                    }
                }
                break;
            case 39:
                if (e.shiftKey) {
                    // 飞机本身向右旋转
                    hpRoll.roll += deltaRadians;
                    if (hpRoll.roll > Cesium.Math.TWO_PI) {
                        hpRoll.roll -= Cesium.Math.TWO_PI;
                    }
                } else {
                    // 向右飞行
                    hpRoll.heading += deltaRadians;
                    if (hpRoll.heading > Cesium.Math.TWO_PI) {
                        hpRoll.heading -= Cesium.Math.TWO_PI;
                    }
                }
                break;
            case 37:
                if (e.shiftKey) {
                    // 飞机本身向左旋转
                    hpRoll.roll -= deltaRadians;
                    if (hpRoll.roll < 0.0) {
                        hpRoll.roll += Cesium.Math.TWO_PI;
                    }
                } else {
                    // 向左飞行
                    hpRoll.heading -= deltaRadians;
                    if (hpRoll.heading < 0.0) {
                        hpRoll.heading += Cesium.Math.TWO_PI;
                    }
                }
                break;
            default:
        }
    });

    var headingSpan = document.getElementById('heading');
    var pitchSpan = document.getElementById('pitch');
    var rollSpan = document.getElementById('roll');
    var speedSpan = document.getElementById('speed');
    var fromBehind = document.getElementById('fromBehind');

    //给左边的通知栏更新数据同时刷新飞机位置(这里也是个1ms一次的回调)
    viewer.scene.preRender.addEventListener(function(scene, time) {
        headingSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.heading).toFixed(1);
        pitchSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.pitch).toFixed(1);
        rollSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.roll).toFixed(1);
        speedSpan.innerHTML = speed.toFixed(1);

        //选择的笛卡尔分量Cartesian3.UNIT_X(x轴单位长度)乘以一个标量speed/10,得到速度向量speedVector
        speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X, speed / 10, speedVector);
        //飞机的模型矩阵与速度向量speedVector相乘,得到position
        position = Cesium.Matrix4.multiplyByPoint(planePrimitive.modelMatrix, speedVector, position);
        //添加一个路径模型(就是白色的尾气)
        pathPosition.addSample(Cesium.JulianDate.now(), position);
        //飞机位置+旋转角度+地球+坐标矩阵=飞机模型矩阵
        Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform, planePrimitive.modelMatrix);

        if (fromBehind.checked) {
            // 镜头跟随
            Cesium.Matrix4.multiplyByPoint(planePrimitive.modelMatrix, planePrimitive.boundingSphere.center, center);
            hpRange.heading = hpRoll.heading;
            hpRange.pitch = hpRoll.pitch;
            camera.lookAt(center, hpRange);
        }
    });
     

    如上就是这个Demo的源码了,具体运行我就不展示了(csdn上传不了这么大的gif),还是很有趣的
    我觉得注释已经很详细了,就不多说了,不清楚或者发现错误的请留言,大家一起学习
    ---------------------
    作者:simple-soul
    来源:CSDN
    原文:https://blog.csdn.net/umgsoil/article/details/74923013
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    面向对象编程(一)
    函数嵌套(闭包)、阶乘、斐波那数列知识
    函数的定义及用法
    常见例子
    Python解析JSON详解
    linux yum install mvn
    消息组件
    websphere 安装中出现JNDI资源找不到问题总结
    多业务Nginx解决方式
    python-pip 安装使用问题
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/10242532.html
Copyright © 2020-2023  润新知