SuperMap iClient3D for WebGL教程 Camera

SuperMap iClient3D for WebGL教程 Camera

WuYK

在WebGL场景里,有一类很重要的对象,那就是我们的相机Camera对象。这里的Camera相当于人的眼睛,从坐标的那个视点去观察目标。该类对象可以对场景进行缩放,平移,旋转等操作。

该对象主要由位置、方向和视锥体来定义,现在我们就从这三个方面说起。

一.先从视锥体说起,因为这个相当于是我们Camera视点投影的基础
视锥体是当前camera视野的空间区域,主要介绍PerspectiveFrustum,即Webgl默认的视锥体。
PerspectiveFrustum:(Webgl默认的视锥体,投射投影视锥体)
在这里插入图片描述
该视锥体主要由4个参数组成,即aspectRatio ,fov,near,far。
参数fov定义视野在Y-Z平面的角度,范围是[0.0, 180.0];参数aspect是投影平面宽度与高度的比率;参数Near和Far分别是近远裁剪面到视点(沿Z负轴)的距离,它们总为正值。以上两个函数缺省时,视点都在原点,视线沿Z轴指向负方向。
二.位置与方向
这里我把这两个点结合到一起说,因为通常我们都是两个结合在一起使用的。

说到位置与方向,那不得不又说到Camera的定位方法。主要介绍三种,请看如下所示:

LookAt
通过Camera.LookAt可以定位到某一个点,正如其单词的表面意思,定位过后我们就没办法对定位点进行平移操作了,只能进行旋转,缩放观察。

var center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0);
scene.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));
// 2. 利用HeadingPitchRange设置偏移
var center = Cesium.Cartesian3.fromDegrees(-72.0, 40.0);
var heading = Cesium.Math.toRadians(50.0);
var pitch = Cesium.Math.toRadians(-20.0);
var range = 5000.0;
scene.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));

在这里插入图片描述

SetView
这个定位方法和LookAt相比较就是,它可以定位矩形范围,而且定位过后可以平移操作,相当于只是设置一个视点。
在这里插入图片描述
destination:即相机的视点或者区域,可以是Cartesian3对象或者是Rectangle。
orientation:即相机的方位角,主要包含方位角(heading)、俯仰角(pitch)、滚动角(roll)。由下图来理解:
在这里插入图片描述

 scene.camera.setView({
  destination : Cesium.Cartesian3.fromDegrees(116.383820892022 , 39.9972582230088 ,47.3775521684438 ), // 设置位置

  orientation: {
    heading : Cesium.Math.toRadians(30.0), // 方向
    pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
    roll : 0
  }
});
});

flyTo
这个和之前两个定位有一个很大的区别,那就是它可以飞(fly),会有一个从当前视点到目标点的一个动画效果展示。
在这里插入图片描述

scene.camera.flyTo({
        destination :  Cesium.Cartesian3.fromDegrees(116.383820892022 , 39.9972582230088 ,47.3775521684438), // 设置位置
        orientation: {
            heading : Cesium.Math.toRadians(30.0), // 方向
            pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
            roll : 0
        },
        duration:3, // 设置飞行持续时间,默认会根据距离来计算
        complete: function () {
            // 到达位置后执行的回调函数
            console.log('到达目的地');
        },
        cancle: function () {
            // 如果取消飞行则会调用此函数
            console.log('飞行取消')
        },
        pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰角度,并将地球保持在视口中。
        maximumHeight:5000, // 相机最大飞行高度
        flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
    });

说了camera的三种定位方法,再说说Camera的一些常用的方法。

camera.zoomIn(amount); 相机向前移动
camera.zoomOut(amount); 相机向后移动

camera.look
camera.lookLeft(amount);沿其右向量的相反方向围绕其向上向量旋转相机镜头
camera.lookRight(amount);沿其右向量围绕其向上向量旋转相机镜头
camera.lookUp(amount);沿向上向量的方向围绕其右向量旋转相机镜头
camera.lookDown(amount);沿其上向量的相反方向围绕其右向量旋转相机镜头

