This is the 19th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021″
preface
Previous articles in this series:
- 【 VUe-Cesium 】 3d map development using Cesium on VUE (part 1)
- 【 VUe-Cesium 】 3d map development using Cesium on VUE (part 2)
- 【 VUe-cesium 】 3d map development using Cesium on VUE (ii) Continued
- 【 VUe-Cesium 】 3d map development using Cesium on VUE (3)
- 【 VUe-cesium 】 using CESium on VUE to develop 3d map (four) map loading
- 【 VUe-cesium 】 Using CESium on VUE to develop 3d map (five) point loading
- [VUe-cesium] using CESium on VUE to develop 3d map (six) point frame
- [Vue-cesium] 3d map development using CESium on VUE (7) positioning and optimization
- [Vue-cesium] Develop 3d maps with Cesium on VUE (8) Click ripple effects
- [VUe-cesium] 3d map development using CESium on VUE (9) Ripple effect offset problem
- [VUe-cesium] Develop 3d map using Cesium on VUE (10) show hidden point names
- [VUe-cesium] Using CESium on VUE to develop 3d map (11) point hover, space effect
This lecture is about loading 3d tiles.
This time, I happened to find a ready-made 3D model on the Internet, so I tried it out and loaded 3d tiles
preview
Model data
Same old rule. Materials first
3D model address: portal
It’s a pretty big model
Introduction to 3 d tiles
A brief introduction to 3D tiles
The 3DTiles dataset is a kind of data set defined by AnalyticlGraphics of Cesium in March 2016. The 3DTiles dataset is rendered in blocks and hierarchically, which can greatly reduce the burden of browser and GPU. And format the public data format.
3D Tiles are an open specification for streaming large heterogeneous 3D geospatial datasets. To extend Cesium’s terrain and image streams, 3D Tiles will be used to stream 3D content, including buildings, trees, point clouds and vector data.
Open dry
I put the downloaded model under public/DemoData and create a new folder Scene to store the model data
This is because the proxy for local data was previously configured in vue.config.js
Here’s why you call the 3D model like you call the interface data, because the way you load the 3D model in Cesium is a Promise, right
The code for loading the model method is as follows
methods: {
// Load the 3D Tiles
/ / https://gitee.com/HQCode/Cesium-test/blob/master/lesson02/Scene/testm3DTiles.json data sources
load3DTiles() {
const Cesium = this.cesium;
let tilesetModel = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: "LocalDemoApi/Scene/testm3DTiles.json",})); tilesetModel.readyPromise.then((currentModel) = > {
// Locate the model
this.viewer.zoomTo(currentModel, new Cesium.HeadingPitchRange(0.5, -0.2, currentModel.boundingSphere.radius * 1.0));
}).otherwise((error) = > {
console.log(error); }); },... }Copy the code
Call the above method load
The model is loaded
The model is loaded, but it’s not in the right place, it’s in the air, why is that? And the reason is very simple,
-
When 3d Tiles files are generated, they have location and height. The generated data may float in the air, not necessarily on the ground, which is not what we want. We want the results to be attached to the ground.
-
The location of the individual tiles is written into the data (.b3dm and corresponding JSON files), and it would be best if the tileset could be adjusted as a whole
-
The base map and terrain used to generate the 3DTiles file may be different from cesium loading, and the manual adjustment of the position of the model may have some deviation. Therefore, after loading the 3DTiles model on the digital earth, most of the chances are that the position will need to be adjusted again
Adjusting the 3DTiles position is essentially a matrix operation
Just a quick look at matrix operations
// create a translation matrix
// m = Cesium.Matrix4.fromArray([
// 1.0, 0.0, 0.0, 0.0,
// 0.0, 1.0, 0.0, 0.0,
// 0.0, 0.0, 1.0, 0.0,
// x, y, z, 1.0
// ]);
// create a translation matrix
var translation = Cesium.Cartesian3.fromArray([x, y, z]);
m = Cesium.Matrix4.fromTranslation(translation);
tilesetModel.modelMatrix = m;
Copy the code
We just keep changing x,y, and z to adjust the position of the object
Get the appropriate x,y, and z values, and set the modelMatrix to the x,y, and z values when loading the 3D tiles
Another method is to calculate the offset (for example, height)
// Set the specified height
function changeHeight(height) {
height = Number(height);
if (isNaN(height)) {
return;
}
var cartographic = Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude,height);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
}
Copy the code
Now let’s adjust the position of the 3D model
Let’s look at the documentation
Set the location
On this graph, we can see that it’s this is 3d Cartesian coordinates
We are usually familiar with latitude and longitude in the form of 120. Xx 30. XXX.
So let’s do an online debugging of the latitude and longitude method, to debug the appropriate latitude and longitude and see what happens
The top of the JS area defines some variables for the 3D model
Let’s start with the positioning frame for the 3D model
Corresponding CSS style
I wanted to move the model to the other side of the point position THAT I had made before, but I found that the position of the model was thousands of miles away from my point position, and then when I moved the model, I found that X,y and Z had to be adjusted, it was too far away to move.
I thought that in the actual project, the model given can not be too far off the mark under normal circumstances. The model I found randomly on the Internet is really more random. Therefore, I will not move the model, everyone can see the effect.
Finally, load the 3D Tiles code in its entirety
Only the code related to the 3D model is shown here, for the rest I use… Omit, other code can see my previous articles
<template>
<div id="container" class="box">
<div id="cesiumContainer"></div>
<! -- Adjust 3d model position method -->
<div id="getposition">
<span style="margin: 6px 0px 6px 6px;">Adjust 3d model position</span>
<br />
<button class="position-item" @click="change(0)">x+</button>
<button class="position-item" @click="change(1)">x-</button>
<button class="position-item" @click="change(2)">y+</button>
<button class="position-item" @click="change(3)">y-</button>
<button class="position-item" @click="change(4)">z+</button>
<button class="position-item" @click="change(5)">z-</button>
<br />
<span style="margin: 6px 0px 6px 6px;">Set movement amount:</span>
<button class="step-style" @click="changeStep(1)">1</button>
<button class="step-style" @click="changeStep(10)">10</button>
<button class="step-style" @click="changeStep(100)">100</button>
<br />
<button class="position-item" @click="changevisible()">isHide</button>
<div id="result" style=""></div>
</div>
</div>
</template>
<script>
import cesiumPopup from "./cesiumPopup.vue";
let tilesetModel = null; // Store the object to test the 3D model
let step = 100; // Test the amount of step per move of the 3D model
// let x = 0;
// let y = 0;
// let z = 0;
let x = 360.0;
let y = -920.0;
let z = -820.0;
let m = null; // Translation matrix 3d model translation method
export default {
name: "cesiumMap".components: {
cesiumPopup,
},
data() {
return {
viewer: undefined.pointEntities: [].// Save the point view
pointEntitiesLine: [].// Store the point line entity
popData: { // Pass the data into the popbox
pointId: "--".title: "--",}}; },methods: {
init(){... },loadPoints(){...// Test loading 3d data 3D tiles
this.load3DTiles(); },...// Load the 3D Tiles
/ / https://gitee.com/HQCode/Cesium-test/blob/master/lesson02/Scene/testm3DTiles.json data sources
load3DTiles() {
const Cesium = this.cesium;
tilesetModel = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: "LocalDemoApi/Scene/testm3DTiles.json",})); tilesetModel.readyPromise.then((currentModel) = > {
// Locate the model
this.viewer.zoomTo(currentModel, new Cesium.HeadingPitchRange(0.5, -0.2, currentModel.boundingSphere.radius * 1.0));
this.changeHeight(20);
}).otherwise((error) = > {
console.log(error);
});
},
// Adjust the 3d model position
change(type) {
const Cesium = this.cesium;
switch (type) {
case 0:
x += step;
break;
case 1:
x -= step;
break;
case 2:
y += step;
break;
case 3:
y -= step;
break;
case 4:
z += step;
break;
case 5:
z -= step;
break;
}
// create a translation matrix
// m = Cesium.Matrix4.fromArray([
// 1.0, 0.0, 0.0, 0.0,
// 0.0, 1.0, 0.0, 0.0,
// 0.0, 0.0, 1.0, 0.0,
// x, y, z, 1.0
// ]);
// create a translation matrix
var translation = Cesium.Cartesian3.fromArray([x, y, z]);
console.log('translation', translation);
m = Cesium.Matrix4.fromTranslation(translation);
document.getElementById("result").innerText = "x:" + x + " y:" + y + " z:" + z;
tilesetModel.modelMatrix = m;
},
// Set the amount of movement of the 3D model, used when adjusting the position
changeStep(stepin) {
step = stepin;
},
// Show/hide the 3D model
changevisible() {
// console.log(tilesetModel);tilesetModel.show = ! tilesetModel.show; },// Call the function directly to adjust the height. Height indicates the height of the object above the ground
changeHeight(height) {
const Cesium = this.cesium;
height = Number(height);
if (isNaN(height)) {
return;
}
var cartographic = Cesium.Cartographic.fromCartesian(tilesetModel.boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
var translation = Cesium.Cartesian3.subtract(offset, surface, newCesium.Cartesian3()); tilesetModel.modelMatrix = Cesium.Matrix4.fromTranslation(translation); }},mounted() {
this.init();
this.loadPoints(); }};</script>
<style scoped lang="scss">
#cesiumContainer {
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
overflow: hidden;
}
.box {
height: 100%;
}
.leftContent {
position: absolute;
top: 200px;
width: 300px;
background-color: rgb(255 255 255 / 85%);
height: 500px;
border-radius: 8px;
}
#getposition {
position: absolute;
bottom: 2px;
left: 9px;
width: 300px;
height: 175px;
background-color: rgba(3.22.37.0.85);
border-radius: 0px 5px 5px 0px;
color: white;
}
.position-item {
display: inline-block;
width: 50px;
height: 20px;
line-height: 20px;
text-align: center;
border: 1px solid #0090ff;
margin: 5px;
color: white;
background-color: #0090ff;
border-radius: 6px;
cursor: pointer;
}
#result {
background: transparent;
padding: 0px 0px 0px 10px;
color: white;
}
.step-style {
display: inline-block;
width: 38px;
text-align: center;
border: 1px solid #0490ff;
border-radius: 6px;
background-color: #0490ff;
margin-left: 8px;
cursor: pointer;
color: white;
}
</style>
Copy the code
Reference documentation
- Add 3D Tiles and reposition them to the floor
- Load and adjust 3D Tiles using Cesium
- Cesium Learning Series summary
Now that you’ve seen this, please give me a thumbs up before you go, because your thumbs up means a lot to me