Qt Quick 3D - Custom Geometry Example
// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick3D import QtQuick3D.Helpers import CustomGeometryExample ApplicationWindow { id: window width: 1280 height: 720 visible: true title: "Custom Geometry Example" property bool isLandscape: width > height View3D { id: v3d anchors.left: window.isLandscape ? controlsPane.right : parent.left anchors.top: window.isLandscape ? parent.top : controlsPane.bottom anchors.right: parent.right anchors.bottom: parent.bottom camera: camera environment: SceneEnvironment { id: env backgroundMode: SceneEnvironment.Color clearColor: "#002b36" } Node { id: originNode PerspectiveCamera { id: cameraNode z: 600 } } DirectionalLight { id: directionalLight color: Qt.rgba(0.4, 0.2, 0.6, 1.0) ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0) } PointLight { id: pointLight position: Qt.vector3d(0, 0, 100) color: Qt.rgba(0.1, 1.0, 0.1, 1.0) ambientColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) } Model { id: gridModel visible: false scale: Qt.vector3d(100, 100, 100) geometry: GridGeometry { id: grid horizontalLines: 20 verticalLines: 20 } materials: [ DefaultMaterial { lineWidth: sliderLineWidth.value } ] } Model { id: triangleModel visible: false scale: Qt.vector3d(100, 100, 100) geometry: ExampleTriangleGeometry { normals: cbNorm.checked normalXY: sliderNorm.value uv: cbUV.checked uvAdjust: sliderUV.value } materials: [ DefaultMaterial { Texture { id: baseColorMap source: "qt_logo_rect.png" } cullMode: DefaultMaterial.NoCulling diffuseMap: cbTexture.checked ? baseColorMap : null specularAmount: 0.5 } ] } Model { id: pointModel visible: false scale: Qt.vector3d(100, 100, 100) geometry: ExamplePointGeometry { } materials: [ DefaultMaterial { lighting: DefaultMaterial.NoLighting cullMode: DefaultMaterial.NoCulling diffuseColor: "yellow" pointSize: sliderPointSize.value } ] } Model { id: torusModel visible: false geometry: TorusMesh { radius: radiusSlider.value tubeRadius: tubeRadiusSlider.value segments: segmentsSlider.value rings: ringsSlider.value } materials: [ PrincipledMaterial { id: torusMaterial baseColor: "#dc322f" metalness: 0.0 roughness: 0.1 } ] } OrbitCameraController { origin: originNode camera: cameraNode } } Pane { id: controlsPane width: window.isLandscape ? implicitWidth : window.width height: window.isLandscape ? window.height : implicitHeight ColumnLayout { GroupBox { title: "Mode" ButtonGroup { id: modeGroup buttons: [ radioGridGeom, radioCustGeom, radioPointGeom, radioQMLGeom ] } ColumnLayout { RadioButton { id: radioGridGeom text: "GridGeometry" checked: true } RadioButton { id: radioCustGeom text: "Custom geometry from application (triangle)" checked: false } RadioButton { id: radioPointGeom text: "Custom geometry from application (points)" checked: false } RadioButton { id: radioQMLGeom text: "Custom geometry from QML" checked: false } } } Pane { id: gridSettings visible: false ColumnLayout { Button { text: "+ Y Cells" onClicked: grid.horizontalLines += 1 Layout.alignment: Qt.AlignHCenter } RowLayout { Layout.alignment: Qt.AlignHCenter Button { text: "- X Cells" onClicked: grid.verticalLines -= 1 } Button { text: "+ X Cells" onClicked: grid.verticalLines += 1 } } Button { text: "- Y Cells" onClicked: grid.horizontalLines -= 1 Layout.alignment: Qt.AlignHCenter } Label { text: "Line width (if supported)" } Slider { Layout.fillWidth: true id: sliderLineWidth from: 1.0 to: 10.0 stepSize: 0.5 value: 1.0 } } } Pane { id: triangleSettings visible: false ColumnLayout { CheckBox { id: cbNorm text: "provide normals in geometry" checked: false } RowLayout { enabled: cbNorm.checked Label { Layout.fillWidth: true text: "Normal adjust: " } Slider { id: sliderNorm from: 0.0 to: 1.0 stepSize: 0.01 value: 0.0 } } CheckBox { id: cbTexture text: "enable base color map" checked: false } CheckBox { id: cbUV text: "provide UV in geometry" checked: false } RowLayout { enabled: cbUV.checked Label { Layout.fillWidth: true text: "UV adjust:" } Slider { id: sliderUV from: 0.0 to: 1.0 stepSize: 0.01 value: 0.0 } } } } Pane { id: pointSettings visible: false RowLayout { ColumnLayout { RowLayout { Label { text: "Point size (if supported)" } Slider { id: sliderPointSize from: 1.0 to: 16.0 stepSize: 1.0 value: 1.0 } } } } } Pane { id: torusSettings visible: false ColumnLayout { Label { text: "Radius: (" + radiusSlider.value + ")" } Slider { id: radiusSlider from: 1.0 to: 1000.0 stepSize: 1.0 value: 200 } Label { text: "Tube Radius: (" + tubeRadiusSlider.value + ")" } Slider { id: tubeRadiusSlider from: 1.0 to: 500.0 stepSize: 1.0 value: 50 } Label { text: "Rings: (" + ringsSlider.value + ")" } Slider { id: ringsSlider from: 3 to: 35 stepSize: 1.0 value: 20 } Label { text: "Segments: (" + segmentsSlider.value + ")" } Slider { id: segmentsSlider from: 3 to: 35 stepSize: 1.0 value: 20 } CheckBox { id: wireFrameCheckbox text: "Wireframe Mode" checked: false onCheckedChanged: { env.debugSettings.wireframeEnabled = checked torusMaterial.cullMode = checked ? Material.NoCulling : Material.BackFaceCulling } } } } } states: [ State { name: "gridMode" when: radioGridGeom.checked PropertyChanges { gridModel.visible: true gridSettings.visible: true env.debugSettings.wireframeEnabled: false originNode.position: Qt.vector3d(0, 0, 0) originNode.rotation: Qt.quaternion(1, 0, 0, 0) cameraNode.z: 600 } }, State { name: "triangleMode" when: radioCustGeom.checked PropertyChanges { triangleModel.visible: true triangleSettings.visible: true env.debugSettings.wireframeEnabled: false originNode.position: Qt.vector3d(0, 0, 0) originNode.rotation: Qt.quaternion(1, 0, 0, 0) cameraNode.z: 600 } }, State { name: "pointMode" when: radioPointGeom.checked PropertyChanges { pointModel.visible: true pointSettings.visible: true env.debugSettings.wireframeEnabled: false originNode.position: Qt.vector3d(0, 0, 0) originNode.rotation: Qt.quaternion(1, 0, 0, 0) cameraNode.z: 600 } }, State { name: "qmlMode" when: radioQMLGeom.checked PropertyChanges { torusModel.visible: true torusSettings.visible: true directionalLight.eulerRotation: Qt.vector3d(-40, 0, 0) directionalLight.color: "white" pointLight.color: "white" pointLight.position: Qt.vector3d(0, 0, 0) originNode.position: Qt.vector3d(0, 0, 0) originNode.eulerRotation: Qt.vector3d(-40, 0, 0) cameraNode.z: 600 } } ] } }