Skip to content

Commit

Permalink
3D View new changes: OSM file is not mondatory, docs updated, using f…
Browse files Browse the repository at this point in the history
…lickable for 3D Settings, using Loader for Viewer3DManager, touchscreen added
  • Loading branch information
omid-esrafilian committed Feb 17, 2024
1 parent 61a7b53 commit 196192c
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 215 deletions.
Binary file added docs/assets/viewer_3d/open_3d_viewer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 17 additions & 4 deletions docs/en/qgc-user-guide/viewer_3d/viewer_3d.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,24 @@ You can use it to:
![3D View](../../../assets/viewer_3d/viewer_3d_overview.jpg)

# UI Overview
The screenshot above shows the main elements of the 3D View. You can navigate through the 3D View by using the mouse as follows:
- **To move horizontally and vertically**: Press and hold mouse left click, then move the cursor.
- **To rotate**: Press and hold mouse right click, then move the cursor.
- **To zoom**: Use the mouse wheel\middle button.
The screenshot above shows the main elements of the 3D View.

To open the 3D View, when you are in the [Fly View](../fly_view/fly_view.md), from the toolbar on the left, select the 3D View icon as shown below:

![3D View](../../../assets/viewer_3d/open_3d_viewer.jpg)

Once the 3D View is opened, you can navigate through the 3D environment by using either a mouse or a touchscreen as follows:
- **Mouse:**
- **To move horizontally and vertically**: Press and hold the mouse left-click, then move the cursor.
- **To rotate**: Press and hold the mouse right-click, then move the cursor.
- **To zoom**: Use the mouse wheel\middle button.

- **Touchscreen:**
- **To move horizontally and vertically**: Use a single finger, then tap and move your finger.
- **To rotate**: Use two fingers, then tap and move your fingers while keeping them together.
- **To zoom**: Use a pinch with two fingers and move them together or apart to zoom in or out.

To visualize the 3D map of a particular area in the 3D viewer, you have to download the .osm file of that area from the [OpenStreetMap](https://www.openstreetmap.org/#map=16/47.3964/8.5498) website and then import it through the Setting menu. More details on the Setting menu can be found in the next section.
# Setting icon ![Setting icons](../../../assets/viewer_3d/icon_3d_view.jpg)
This icon will open a pop-up window for setting up the 3D View as shown below:

Expand Down
35 changes: 20 additions & 15 deletions src/Viewer3D/CityMapGeometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ CityMapGeometry::CityMapGeometry()
_modelName = "city_map_defualt_name";
_vertexData.clear();
_mapLoadedFlag = 0;

connect(this, &CityMapGeometry::osmFilePathChanged, this, &CityMapGeometry::updateData);
connect(this, &CityMapGeometry::osmParserChanged, this, &CityMapGeometry::updateData);
}

void CityMapGeometry::setModelName(QString modelName)
Expand All @@ -31,35 +28,44 @@ void CityMapGeometry::setOsmFilePath(QString filePath)
_mapLoadedFlag = 0;
_osmFilePath = filePath;
emit osmFilePathChanged();

updateData();
loadOsmMap();
}

void CityMapGeometry::setOsmParser(OsmParser *newOsmParser)
{
_osmParser = newOsmParser;

if(_osmParser){
connect(_osmParser, &OsmParser::buildingLevelHeightChanged, this, &CityMapGeometry::updateData);
connect(_osmParser, &OsmParser::buildingLevelHeightChanged, this, &CityMapGeometry::updateViewer);
connect(_osmParser, &OsmParser::mapChanged, this, &CityMapGeometry::updateViewer);
}
emit osmParserChanged();
loadOsmMap();
}

//! [update data]
void CityMapGeometry::updateData()
bool CityMapGeometry::loadOsmMap()
{
clear();
if(_mapLoadedFlag){
return true;
}

if(!_osmParser){
return;
return false;
}
_mapLoadedFlag = 1;
_osmParser->parseOsmFile(_osmFilePath);
return true;
}

