Cesium模型漫游过程中姿态动态调整

21 篇文章 0 订阅
13 篇文章 6 订阅

一、功能设计

模型漫游过程中姿态动态调整有两种情况:

1)速度沿默认方向-运动过程中的姿态动态调节

2)沿速度矢量方向-运动过程中姿态的动态调节

二、对数据和服务的要求

gltf数据

三、接口设计

通过修改AnimationTool上的modelHeading,modelPitch,modelRoll来进行姿态动态调节


//新建一个AnimationTool对象
var animation = new Cesium.AnimationTool(viewer, {               
//修改模型的方位角
modelHeading = 20;
//修改模型的俯仰角
modelPitch=10;
//修改模型的倾斜角
modelRoll=10;
},
3.1.速度沿默认方向-运动过程中的姿态动态调节
3.2.沿速度矢量方向-运动过程中姿态的动态调节

四、算法逻辑设计

在兼容设置 模型是否朝速度矢量方向(文档跳转)的基础上,提供在沿默认方向和沿速度矢量方向两种运动模式下的模型姿态动态调整。

两种模式的实现均是外部传入模型的heading,pitch,roll参数,内部通过访问器获取,通过一系列计算得到确切的方向值,赋值给当前模型的orientation 属性 ,实现模型朝向的动态修改

4.1.速度沿默认方向-运动过程中的姿态动态调节

1.基于当前模型的位置和外部提供的模型heading,pitch,roll参数,计算hpr最终得到朝向参数;


//模型默认状态下,计算其朝向四元数
function getDefaultQuaternion(position, rotateX, rotateY, rotateZ) {
    //三个角转弧度
    let heading = CMath.toRadians(rotateZ);
    let pitch = CMath.toRadians(rotateY);
    let roll = CMath.toRadians(rotateX);
    //通过方位角,俯仰角和倾斜角得到hpr参数
    let hpr = new HeadingPitchRoll(heading, pitch, roll);
    //基于模型当前位置和hpr得到朝向
    let orientation = Transforms.headingPitchRollQuaternion(position, hpr);
    return orientation;
}

2.获取当前模型的位置


//获得当前时间模型所在的位置
var curPosition = Property.getValueOrUndefined(this._animationModel.position, this._viewer.clock.currentTime, curPosition);

3.得到朝向并赋给当前模型使生效


 this._animationModel.orientation = getDefaultQuaternion(curPosition, this._modelRoll, this._modelPitch, this._modelHeading);
4.2.沿速度矢量方向-运动过程中姿态的动态调节

根据模型的速度信息、位置信息,建立模型本体坐标系,进而获取站心坐标系到模型坐标系的旋转矩阵,根据这个旋转矩阵获取欧拉角,最后再用模型的当前位置和欧拉角获得朝向四元数。

1.计算站心坐标系到模型坐标系的旋转矩阵


//速度归一化
let normal = Cartesian3.normalize(Velocity, new Cartesian3());
//计算模型坐标系的旋转矩阵
let satRotationMatrix = Transforms.rotationMatrixFromPositionVelocity(position, normal, Ellipsoid.WGS84);
//模型坐标系到地面坐标系旋转平移矩阵
let m = Matrix4.fromRotationTranslation(satRotationMatrix, position);
//站心坐标系到地固坐标系的旋转平移矩阵
let m1 = Transforms.eastNorthUpToFixedFrame(position, Ellipsoid.WGS84, new Matrix4());
//站心坐标系到模型坐标系的旋转平移矩阵
let m3 = Matrix4.multiply(Matrix4.inverse(m1, new Matrix4()), m, new Matrix4());

2.计算模型姿态旋转矩阵


rotateX = rotateX || 0;
rotateY = rotateY || 0;
rotateZ = rotateZ || 0;
let heading = rotateZ,
    pitch = rotateY,
    roll = rotateX;
let postureHpr = new HeadingPitchRoll(CMath.toRadians(heading), CMath.toRadians(pitch), CMath.toRadians(roll));
let postureMatrix = Matrix3.fromHeadingPitchRoll(postureHpr);

3.得到最终的旋转矩阵来计算朝向


//3.最终的旋转矩阵
let mat3 = Matrix4.getMatrix3(m3, new Matrix3());
let finalMatrix = Matrix3.multiply(mat3, postureMatrix, new Matrix3());
let quaternion1 = Quaternion.fromRotationMatrix(finalMatrix);
let hpr = HeadingPitchRoll.fromQuaternion(quaternion1);
let q2 = Transforms.headingPitchRollQuaternion(position, hpr);
return q2;

4.获取当前模型的位置


//获得当前时间模型所在的位置
var curPosition = Property.getValueOrUndefined(this._animationModel.position, this._viewer.clock.currentTime, curPosition);
5.获取速度向量
/获得当前时刻的速度向量
this._animationModel.velocityVector = new VelocityVectorProperty(this._animationModel.position, true);
var curVelocityVector = this._animationModel.velocityVector.getValue(this._viewer.clock.currentTime, new Cartesian3());
4.赋值给当前模型使生效
this._animationModel.orientation = getVelocityQuaternion(curPosition, curVelocityVector, this._modelRoll, this._modelPitch, this._modelHeading);

知识补充:

地固坐标系:也叫地心地固直角坐标系。其原点为地球的质心,x轴延伸通过本初子午线(0度经度)和赤道(0deglatitude)的交点。 z轴延伸通过的北极(即,与地球旋转轴重合)。 y轴完成右手坐标系,穿过赤道和90度经度。

站心坐标系站心坐标系以用户所在位置P为坐标原点。

坐标系定义为: X轴:指向东边 Y轴:指向北边 Z轴:指向天顶,飞行器的偏航、俯仰、滚转即是以站心直角坐标系为参考

模型坐标系:模型坐标系以物体的中心为坐标原点,物体旋转、平移等操作都是围绕局部坐标系进行的。这时当物体模型进行旋转、平移等操作时,局部坐标系也执行相应的旋转、平移等操作。局部坐标系是一个假想的坐标系,该坐标系与物体的相对位置至始至终是不变的,假想出这个坐标系的目的主要是为了正向理解对三维场景中物体执行的平移和旋转操作。使用局部坐标系理解模型变换时,所有的变换操作直接作用与局部坐标系,由于局部坐标系与物体的相对位置不变,因此对局部坐标系进行平移、旋转和缩放时,物体在场景中位置和形状也会发生相应的变化。

欧拉角:用一句话说,欧拉角就是物体绕坐标系三个坐标轴(x,y,z轴)的旋转角度。

在这里,坐标系可以是世界坐标系,也可以是物体坐标系,旋转顺序也是任意的,可以是xyz,xzy,yxz,zxy,yzx,zyx中的任何一种。

所以说欧拉角多种多样。欧拉角可分为两种情况:

1,静态:即绕世界坐标系三个轴的旋转,由于物体旋转过程中坐标轴保持静止,所以称为静态。

2,动态:即绕物体坐标系三个轴的旋转,由于物体旋转过程中坐标轴随着物体做相同的转动,所以称为动态。

五、遗留问题

六、参考链接

【1】【Cesium】计算模型的朝向四元数,实现模型运动中调整朝向

【2】Cesium设置模型朝向速度矢量方向

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 3dtiles模型动态压平可以通过合理设置Cesium的CameraOptions属性来实现,如设置camera.frustum.far,camera.frustum.near,camera.frustum.fov等属性。 ### 回答2: 在Cesium,要实现3D Tiles模型动态压平,可以通过以下步骤实现: 1. 首先,加载3D Tiles模型文件。可以使用Cesium的`Cesium3DTileset`对象来加载3D Tiles模型文件,并将其添加到场景。例如: ```javascript var tileset = new Cesium.Cesium3DTileset({ url: 'path/to/3dtiles/file' }); viewer.scene.primitives.add(tileset); ``` 2. 为了实现动态压平效果,需要使用相机的高度来改变3D Tiles模型的显示程度。可以通过监听相机的高度变化,动态调整模型的显示程度。例如: ```javascript viewer.scene.camera.moveEnd.addEventListener(function() { var cameraHeight = viewer.scene.camera.positionCartographic.height; tileset.maximumScreenSpaceError = cameraHeight / 1000; // 调整最大屏幕空间误差参数 }); ``` 将`maximumScreenSpaceError`参数值设置为相机高度的适当比例,可以根据实际需要调整。 3. 接下来,需要在3D Tiles模型加载完成后,使用`readyPromise`来确保模型已经完全加载进来。这样可以避免在模型加载过程产生抖动或镜像效果。例如: ```javascript tileset.readyPromise.then(function(tileset) { tileset.maximumScreenSpaceError = viewer.scene.camera.positionCartographic.height / 1000; }); ``` 通过以上步骤,就可以实现Cesium3D Tiles模型动态压平效果。根据相机高度的变化,模型的显示程度将自动调整,从而实现动态压平的效果。 ### 回答3: 在Cesium实现3dtiles模型动态压平,需要进行以下步骤: 1. 导入Cesium的3dtiles模型:首先,你需要使用Cesium的加载器函数将3dtiles模型导入到Cesium。加载器函数会加载3dtiles文件并将其在场景呈现为3D模型。 2. 获取模型的高度信息:在Cesium,可以使用模型的位置和高度信息来动态压平模型。你可以使用Cesium提供的函数来获取模型的高度信息,例如`model.position`和`model.height`。 3. 实现动态压平:一旦获得了模型的高度信息,你可以使用Cesium的几何操作函数来动态压平模型Cesium的函数可以用于改变模型的顶点坐标,以实现压平效果。例如,你可以根据模型的高度信息修改顶点的Y坐标,并重新计算法线和纹理坐标。 4. 更新模型:完成对模型动态压平后,你需要使用Cesium提供的API来更新模型。可以使用Cesium的更新函数来应用新的顶点坐标、法线和纹理坐标,以确保3D模型在场景正确显示。 总结:实现Cesium动态压平需要导入3dtiles模型、获取模型的高度信息,使用几何操作函数进行动态压平,然后更新模型以显示在场景。这些步骤将确保3D模型Cesium进行动态压平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值