-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScene3D.qml
More file actions
125 lines (105 loc) · 4.93 KB
/
Scene3D.qml
File metadata and controls
125 lines (105 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import QtQuick
import QtQuick3D
import QtQuick3D.Helpers
import "resources"
View3D {
id: root
// ── Propiedades que C++ escribe con setProperty() ──────────────
// Los valores que llegan desde el MPU ya son grados (ej: -2.14, 1.85)
property real carPitch: 0 // cabeceo → eje X del mundo
property real carRoll: 0 // balanceo → eje Z del mundo
property real carYaw: 0 // giro → eje Y del mundo
// ── Función que construye el quaternion final ──────────────────
// Un quaternion representa una rotación como:
// q = (cos(ángulo/2), sin(ángulo/2)*eje_x, sin(ángulo/2)*eje_y, sin(ángulo/2)*eje_z)
// Qt.quaternion(w, x, y, z)
//
// IMPORTANTE: los ángulos vienen en GRADOS desde el MPU,
// hay que convertirlos a RADIANES para Math.sin/cos
// Dividimos el ángulo por 2 porque el quaternion trabaja con la mitad del ángulo
function buildRotation(pitch, roll, yaw) {
// Convertimos cada ángulo a radianes y lo dividimos por 2
var halfP = pitch * Math.PI / 360.0 // pitch/2 en radianes
var halfR = -roll * Math.PI / 360.0 // roll/2 en radianes
var halfY = yaw * Math.PI / 360.0 // yaw/2 en radianes
// Quaternion para Pitch (rotación alrededor del eje X)
// eje X = (1, 0, 0) → Qt.quaternion(w, x*sin, y*sin, z*sin)
var qPitch = Qt.quaternion(
Math.cos(halfP), // w
Math.sin(halfP), // x ← eje X activo
0, // y
0 // z
)
// Quaternion para Yaw (rotación alrededor del eje Y)
// eje Y = (0, 1, 0)
var qYaw = Qt.quaternion(
Math.cos(halfY), // w
0, // x
Math.sin(halfY), // y ← eje Y activo
0 // z
)
// Quaternion para Roll (rotación alrededor del eje Z)
// eje Z = (0, 0, 1)
var qRoll = Qt.quaternion(
Math.cos(halfR), // w
0, // x
0, // y
Math.sin(halfR) // z ← eje Z activo
)
// Multiplicamos en orden aeronáutico: Yaw → Pitch → Roll
// La multiplicación de quaternions combina las rotaciones
// SIN que una afecte los ejes de la otra (no hay Gimbal Lock)
return qYaw.times(qPitch).times(qRoll)
}
// ── Entorno ────────────────────────────────────────────────────
environment: SceneEnvironment {
clearColor: "#b0c4de"
backgroundMode: SceneEnvironment.Color
}
// ── Cámara ─────────────────────────────────────────────────────
PerspectiveCamera {
id: camera
z: 300
y: 100
eulerRotation.x: -15
}
// ── Control de órbita con el mouse ─────────────────────────────
OrbitCameraController {
anchors.fill: parent
origin: carModel
camera: camera
}
// ── Iluminación ────────────────────────────────────────────────
DirectionalLight {
eulerRotation.x: -45
eulerRotation.y: 45
ambientColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
}
// ── Suelo (Plano horizontal) ───────────────────────────────────
Model {
id: groundPlane
source: "#Rectangle"
// Posición vertical: Ajusta este valor (ej. -50 o -100) si las
// ruedas del auto quedan "enterradas" en el piso.
y: 0
// Escala: Como el auto está escalado a 1500, el suelo debe ser masivo
scale: Qt.vector3d(5000, 5000, 1)
// Rotación: Acuesta el rectángulo para que actúe como piso
eulerRotation.x: -90
materials: PrincipledMaterial {
baseColor: "#FFFFFF" // Un color gris tipo asfalto
roughness: 0.9 // Opaco, para que no parezca un espejo
metalness: 0.0
}
}
// ── Modelo 3D del robot ────────────────────────────────────────
AutoMicroSimplify {
id: carModel
position: Qt.vector3d(0, 0, 0)
scale: Qt.vector3d(1500, 1500, 1500)
// ✅ Aquí es donde se aplica el quaternion al modelo
// Cada vez que carPitch, carRoll o carYaw cambian (porque C++
// llama a setProperty), Qt recalcula esta expresión automáticamente
rotation: root.buildRotation(root.carPitch, root.carRoll, root.carYaw)
}
}