cesium实现飞机与键盘交互[HPR][plane][fps]-程序员宅基地

技术标签: cesium & gl  cesium  frontEnd  

在cesium中实现键盘监听控制飞机的heading pitch roll

主要参考例子:

https://sandcastle.cesium.com/index.html?src=HeadingPitchRoll.html

上述例子中的第一人称视角处理有纰漏,改进后的效果和实现的代码如下:

在这里插入图片描述

            let canvas = viewer.canvas;
            canvas.setAttribute("tabindex", "0"); // needed to put focus on the canvas
            canvas.addEventListener("click", function () {
    
                canvas.focus();
            });
            canvas.focus();

            let scene = viewer.scene;

            let pathPosition = new SampledPositionProperty();
            this.planePath = viewer.entities.add({
    
                id: "keyboardDemoPlanePath",
                position: pathPosition,
                // name: "path",
                path: {
    
                    show: true,
                    leadTime: 0,
                    trailTime: 60,
                    width: 10,
                    resolution: 1,
                    material: new PolylineGlowMaterialProperty({
    
                        glowPower: 0.3,
                        taperPower: 0.3,
                        color: Color.PALEGOLDENROD
                    })
                }
            });

            let camera = viewer.camera;
            let controller = scene.screenSpaceCameraController;
            let r = 0;
            let center = new Cartesian3();

            let hpRoll = new HeadingPitchRoll();
            let hpRange = new HeadingPitchRange();
            let speed = 1;
            let deltaRadians = _Math.toRadians(3.0);

            let position = Cartesian3.fromDegrees(
                114.4152843,
                30.512368,
                5000.0
            );
            let speedVector = new Cartesian3();
            let fixedFrameTransform = Transforms.localFrameToFixedFrameGenerator(
                "north",
                "west"
            );

            let planePrimitive = scene.primitives.add(
                Model.fromGltf({
    
                    url: `${
      webSetting.assetsUrl}/map/su30.gltf`,
                    // url: `${webSetting.assetsUrl}/map/apaqi_x-90_y180.glb`,
                    modelMatrix: Transforms.headingPitchRollToFixedFrame(
                        position,
                        hpRoll,
                        Ellipsoid.WGS84,
                        fixedFrameTransform
                    ),
                    minimumPixelSize: 256
                })
            );
            this.plane = planePrimitive;

            planePrimitive.readyPromise.then(function (model) {
    
                // Play and loop all animations at half-speed
                model.activeAnimations.addAll({
    
                    multiplier: 0.5,
                    loop: ModelAnimationLoop.REPEAT
                });

                // Zoom to model
                r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
                controller.minimumZoomDistance = r * 0.5;
                Matrix4.multiplyByPoint(
                    model.modelMatrix,
                    model.boundingSphere.center,
                    center
                );
                let heading = _Math.toRadians(230.0);
                let pitch = _Math.toRadians(-20.0);
                hpRange.heading = heading;
                hpRange.pitch = pitch;
                hpRange.range = r * 50.0;
                camera.lookAt(center, hpRange);
            });

            this.keyBoardListener = function (e) {
    
                switch (e.keyCode) {
    
                    case 40:
                        if (e.shiftKey) {
    
                            // speed down
                            speed -= 10;
                            speed = Math.max(speed, 1);
                        } else {
    
                            // pitch down
                            hpRoll.pitch -= deltaRadians;
                            if (hpRoll.pitch < -_Math.TWO_PI) {
    
                                hpRoll.pitch += _Math.TWO_PI;
                            }
                        }
                        break;
                    case 38:
                        if (e.shiftKey) {
    
                            // speed up
                            speed += 10;
                            speed = Math.min(speed, 1000);
                        } else {
    
                            // pitch up
                            hpRoll.pitch += deltaRadians;
                            if (hpRoll.pitch > _Math.TWO_PI) {
    
                                hpRoll.pitch -= _Math.TWO_PI;
                            }
                        }
                        break;
                    case 39:
                        if (e.shiftKey) {
    
                            // roll right
                            hpRoll.roll += deltaRadians;
                            if (hpRoll.roll > _Math.TWO_PI) {
    
                                hpRoll.roll -= _Math.TWO_PI;
                            }
                        } else {
    
                            // turn right
                            hpRoll.heading += deltaRadians;
                            if (hpRoll.heading > _Math.TWO_PI) {
    
                                hpRoll.heading -= _Math.TWO_PI;
                            }
                        }
                        break;
                    case 37:
                        if (e.shiftKey) {
    
                            // roll left until
                            hpRoll.roll -= deltaRadians;
                            if (hpRoll.roll < 0.0) {
    
                                hpRoll.roll += _Math.TWO_PI;
                            }
                        } else {
    
                            // turn left
                            hpRoll.heading -= deltaRadians;
                            if (hpRoll.heading < 0.0) {
    
                                hpRoll.heading += _Math.TWO_PI;
                            }
                        }
                        break;
                    default:
                        break;
                }
            };
            document.addEventListener("keydown", this.keyBoardListener);

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

            this.preUpateSpeedViewFunc = (scene, time) => {
    
                speedVector = Cartesian3.multiplyByScalar(
                    Cartesian3.UNIT_X,
                    speed / 10,
                    speedVector
                );

                // let lastPosition = position.clone();
                position = Matrix4.multiplyByPoint(
                    planePrimitive.modelMatrix,
                    speedVector,
                    position
                );
                this.center = position;


                // pathPosition.addSample(JulianDate.now(), position);
                pathPosition.addSample(time, position);
                // console.log("adding: t->p: ", JulianDate.now().toString(), " -> ",position.toString());
                Transforms.headingPitchRollToFixedFrame(
                    position,
                    hpRoll,
                    Ellipsoid.WGS84,
                    fixedFrameTransform,
                    planePrimitive.modelMatrix
                );
                
                // view at fisrt player 
                if (this.fpsFlag) {
    
                    // Zoom to model
                    Matrix4.multiplyByPoint(
                        planePrimitive.modelMatrix,
                        planePrimitive.boundingSphere.center,
                        center
                    );

                    hpRange.heading = hpRoll.heading;
                    hpRange.pitch = hpRoll.pitch;
                    hpRange.range =  camera.frustum.near * 0.05;
                    // mainly using this to set the camera position relatively to the plane
                    camera.lookAt(center, hpRange);
                    camera.moveForward(8.2);
                    camera.moveLeft(2.65);
                    camera.moveUp(0.7);
                    // console.log("cur camera hpr is: ",camera.heading, " ", camera.pitch, " ", camera.roll,
                    // "hpRoll's hpr is ", hpRoll.heading, " ", hpRoll.pitch, " ", hpRoll.roll, " ");
                    
                    // set the hpr according to the hpr of the plane
                    camera.setView({
    
                        orientation: {
    
                            heading : hpRoll.heading, // east, default value is 0.0 (north)
                            pitch : hpRoll.pitch,    // default value (looking down)
                            roll : hpRoll.roll                             // default value
                        }
                    });
                }
            };
            viewer.scene.preUpdate.addEventListener(this.preUpateSpeedViewFunc, this);

            this.preUpateHPRFunc = (scene, time) => {
    
                this.headingShow = _Math.toDegrees(hpRoll.heading).toFixed(2);

                this.pitchShow = _Math.toDegrees(hpRoll.pitch).toFixed(2);
                this.rollShow = _Math.toDegrees(hpRoll.roll).toFixed(2);
                this.speedShow = speed.toFixed(2);

                let tmp = Cartographic.fromCartesian(this.center, Ellipsoid.WGS84);
                this.planeLon = tmp.longitude.toFixed(2);
                this.planeLat = tmp.latitude.toFixed(2);
                this.planeHei = tmp.height.toFixed(2);
            };
            viewer.scene.preRender.addEventListener(this.preUpateHPRFunc, this);
        });
    }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cxy_hust/article/details/115874361

