2import QGroundControl.Controls
3import QGroundControl.Viewer3D
5import QtQuick3D.Helpers
10 property var _altitudeBias: _viewer3DSetting.altitudeBias.rawValue
11 property var _backendQml: null
12 property Node _camera: null
13 property var _missionController: (_planMasterController) ? (_planMasterController.missionController) : (null)
14 property var _planMasterController: null
15 property bool _rtlActive: false
16 property var _vehicle: null
17 property var _viewer3DSetting: QGroundControl.settingsManager.viewer3DSettings
18 property alias waypointConeModel: _waypointConeModel
19 property alias waypointInstancing: waypointInstancing
21 function addMissionItemsToListModel() {
22 missionWaypointListModel.clear();
23 waypointInstancing.selectedIndex = -1;
24 waypointInstancing.clear();
25 var _geo2EnuCopy = geo2Enu;
26 var launchItemCoordinate = null;
27 var _missionItemPrevious = null;
30 for (var i = 0; i < _missionController.visualItems.count; i++) {
31 var _missionItem = _missionController.visualItems.get(i);
32 if (isLaunchItem(_missionItem)) {
33 launchItemCoordinate = _missionItem.coordinate;
36 if (isItemAcceptable(_missionItem)) {
37 if (isReturnToLaunchItem(_missionItem)) {
39 _geo2EnuCopy.coordinate = (_vehicle.homePosition) ? (_vehicle.homePosition) : (_missionItem.coordinate);
40 _geo2EnuCopy.coordinate.altitude = _missionItemPrevious.altitude.value;
42 _geo2EnuCopy.coordinate = _missionItem.coordinate;
43 _geo2EnuCopy.coordinate.altitude = _missionItem.altitude.value;
45 var name = getItemName(_missionItem);
46 var lx = _geo2EnuCopy.localCoordinate.x;
47 var ly = _geo2EnuCopy.localCoordinate.y;
48 var lz = _geo2EnuCopy.coordinate.altitude;
49 missionWaypointListModel.append({
54 "index": _missionItem.sequenceNumber
56 waypointInstancing.addEntry(Qt.vector3d(lx * 10, ly * 10, (lz + _altitudeBias) * 10), Qt.vector3d(0.1, 0.1, 0.1), Quaternion.fromEulerAngles(Qt.vector3d(90, 0, 0)), waypointColor(name));
57 if (name === "L" || name === "W") {
58 _missionItemPrevious = _missionItem;
64 function addSegmentToMissionPathModel() {
65 pathInstancing.clear();
66 var _geo2EnuCopy = geo2Enu;
69 var _missionItemPrevious = null;
70 var launchItemCoordinate;
72 for (var i = 0; i < _missionController.visualItems.count; i++) {
73 _missionItem = _missionController.visualItems.get(i);
74 if (isLaunchItem(_missionItem)) {
75 launchItemCoordinate = _missionItem.coordinate;
78 if (_missionItem.isTakeoffItem) {
79 _missionItemPrevious = _missionItem;
82 if (_missionItemPrevious === null) {
85 if (getItemName(_missionItem) === "L" || getItemName(_missionItem) === "W") {
86 _geo2EnuCopy.coordinate = _missionItemPrevious.coordinate;
87 _geo2EnuCopy.coordinate.altitude = _missionItemPrevious.altitude.value;
88 var p1 = Qt.vector3d(_geo2EnuCopy.localCoordinate.x * 10, _geo2EnuCopy.localCoordinate.y * 10, (_geo2EnuCopy.coordinate.altitude + _altitudeBias) * 10);
90 if (isReturnToLaunchItem(_missionItem)) {
91 _geo2EnuCopy.coordinate = (_vehicle.homePosition) ? (_vehicle.homePosition) : (_missionItem.coordinate);
92 _geo2EnuCopy.coordinate.altitude = _missionItemPrevious.altitude.value;
94 _geo2EnuCopy.coordinate = _missionItem.coordinate;
95 _geo2EnuCopy.coordinate.altitude = _missionItem.altitude.value;
97 var p2 = Qt.vector3d(_geo2EnuCopy.localCoordinate.x * 10, _geo2EnuCopy.localCoordinate.y * 10, (_geo2EnuCopy.coordinate.altitude + _altitudeBias) * 10);
99 var color = isReturnToLaunchItem(_missionItem) ? "red" : "orange";
100 pathInstancing.addLineSegment(p1, p2, 8, color);
101 _missionItemPrevious = _missionItem;
106 function getItemName(missionItem) {
107 if (isLaunchItem(missionItem) || isReturnToLaunchItem(missionItem)) {
111 if (missionItem.isTakeoffItem) {
112 return qsTr("T"); //Takeoff
115 if (missionItem.specifiesCoordinate) {
116 switch (missionItem.command) {
118 return qsTr("W"); //Waypoint
120 return qsTr("T"); //Takeoff
122 return qsTr("R"); //ROI
124 return qsTr("R"); //ROI DEPRECATED
130 function isItemAcceptable(missionItem) {
131 const acceptableCmdIds = [16 // Waypoint
132 , 20 // Return To Launch
135 , 201 // ROI DEPRECATED
136 ,]; // based on MavCmdInfoCommon.json file
137 return acceptableCmdIds.includes(missionItem.command);
140 function isLaunchItem(missionItem) {
141 return missionItem.abbreviation === "L";
144 function isReturnToLaunchItem(missionItem) {
145 return missionItem.command === 20;
148 function waypointColor(itemName) {
149 if (itemName === "T")
151 if (itemName === "R")
153 if (itemName === "L")
158 Viewer3DGeoCoordinateType {
161 gpsRef: _backendQml.gpsRef
165 id: missionWaypointListModel
168 Component.onDestruction: {
169 // This is necessary insurance to prevent crashes after destruction when "keepSceneAlive" setting is disabled.
170 missionWaypointListModel.clear()
176 objectName: "viewer3DDroneModel"
178 altitudeBias: _altitudeBias
179 gpsRef: _backendQml.gpsRef
180 modelScale: Qt.vector3d(0.05, 0.05, 0.05)
185 id: waypointInstancing
190 id: _waypointConeModel
192 instancing: waypointInstancing
193 instancingLodMax: 5000
198 materials: DefaultMaterial {
199 diffuseColor: "white"
204 model: missionWaypointListModel
207 position: Qt.vector3d(model.x * 10, model.y * 10, (model.z + _altitudeBias) * 10)
209 // Billboard: copy the camera's orientation so the label plane stays
210 // parallel to the screen and upright. LookAtNode is unsuitable here
211 // because it assumes a Y-up world while this scene is Z-up.
215 rotation: vehicle3DBody._camera ? vehicle3DBody._camera.sceneRotation : Qt.quaternion(1, 0, 0, 0)
217 // Plain Text (not QGCLabel): QGCLabel sets font.pointSize, and
218 // combining that with the fixed pixelSize needed here makes Qt
219 // warn "Both point size and pixel size set".
222 font.family: ScreenTools.normalFontFamily
224 text: (model.itemName === "W") ? String(model.index) : model.itemName
236 instancing: pathInstancing
237 instancingLodMax: 8000
240 materials: DefaultMaterial {
241 diffuseColor: "white"
246 function onVisualItemsReset() {
247 addMissionItemsToListModel();
248 addSegmentToMissionPathModel();
251 enabled: target !== null
252 target: _missionController
256 function onGpsRefChanged() {
257 addMissionItemsToListModel();
258 addSegmentToMissionPathModel();
261 enabled: target !== null
266 function onHomePositionChanged() {
268 addMissionItemsToListModel();
269 addSegmentToMissionPathModel();
273 enabled: target !== null