cesium实现飞机与键盘交互[HPR][plane][fps]

在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);
        });
    }

猜你喜欢

转载自blog.csdn.net/cxy_hust/article/details/115874361
FPS