[ui][3D] add EnvironmentMapEntity to display equirectangular images

Load EXR files in the 3D viewport as environment maps mapped on a sphere "attached"  to the camera.
* improve exr loading strategy by considering depthmaps and env maps
* update to DepthMapEntity 2.1 (required to get the loading status)
This commit is contained in:
Yann Lanthony 2019-12-12 19:10:08 +01:00
parent fbfb7d6143
commit 63ffb20819
No known key found for this signature in database
GPG key ID: 519FAE6DF7A70642
5 changed files with 82 additions and 9 deletions

View file

@ -1,4 +1,4 @@
import DepthMapEntity 2.0 import DepthMapEntity 2.1
/** /**
* Support for Depth Map files (EXR) in Qt3d. * Support for Depth Map files (EXR) in Qt3d.

View file

@ -0,0 +1,48 @@
import QtQuick 2.9
import Qt3D.Core 2.1
import Qt3D.Render 2.1
import Qt3D.Extras 2.10
/**
* EnvironmentMap maps an equirectangular image on a Sphere.
* The 'position' property can be used to virually attach it to a camera
* and get the impression of an environment at an infinite distance.
*/
Entity {
id: root
/// Source of the equirectangular image
property url source
/// Radius of the sphere
property alias radius: sphereMesh.radius
/// Number of slices of the sphere
property alias slices: sphereMesh.slices
/// Number of rings of the sphere
property alias rings: sphereMesh.rings
/// Position of the sphere
property alias position: transform.translation
components: [
SphereMesh {
id: sphereMesh
radius: 1000
slices: 50
rings: 50
},
Transform {
id: transform
translation: root.position
},
DiffuseMapMaterial {
ambient: "#FFF"
shininess: 0
specular: "#000"
diffuse: TextureLoader {
magnificationFilter: Texture.Linear
mirrored: true
source: root.source
}
}
]
}

View file

@ -16,6 +16,9 @@ Entity {
property bool pickingEnabled: false property bool pickingEnabled: false
readonly property alias count: instantiator.count // number of instantiated media delegates readonly property alias count: instantiator.count // number of instantiated media delegates
/// Camera to consider for positionning
property Camera camera: null
/// True while at least one media is being loaded /// True while at least one media is being loaded
readonly property bool loading: { readonly property bool loading: {
for(var i=0; i<m.mediaModel.count; ++i) { for(var i=0; i<m.mediaModel.count; ++i) {
@ -173,6 +176,7 @@ Entity {
// source based on currentSource + "requested" property // source based on currentSource + "requested" property
readonly property string finalSource: model.requested ? currentSource : "" readonly property string finalSource: model.requested ? currentSource : ""
camera: root.camera
renderMode: root.renderMode renderMode: root.renderMode
enabled: visible enabled: visible

View file

@ -1,7 +1,7 @@
import QtQuick 2.9 import QtQuick 2.9
import Qt3D.Core 2.1 import Qt3D.Core 2.1
import Qt3D.Render 2.1 import Qt3D.Render 2.1
import Qt3D.Extras 2.1 import Qt3D.Extras 2.10
import QtQuick.Scene3D 2.0 import QtQuick.Scene3D 2.0
import "Materials" import "Materials"
import Utils 1.0 import Utils 1.0
@ -20,6 +20,9 @@ import Utils 1.0
property var object: null property var object: null
property int renderMode property int renderMode
/// Scene's current camera
property Camera camera: null
property bool cached: false property bool cached: false
onSourceChanged: { onSourceChanged: {
@ -44,7 +47,7 @@ import Utils 1.0
switch(Filepath.extension(source)) { switch(Filepath.extension(source)) {
case ".abc": if(Viewer3DSettings.supportAlembic) component = abcLoaderEntityComponent; break; case ".abc": if(Viewer3DSettings.supportAlembic) component = abcLoaderEntityComponent; break;
case ".exr": if(Viewer3DSettings.supportDepthMap) component = depthMapLoaderComponent; break; case ".exr": if(Viewer3DSettings.supportDepthMap) component = exrLoaderComponent; break;
case ".obj": case ".obj":
default: component = sceneLoaderEntityComponent; break; default: component = sceneLoaderEntityComponent; break;
} }
@ -103,14 +106,31 @@ import Utils 1.0
} }
Component { Component {
id: depthMapLoaderComponent id: exrLoaderComponent
MediaLoaderEntity { MediaLoaderEntity {
id: depthMapLoaderEntity id: exrLoaderEntity
Component.onCompleted: { Component.onCompleted: {
var obj = Viewer3DSettings.depthMapLoaderComp.createObject(depthMapLoaderEntity, { // EXR loading strategy:
'source': source // - [1] as a depth map
}); var obj = Viewer3DSettings.depthMapLoaderComp.createObject(
faceCount = Scene3DHelper.faceCount(obj); exrLoaderEntity, {
'source': source
});
if(obj.status === SceneLoader.Ready)
{
faceCount = Scene3DHelper.faceCount(obj);
root.status = SceneLoader.Ready;
return;
}
// - [2] as an environment map
obj.destroy()
obj = Qt.createComponent("EnvironmentMapEntity.qml").createObject(
exrLoaderEntity, {
'source': source,
'position': Qt.binding(function() { return root.camera.position })
});
root.status = SceneLoader.Ready; root.status = SceneLoader.Ready;
} }
} }

View file

@ -221,6 +221,7 @@ FocusScope {
// Picking to set focus point (camera view center) // Picking to set focus point (camera view center)
// Only activate it when a double click may happen or when the 'Control' key is pressed // Only activate it when a double click may happen or when the 'Control' key is pressed
pickingEnabled: cameraController.pickingActive || doubleClickTimer.running pickingEnabled: cameraController.pickingActive || doubleClickTimer.running
camera: cameraSelector.camera
components: [ components: [
Transform { Transform {