if(_mapLoadedFlag == 0){
_osmParser->parseOsmFile(_osmFilePath);
_mapLoadedFlag = 1;
void CityMapGeometry::updateViewer()
{
clear();

if(!_osmParser){
return;
}

if(_mapLoadedFlag){
if(loadOsmMap()){
_vertexData = _osmParser->buildingToMesh();

int stride = 3 * sizeof(float);
Expand All @@ -72,7 +78,6 @@ void CityMapGeometry::updateData()
addAttribute(QQuick3DGeometry::Attribute::PositionSemantic,
0,
QQuick3DGeometry::Attribute::F32Type);

}
update();
}
Expand Down
5 changes: 3 additions & 2 deletions src/Viewer3D/CityMapGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ class CityMapGeometry : public QQuick3DGeometry
OsmParser* osmParser(){ return _osmParser;}
void setOsmParser(OsmParser* newOsmParser);

bool loadOsmMap();

signals:
void modelNameChanged();
void osmFilePathChanged();
void gpsRefChanged();
void osmParserChanged();

private:
void updateData();
void updateViewer();

QString _modelName;
QString _osmFilePath;
Expand Down
4 changes: 2 additions & 2 deletions src/Viewer3D/OsmParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ void OsmParser::parseOsmFile(QString filePath)
component = component.nextSibling().toElement();
}
_mapLoadedFlag = true;
emit newMapLoaded();
qDebug() << _mapBuildings.size() << " Buildings added to the 3D viewer!!!";
emit mapChanged();
qDebug() << _mapBuildings.size() << " Buildings loaded!!!";
}

void OsmParser::decodeNodeTags(QDomElement &xmlComponent, QMap<uint64_t, QGeoCoordinate> &nodeMap)
Expand Down
2 changes: 1 addition & 1 deletion src/Viewer3D/OsmParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class OsmParser : public QObject

