Qt Quick 3D Physik – Beispiel für zusammengesetzte Formen
Veranschaulicht die Verwendung komplexer Kollisionsformen.

Dieses Beispiel zeigt, wie man mehr als eine Kollisionsform verwendet, um komplexe Objekte für die Kollisionserkennung zu erstellen. Die Szene besteht aus einer grünen statischen Ebene und einer Reihe von miteinander verbundenen Verbindungsstücken. Zu Beginn ist die Simulation deaktiviert. Nach einiger Zeit oder wenn der Benutzer die Leertaste drückt, startet die Simulation. Es startet eine Animation, bei der sich die Gliederstangen ganz links und ganz rechts horizontal hin und her bewegen.
Einrichtung
Wie üblich müssen wir unsere „ PhysicsWorld “ hinzufügen:
PhysicsWorld {
id: physicsWorld
enableCCD: true
maximumTimestep: 20
scene: viewport.scene
}Wir nehmen die übliche Einrichtung vor, bei der wir eine Umgebung, eine Kamera und Lichtquellen haben:
environment: SceneEnvironment {
antialiasingMode: SceneEnvironment.MSAA
backgroundMode: SceneEnvironment.Color
clearColor: "lightblue"
}
focus: true
PerspectiveCamera {
id: camera
position: Qt.vector3d(0, 900, 1500)
eulerRotation: Qt.vector3d(-10, 0, 0)
clipFar: 15500
clipNear: 1
}
DirectionalLight {
eulerRotation.x: -45
eulerRotation.y: 45
castsShadow: true
brightness: 1.5
shadowMapQuality: Light.ShadowMapQualityHigh
}Physikalische Objekte
Wir haben unsere übliche statische Ebene:
StaticRigidBody {
position: Qt.vector3d(0, -100, 0)
eulerRotation: Qt.vector3d(-90, 0, 0)
collisionShapes: PlaneShape {}
Model {
source: "#Rectangle"
scale: Qt.vector3d(500, 500, 1)
materials: PrincipledMaterial {
baseColor: "green"
}
castsShadows: false
receivesShadows: true
}
}Anschließend erstellen wir Instanzen unserer Verbindungen.
MeshLink {
id: leftLink
isKinematic: true
property vector3d startPos: Qt.vector3d(-6 * viewport.ringDistance,
viewport.ringY,
0)
property vector3d startRot: Qt.vector3d(90, 0, 0)
kinematicPosition: startPos
position: startPos
kinematicEulerRotation: startRot
eulerRotation: startRot
color: "red"
}
CapsuleLink {
position: Qt.vector3d(-5 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
MeshLink {
position: Qt.vector3d(-4 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
MeshLink {
position: Qt.vector3d(-3 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
}
MeshLink {
position: Qt.vector3d(-2 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
MeshLink {
position: Qt.vector3d(-1 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
}
CapsuleLink {
position: Qt.vector3d(0, viewport.ringY, 0)
}
MeshLink {
position: Qt.vector3d(1 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
}
MeshLink {
position: Qt.vector3d(2 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
MeshLink {
position: Qt.vector3d(3 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
}
MeshLink {
position: Qt.vector3d(4 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
CapsuleLink {
position: Qt.vector3d(5 * viewport.ringDistance, viewport.ringY, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
}
MeshLink {
id: rightLink
isKinematic: true
property vector3d startPos: Qt.vector3d(6 * viewport.ringDistance,
viewport.ringY,
0)
property vector3d startRot: Qt.vector3d(90, 0, 0)
kinematicPosition: startPos
position: startPos
kinematicEulerRotation: startRot
eulerRotation: startRot
color: "red"
}Das erste Verbindungsglied auf der linken Seite hat die Eigenschaft „ isKinematic “ auf „ true “ gesetzt, damit wir es über eine Animation steuern können. Da es sich um ein kinematisches Objekt handelt, müssen wir die Eigenschaften „ kinematicPosition “ und „ kinematicRotation “ festlegen. Wir animieren es, indem wir die Eigenschaft „ kinematicPosition “ animieren. Die anderen Verbindungsglieder werden mit einem gewissen Abstand zueinander instanziiert.
Um eine flüssige Animation zu erhalten, die der physikalischen Simulation exakt folgt, verwenden wir einen „ AnimationController “, den wir mit dem Signal „ onFrameDone “ des „ PhysicsWorld “ verbinden. Auf diese Weise verlangsamt sich die Animation entsprechend, falls es zu Frame-Ausfällen kommen sollte, die die Simulation verlangsamen. Wir verwenden einen „ SequentialAnimation “ mit vier „ NumberAnimation “, um die Ringe ganz links und ganz rechts hin und her zu bewegen. Dies ist der QML-Code für die Animation:
Connections {
target: physicsWorld
property real totalAnimationTime: 12000
function onFrameDone(timeStep) {
let progressStep = timeStep / totalAnimationTime
animationController.progress += progressStep
if (animationController.progress >= 1) {
animationController.completeToEnd()
animationController.reload()
animationController.progress = 0
}
}
}
AnimationController {
id: animationController
animation: SequentialAnimation {
NumberAnimation {
target: leftLink
property: "kinematicPosition.x"
to: 3 * viewport.ringDistance
from: -6 * viewport.ringDistance
easing.type: Easing.InOutCubic
duration: 1000
}
NumberAnimation {
target: leftLink
property: "kinematicPosition.x"
from: 3 * viewport.ringDistance
to: -6 * viewport.ringDistance
easing.type: Easing.InOutCubic
duration: 1000
}
NumberAnimation {
target: rightLink
property: "kinematicPosition.x"
to: -3 * viewport.ringDistance
from: 6 * viewport.ringDistance
easing.type: Easing.InOutCubic
duration: 1000
}
NumberAnimation {
target: rightLink
property: "kinematicPosition.x"
from: -3 * viewport.ringDistance
to: 6 * viewport.ringDistance
easing.type: Easing.InOutCubic
duration: 1000
}
}
}Das Interessante daran ist, was in den Dateien „Mesh Link“ und „Capsule Link“ vor sich geht. Schauen wir uns jede davon einmal genauer an.
Mesh-Link
DynamicRigidBody {
id: root
scale: Qt.vector3d(100, 100, 100)
property color color: "white"
PrincipledMaterial {
id: _material
baseColor: root.color
metalness: 1.0
roughness: 0.5
}
Model {
source: "meshes/ring.mesh"
materials: [_material]
}
collisionShapes: [
ConvexMeshShape {
source: "meshes/segmentedRing_001.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_002.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_003.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_004.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_005.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_006.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_007.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_008.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_009.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_010.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_011.mesh"
},
ConvexMeshShape {
source: "meshes/segmentedRing_012.mesh"
}
]
}Der „Mesh Link“ ist ein dynamischer starrer Körper mit einem Modell und einem Material. Das Modell lädt das Mesh aus einer Mesh-Datei. Außerdem gibt es eine Liste von Kollisionsformen, die miteinander kombiniert werden und eine zusammengesetzte Form für die Kollisionserkennung bilden. Jede Form ist eine „Convex Mesh“-Form, die das Mesh aus einer Quelldatei lädt. Eine konvexe Form ist im Grunde eine Form, bei der die Verbindungslinie zwischen zwei beliebigen Punkten innerhalb der Form immer innerhalb der Form liegt.
Wenn wir uns das bei aktiviertem Debug-Modus genauer ansehen, bilden die Kollisionsformen wie folgt die zusammengesetzte Kollisionsform:

Kapsel-Verbindung
DynamicRigidBody {
id: root
property real len: 170
property real w: 17
PrincipledMaterial {
id: material3
baseColor: "yellow"
metalness: 1.0
roughness: 0.5
}
Node {
opacity: 1
Model {
materials: material3
source: "#Cylinder"
scale: Qt.vector3d(root.w / 100, root.len / 100, root.w / 100)
eulerRotation.z: 90
y: -root.len / 2
}
Model {
materials: material3
source: "#Cylinder"
scale: Qt.vector3d(root.w / 100, root.len / 100, root.w / 100)
eulerRotation.z: 90
y: root.len / 2
}
Model {
materials: material3
source: "#Cylinder"
scale: Qt.vector3d(root.w / 100, root.len / 100, root.w / 100)
x: root.len / 2
}
Model {
materials: material3
source: "#Cylinder"
scale: Qt.vector3d(root.w / 100, root.len / 100, root.w / 100)
x: -root.len / 2
}
Model {
materials: material3
source: "#Sphere"
scale: Qt.vector3d(root.w / 100, root.w / 100, root.w / 100)
x: -root.len / 2
y: -root.len / 2
}
Model {
materials: material3
source: "#Sphere"
scale: Qt.vector3d(root.w / 100, root.w / 100, root.w / 100)
x: -root.len / 2
y: root.len / 2
}
Model {
materials: material3
source: "#Sphere"
scale: Qt.vector3d(root.w / 100, root.w / 100, root.w / 100)
x: root.len / 2
y: -root.len / 2
}
Model {
materials: material3
source: "#Sphere"
scale: Qt.vector3d(root.w / 100, root.w / 100, root.w / 100)
x: root.len / 2
y: root.len / 2
}
}
collisionShapes: [
CapsuleShape {
y: -root.len / 2
height: root.len
diameter: root.w
},
CapsuleShape {
y: root.len / 2
height: root.len
diameter: root.w
},
CapsuleShape {
x: -root.len / 2
eulerRotation.z: 90
height: root.len
diameter: root.w
},
CapsuleShape {
x: root.len / 2
eulerRotation.z: 90
height: root.len
diameter: root.w
}
]
}Der „Capsule Link“ ist ein dynamischer starrer Körper, bei dem einige Modelle dasselbe Material verwenden. Diese Verbindung besteht aus mehreren Zylindern und Kugeln. Wie beim „Mesh Link“ gibt es auch hier eine Liste von Kollisionsformen. In diesem Fall handelt es sich bei jeder Form um eine Kapselform.
Wenn wir uns das bei aktiviertem Debug-Modus genauer ansehen, erkennen wir, wie die Kollisionsformen die zusammengesetzte Kollisionsform bilden.

Dateien:
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.