camera.move
camera.moveBackward(amount);效果与camera.zoomOut(amount)一致
camera.moveForward(amount);效果与camera.zoomIn(amount)一致
camera.moveLeft(amount);镜头向左平移
camera.moveRight(amount);镜头向右平移
camera.moveUp(amount);镜头向上平移
camera.moveDown(amount);镜头向下平移

camera的look系列方法和move都可以改变视角,但本质还是有很大的区别
如果把camera看作一个人,那么look相当于人的眼睛,进行四处旋转张望,而move相当于人的脚,可以四处走动

我们可以根据这些参数构造与键盘搭配使用的方法,来模拟第一人称在场景漫游。

var ellipsoid = scene.globe.ellipsoid;
					var canvas = viewer.cancas;
					var camera = scene.camera;
					var Camera_actions = {						
						lookLeft: false,
						lookRight: false,
						moveForward : false,
						moveBackward: false,
						moveLeft: false,
						moveRight: false
					};

					function getAction(keyCode) {
						switch(keyCode) {
							case 'W'.charCodeAt(0): 
								return 'moveForward';
							case 'S'.charCodeAt(0): 
								return 'moveBackward';
							case 'A'.charCodeAt(0): 
								return 'moveLeft';
							case 'D'.charCodeAt(0): 
								return 'moveRight';
							case 'Q'.charCodeAt(0): 
								return 'lookLeft';
							case 'E'.charCodeAt(0): 
								return 'lookRight';
							default:
								return undefined;
						}
					}
					document.addEventListener('keydown', function(e) {
						var action = getAction(e.keyCode);
						if(typeof action !== 'undefined') {
							Camera_actions[action] = true;
						}
					}, false);
					document.addEventListener('keyup', function(e) {
						var action = getAction(e.keyCode);
						if(typeof action !== 'undefined') {
							Camera_actions[action] = false;
						}
					}, false);
					scene.postRender.addEventListener(function(time) {
						var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
						var moveRate = cameraHeight / 50.0;

						if(Camera_actions.lookLeft) {
							camera.lookLeft(0.01);
						}
						if(Camera_actions.lookRight) {
							camera.lookRight(0.01);
						}
						if(Camera_actions.moveForward) {
							camera.moveForward(moveRate);
						}
						if(Camera_actions.moveBackward) {
							camera.moveBackward(moveRate);
						}
						if(Camera_actions.moveLeft) {
							camera.moveLeft(moveRate);
						}
						if(Camera_actions.moveRight) {
							camera.moveRight(moveRate);
						}
					});

以下是效果图,通过键盘来进行场景的漫游,这是第一人称相机漫游。
我们也可以通过控制键盘参数设置场景中的模型的移动,结合camera的移动,就可以构成控制模型第三人称移动的效果了。
在这里插入图片描述

Camera的look方法是以某个点为轴进行旋转,那么我们有办法让Camera旋转观察某个点吗。答案是当然可以。

通过Camera.flyCircle()

var scene = viewer.scene;
var camera = scene.camera;
var handlerPoint = new Cesium.DrawHandler(viewer,Cesium.DrawMode.Point);
    handlerPoint.drawEvt.addEventListener(function(result){
    center = result.object.position;
//相机绕中心点旋转。
    camera.flyCircle(center);
    });

当然这个函数默认是旋转一次的,如果要开启循环旋转,设置以下即可
camera.flyCircleLoop = true;
停止旋转用
camera.stopFlyCircle()

Camera还有几个比较重要的事件
camera.moveEnd事件:相机停止移动时将引发的事件。
camera.moveStart事件:相机开始移动时将引发的事件。
camera.changed事件:相机改变事件,可以理解为相机的任何动作都会触发改事件。
我们可以把这些事件应用到实际项目中去,比如实时展示相机的高度,经纬度信息等。

关于camera的介绍就到这里啦,关于camera还有很多需要学习的地方,大家也可以通过官方api文档进行深入的学习http://support.supermap.com.cn:8090/webgl/Build/Documentation/Camera.html?classFilter=camera。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值