signals:
void gpsRefChanged(QGeoCoordinate newGpsRef);
void newMapLoaded();
void mapChanged();
void buildingLevelHeightChanged(void);

};
Expand Down
6 changes: 5 additions & 1 deletion src/Viewer3D/Viewer3D/Models3D/CameraLightModel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Node {

property real _tilt: 0.001
property real _pan: 0.001
property real _zoom: 1000
property real _zoom: 1500


DirectionalLight {
Expand Down Expand Up @@ -58,6 +58,10 @@ Node {

id: cameraPerspectiveOne

eulerRotation{
x: -90
}

}
}
}
Expand Down
179 changes: 131 additions & 48 deletions src/Viewer3D/Viewer3D/Models3D/Viewer3DModel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,54 @@ import QGroundControl.Vehicle
View3D {
id: topView
property var viewer3DManager: null
property bool viewer3DOpen: false
property real rotationSpeed: 0.1
property real movementSpeed: 1
property real zoomSpeed: 0.3

function rotateCamera(newPose: vector2d, lastPose: vector2d) {
let rotation_vec = Qt.vector2d(newPose.y - lastPose.y, newPose.x - lastPose.x);

let dx_l = rotation_vec.x * rotationSpeed
let dy_l = rotation_vec.y * rotationSpeed

standAloneScene.cameraOneRotation.x += dx_l
standAloneScene.cameraOneRotation.y += dy_l
}

function moveCamera(newPose: vector2d, lastPose: vector2d) {
let _roll = standAloneScene.cameraOneRotation.x * (3.1415/180)
let _pitch = standAloneScene.cameraOneRotation.y * (3.1415/180)

let dx_l = (newPose.x - lastPose.x) * movementSpeed
let dy_l = (newPose.y - lastPose.y) * movementSpeed

//Note: Rotation Matrix is computed as: R = R(-_pitch) * R(_roll)
// Then the corerxt tramslation is: d = R * [dx_l; dy_l; dz_l]

let dx = dx_l * Math.cos(_pitch) - dy_l * Math.sin(_pitch) * Math.sin(_roll)
let dy = dy_l * Math.cos(_roll)
let dz = dx_l * Math.sin(_pitch) + dy_l * Math.cos(_pitch) * Math.sin(_roll)

standAloneScene.cameraTwoPosition.x -= dx
standAloneScene.cameraTwoPosition.y += dy
standAloneScene.cameraTwoPosition.z += dz
}

function zoomCamera(zoomValue){
let dz_l = zoomValue * zoomSpeed;

let _roll = standAloneScene.cameraOneRotation.x * (3.1415/180)
let _pitch = standAloneScene.cameraOneRotation.y * (3.1415/180)

let dx = -dz_l * Math.cos(_roll) * Math.sin(_pitch)
let dy = -dz_l * Math.sin(_roll)
let dz = dz_l * Math.cos(_pitch) * Math.cos(_roll)

standAloneScene.cameraTwoPosition.x -= dx
standAloneScene.cameraTwoPosition.y += dy
standAloneScene.cameraTwoPosition.z += dz
}

camera: standAloneScene.cameraOne
importScene: CameraLightModel{
Expand All @@ -31,7 +78,7 @@ View3D {
// renderMode: View3D.Inline

environment: SceneEnvironment {
clearColor: "white"
clearColor: "#F9F9F9"
backgroundMode: SceneEnvironment.Color
}

Expand Down Expand Up @@ -78,66 +125,102 @@ View3D {
vehicle3DLoader.sourceComponent = vehicle3DComponent
}

MouseArea{
property real _transferSpeed: 1
property real _rotationSpeed: 0.1
property real _zoomSpeed: 0.3
DragHandler {
property bool _isMoving: false
property point _lastPose;

anchors.fill: parent
acceptedButtons: Qt.AllButtons;


onPressed: (mouse)=> {
_lastPose = Qt.point(mouse.x, mouse.y);
}

onPositionChanged: (mouse)=> {
let _roll = standAloneScene.cameraOneRotation.x * (3.1415/180)
let _pitch = standAloneScene.cameraOneRotation.y * (3.1415/180)
// let yaw = standAloneScene.cameraOneRotation.z * (3.1415/180)

if (mouse.buttons === Qt.LeftButton) { // Left button for translate
let dx_l = (mouse.x - _lastPose.x) * _transferSpeed
let dy_l = (mouse.y - _lastPose.y) * _transferSpeed
id: cameraMovementDragHandler
target: null
acceptedModifiers: Qt.NoModifier
acceptedButtons: Qt.LeftButton
enabled: viewer3DOpen

//Note: Rotation Matrix is computed as: R = R(-_pitch) * R(_roll)
// Then the corerxt tramslation is: d = R * [dx_l; dy_l; dz_l]
onCentroidChanged: {
if(_isMoving){
moveCamera(centroid.position, _lastPose);
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
}
}

let dx = dx_l * Math.cos(_pitch) - dy_l * Math.sin(_pitch) * Math.sin(_roll)
let dy = dy_l * Math.cos(_roll)
let dz = dx_l * Math.sin(_pitch) + dy_l * Math.cos(_pitch) * Math.sin(_roll)
onActiveChanged: {
if(active){ // When mouse is pressed
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
_isMoving = true
}else{ // When mouse is released
_isMoving = false
}
}
}

standAloneScene.cameraTwoPosition.x -= dx
standAloneScene.cameraTwoPosition.y += dy
standAloneScene.cameraTwoPosition.z += dz
}else if (mouse.buttons === Qt.RightButton){ // Right button for rotation
DragHandler {
property bool _isRotating: false
property point _lastPose;

let rotation_vec = Qt.vector2d(mouse.y - _lastPose.y, mouse.x - _lastPose.x);
id: cameraRotationDragHandler
target: null
acceptedModifiers: Qt.NoModifier
acceptedButtons: Qt.RightButton
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
enabled: viewer3DOpen

onCentroidChanged: {
if(_isRotating){
rotateCamera(centroid.position, _lastPose);
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
}
}

let dx_l = rotation_vec.x * _rotationSpeed
let dy_l = rotation_vec.y * _rotationSpeed
onActiveChanged: {
if(active){ // When mouse is pressed
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
_isRotating = true
}else{// When mouse is released
_isRotating = false
}
}
}

standAloneScene.cameraOneRotation.x += dx_l
standAloneScene.cameraOneRotation.y += dy_l
PinchHandler {
id: zoomRotationPinchHandler
target: null

}
_lastPose = Qt.point(mouse.x, mouse.y)
}
property bool _isRotating: false
property point _lastPose;
property real _lastZoomValue;
enabled: viewer3DOpen

onWheel: (wheel)=> {
let dz_l = -wheel.angleDelta.y * _zoomSpeed
onCentroidChanged: {
if(_isRotating){
rotateCamera(centroid.position, _lastPose);
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
}
}

let _roll = standAloneScene.cameraOneRotation.x * (3.1415/180)
let _pitch = standAloneScene.cameraOneRotation.y * (3.1415/180)
onActiveChanged: {
if (active) {
_lastPose = Qt.point(centroid.position.x, centroid.position.y);
_lastZoomValue = 0
_isRotating = true;
} else {
_isRotating = false;
}
}
onActiveScaleChanged: {
let zoomValue = (activeScale > 1)?(activeScale - 1):(-((1/activeScale) - 1))
zoomCamera(- 1000 * (zoomValue - _lastZoomValue))
_lastZoomValue = zoomValue
}
}

let dx = -dz_l * Math.cos(_roll) * Math.sin(_pitch)
let dy = -dz_l * Math.sin(_roll)
let dz = dz_l * Math.cos(_pitch) * Math.cos(_roll)
WheelHandler {
id: wheelHandler
orientation: Qt.Vertical
target: null
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
enabled: viewer3DOpen

standAloneScene.cameraTwoPosition.x -= dx
standAloneScene.cameraTwoPosition.y += dy
standAloneScene.cameraTwoPosition.z += dz
onWheel: event => {
zoomCamera(-event.angleDelta.y)
}
}
}
Loading

0 comments on commit 196192c

Please sign in to comment.