智能推荐

scss常见用法_scss常用-程序员宅基地

文章浏览阅读3.3w次,点赞4次,收藏21次。简介Sass 有两种语法规则(syntaxes),目前新的语法规则(从 Sass 3开始)被称为 “SCSS”( 时髦的css(Sassy CSS)),它是css3语法的的拓展级,就是说每一个语法正确的CSS3文件也是合法的SCSS文件,SCSS文件使用.scss作为拓展名。第二种语法别成为缩进语法(或者 Sass),它受到了Haml的简洁精炼的启发,它是为了人们可以用和css相近的但是更_scss常用

Samba服务配置及各项参数含义_valid users-程序员宅基地

文章浏览阅读5.4k次,点赞4次,收藏28次。Samba服务的主配置文件是smb.conf,默认在/etc/samba/目录下。smb.conf含有多个段,每个段由段名开始,直到下个段名。每个段名放在方括号中间。每段的参数的格式是:名称=指。配置文件中一行一个段名和参数,段名和参数名不分大小写。除了[global]段外,所有的段都可以看作是一个共享资源。段名是该共享资源的名字,段里的参数是该共享资源的属性。Samba安装好后,使用testpa..._valid users

爱奇艺2018.9.28笔试 清雨的自助餐_n种食物,排成一排,可以选择若干种,但是不能选择-程序员宅基地

文章浏览阅读287次。题目描述有N种食物,排成一排,选择里面的若干食物,但不能选择相邻的食物。一个也不选也是一种选择的方法。问有多少种选择的方法?输入:一个整数n输出:一个正整数表示答案样例输入:3样例输出:5提示:方法有1、2、3、1和3、不选。共5种。斐波那契n从1开始,f(1)=2f(2)=3f(3)=5…n = eval(input())li = [0]*3li[1]..._n种食物,排成一排,可以选择若干种,但是不能选择

