QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
Viewer3DModel.qml
Go to the documentation of this file.
1import QtPositioning
2import QtQuick3D
3
4import QGroundControl
5import QGroundControl.Controls
6
7View3D {
8 id: topView
9
10 objectName: "viewer3DView"
11
12 readonly property real _viewDistance: 50000
13 readonly property var _gpsRef: QGCViewer3DManager.gpsRef
14 readonly property bool _mapLoaded: QGCViewer3DManager.mapProvider ? QGCViewer3DManager.mapProvider.mapLoaded : false
15
16 // Exposed so FlyView can position the scale bar alongside the other widgets
17 readonly property Viewer3DCameraController cameraController: _cameraController
18
19 camera: standAloneScene.cameraOne
20
21 environment: SceneEnvironment {
22 antialiasingMode: SceneEnvironment.MSAA
23 antialiasingQuality: SceneEnvironment.High
24 backgroundMode: SceneEnvironment.Color
25 clearColor: _skyColor
26
27 fog: Fog {
28 color: _skyColor
29 depthCurve: 1.0
30 depthEnabled: true
31 depthFar: _viewDistance
32 depthNear: 1000
33 enabled: true
34 }
35 }
36
37 QGCPalette { id: qgcPal }
38
39 readonly property color _skyColor: qgcPal.window
40 importScene: CameraLightModel {
41 id: standAloneScene
42
43 cameraHeading: cameraController.heading
44 cameraTilt: cameraController.tilt
45 cameraZoom: cameraController.distance
46 orbitCenter: cameraController.orbitCenter
47 viewDistance: _viewDistance
48 }
49
50 Viewer3DCameraController {
51 id: _cameraController
52
53 fieldOfView: standAloneScene.cameraOne.fieldOfView
54 viewportSize: Qt.size(topView.width, topView.height)
55 }
56
57 function _resetCameraForContent() {
58 if (_mapLoaded) {
59 cameraController.reset();
60 } else {
61 // Without an OSM map there is no terrain; a top-down view shows
62 // nothing useful. Look at the vehicle from the side, slightly above.
63 cameraController.lookAt(Qt.vector3d(0, 0, 0), 0, 75, 400);
64 }
65 }
66
67 Component.onCompleted: {
68 vehicle3DLoader.active = true;
69 mapGeometryLoader.active = true;
70 _resetCameraForContent();
71 }
72 on_GpsRefChanged: {
73 _resetCameraForContent();
74 }
75 on_MapLoadedChanged: {
76 _resetCameraForContent();
77 }
78
79 Component {
80 id: buildingsGeometryComponent
81
82 Node {
83 Model {
84 id: cityMapModel
85
86 scale: Qt.vector3d(10, 10, 10)
87 visible: true
88
89 geometry: CityMapGeometry {
90 id: cityMapGeometry
91
92 mapProvider: QGCViewer3DManager.mapProvider
93 modelName: "city_map"
94 }
95 materials: [
96 PrincipledMaterial {
97 baseColor: "gray"
98 indexOfRefraction: 4.0
99 metalness: 0.1
100 opacity: 1.0
101 roughness: 0.5
102 specularAmount: 1.0
103 }
104 ]
105 }
106
107 Model {
108 id: pointModel
109
110 scale: Qt.vector3d(10, 10, 10)
111 visible: true
112
113 geometry: Viewer3DTerrainGeometry {
114 id: terrainGeometryManager
115
116 refCoordinate: _gpsRef
117 }
118 materials: CustomMaterial {
119 property TextureInput someTextureMap: TextureInput {
120 texture: Texture {
121 textureData: _terrainTextureManager
122 }
123 }
124
125 fragmentShader: "/qml/QGroundControl/Viewer3D/ShaderFragment/earthMaterial.frag"
126 vertexShader: "/qml/QGroundControl/Viewer3D/ShaderVertex/earthMaterial.vert"
127 }
128 }
129
130 Viewer3DTerrainTexture {
131 id: _terrainTextureManager
132
133 readonly property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
134
135 fallbackCenter: _activeVehicle ? _activeVehicle.homePosition : QtPositioning.coordinate()
136 mapProvider: QGCViewer3DManager.mapProvider
137
138 onTextureGeometryDoneChanged: {
139 if (textureGeometryDone === true) {
140 terrainGeometryManager.sectorCount = tileCount.width;
141 terrainGeometryManager.stackCount = tileCount.height;
142 terrainGeometryManager.roiMin = roiMinCoordinate;
143 terrainGeometryManager.roiMax = roiMaxCoordinate;
144 terrainGeometryManager.updateEarthData();
145 }
146 }
147 }
148 }
149 }
150
151 Loader3D {
152 id: mapGeometryLoader
153
154 active: false
155 sourceComponent: buildingsGeometryComponent
156 }
157
158 Component {
159 id: vehicle3DComponent
160
161 Repeater3D {
162 model: QGroundControl.multiVehicleManager.vehicles
163
164 delegate: Viewer3DVehicleItems {
165 _backendQml: QGCViewer3DManager
166 _camera: standAloneScene.cameraOne
167 _planMasterController: masterController
168 _vehicle: object
169
170 PlanMasterController {
171 id: masterController
172
173 Component.onCompleted: startStaticActiveVehicle(object)
174 }
175 }
176 }
177 }
178
179 Loader3D {
180 id: vehicle3DLoader
181
182 active: false
183 sourceComponent: vehicle3DComponent
184 }
185
186 Viewer3DCameraControls {
187 anchors.fill: parent
188 controller: cameraController
189 }
190
191 TapHandler {
192 function deselectAllWaypoints() {
193 if (!vehicle3DLoader.item)
194 return;
195 for (var i = 0; i < vehicle3DLoader.item.count; i++) {
196 vehicle3DLoader.item.objectAt(i).waypointInstancing.selectedIndex = -1;
197 }
198 }
199
200 onTapped: function (eventPoint) {
201 if (!vehicle3DLoader.item)
202 return;
203
204 var models = [];
205 for (var i = 0; i < vehicle3DLoader.item.count; i++) {
206 models.push(vehicle3DLoader.item.objectAt(i).waypointConeModel);
207 }
208
209 var results = topView.pickSubset(eventPoint.position.x, eventPoint.position.y, models);
210 if (results.length === 0) {
211 deselectAllWaypoints();
212 return;
213 }
214
215 var result = results[0];
216 for (var i = 0; i < vehicle3DLoader.item.count; i++) {
217 var vehicleItem = vehicle3DLoader.item.objectAt(i);
218 if (result.objectHit === vehicleItem.waypointConeModel) {
219 vehicleItem.waypointInstancing.selectedIndex = result.instanceIndex;
220 return;
221 }
222 }
223
224 deselectAllWaypoints();
225 }
226 }
227}