From 50ac9a6bf8bd1b41bef383e0827cc4365c029cec Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sun, 17 Nov 2024 23:02:06 +0100 Subject: [PATCH] Add possibility to shift origin of 3D map scenes This introduces a new class QgsGeoTransform (derived from QTransform) that keeps chunk's translation vector as a QgsVector3D (i.e. in double coordinates) and if there is a shift of the origin, 3D map scene and chunk entities react to it by adjusting the underlying QTransform. --- python/3d/auto_additions/qgs3dmapsettings.py | 2 +- .../3d/auto_generated/qgs3dmapsettings.sip.in | 9 ++++ .../auto_generated/qgscameracontroller.sip.in | 7 +++ .../3d/auto_additions/qgs3dmapsettings.py | 2 +- .../3d/auto_generated/qgs3dmapsettings.sip.in | 9 ++++ .../auto_generated/qgscameracontroller.sip.in | 7 +++ src/3d/CMakeLists.txt | 2 + src/3d/chunks/qgschunkedentity.cpp | 9 ++++ src/3d/lights/qgsdirectionallightsettings.cpp | 2 - src/3d/lights/qgspointlightsettings.cpp | 4 +- src/3d/qgs3dmapscene.cpp | 28 ++++++++++++ src/3d/qgs3dmapscene.h | 2 + src/3d/qgs3dmapsettings.cpp | 4 ++ src/3d/qgs3dmapsettings.h | 7 +++ src/3d/qgscameracontroller.cpp | 17 +++++++ src/3d/qgscameracontroller.h | 10 +++++ src/3d/qgsgeotransform.cpp | 23 ++++++++++ src/3d/qgsgeotransform.h | 44 +++++++++++++++++++ src/3d/qgsrubberband3d.cpp | 6 --- src/3d/qgstiledscenechunkloader_p.cpp | 10 ++++- src/3d/symbols/qgsline3dsymbol_p.cpp | 11 +++-- src/3d/symbols/qgspoint3dsymbol_p.cpp | 32 ++++++-------- src/3d/symbols/qgspointcloud3dsymbol_p.cpp | 6 +-- src/3d/symbols/qgspolygon3dsymbol_p.cpp | 12 +++-- src/3d/terrain/qgsdemterraintileloader_p.cpp | 8 ++-- src/3d/terrain/qgsflatterraingenerator.cpp | 14 +++--- 26 files changed, 225 insertions(+), 62 deletions(-) create mode 100644 src/3d/qgsgeotransform.cpp create mode 100644 src/3d/qgsgeotransform.h diff --git a/python/3d/auto_additions/qgs3dmapsettings.py b/python/3d/auto_additions/qgs3dmapsettings.py index ad88278a3331..583dc72ced3a 100644 --- a/python/3d/auto_additions/qgs3dmapsettings.py +++ b/python/3d/auto_additions/qgs3dmapsettings.py @@ -1,6 +1,6 @@ # The following has been generated automatically from src/3d/qgs3dmapsettings.h try: - Qgs3DMapSettings.__attribute_docs__ = {'settingsChanged': 'Emitted when one of the configuration settings has changed\n\n.. versionadded:: 3.24\n', 'backgroundColorChanged': 'Emitted when the background color has changed\n', 'selectionColorChanged': 'Emitted when the selection color has changed\n', 'layersChanged': 'Emitted when the list of map layers for 3d rendering has changed.\n\n.. seealso:: :py:func:`setLayers`\n\n.. seealso:: :py:func:`layers`\n', 'terrainGeneratorChanged': 'Emitted when the terrain generator has changed\n', 'terrainVerticalScaleChanged': 'Emitted when the vertical scale of the terrain has changed\n', 'mapTileResolutionChanged': 'Emitted when the map tile resoulution has changed\n', 'maxTerrainScreenErrorChanged': 'Emitted when the maximum terrain screen error has changed\n', 'maxTerrainGroundErrorChanged': 'Emitted when the maximum terrain ground error has changed\n', 'terrainElevationOffsetChanged': 'Emitted when the terrain elevation offset is changed\n\n.. versionadded:: 3.16\n', 'terrainShadingChanged': 'Emitted when terrain shading enabled flag or terrain shading material has changed\n\n.. versionadded:: 3.6\n', 'terrainMapThemeChanged': "Emitted when terrain's map theme has changed\n\n.. versionadded:: 3.6\n", 'renderersChanged': "Emitted when the list of map's extra renderers have been modified\n\n.. versionadded:: 3.10\n", 'showTerrainBoundingBoxesChanged': "Emitted when the flag whether terrain's bounding boxes are shown has changed\n", 'showTerrainTilesInfoChanged': "Emitted when the flag whether terrain's tile info is shown has changed\n", 'showCameraViewCenterChanged': "Emitted when the flag whether camera's view center is shown has changed\n\n.. versionadded:: 3.4\n", 'showCameraRotationCenterChanged': "Emitted when the flag whether camera's rotation center is shown has changed\n\n.. versionadded:: 3.24\n", 'showLightSourceOriginsChanged': 'Emitted when the flag whether light source origins are shown has changed.\n\n.. versionadded:: 3.15\n', 'showLabelsChanged': 'Emitted when the flag whether labels are displayed on terrain tiles has changed\n', 'eyeDomeLightingEnabledChanged': 'Emitted when the flag whether eye dome lighting is used has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingStrengthChanged': 'Emitted when the eye dome lighting strength has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingDistanceChanged': 'Emitted when the eye dome lighting distance has changed\n\n.. versionadded:: 3.18\n', 'debugShadowMapSettingsChanged': 'Emitted when shadow map debugging has changed\n\n.. versionadded:: 3.18\n', 'debugDepthMapSettingsChanged': 'Emitted when depth map debugging has changed\n\n.. versionadded:: 3.18\n', 'pointLightsChanged': 'Emitted when the list of point lights changes\n\n.. versionadded:: 3.6\n', 'lightSourcesChanged': 'Emitted when any of the light source settings in the map changes.\n\n.. versionadded:: 3.26\n', 'directionalLightsChanged': 'Emitted when the list of directional lights changes\n\n.. versionadded:: 3.16\n', 'fieldOfViewChanged': 'Emitted when the camera lens field of view changes\n\n.. versionadded:: 3.8\n', 'projectionTypeChanged': 'Emitted when the camera lens projection type changes\n\n.. versionadded:: 3.18\n', 'cameraNavigationModeChanged': 'Emitted when the camera navigation mode was changed\n\n.. versionadded:: 3.18\n', 'cameraMovementSpeedChanged': 'Emitted when the camera movement speed was changed\n\n.. versionadded:: 3.18\n', 'skyboxSettingsChanged': 'Emitted when skybox settings are changed\n\n.. versionadded:: 3.16\n', 'shadowSettingsChanged': 'Emitted when shadow rendering settings are changed\n\n.. versionadded:: 3.16\n', 'ambientOcclusionSettingsChanged': 'Emitted when ambient occlusion rendering settings are changed\n\n.. versionadded:: 3.28\n', 'fpsCounterEnabledChanged': 'Emitted when the FPS counter is enabled or disabled\n\n.. versionadded:: 3.18\n', 'viewFrustumVisualizationEnabledChanged': "Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled\n\n.. versionadded:: 3.26\n", 'axisSettingsChanged': 'Emitted when 3d axis rendering settings are changed\n\n.. versionadded:: 3.26\n', 'debugOverlayEnabledChanged': 'Emitted when the debug overaly is enabled or disabled\n\n.. versionadded:: 3.26\n', 'extentChanged': "Emitted when the 3d view's 2d extent has changed\n\n.. seealso:: :py:func:`setExtent`\n\n.. versionadded:: 3.30\n", 'showExtentIn2DViewChanged': "Emitted when the parameter to display 3d view's extent in the 2D canvas has changed\n\n.. seealso:: :py:func:`setShowExtentIn2DView`\n\n.. versionadded:: 3.32\n"} + Qgs3DMapSettings.__attribute_docs__ = {'settingsChanged': 'Emitted when one of the configuration settings has changed\n\n.. versionadded:: 3.24\n', 'backgroundColorChanged': 'Emitted when the background color has changed\n', 'selectionColorChanged': 'Emitted when the selection color has changed\n', 'layersChanged': 'Emitted when the list of map layers for 3d rendering has changed.\n\n.. seealso:: :py:func:`setLayers`\n\n.. seealso:: :py:func:`layers`\n', 'terrainGeneratorChanged': 'Emitted when the terrain generator has changed\n', 'terrainVerticalScaleChanged': 'Emitted when the vertical scale of the terrain has changed\n', 'mapTileResolutionChanged': 'Emitted when the map tile resoulution has changed\n', 'maxTerrainScreenErrorChanged': 'Emitted when the maximum terrain screen error has changed\n', 'maxTerrainGroundErrorChanged': 'Emitted when the maximum terrain ground error has changed\n', 'terrainElevationOffsetChanged': 'Emitted when the terrain elevation offset is changed\n\n.. versionadded:: 3.16\n', 'terrainShadingChanged': 'Emitted when terrain shading enabled flag or terrain shading material has changed\n\n.. versionadded:: 3.6\n', 'terrainMapThemeChanged': "Emitted when terrain's map theme has changed\n\n.. versionadded:: 3.6\n", 'renderersChanged': "Emitted when the list of map's extra renderers have been modified\n\n.. versionadded:: 3.10\n", 'showTerrainBoundingBoxesChanged': "Emitted when the flag whether terrain's bounding boxes are shown has changed\n", 'showTerrainTilesInfoChanged': "Emitted when the flag whether terrain's tile info is shown has changed\n", 'showCameraViewCenterChanged': "Emitted when the flag whether camera's view center is shown has changed\n\n.. versionadded:: 3.4\n", 'showCameraRotationCenterChanged': "Emitted when the flag whether camera's rotation center is shown has changed\n\n.. versionadded:: 3.24\n", 'showLightSourceOriginsChanged': 'Emitted when the flag whether light source origins are shown has changed.\n\n.. versionadded:: 3.15\n', 'showLabelsChanged': 'Emitted when the flag whether labels are displayed on terrain tiles has changed\n', 'eyeDomeLightingEnabledChanged': 'Emitted when the flag whether eye dome lighting is used has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingStrengthChanged': 'Emitted when the eye dome lighting strength has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingDistanceChanged': 'Emitted when the eye dome lighting distance has changed\n\n.. versionadded:: 3.18\n', 'debugShadowMapSettingsChanged': 'Emitted when shadow map debugging has changed\n\n.. versionadded:: 3.18\n', 'debugDepthMapSettingsChanged': 'Emitted when depth map debugging has changed\n\n.. versionadded:: 3.18\n', 'pointLightsChanged': 'Emitted when the list of point lights changes\n\n.. versionadded:: 3.6\n', 'lightSourcesChanged': 'Emitted when any of the light source settings in the map changes.\n\n.. versionadded:: 3.26\n', 'directionalLightsChanged': 'Emitted when the list of directional lights changes\n\n.. versionadded:: 3.16\n', 'fieldOfViewChanged': 'Emitted when the camera lens field of view changes\n\n.. versionadded:: 3.8\n', 'projectionTypeChanged': 'Emitted when the camera lens projection type changes\n\n.. versionadded:: 3.18\n', 'cameraNavigationModeChanged': 'Emitted when the camera navigation mode was changed\n\n.. versionadded:: 3.18\n', 'cameraMovementSpeedChanged': 'Emitted when the camera movement speed was changed\n\n.. versionadded:: 3.18\n', 'skyboxSettingsChanged': 'Emitted when skybox settings are changed\n\n.. versionadded:: 3.16\n', 'shadowSettingsChanged': 'Emitted when shadow rendering settings are changed\n\n.. versionadded:: 3.16\n', 'ambientOcclusionSettingsChanged': 'Emitted when ambient occlusion rendering settings are changed\n\n.. versionadded:: 3.28\n', 'fpsCounterEnabledChanged': 'Emitted when the FPS counter is enabled or disabled\n\n.. versionadded:: 3.18\n', 'viewFrustumVisualizationEnabledChanged': "Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled\n\n.. versionadded:: 3.26\n", 'axisSettingsChanged': 'Emitted when 3d axis rendering settings are changed\n\n.. versionadded:: 3.26\n', 'debugOverlayEnabledChanged': 'Emitted when the debug overaly is enabled or disabled\n\n.. versionadded:: 3.26\n', 'extentChanged': "Emitted when the 3d view's 2d extent has changed\n\n.. seealso:: :py:func:`setExtent`\n\n.. versionadded:: 3.30\n", 'showExtentIn2DViewChanged': "Emitted when the parameter to display 3d view's extent in the 2D canvas has changed\n\n.. seealso:: :py:func:`setShowExtentIn2DView`\n\n.. versionadded:: 3.32\n", 'originChanged': "Emitted when the world's origin point has been shifted\n\n.. seealso:: :py:func:`setOrigin`\n\n.. versionadded:: 3.42\n"} Qgs3DMapSettings.__signal_arguments__ = {'terrainElevationOffsetChanged': ['newElevation: float'], 'fpsCounterEnabledChanged': ['fpsCounterEnabled: bool'], 'debugOverlayEnabledChanged': ['debugOverlayEnabled: bool']} except NameError: pass diff --git a/python/3d/auto_generated/qgs3dmapsettings.sip.in b/python/3d/auto_generated/qgs3dmapsettings.sip.in index b61477204b62..f5b69a1435ab 100644 --- a/python/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/3d/auto_generated/qgs3dmapsettings.sip.in @@ -966,6 +966,15 @@ Emitted when the parameter to display 3d view's extent in the 2D canvas has chan .. seealso:: :py:func:`setShowExtentIn2DView` .. versionadded:: 3.32 +%End + + void originChanged(); +%Docstring +Emitted when the world's origin point has been shifted + +.. seealso:: :py:func:`setOrigin` + +.. versionadded:: 3.42 %End private: diff --git a/python/3d/auto_generated/qgscameracontroller.sip.in b/python/3d/auto_generated/qgscameracontroller.sip.in index 53b9bbd2c555..0c8da04c4313 100644 --- a/python/3d/auto_generated/qgscameracontroller.sip.in +++ b/python/3d/auto_generated/qgscameracontroller.sip.in @@ -181,6 +181,13 @@ Rotates the camera on itself. Returns ``True`` if the camera controller will handle the specified key ``event``, preventing it from being instead handled by parents of the 3D window before the controller ever receives it. +%End + + void setOrigin( const QgsVector3D &origin ); +%Docstring +Reacts to the shift of origin of the scene, updating camera pose and +any other member variables so that the origin stays at the same position +relative to other entities. %End public slots: diff --git a/python/PyQt6/3d/auto_additions/qgs3dmapsettings.py b/python/PyQt6/3d/auto_additions/qgs3dmapsettings.py index ad88278a3331..583dc72ced3a 100644 --- a/python/PyQt6/3d/auto_additions/qgs3dmapsettings.py +++ b/python/PyQt6/3d/auto_additions/qgs3dmapsettings.py @@ -1,6 +1,6 @@ # The following has been generated automatically from src/3d/qgs3dmapsettings.h try: - Qgs3DMapSettings.__attribute_docs__ = {'settingsChanged': 'Emitted when one of the configuration settings has changed\n\n.. versionadded:: 3.24\n', 'backgroundColorChanged': 'Emitted when the background color has changed\n', 'selectionColorChanged': 'Emitted when the selection color has changed\n', 'layersChanged': 'Emitted when the list of map layers for 3d rendering has changed.\n\n.. seealso:: :py:func:`setLayers`\n\n.. seealso:: :py:func:`layers`\n', 'terrainGeneratorChanged': 'Emitted when the terrain generator has changed\n', 'terrainVerticalScaleChanged': 'Emitted when the vertical scale of the terrain has changed\n', 'mapTileResolutionChanged': 'Emitted when the map tile resoulution has changed\n', 'maxTerrainScreenErrorChanged': 'Emitted when the maximum terrain screen error has changed\n', 'maxTerrainGroundErrorChanged': 'Emitted when the maximum terrain ground error has changed\n', 'terrainElevationOffsetChanged': 'Emitted when the terrain elevation offset is changed\n\n.. versionadded:: 3.16\n', 'terrainShadingChanged': 'Emitted when terrain shading enabled flag or terrain shading material has changed\n\n.. versionadded:: 3.6\n', 'terrainMapThemeChanged': "Emitted when terrain's map theme has changed\n\n.. versionadded:: 3.6\n", 'renderersChanged': "Emitted when the list of map's extra renderers have been modified\n\n.. versionadded:: 3.10\n", 'showTerrainBoundingBoxesChanged': "Emitted when the flag whether terrain's bounding boxes are shown has changed\n", 'showTerrainTilesInfoChanged': "Emitted when the flag whether terrain's tile info is shown has changed\n", 'showCameraViewCenterChanged': "Emitted when the flag whether camera's view center is shown has changed\n\n.. versionadded:: 3.4\n", 'showCameraRotationCenterChanged': "Emitted when the flag whether camera's rotation center is shown has changed\n\n.. versionadded:: 3.24\n", 'showLightSourceOriginsChanged': 'Emitted when the flag whether light source origins are shown has changed.\n\n.. versionadded:: 3.15\n', 'showLabelsChanged': 'Emitted when the flag whether labels are displayed on terrain tiles has changed\n', 'eyeDomeLightingEnabledChanged': 'Emitted when the flag whether eye dome lighting is used has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingStrengthChanged': 'Emitted when the eye dome lighting strength has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingDistanceChanged': 'Emitted when the eye dome lighting distance has changed\n\n.. versionadded:: 3.18\n', 'debugShadowMapSettingsChanged': 'Emitted when shadow map debugging has changed\n\n.. versionadded:: 3.18\n', 'debugDepthMapSettingsChanged': 'Emitted when depth map debugging has changed\n\n.. versionadded:: 3.18\n', 'pointLightsChanged': 'Emitted when the list of point lights changes\n\n.. versionadded:: 3.6\n', 'lightSourcesChanged': 'Emitted when any of the light source settings in the map changes.\n\n.. versionadded:: 3.26\n', 'directionalLightsChanged': 'Emitted when the list of directional lights changes\n\n.. versionadded:: 3.16\n', 'fieldOfViewChanged': 'Emitted when the camera lens field of view changes\n\n.. versionadded:: 3.8\n', 'projectionTypeChanged': 'Emitted when the camera lens projection type changes\n\n.. versionadded:: 3.18\n', 'cameraNavigationModeChanged': 'Emitted when the camera navigation mode was changed\n\n.. versionadded:: 3.18\n', 'cameraMovementSpeedChanged': 'Emitted when the camera movement speed was changed\n\n.. versionadded:: 3.18\n', 'skyboxSettingsChanged': 'Emitted when skybox settings are changed\n\n.. versionadded:: 3.16\n', 'shadowSettingsChanged': 'Emitted when shadow rendering settings are changed\n\n.. versionadded:: 3.16\n', 'ambientOcclusionSettingsChanged': 'Emitted when ambient occlusion rendering settings are changed\n\n.. versionadded:: 3.28\n', 'fpsCounterEnabledChanged': 'Emitted when the FPS counter is enabled or disabled\n\n.. versionadded:: 3.18\n', 'viewFrustumVisualizationEnabledChanged': "Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled\n\n.. versionadded:: 3.26\n", 'axisSettingsChanged': 'Emitted when 3d axis rendering settings are changed\n\n.. versionadded:: 3.26\n', 'debugOverlayEnabledChanged': 'Emitted when the debug overaly is enabled or disabled\n\n.. versionadded:: 3.26\n', 'extentChanged': "Emitted when the 3d view's 2d extent has changed\n\n.. seealso:: :py:func:`setExtent`\n\n.. versionadded:: 3.30\n", 'showExtentIn2DViewChanged': "Emitted when the parameter to display 3d view's extent in the 2D canvas has changed\n\n.. seealso:: :py:func:`setShowExtentIn2DView`\n\n.. versionadded:: 3.32\n"} + Qgs3DMapSettings.__attribute_docs__ = {'settingsChanged': 'Emitted when one of the configuration settings has changed\n\n.. versionadded:: 3.24\n', 'backgroundColorChanged': 'Emitted when the background color has changed\n', 'selectionColorChanged': 'Emitted when the selection color has changed\n', 'layersChanged': 'Emitted when the list of map layers for 3d rendering has changed.\n\n.. seealso:: :py:func:`setLayers`\n\n.. seealso:: :py:func:`layers`\n', 'terrainGeneratorChanged': 'Emitted when the terrain generator has changed\n', 'terrainVerticalScaleChanged': 'Emitted when the vertical scale of the terrain has changed\n', 'mapTileResolutionChanged': 'Emitted when the map tile resoulution has changed\n', 'maxTerrainScreenErrorChanged': 'Emitted when the maximum terrain screen error has changed\n', 'maxTerrainGroundErrorChanged': 'Emitted when the maximum terrain ground error has changed\n', 'terrainElevationOffsetChanged': 'Emitted when the terrain elevation offset is changed\n\n.. versionadded:: 3.16\n', 'terrainShadingChanged': 'Emitted when terrain shading enabled flag or terrain shading material has changed\n\n.. versionadded:: 3.6\n', 'terrainMapThemeChanged': "Emitted when terrain's map theme has changed\n\n.. versionadded:: 3.6\n", 'renderersChanged': "Emitted when the list of map's extra renderers have been modified\n\n.. versionadded:: 3.10\n", 'showTerrainBoundingBoxesChanged': "Emitted when the flag whether terrain's bounding boxes are shown has changed\n", 'showTerrainTilesInfoChanged': "Emitted when the flag whether terrain's tile info is shown has changed\n", 'showCameraViewCenterChanged': "Emitted when the flag whether camera's view center is shown has changed\n\n.. versionadded:: 3.4\n", 'showCameraRotationCenterChanged': "Emitted when the flag whether camera's rotation center is shown has changed\n\n.. versionadded:: 3.24\n", 'showLightSourceOriginsChanged': 'Emitted when the flag whether light source origins are shown has changed.\n\n.. versionadded:: 3.15\n', 'showLabelsChanged': 'Emitted when the flag whether labels are displayed on terrain tiles has changed\n', 'eyeDomeLightingEnabledChanged': 'Emitted when the flag whether eye dome lighting is used has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingStrengthChanged': 'Emitted when the eye dome lighting strength has changed\n\n.. versionadded:: 3.18\n', 'eyeDomeLightingDistanceChanged': 'Emitted when the eye dome lighting distance has changed\n\n.. versionadded:: 3.18\n', 'debugShadowMapSettingsChanged': 'Emitted when shadow map debugging has changed\n\n.. versionadded:: 3.18\n', 'debugDepthMapSettingsChanged': 'Emitted when depth map debugging has changed\n\n.. versionadded:: 3.18\n', 'pointLightsChanged': 'Emitted when the list of point lights changes\n\n.. versionadded:: 3.6\n', 'lightSourcesChanged': 'Emitted when any of the light source settings in the map changes.\n\n.. versionadded:: 3.26\n', 'directionalLightsChanged': 'Emitted when the list of directional lights changes\n\n.. versionadded:: 3.16\n', 'fieldOfViewChanged': 'Emitted when the camera lens field of view changes\n\n.. versionadded:: 3.8\n', 'projectionTypeChanged': 'Emitted when the camera lens projection type changes\n\n.. versionadded:: 3.18\n', 'cameraNavigationModeChanged': 'Emitted when the camera navigation mode was changed\n\n.. versionadded:: 3.18\n', 'cameraMovementSpeedChanged': 'Emitted when the camera movement speed was changed\n\n.. versionadded:: 3.18\n', 'skyboxSettingsChanged': 'Emitted when skybox settings are changed\n\n.. versionadded:: 3.16\n', 'shadowSettingsChanged': 'Emitted when shadow rendering settings are changed\n\n.. versionadded:: 3.16\n', 'ambientOcclusionSettingsChanged': 'Emitted when ambient occlusion rendering settings are changed\n\n.. versionadded:: 3.28\n', 'fpsCounterEnabledChanged': 'Emitted when the FPS counter is enabled or disabled\n\n.. versionadded:: 3.18\n', 'viewFrustumVisualizationEnabledChanged': "Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled\n\n.. versionadded:: 3.26\n", 'axisSettingsChanged': 'Emitted when 3d axis rendering settings are changed\n\n.. versionadded:: 3.26\n', 'debugOverlayEnabledChanged': 'Emitted when the debug overaly is enabled or disabled\n\n.. versionadded:: 3.26\n', 'extentChanged': "Emitted when the 3d view's 2d extent has changed\n\n.. seealso:: :py:func:`setExtent`\n\n.. versionadded:: 3.30\n", 'showExtentIn2DViewChanged': "Emitted when the parameter to display 3d view's extent in the 2D canvas has changed\n\n.. seealso:: :py:func:`setShowExtentIn2DView`\n\n.. versionadded:: 3.32\n", 'originChanged': "Emitted when the world's origin point has been shifted\n\n.. seealso:: :py:func:`setOrigin`\n\n.. versionadded:: 3.42\n"} Qgs3DMapSettings.__signal_arguments__ = {'terrainElevationOffsetChanged': ['newElevation: float'], 'fpsCounterEnabledChanged': ['fpsCounterEnabled: bool'], 'debugOverlayEnabledChanged': ['debugOverlayEnabled: bool']} except NameError: pass diff --git a/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in index b61477204b62..f5b69a1435ab 100644 --- a/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in @@ -966,6 +966,15 @@ Emitted when the parameter to display 3d view's extent in the 2D canvas has chan .. seealso:: :py:func:`setShowExtentIn2DView` .. versionadded:: 3.32 +%End + + void originChanged(); +%Docstring +Emitted when the world's origin point has been shifted + +.. seealso:: :py:func:`setOrigin` + +.. versionadded:: 3.42 %End private: diff --git a/python/PyQt6/3d/auto_generated/qgscameracontroller.sip.in b/python/PyQt6/3d/auto_generated/qgscameracontroller.sip.in index 53b9bbd2c555..0c8da04c4313 100644 --- a/python/PyQt6/3d/auto_generated/qgscameracontroller.sip.in +++ b/python/PyQt6/3d/auto_generated/qgscameracontroller.sip.in @@ -181,6 +181,13 @@ Rotates the camera on itself. Returns ``True`` if the camera controller will handle the specified key ``event``, preventing it from being instead handled by parents of the 3D window before the controller ever receives it. +%End + + void setOrigin( const QgsVector3D &origin ); +%Docstring +Reacts to the shift of origin of the scene, updating camera pose and +any other member variables so that the origin stays at the same position +relative to other entities. %End public slots: diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 96d2445c6cd6..42904ad8a7e7 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -24,6 +24,7 @@ set(QGIS_3D_SRCS qgsfeature3dhandler_p.cpp qgsfgutils.cpp qgsframegraph.cpp + qgsgeotransform.cpp qgsgltf3dutils.cpp qgsimagetexture.cpp qgslayoutitem3dmap.cpp @@ -138,6 +139,7 @@ set(QGIS_3D_HDRS qgscamerapose.h qgsfgutils.h qgsframegraph.h + qgsgeotransform.h qgsgltf3dutils.h qgslayoutitem3dmap.h qgsmeshlayer3drenderer.h diff --git a/src/3d/chunks/qgschunkedentity.cpp b/src/3d/chunks/qgschunkedentity.cpp index db1c8eb00104..148e196bf5a7 100644 --- a/src/3d/chunks/qgschunkedentity.cpp +++ b/src/3d/chunks/qgschunkedentity.cpp @@ -24,6 +24,7 @@ #include "qgschunklist_p.h" #include "qgschunkloader.h" #include "qgschunknode.h" +#include "qgsgeotransform.h" #include "qgseventtracing.h" @@ -163,6 +164,14 @@ void QgsChunkedEntity::handleSceneUpdate( const SceneContext &sceneContext ) continue; } node->entity()->setEnabled( true ); + + // let's make sure that any entity we're about to show has the right scene origin set + const QList transforms = node->entity()->findChildren(); + for ( QgsGeoTransform *transform : transforms ) + { + transform->setOrigin( mMapSettings->origin() ); + } + #ifdef QGISDEBUG ++enabled; #endif diff --git a/src/3d/lights/qgsdirectionallightsettings.cpp b/src/3d/lights/qgsdirectionallightsettings.cpp index c7d30a26f924..e70dd7a0c1e7 100644 --- a/src/3d/lights/qgsdirectionallightsettings.cpp +++ b/src/3d/lights/qgsdirectionallightsettings.cpp @@ -34,7 +34,6 @@ QgsDirectionalLightSettings *QgsDirectionalLightSettings::clone() const Qt3DCore::QEntity *QgsDirectionalLightSettings::createEntity( const Qgs3DMapSettings &, Qt3DCore::QEntity *parent ) const { Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity( parent ); - Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform; Qt3DRender::QDirectionalLight *light = new Qt3DRender::QDirectionalLight; light->setColor( color() ); @@ -43,7 +42,6 @@ Qt3DCore::QEntity *QgsDirectionalLightSettings::createEntity( const Qgs3DMapSett light->setWorldDirection( QVector3D( direction.x(), direction.y(), direction.z() ) ); lightEntity->addComponent( light ); - lightEntity->addComponent( lightTransform ); return lightEntity; } diff --git a/src/3d/lights/qgspointlightsettings.cpp b/src/3d/lights/qgspointlightsettings.cpp index 1f35154d5c87..344294fc394d 100644 --- a/src/3d/lights/qgspointlightsettings.cpp +++ b/src/3d/lights/qgspointlightsettings.cpp @@ -39,9 +39,7 @@ Qt3DCore::QEntity *QgsPointLightSettings::createEntity( const Qgs3DMapSettings & { Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(); Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform; - lightTransform->setTranslation( QVector3D( position().x(), - position().y(), - position().z() ) ); + lightTransform->setTranslation( position().toVector3D() ); Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight; light->setColor( color() ); diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index 046ab22000a4..8653d11e62e6 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -52,6 +52,7 @@ #include "qgschunkedentity.h" #include "qgschunknode.h" #include "qgseventtracing.h" +#include "qgsgeotransform.h" #include "qgsmaterial.h" #include "qgsmeshlayer.h" #include "qgsmeshlayer3drenderer.h" @@ -145,6 +146,8 @@ Qgs3DMapScene::Qgs3DMapScene( Qgs3DMapSettings &map, QgsAbstract3DEngine *engine connect( &map, &Qgs3DMapSettings::axisSettingsChanged, this, &Qgs3DMapScene::on3DAxisSettingsChanged ); + connect( &map, &Qgs3DMapSettings::originChanged, this, &Qgs3DMapScene::onOriginChanged ); + connect( QgsApplication::sourceCache(), &QgsSourceCache::remoteSourceFetched, this, [ = ]( const QString & url ) { const QList modelVectorLayers = mModelVectorLayers; @@ -487,6 +490,13 @@ void Qgs3DMapScene::createTerrainDeferred() connect( mTerrain, &QgsTerrainEntity::pendingJobsCountChanged, this, &Qgs3DMapScene::terrainPendingJobsCountChanged ); connect( mTerrain, &Qgs3DMapSceneEntity::newEntityCreated, this, [this]( Qt3DCore::QEntity * entity ) { + // let's make sure that any entity we're about to show has the right scene origin set + const QList transforms = entity->findChildren(); + for ( QgsGeoTransform *transform : transforms ) + { + transform->setOrigin( mMap.origin() ); + } + // enable clipping on the terrain if necessary handleClippingOnEntity( entity ); } ); @@ -745,6 +755,13 @@ void Qgs3DMapScene::removeLayerEntity( QgsMapLayer *layer ) void Qgs3DMapScene::finalizeNewEntity( Qt3DCore::QEntity *newEntity ) { + // let's make sure that any entity we're about to show has the right scene origin set + const QList transforms = newEntity->findChildren(); + for ( QgsGeoTransform *transform : transforms ) + { + transform->setOrigin( mMap.origin() ); + } + // set clip planes on the new entity if necessary handleClippingOnEntity( newEntity ); @@ -1178,6 +1195,17 @@ void Qgs3DMapScene::on3DAxisSettingsChanged() } } +void Qgs3DMapScene::onOriginChanged() +{ + const QList geoTransforms = findChildren(); + for ( QgsGeoTransform *transform : geoTransforms ) + { + transform->setOrigin( mMap.origin() ); + } + + mCameraController->setOrigin( mMap.origin() ); +} + void Qgs3DMapScene::handleClippingOnEntity( QEntity *entity ) const { if ( mClipPlanesEquations.isEmpty() ) // no clip plane equations, disable clipping diff --git a/src/3d/qgs3dmapscene.h b/src/3d/qgs3dmapscene.h index 3a880f59d87c..9a8ef9dafa84 100644 --- a/src/3d/qgs3dmapscene.h +++ b/src/3d/qgs3dmapscene.h @@ -308,6 +308,8 @@ class _3D_EXPORT Qgs3DMapScene : public QObject void on3DAxisSettingsChanged(); + void onOriginChanged(); + bool updateCameraNearFarPlanes(); private: diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 385adbb99390..c3aa2c719431 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -507,7 +507,11 @@ void Qgs3DMapSettings::setOrigin( const QgsVector3D &origin ) { QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( origin == mOrigin ) + return; + mOrigin = origin; + emit originChanged(); } QgsVector3D Qgs3DMapSettings::origin() const diff --git a/src/3d/qgs3dmapsettings.h b/src/3d/qgs3dmapsettings.h index 6aa0070cbd76..66fdcda4f531 100644 --- a/src/3d/qgs3dmapsettings.h +++ b/src/3d/qgs3dmapsettings.h @@ -920,6 +920,13 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec */ void showExtentIn2DViewChanged(); + /** + * Emitted when the world's origin point has been shifted + * \see setOrigin() + * \since QGIS 3.42 + */ + void originChanged(); + private: #ifdef SIP_RUN Qgs3DMapSettings &operator=( const Qgs3DMapSettings & ); diff --git a/src/3d/qgscameracontroller.cpp b/src/3d/qgscameracontroller.cpp index bebbae2c70c9..62f35355f4b9 100644 --- a/src/3d/qgscameracontroller.cpp +++ b/src/3d/qgscameracontroller.cpp @@ -35,6 +35,7 @@ QgsCameraController::QgsCameraController( Qgs3DMapScene *scene ) , mCameraBefore( new Qt3DRender::QCamera ) , mMouseHandler( new Qt3DInput::QMouseHandler ) , mKeyboardHandler( new Qt3DInput::QKeyboardHandler ) + , mOrigin( scene->mapSettings()->origin() ) { mMouseHandler->setSourceDevice( new Qt3DInput::QMouseDevice() ); connect( mMouseHandler, &Qt3DInput::QMouseHandler::positionChanged, @@ -1111,3 +1112,19 @@ void QgsCameraController::setMouseParameters( const MouseOperation &newOperation mCameraPose.updateCamera( mCameraBefore.get() ); } } + +void QgsCameraController::setOrigin( const QgsVector3D &origin ) +{ + QgsVector3D diff = origin - mOrigin; + mCameraPose.setCenterPoint( mCameraPose.centerPoint() - diff ); + + // update other members that depend on world coordinates + mCameraBefore->setPosition( ( QgsVector3D( mCameraBefore->position() ) - diff ).toVector3D() ); + mCameraBefore->setViewCenter( ( QgsVector3D( mCameraBefore->viewCenter() ) - diff ).toVector3D() ); + mDragPoint = ( QgsVector3D( mDragPoint ) - diff ).toVector3D(); + mRotationCenter = ( QgsVector3D( mRotationCenter ) - diff ).toVector3D(); + + mOrigin = origin; + + updateCameraFromPose(); +} diff --git a/src/3d/qgscameracontroller.h b/src/3d/qgscameracontroller.h index 2eacd96f3375..54772f992114 100644 --- a/src/3d/qgscameracontroller.h +++ b/src/3d/qgscameracontroller.h @@ -197,6 +197,13 @@ class _3D_EXPORT QgsCameraController : public QObject */ bool willHandleKeyEvent( QKeyEvent *event ); + /** + * Reacts to the shift of origin of the scene, updating camera pose and + * any other member variables so that the origin stays at the same position + * relative to other entities. + */ + void setOrigin( const QgsVector3D &origin ); + public slots: /** @@ -354,6 +361,9 @@ class _3D_EXPORT QgsCameraController : public QObject MouseOperation mCurrentOperation = MouseOperation::None; + // 3D world's origin in map coordinates + QgsVector3D mOrigin; + // To test the cameracontroller friend class TestQgs3DRendering; friend class TestQgs3DCameraController; diff --git a/src/3d/qgsgeotransform.cpp b/src/3d/qgsgeotransform.cpp new file mode 100644 index 000000000000..cc2ddfd6f281 --- /dev/null +++ b/src/3d/qgsgeotransform.cpp @@ -0,0 +1,23 @@ +#include "qgsgeotransform.h" + + +///@cond PRIVATE + +QgsGeoTransform::QgsGeoTransform( Qt3DCore::QNode *parent ) + : Qt3DCore::QTransform( parent ) +{ +} + +void QgsGeoTransform::setGeoTranslation( const QgsVector3D &translation ) +{ + mTranslation = translation; + setTranslation( ( mTranslation - mOrigin ).toVector3D() ); +} + +void QgsGeoTransform::setOrigin( const QgsVector3D &origin ) +{ + mOrigin = origin; + setTranslation( ( mTranslation - mOrigin ).toVector3D() ); +} + +///@endcond diff --git a/src/3d/qgsgeotransform.h b/src/3d/qgsgeotransform.h new file mode 100644 index 000000000000..f9ea431ddf59 --- /dev/null +++ b/src/3d/qgsgeotransform.h @@ -0,0 +1,44 @@ +#ifndef QGSGEOTRANSFORM_H +#define QGSGEOTRANSFORM_H + +///@cond PRIVATE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QGIS API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// + +#define SIP_NO_FILE + +#include + +#include "qgsvector3d.h" + + +/** + * Specialied kind of QTransform that: + * - stores translation as QgsVector3D, i.e. in double precision + * - reacts to map scene's origin shifts and updates the QTransform accordingly + */ +class QgsGeoTransform : public Qt3DCore::QTransform +{ + Q_OBJECT + public: + explicit QgsGeoTransform( Qt3DCore::QNode *parent = nullptr ); + + void setGeoTranslation( const QgsVector3D &translation ); + + void setOrigin( const QgsVector3D &origin ); + + private: + QgsVector3D mTranslation; + QgsVector3D mOrigin; +}; + +///@endcond + +#endif // QGSGEOTRANSFORM_H diff --git a/src/3d/qgsrubberband3d.cpp b/src/3d/qgsrubberband3d.cpp index eb4f8f9cc6ca..ff0e77e9f7a2 100644 --- a/src/3d/qgsrubberband3d.cpp +++ b/src/3d/qgsrubberband3d.cpp @@ -80,9 +80,6 @@ QgsRubberBand3D::QgsRubberBand3D( Qgs3DMapSettings &map, QgsWindow3DEngine *engi mLineEntity->addComponent( mLineMaterial ); - Qt3DCore::QTransform *lineTransform = new Qt3DCore::QTransform; - mLineEntity->addComponent( lineTransform ); - // Rubberband vertex markers mMarkerEntity = new Qt3DCore::QEntity( parentEntity ); mMarkerGeometry = new QgsBillboardGeometry(); @@ -102,9 +99,6 @@ QgsRubberBand3D::QgsRubberBand3D( Qgs3DMapSettings &map, QgsWindow3DEngine *engi mMarkerSymbol = QgsMarkerSymbol::createSimple( props ); updateMarkerMaterial(); mMarkerEntity->addComponent( mMarkerGeometryRenderer ); - - Qt3DCore::QTransform *markerTransform = new Qt3DCore::QTransform; - mMarkerEntity->addComponent( markerTransform ); } QgsRubberBand3D::~QgsRubberBand3D() diff --git a/src/3d/qgstiledscenechunkloader_p.cpp b/src/3d/qgstiledscenechunkloader_p.cpp index 8ad8739c6a75..aaa77b5b13dc 100644 --- a/src/3d/qgstiledscenechunkloader_p.cpp +++ b/src/3d/qgstiledscenechunkloader_p.cpp @@ -21,6 +21,7 @@ #include "qgsapplication.h" #include "qgscesiumutils.h" #include "qgscoordinatetransform.h" +#include "qgsgeotransform.h" #include "qgsgltf3dutils.h" #include "qgsquantizedmeshtiles.h" #include "qgsraycastingutils_p.h" @@ -63,7 +64,8 @@ QgsTiledSceneChunkLoader::QgsTiledSceneChunkLoader( QgsChunkNode *node, const Qg const QgsCoordinateTransform &boundsTransform = factory.mBoundsTransform; const QgsChunkNodeId tileId = node->tileId(); - const QFuture future = QtConcurrent::run( [this, tileId, zValueScale, zValueOffset, boundsTransform] + const QgsVector3D chunkOrigin = node->box3D().center(); + const QFuture future = QtConcurrent::run( [this, tileId, zValueScale, zValueOffset, boundsTransform, chunkOrigin] { const QgsTiledSceneTile tile = mIndex.getTile( tileId.uniqueId ); @@ -92,7 +94,7 @@ QgsTiledSceneChunkLoader::QgsTiledSceneChunkLoader( QgsChunkNode *node, const Qg QgsGltf3DUtils::EntityTransform entityTransform; entityTransform.tileTransform = ( tile.transform() ? *tile.transform() : QgsMatrix4x4() ); - entityTransform.sceneOriginTargetCrs = mFactory.mRenderContext.origin(); + entityTransform.sceneOriginTargetCrs = chunkOrigin; entityTransform.ecefToTargetCrs = &mFactory.mBoundsTransform; entityTransform.zValueScale = zValueScale; entityTransform.zValueOffset = zValueOffset; @@ -130,6 +132,10 @@ QgsTiledSceneChunkLoader::QgsTiledSceneChunkLoader( QgsChunkNode *node, const Qg QgsDebugError( "gltf load errors: " + errors.join( '\n' ) ); } + QgsGeoTransform *transform = new QgsGeoTransform; + transform->setGeoTranslation( chunkOrigin ); + mEntity->addComponent( transform ); + if ( mEntity ) mEntity->moveToThread( QgsApplication::instance()->thread() ); } ); diff --git a/src/3d/symbols/qgsline3dsymbol_p.cpp b/src/3d/symbols/qgsline3dsymbol_p.cpp index 7357eb9fcd27..fa6a8359014c 100644 --- a/src/3d/symbols/qgsline3dsymbol_p.cpp +++ b/src/3d/symbols/qgsline3dsymbol_p.cpp @@ -15,6 +15,7 @@ #include "qgsline3dsymbol_p.h" +#include "qgsgeotransform.h" #include "qgsline3dsymbol.h" #include "qgslinematerial_p.h" #include "qgslinevertexdata_p.h" @@ -227,9 +228,8 @@ void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, cons renderer->setGeometry( geometry ); // add transform (our geometry has coordinates relative to mChunkOrigin) - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( mChunkOrigin ); // make entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; @@ -395,9 +395,8 @@ void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Q renderer->setRestartIndexValue( 0 ); // add transform (our geometry has coordinates relative to mChunkOrigin) - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( mChunkOrigin ); // make entity entity->addComponent( renderer ); diff --git a/src/3d/symbols/qgspoint3dsymbol_p.cpp b/src/3d/symbols/qgspoint3dsymbol_p.cpp index 90298d6e6d6f..8700078424a3 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.cpp +++ b/src/3d/symbols/qgspoint3dsymbol_p.cpp @@ -19,7 +19,6 @@ #include #include #include -#include typedef Qt3DRender::QAttribute Qt3DQAttribute; typedef Qt3DRender::QBuffer Qt3DQBuffer; @@ -58,6 +57,7 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include "qgspoint3dsymbol.h" #include "qgsapplication.h" +#include "qgsgeotransform.h" #include "qgsvectorlayer.h" #include "qgs3dutils.h" #include "qgsbillboardgeometry.h" @@ -214,9 +214,8 @@ void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co QgsMaterial *mat = material( mSymbol.get(), materialContext ); // add transform (our geometry has coordinates relative to mChunkOrigin) - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( mChunkOrigin ); // build the entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; @@ -421,7 +420,7 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler static void addSceneEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsVector3D &chunkOrigin, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ); static void addMeshEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsVector3D &chunkOrigin, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ); - static Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol, const QgsVector3D &chunkOrigin, const QgsVector3D &contextOrigin ); + static QgsGeoTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol, const QgsVector3D &chunkOrigin ); //! temporary data we will pass to the tessellator struct PointData @@ -504,6 +503,7 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsVector3D &chunkOrigin, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) { + Q_UNUSED( context ); for ( const QVector3D &position : positions ) { const QString source = QgsApplication::sourceCache()->localFilePath( symbol->shapeProperty( QStringLiteral( "model" ) ).toString() ); @@ -518,7 +518,7 @@ void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DRenderContext &c modelLoader->setSource( url ); entity->addComponent( modelLoader ); - entity->addComponent( transform( position, symbol, chunkOrigin, context.origin() ) ); + entity->addComponent( transform( position, symbol, chunkOrigin ) ); entity->setParent( parent ); // cppcheck wrongly believes entity will leak @@ -553,7 +553,7 @@ void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DRenderContext &co entity->addComponent( mesh ); entity->addComponent( mat ); - entity->addComponent( transform( position, symbol, chunkOrigin, context.origin() ) ); + entity->addComponent( transform( position, symbol, chunkOrigin ) ); entity->setParent( parent ); // cppcheck wrongly believes entity will leak @@ -562,15 +562,12 @@ void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DRenderContext &co } } -Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position, const QgsPoint3DSymbol *symbol, const QgsVector3D &chunkOrigin, const QgsVector3D &contextOrigin ) +QgsGeoTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position, const QgsPoint3DSymbol *symbol, const QgsVector3D &chunkOrigin ) { // position is relative to chunkOrigin - QVector3D nodeTranslation = ( chunkOrigin - contextOrigin ).toVector3D(); - QMatrix4x4 translation; - translation.translate( nodeTranslation + position ); - - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - tr->setMatrix( translation * symbol->transform() ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setMatrix( symbol->transform() ); + tr->setGeoTranslation( chunkOrigin + position + tr->translation() ); return tr; } @@ -673,11 +670,8 @@ void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co } // Billboard Transform - Qt3DCore::QTransform *billboardTransform = new Qt3DCore::QTransform(); - QVector3D billboardHeightTranslation( 0, 0, mSymbol->billboardHeight() ); - // our geometry has coordinates relative to mChunkOrigin - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - billboardTransform->setTranslation( billboardHeightTranslation + nodeTranslation ); + QgsGeoTransform *billboardTransform = new QgsGeoTransform; + billboardTransform->setGeoTranslation( mChunkOrigin + QgsVector3D( 0, 0, mSymbol->billboardHeight() ) ); // Build the entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; diff --git a/src/3d/symbols/qgspointcloud3dsymbol_p.cpp b/src/3d/symbols/qgspointcloud3dsymbol_p.cpp index 80b9b4f8a0b7..f1ce9895e71c 100644 --- a/src/3d/symbols/qgspointcloud3dsymbol_p.cpp +++ b/src/3d/symbols/qgspointcloud3dsymbol_p.cpp @@ -25,6 +25,7 @@ #include "qgspointcloudblockrequest.h" #include "qgsfeedback.h" #include "qgsaabb.h" +#include "qgsgeotransform.h" #include #include @@ -307,9 +308,8 @@ void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const // Transform: chunks are using coordinates relative to chunk origin, with X,Y,Z axes being the same // as map coordinates, so we need to rotate and translate entities to get them into world coordinates - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( out.positionsOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( out.positionsOrigin ); // Material QgsMaterial *mat = new QgsMaterial; diff --git a/src/3d/symbols/qgspolygon3dsymbol_p.cpp b/src/3d/symbols/qgspolygon3dsymbol_p.cpp index 808b2eb04f7c..77e4633e00c0 100644 --- a/src/3d/symbols/qgspolygon3dsymbol_p.cpp +++ b/src/3d/symbols/qgspolygon3dsymbol_p.cpp @@ -23,7 +23,6 @@ #include "qgstessellator.h" #include "qgsphongtexturedmaterialsettings.h" -#include #include #include @@ -40,6 +39,7 @@ #include "qgsmultipolygon.h" #include "qgspolygon.h" #include "qgsmessagelog.h" +#include "qgsgeotransform.h" #include "qgslinevertexdata_p.h" #include "qgslinematerial_p.h" @@ -262,9 +262,8 @@ void QgsPolygon3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3D renderer->setRestartIndexValue( 0 ); // add transform (our geometry has coordinates relative to mChunkOrigin) - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( mChunkOrigin ); // make entity entity->addComponent( renderer ); @@ -300,9 +299,8 @@ void QgsPolygon3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs renderer->setGeometry( geometry ); // add transform (our geometry has coordinates relative to mChunkOrigin) - Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - QVector3D nodeTranslation = ( mChunkOrigin - context.origin() ).toVector3D(); - tr->setTranslation( nodeTranslation ); + QgsGeoTransform *tr = new QgsGeoTransform; + tr->setGeoTranslation( mChunkOrigin ); // make entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; diff --git a/src/3d/terrain/qgsdemterraintileloader_p.cpp b/src/3d/terrain/qgsdemterraintileloader_p.cpp index cda173a5d1f1..44385847cbd8 100644 --- a/src/3d/terrain/qgsdemterraintileloader_p.cpp +++ b/src/3d/terrain/qgsdemterraintileloader_p.cpp @@ -17,11 +17,11 @@ #include "moc_qgsdemterraintileloader_p.cpp" #include "qgs3dmapsettings.h" -#include "qgs3dutils.h" #include "qgschunknode.h" #include "qgsdemterraingenerator.h" #include "qgsdemterraintilegeometry_p.h" #include "qgseventtracing.h" +#include "qgsgeotransform.h" #include "qgsonlineterraingenerator.h" #include "qgsterrainentity.h" #include "qgsterraintexturegenerator_p.h" @@ -113,10 +113,8 @@ Qt3DCore::QEntity *QgsDemTerrainTileLoader::createEntity( Qt3DCore::QEntity *par createTextureComponent( entity, map->isTerrainShadingEnabled(), map->terrainShadingMaterial(), !map->layers().empty() ); // create transform - - Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(); - QgsVector3D translation = Qgs3DUtils::mapToWorldCoordinates( QgsVector3D( extent.xMinimum(), extent.yMinimum(), 0 ), map->origin() ); - transform->setTranslation( translation.toVector3D() ); + QgsGeoTransform *transform = new QgsGeoTransform; + transform->setGeoTranslation( QgsVector3D( extent.xMinimum(), extent.yMinimum(), 0 ) ); entity->addComponent( transform ); mNode->setExactBox3D( QgsBox3D( extent.xMinimum(), extent.yMinimum(), zMin * map->terrainVerticalScale(), diff --git a/src/3d/terrain/qgsflatterraingenerator.cpp b/src/3d/terrain/qgsflatterraingenerator.cpp index a0b04009f9d7..6ae1cff5ec3b 100644 --- a/src/3d/terrain/qgsflatterraingenerator.cpp +++ b/src/3d/terrain/qgsflatterraingenerator.cpp @@ -17,13 +17,13 @@ #include "moc_qgsflatterraingenerator.cpp" #include -#include #include "qgs3dmapsettings.h" #include "qgschunknode.h" +#include "qgsgeotransform.h" #include "qgsterrainentity.h" #include "qgsterraintileentity_p.h" -#include "qgs3dutils.h" + /// @cond PRIVATE @@ -58,8 +58,8 @@ Qt3DCore::QEntity *FlatTerrainChunkLoader::createEntity( Qt3DCore::QEntity *pare // create transform - Qt3DCore::QTransform *transform = nullptr; - transform = new Qt3DCore::QTransform(); + QgsGeoTransform *transform = nullptr; + transform = new QgsGeoTransform(); entity->addComponent( transform ); // set up transform according to the extent covered by the quad geometry @@ -74,12 +74,12 @@ Qt3DCore::QEntity *FlatTerrainChunkLoader::createEntity( Qt3DCore::QEntity *pare box3D.zMaximum() ); const double xSide = commonExtent.width(); const double ySide = commonExtent.height(); - const double xMin = commonExtent.xMinimum() - map->origin().x(); - const double yMin = commonExtent.yMinimum() - map->origin().y(); + const double xMin = commonExtent.xMinimum(); + const double yMin = commonExtent.yMinimum(); transform->setRotation( QQuaternion::fromAxisAndAngle( QVector3D( 1, 0, 0 ), 90 ) ); // QPlaneGeometry uses XZ as the base plane transform->setScale3D( QVector3D( static_cast( xSide ), 1, static_cast( ySide ) ) ); - transform->setTranslation( QVector3D( static_cast( xMin + xSide / 2 ), static_cast( yMin + ySide / 2 ), 0 ) ); + transform->setGeoTranslation( QgsVector3D( xMin + xSide / 2, yMin + ySide / 2, 0 ) ); createTextureComponent( entity, map->isTerrainShadingEnabled(), map->terrainShadingMaterial(), !map->layers().empty() );