java date 加一个月_如何在Java中向当前日期添加一个月?-程序员宅基地

文章浏览阅读794次。陪伴而非守候LocalDate::plusMonths例:LocalDate.now( ) .plusMonths( 1 );最好指定时区。LocalDate.now( ZoneId.of( "America/Montreal" ) .plusMonths( 1 );java.time该java.time框架是建立在Java 8和更高版本。这些类取代旧的麻烦日期时间..._日期 加1个月java

Python + WinAppDriver + Appium 对Windows桌面应用程序进行界面(UI)自动化测试_appium winappdriver-程序员宅基地

文章浏览阅读1.4w次,点赞11次,收藏105次。开发者模式设置Appium连接WinAppDriver配置WinAppDriver支持的查找元素方法查询控件信息VNC Viewer 连接远程电脑桌面 UI自动化测试的示例代码#!/usr/bin/env python# -*- encoding: utf-8 -*-'''@Author: 思文伟@Date: 2021/03/30 15:49:32'''import ioimport osimport sysfrom appium impor..._appium winappdriver

android studio实验之个人介绍界面_安卓studio用xml写一个自我介绍代码-程序员宅基地

文章浏览阅读4.1k次,点赞7次,收藏52次。个人介绍界面_安卓studio用xml写一个自我介绍代码

随便推点

WMS与TMS实施流程-程序员宅基地

文章浏览阅读1.1k次。导读国内有庞大的仓储物流从业人员队伍,很多人想深入了解WMS与TMS究竟是什么。本文详细解析WMS与TMS的选型与实施。WMS实施(上)和其它软件项目的实施大同小异,这里整理了WMS选型和上线过程中容易被忽略的10大误区。1、过分相信软件商的系统演示。在演示会上,一定要控制交流的内容和进程,尽量使用自己的作业数据。2、只关注软件本身,忘了关注将来的实施顾问和厂商背景。再好的WMS也要在标准软件之外加上10%-50%的定制工作,最好签一份系统维护合同,虽然会花钱,但是来自厂家的支持永远巨划

详述CRC校验码(附代码)-程序员宅基地

文章浏览阅读1.2w次,点赞13次,收藏99次。关注+星标公众号,不错过精彩内容来源| 一口LinuxCRC校验应用比较广泛,通常在通信领域用的比较多,即便是自定义通信协议,也可以添加CRC校验码,使其通信更加可靠。今天就来进一步描述..._crc校验代码

Oracle 12.2.0.1.0 PDB随着CDB启动而启动-程序员宅基地

文章浏览阅读382次。Oracle12.2.0.1.0 PDB随着CDB启动而启动 Oracle 12.1和Oracle12.2版本,默认情况下PDB不会随着CDB启动而启动; 为了实现PDB随着CD..._创建一个触发器让pdb能够在cdb启动时打开,并验证效果。

Idea配置tomcat时没有artifacts包解决办法_idea tomcat web项目缺少artofsolving包-程序员宅基地

文章浏览阅读4.5k次,点赞5次,收藏8次。不知道为啥我的idea老是莫名其妙的报错,可能是在针对我1.这个时候大家可以看到是没有 artifacts包的在下方也有这个警告导致tomcat无法成功配置2.我在网上找的解决办法是将这个勾上但是我默认就是勾上的没有解决我的问题 3.我将maven环境更新了一下于是成功解决了结论:更新Maven环境即可 ..._idea tomcat web项目缺少artofsolving包

【Ubuntu用法】ubuntu下源码安装OpenSSH_ubuntu下载ssh-程序员宅基地

文章浏览阅读3.1k次。由于OpenSSH依赖于openssl,因此先安装opensslopenssl安装流程下载openssl源码openssl下载的地址为:https://www.openssl.org/source/openssl-1.1.1h.tar.gz注:此处我使用的版本是openssl-1.1.1h解压源码解压命令:tar zxvf openssl-1.1.h.tar.gz编译安装在这之前,先卸载掉老版本。卸载命令为:$ sudo apt-get purge openssl然后删掉老版本的_ubuntu下载ssh

致翔OA漏洞学习——msglog.aspx SQL注入漏洞_aspx注入漏洞-程序员宅基地

文章浏览阅读2.8k次,点赞8次,收藏10次。警告请勿使用本文提到的内容违反法律。本文不提供任何担保一、概述致翔OA msglog.aspx文件存在SQL注入漏洞,攻击者通过漏洞可获取敏感信息。注:注入参数为user。_aspx注入漏洞

推荐文章

热门文章

相关标签