qtdoc/examples/demos/documentviewer/plugins/q3dviewer/q3dviewer.qml

104 lines
2.9 KiB
QML

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick3D
import QtQuick3D.AssetUtils
import QtQuick3D.Helpers
import QtQuick.Controls
Rectangle {
id: window
anchors.fill: parent
visible: true
color: "#848895"
border.color: "black"
property url fileName
property bool isMesh
property var myLoader
onFileNameChanged: {
if (myLoader) {
myLoader.destroy()
myLoader = undefined
}
if (isMesh) {
displayModel.source = fileName
} else {
displayModel.source = ""
myLoader = dynamicLoader.createObject(displayModel)
}
}
View3D {
anchors.fill: parent
camera: camera
DirectionalLight {
ambientColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
brightness: 1.0
eulerRotation.x: -25
}
Model {
id: displayModel
scale: Qt.vector3d(1, 1, 1)
materials: [
PrincipledMaterial {
baseColor: "#41cd52"
metalness: 0.0
roughness: 0.1
opacity: 1.0
}
]
function handleBoundsChanged(bounds) {
let scaleF = 1/bounds.maximum.plus(bounds.minimum).length()
scale = Qt.vector3d(scaleF, scaleF, scaleF)
position = bounds.maximum.plus(bounds.minimum).times(-0.5 * scaleF)
camera.z = bounds.maximum.minus(bounds.minimum).length() * scaleF / Math.tan(camera.fieldOfView / 180 * Math.PI)
}
Component {
id: dynamicLoader
RuntimeLoader {
id: loader
source: window.fileName
onBoundsChanged: { displayModel.handleBoundsChanged(loader.bounds) }
}
}
onBoundsChanged: {
if (window.isMesh) {
displayModel.handleBoundsChanged(displayModel.bounds)
}
}
}
Node {
id: cameraNode
property real dragScale: - (camera.z - 0.5) * Math.tan(camera.fieldOfView / 180 * Math.PI)
PerspectiveCamera {
id: camera
clipNear: 0.0001
clipFar: 1000
position: Qt.vector3d(0.0, 0.0, 10)
fieldOfView: 20
}
}
}
WheelHandler {
target: null
onWheel: event => camera.z -= camera.z * event.angleDelta.y * 0.0005;
}
DragHandler {
id: orbitDrag
target: null
xAxis.onActiveValueChanged: delta => cameraNode.eulerRotation.y += delta * cameraNode.dragScale
yAxis.onActiveValueChanged: delta => cameraNode.eulerRotation.x += delta * cameraNode.dragScale
}
}