当前位置:网站首页>QT quick 3D learning: mouse picking up objects
QT quick 3D learning: mouse picking up objects
2022-06-12 22:15:00 【Gongjianbo】
( Be careful , Open source Qt Quick 3D It is not used by dogs GPL agreement )
Qt Creator There is one of them. picking An example of , For demonstration View3D Picking up objects in :

Based on the examples , I added a simple drag effect , As shown in the figure :

In the use of OpenGL When picking is realized , We can use the ray method .Qt Quick 3D The pick operation is encapsulated in , adopt View3D Of pick function , You can get it. View3D The object closest to the screen at a certain point in the viewport Model.
PickResult pick(float x, float y)This function returns a PickResult object , Through its objectHit Property to determine whether an object has been picked up .
View3D {
MouseArea {
id: mouse_area
anchors.fill: parent
onPressed: {
// Get point at View Screen coordinates on
pick_screen.text = "(" + mouse.x + ", " + mouse.y + ")"
//pick Take the nearest intersection with the ray path at this point Model Information about , return PickResult object
var result = control.pick(mouse.x, mouse.y)
// Judge objectHit Whether it works , You can only know if you have picked up an object
if (result.objectHit) {
} else {
}
}
}
}
stay Qt5.15 in , Back to PickResult Types have only a few simple properties :
// Pick the distance between the origin and the object , Pick with viewport coordinates, and the origin is the observation point Camera The location of
distance : float
// Pick the selected Model object
objectHit : Model
//pick The position of the point in the scene ,( It may be equivalent to the focal coordinates of the ray and the object surface )
//This property holds the scene position of the hit.
scenePosition : vector3d
//pick Dot UV Location
//This property holds the UV position of the hit.
uvPosition : vector2dstay Qt6.3 in ,View3D Added pickAll Function to pick up all objects at that point , meanwhile PickResult Type also adds some attributes :
// The normal of the selected face in local space
//This property holds the normal of the face that was hit in local coordinate space.
normal : vector3d
//This property holds the scene position of the hit in local coordinate space.
position : vector3d
//This property holds the normal of the face that was hit in scene coordinate space.
sceneNormal : vector3dAfter picking up the object , You can do this Model The node has been operated . this paper Demo I implemented a simple drag operation in , The main process is :
1.pick Save when selected Model Location and pick Viewport screen coordinate difference of position ( Can pass View3D Of mapFrom3DScene Function to convert scene coordinates to viewport coordinates , To use this function, you need to give View3D Set up camera )
2. While the mouse is moving , Restore objects by difference Model Relative position of , Use View3D Of mapTo3DScene Function conversion to get Model New scene coordinates .
( But this logic does not consider perspective projection , Move the scene coordinates xy, Viewport coordinates xy It doesn't change proportionally )
Main code
Github(PickModel.qml): https://github.com/gongjianbo/HelloQtQuick3D
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick3D 1.15
import QtQuick3D.Helpers 1.15
View3D {
id: control
// background
environment: SceneEnvironment {
clearColor: "darkGreen"
backgroundMode: SceneEnvironment.Color
}
// Observation camera
//View3D Of mapTo/mapFrom Coordinate conversion function needs to be set first camera attribute
camera: perspective_camera
PerspectiveCamera {
id: perspective_camera
z: 300
}
// light
DirectionalLight {
eulerRotation.y: 45
}
// Cube
Model {
id: cube_node
objectName: "Cube"
source: "#Cube"
// Can make pick
pickable: true
materials: DefaultMaterial {
diffuseColor: mouse_area.pickNode == cube_node ? "cyan" : "yellow"
}
// The cube turns
SequentialAnimation on eulerRotation {
running: true
loops: Animation.Infinite
PropertyAnimation {
duration: 10000
from: Qt.vector3d(0, 0, 0)
to: Qt.vector3d(360, 360, 360)
}
}
}
// cone
Model {
id: cone_node
objectName: "Cone"
source: "#Cone"
pickable: true
x: 100
z: 50
materials: DefaultMaterial {
diffuseColor: mouse_area.pickNode == cone_node ? "cyan" : "orange"
}
}
// sphere
Model {
id: sphere_node
objectName: "Sphere"
source: "#Sphere"
pickable: true
x: -100
z: -50
materials: DefaultMaterial {
diffuseColor: mouse_area.pickNode == sphere_node ? "cyan" : "purple"
}
}
// Show information about picked objects
Row {
x: 20
y: 20
spacing: 10
Column {
Label {
color: "white"
text: "Pick Node:"
}
Label {
color: "white"
text: "Screen Position:"
}
Label {
color: "white"
text: "Distance:"
}
Label {
color: "white"
text: "World Position:"
}
}
Column {
Label {
id: pick_name
color: "white"
}
Label {
id: pick_screen
color: "white"
}
Label {
id: pick_distance
color: "white"
}
Label {
id: pick_word
color: "white"
}
}
}
MouseArea {
id: mouse_area
anchors.fill: parent
hoverEnabled: false
property var pickNode: null
// Mouse and objects xy The migration
property real xOffset: 0
property real yOffset: 0
property real zOffset: 0
onPressed: {
// Get point at View Screen coordinates on
pick_screen.text = "(" + mouse.x + ", " + mouse.y + ")"
//pick Take the nearest intersection with the ray path at this point Model Information about , return PickResult object
// Because the module has been iterating , The new version can be downloaded from PickResult Object to get more information
//Qt6 It is also provided pickAll Get all that intersect the ray Model Information
var result = control.pick(mouse.x, mouse.y)
// Currently only updated when clicked pick Information about objects
if (result.objectHit) {
pickNode = result.objectHit
pick_name.text = pickNode.objectName
pick_distance.text = result.distance.toFixed(2)
pick_word.text = "("
+ result.scenePosition.x.toFixed(2) + ", "
+ result.scenePosition.y.toFixed(2) + ", "
+ result.scenePosition.z.toFixed(2) + ")"
//console.log('in',pick_screen.text)
//console.log(result.scenePosition)
var map_from = control.mapFrom3DScene(pickNode.scenePosition)
//var map_to = control.mapTo3DScene(Qt.vector3d(mouse.x,mouse.y,map_from.z))
//console.log(map_from)
//console.log(map_to)
xOffset = map_from.x - mouse.x
yOffset = map_from.y - mouse.y
zOffset = map_from.z
} else {
pickNode = null
pick_name.text = "None"
pick_distance.text = " "
pick_word.text = " "
}
}
onPositionChanged: {
if(!mouse_area.containsMouse || !pickNode){
return
}
var pos_temp = Qt.vector3d(mouse.x + xOffset, mouse.y + yOffset, zOffset);
var map_to = control.mapTo3DScene(pos_temp)
pickNode.x = map_to.x
pickNode.y = map_to.y
}
}
}
Reference resources
边栏推荐
- Prefix sum and difference
- #yyds干货盘点# 解决剑指offer:字符流中第一个不重复的字符
- [QNX hypervisor 2.2 user manual] 4.2 supported build environments
- NoSQL - redis configuration and optimization (II) high availability, persistence and performance management
- 设计消息队列存储消息数据的 MySQL 表格
- [Jianzhi offer simple] Jianzhi offer 06 Print linked list from end to end
- SQL tuning guide notes 13:gathering optimizer statistics
- How to abstract a problem into a 0-1 knapsack problem in dynamic programming
- 【QNX Hypervisor 2.2 用户手册】4.4 构建Host
- Leetcode: the maximum number of building change requests that can be reached (if you see the amount of data, you should be mindless)
猜你喜欢

MySQL architecture and basic management (II)

Prefix sum and difference

Ansible playbook和Ansible Roles(三)

leetcodeSQL:574. Elected

SQL tuning guide notes 9:joins

How to write a vscode plug-in by yourself to realize plug-in freedom!

JVisualVM初步使用

SQL tuning guide notes 14:managing extended statistics

Oracle SQL Developer的代码输入框中推荐使用的中文字体

Yyds dry inventory insider news: Series high-frequency interview questions, worth a visit!
随机推荐
Implementation of master-slave replication and master-master replication for MySQL and MariaDB databases
OceanBase 社区版 OCP 功能解读
Oracle SQL Developer的代码输入框中推荐使用的中文字体
(downloadable) Research Report on the development and utilization of government data (2021), a glimpse of the development of Government Office
MySQL architecture and basic management (II)
Yyds dry goods inventory solution Huawei machine test: weighing weight
Ansible playbook和Ansible Roles(三)
What is the difference between a user thread and a daemon thread?
[Jianzhi offer] Jianzhi offer 05 Replace spaces
同花顺能开户吗,在同花顺开户安全么,证券开户怎么开户流程
建立高可用的数据库
在同花顺开户证券安全吗,证券开户怎么开户流程
Ansible playbook and variable (II)
孙老师版本JDBC(2022年6月12日21:34:25)
talent showing itself! Oceanbase was selected into the 2021 "sci tech innovation China" open source innovation list
You can move forward or backward. This function in idea is amazing!
Qt Quick 3D学习:使用鼠标键盘控制节点位置和方向
leetcodeSQL:574. Elected
The 2023 campus recruitment officially opened! Oceanbase would like to make an interview with you this spring
MySQL体系结构及基础管理(二)