Skip to content

Commit

Permalink
add Qgs3DUtils::rayFromScreenPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Jan 13, 2021
1 parent 0073c35 commit e07a393
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
26 changes: 26 additions & 0 deletions src/3d/qgs3dutils.cpp
Expand Up @@ -566,3 +566,29 @@ QgsPhongMaterialSettings Qgs3DUtils::phongMaterialFromQt3DComponent( Qt3DExtras:
settings.setShininess( material->shininess() );
return settings;
}

QgsRay3D Qgs3DUtils::rayFromScreenPoint( const QPoint &point, const QSize &windowSize, Qt3DRender::QCamera *camera )
{
QVector3D deviceCoords( point.x(), point.y(), 0.0 );
// normalized device coordinates
QVector3D normDeviceCoords( 2.0 * deviceCoords.x() / windowSize.width() - 1.0f, 1.0f - 2.0 * deviceCoords.y() / windowSize.height(), camera->nearPlane() );
// clip coordinates
QVector4D rayClip( normDeviceCoords.x(), normDeviceCoords.y(), -1.0, 0.0 );

QMatrix4x4 projMatrix = camera->projectionMatrix();
QMatrix4x4 viewMatrix = camera->viewMatrix();

// ray direction in view coordinates
QVector4D rayDirView = projMatrix.inverted() * rayClip;
// ray origin in world coordinates
QVector4D rayOriginWorld = viewMatrix.inverted() * QVector4D( 0.0f, 0.0f, 0.0f, 1.0f );

// ray direction in world coordinates
rayDirView.setZ( -1.0f );
rayDirView.setW( 0.0f );
QVector4D rayDirWorld4D = viewMatrix.inverted() * rayDirView;
QVector3D rayDirWorld( rayDirWorld4D.x(), rayDirWorld4D.y(), rayDirWorld4D.z() );
rayDirWorld = rayDirWorld.normalized();

return QgsRay3D( QVector3D( rayOriginWorld ), rayDirWorld );
}
6 changes: 6 additions & 0 deletions src/3d/qgs3dutils.h
Expand Up @@ -35,6 +35,9 @@ namespace Qt3DExtras
#include "qgs3danimationsettings.h"
#include "qgs3dtypes.h"
#include "qgsaabb.h"
#include "qgsray3d.h"

#include <Qt3DRender/QCamera>

#include <memory>

Expand Down Expand Up @@ -174,6 +177,9 @@ class _3D_EXPORT Qgs3DUtils

//! Returns phong material settings object based on the Qt3D material
static QgsPhongMaterialSettings phongMaterialFromQt3DComponent( Qt3DExtras::QPhongMaterial *material );

//! Convert from clicked point on the screen to a ray in world coordinates
static QgsRay3D rayFromScreenPoint( const QPoint &point, const QSize &windowSize, Qt3DRender::QCamera *camera );
};

#endif // QGS3DUTILS_H
27 changes: 4 additions & 23 deletions src/app/3d/qgs3dmapcanvas.cpp
Expand Up @@ -34,6 +34,7 @@
#include "qgsflatterraingenerator.h"
#include "qgsonlineterraingenerator.h"
#include "qgsray3d.h"
#include "qgs3dutils.h"

Qgs3DMapCanvas::Qgs3DMapCanvas( QWidget *parent )
: QWidget( parent )
Expand Down Expand Up @@ -257,27 +258,7 @@ void Qgs3DMapCanvas::updateTemporalRange( const QgsDateTimeRange &temporalrange

void Qgs3DMapCanvas::identifyPointCloudOnMouseEvent( QVector<QPair<QgsMapLayer *, QVector<QVariantMap>>> &result, QMouseEvent *event )
{
QVector3D deviceCoords( event->x(), event->y(), 0.0 );
QSize windowSize = mEngine->size();
// normalized device coordinates
QVector3D normDeviceCoords( 2.0 * deviceCoords.x() / windowSize.width() - 1.0f, 1.0f - 2.0 * deviceCoords.y() / windowSize.height(), mEngine->camera()->nearPlane() );
// clip coordinates
QVector4D rayClip( normDeviceCoords.x(), normDeviceCoords.y(), -1.0, 0.0 );

QMatrix4x4 projMatrix = mEngine->camera()->projectionMatrix();
QMatrix4x4 viewMatrix = mEngine->camera()->viewMatrix();

// ray direction in view coordinates
QVector4D rayDirView = projMatrix.inverted() * rayClip;
// ray origin in world coordinates
QVector4D rayOriginWorld = viewMatrix.inverted() * QVector4D( 0.0f, 0.0f, 0.0f, 1.0f );

// ray direction in world coordinates
rayDirView.setZ( -1.0f );
rayDirView.setW( 0.0f );
QVector4D rayDirWorld4D = viewMatrix.inverted() * rayDirView;
QVector3D rayDirWorld( rayDirWorld4D.x(), rayDirWorld4D.y(), rayDirWorld4D.z() );
rayDirWorld = rayDirWorld.normalized();

mScene->identifyPointCloudOnRay( result, QgsRay3D( QVector3D( rayOriginWorld ), rayDirWorld ) );
QgsRay3D ray = Qgs3DUtils::rayFromScreenPoint( event->pos(), mEngine->size(), mEngine->camera() );

mScene->identifyPointCloudOnRay( result, ray );
}

0 comments on commit e07a393

Please sign in to comment.