Cesium教程04_旋转模型
基于 Vue 和 Cesium 的三维地形高度和旋转调节器
引言
本文将介绍如何使用 Vue 和 Cesium 实现一个可调节三维地形模型高度与旋转角度的工具。项目展示了如何通过滑块实时调整地形高度以及模型在 X、Y、Z 轴上的旋转角度,同时实现直观的用户交互。
目录
- 功能演示
- 代码实现
- 模板部分
- 逻辑部分
- 样式部分
- 代码解析
- Cesium 初始化
- 高度调节实现
- 旋转调节实现
- 总结
- 参考资源
功能演示
该工具允许用户通过滑块调整三维模型的以下参数:
- 高度:改变模型在 Z 轴上的位置。
- 旋转角度:分别对 X、Y、Z 轴上的旋转进行调节。
如下为核心交互界面:
- 高度调节:通过滑块控制模型的垂直位置。
- 旋转控制:实时调整模型的旋转角度,并在 Cesium 场景中渲染效果。
代码实现
使用 Vue 的模板语法构建交互界面,包括一个 Cesium 容器和工具栏。工具栏提供高度和旋转角度的调节功能。
<template>
<div>
<!-- Cesium 容器 -->
<div ref="cesiumContainer" class="cesium-container"></div>
<!-- 工具栏 -->
<div class="toolbar">
<!-- 高度调节滑块 -->
<label for="heightSlider">Adjust Height:</label>
<input
id="heightSlider"
type="range"
min="0"
max="100"
v-model="height"
/>
<span>{{ height }} meters</span>
<!-- 旋转调节滑块 -->
<div>
<label for="rotateXSlider">Rotate X:</label>
<input
id="rotateXSlider"
type="range"
min="0"
max="360"
v-model="rotateX"
/>
<span>{{ rotateX }}°</span>
</div>
<div>
<label for="rotateYSlider">Rotate Y:</label>
<input
id="rotateYSlider"
type="range"
min="0"
max="360"
v-model="rotateY"
/>
<span>{{ rotateY }}°</span>
</div>
<div>
<label for="rotateZSlider">Rotate Z:</label>
<input
id="rotateZSlider"
type="range"
min="0"
max="360"
v-model="rotateZ"
/>
<span>{{ rotateZ }}°</span>
</div>
</div>
</div>
</template>
<script>
import { defineComponent, ref, onMounted, watch } from "vue";
import {
Viewer,
Cartesian3,
Cartographic,
Matrix4,
Cesium3DTileset,
Math as CesiumMath,
Matrix3,
Terrain,
} from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
export default defineComponent({
name: "CesiumViewer",
setup() {
const cesiumContainer = ref(null);
const viewer = ref(null);
const tileset = ref(null);
const height = ref(0);
const rotateX = ref(0);
const rotateY = ref(0);
const rotateZ = ref(0);
let rootTransform = null;
const initCesium = async () => {
if (!cesiumContainer.value) {
console.error("Cesium container not found!");
return;
}
try {
viewer.value = new Viewer(cesiumContainer.value, {
terrain: Terrain.fromWorldTerrain(),
});
tileset.value = await Cesium3DTileset.fromIonAssetId(40866);
viewer.value.scene.primitives.add(tileset.value);
viewer.value.zoomTo(tileset.value);
rootTransform = Matrix4.clone(tileset.value.root.transform);
tileset.value.modelMatrix = Matrix4.clone(rootTransform);
tileset.value.root.transform = Matrix4.clone(Matrix4.IDENTITY);
} catch (error) {
console.error("Error initializing Cesium:", error);
}
};
const updateHeight = (newHeight) => {
if (!tileset.value) return;
const numericHeight = Number(newHeight);
const boundingSphere = tileset.value.boundingSphere;
const cartographic = Cartographic.fromCartesian(boundingSphere.center);
const surface = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
const offset = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, numericHeight);
const translation = Cartesian3.subtract(offset, surface, new Cartesian3());
const newModelMatrix = Matrix4.fromTranslation(translation);
tileset.value.modelMatrix = Matrix4.multiply(rootTransform, newModelMatrix, new Matrix4());
};
const updateRotation = (tileset, rotateX, rotateY, rotateZ) => {
if (!tileset) return;
const rotationX = Matrix3.fromRotationX(CesiumMath.toRadians(rotateX));
const rotationY = Matrix3.fromRotationY(CesiumMath.toRadians(rotateY));
const rotationZ = Matrix3.fromRotationZ(CesiumMath.toRadians(rotateZ));
const combinedRotation = Matrix3.multiply(rotationZ, rotationY, new Matrix3());
Matrix3.multiply(combinedRotation, rotationX, combinedRotation);
const rotationMatrix = Matrix4.fromRotationTranslation(combinedRotation, Cartesian3.ZERO);
const modelMatrix = Matrix4.clone(tileset.modelMatrix);
const newModelMatrix = Matrix4.multiply(modelMatrix, rotationMatrix, new Matrix4());
tileset.modelMatrix = newModelMatrix;
};
watch(height, (newHeight) => {
updateHeight(newHeight);
});
watch([rotateX, rotateY, rotateZ], ([newRotateX, newRotateY, newRotateZ]) => {
updateRotation(tileset.value, newRotateX, newRotateY, newRotateZ);
});
onMounted(() => {
initCesium();
});
return {
cesiumContainer,
height,
rotateX,
rotateY,
rotateZ,
};
},
});
</script>
代码解析
###Cesium 初始化
初始化 Cesium Viewer,并加载来自 Ion 平台的 3D 瓦片资源。
###高度调节实现
通过 updateHeight 方法,根据用户输入动态调整模型高度。
旋转调节实现
通过 updateRotation 方法结合矩阵运算实现三维旋转控制。
总结
本项目展示了如何使用 Vue 与 Cesium 构建一个三维地形交互工具,涵盖了模型加载、高度调节与旋转功能的实现。未来可扩展添加更多交互功能,如缩放、模型选择等。
参考资源
Cesium 官方文档
Vue 官方文档