Qt Quick 3D Physics - Joints Example
Demonstrates using joints in a physics scene.

This example demonstrates using a few of the joints available in Quick 3D Physics.
The scene is a typical scene with a PhysicsWorld, a View3D with a PerspectiveCamera and a DirectionalLight:
Window {
width: 640
height: 480
visible: true
title: qsTr("Qt Quick 3D Physics - Joints")
PhysicsWorld {
scene: viewport.scene
running: true
}
View3D {
id: viewport
anchors.fill: parent
environment: SceneEnvironment {
clearColor: "#d6dbdf"
backgroundMode: SceneEnvironment.Color
}
PerspectiveCamera {
position: Qt.vector3d(0, 600, 700)
eulerRotation: Qt.vector3d(-30, 0, 0)
clipFar: 5000
clipNear: 1
}
DirectionalLight {
eulerRotation.x: -45
eulerRotation.y: 45
castsShadow: true
brightness: 1
shadowFactor: 50
shadowMapQuality: Light.ShadowMapQualityHigh
}
Rope {
eulerRotation: Qt.vector3d(0, 0, -90)
position: Qt.vector3d(0, 500, 0)
}
Prismatic {
id: prismatic
position: Qt.vector3d(-250, 100, 0)
}
Revolute {
id: revolute
position: Qt.vector3d(200, 200, 100)
}
StaticRigidBody {
position: Qt.vector3d(0, -100, 0)
eulerRotation: Qt.vector3d(-90, 0, 0)
collisionShapes: PlaneShape {}
Model {
source: "#Rectangle"
scale: Qt.vector3d(20, 20, 1)
materials: PrincipledMaterial {
baseColor: "green"
}
castsShadows: false
receivesShadows: true
}
}
FrameAnimation {
id: animator
running: true
onTriggered: {
prismatic.jointRotation.z += 1
revolute.jointRotation.x += 0.95
}
}
}
}There is a StaticRigidBody with a PlaneShape to act as the floor and three custom QML objects; Rope, Prismatic and Revolute.
Rope {
eulerRotation: Qt.vector3d(0, 0, -90)
position: Qt.vector3d(0, 500, 0)
}
Prismatic {
id: prismatic
position: Qt.vector3d(-250, 100, 0)
}
Revolute {
id: revolute
position: Qt.vector3d(200, 200, 100)
}The Rope object is a series of capsules and a sphere that are connected with spherical joints for the capsules and a fixed joint for the sphere.
Node {
id: root
SphericalJoint {
bodyB: shape0
positionA: root.position
positionB: Qt.vector3d(-20, 0, 0)
}
SphericalJoint {
bodyA: shape0
bodyB: shape1
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(-20, 0, 0)
}
SphericalJoint {
bodyA: shape1
bodyB: shape2
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(-20, 0, 0)
}
SphericalJoint {
bodyA: shape2
bodyB: shape3
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(-20, 0, 0)
}
SphericalJoint {
bodyA: shape3
bodyB: shape4
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(-20, 0, 0)
}
SphericalJoint {
bodyA: shape4
bodyB: shape5
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(-20, 0, 0)
}
FixedJoint {
bodyA: shape5
bodyB: sphere
positionA: Qt.vector3d(20, 0, 0)
positionB: Qt.vector3d(0, 0, 0)
}
DynamicRigidBody {
id: shape0
position: Qt.vector3d(0, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: shape1
position: Qt.vector3d(40, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: shape2
position: Qt.vector3d(80, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: shape3
position: Qt.vector3d(120, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: shape4
position: Qt.vector3d(160, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: shape5
position: Qt.vector3d(200, 0, 0)
collisionShapes: CapsuleShape {
diameter: 10
height: 40
}
Model {
geometry: CapsuleGeometry {
diameter: 10
height: 40
}
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
DynamicRigidBody {
id: sphere
position: Qt.vector3d(240, 0, 0)
scale: Qt.vector3d(0.5, 0.5, 0.5)
collisionShapes: SphereShape {}
Model {
source: "#Sphere"
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
}The Prismatic object consists of two bars locked in a prismatic joint along the x-axis of both of them. With this joint the smaller rod can move freely along this x-axis until it reaches its upper and lower constraint limit.
Node {
id: root
property vector3d jointRotation : Qt.vector3d(0, 0, 0)
PrismaticJoint {
bodyA: prismaticBoxA
bodyB: prismaticBoxB
lowerLimit: -200
upperLimit: 0
positionA: Qt.vector3d(100, 0, 0)
positionB: Qt.vector3d(-100, 0, 0)
}
DynamicRigidBody {
id: prismaticBoxA
kinematicPosition: Qt.vector3d(0, 200, 0)
kinematicEulerRotation: root.jointRotation
isKinematic: true
scale: Qt.vector3d(2, 0.5, 0.5)
collisionShapes: BoxShape {}
Model {
source: "#Cube"
materials: PrincipledMaterial {
baseColor: "yellow"
}
}
}
DynamicRigidBody {
id: prismaticBoxB
position: Qt.vector3d(0, 0, 0)
scale: Qt.vector3d(2, 0.4, 0.4)
collisionShapes: BoxShape {}
Model {
source: "#Cube"
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
}The Revolute object consists of two bars rotated by 90 degrees and locked in a revolute joint.
Node {
id: root
property vector3d jointRotation : Qt.vector3d(0, 90, 0)
RevoluteJoint {
bodyA: revoluteBoxA
bodyB: revoluteBoxB
positionA: Qt.vector3d(100, 0, 0)
positionB: Qt.vector3d(100, 0, 0)
orientationB: Quaternion.fromEulerAngles(0, 0, 90)
angularLimitLower: -Math.PI / 4
angularLimitUpper: Math.PI / 4
enableAngularLimit: true
}
DynamicRigidBody {
id: revoluteBoxA
kinematicPosition: Qt.vector3d(0, 0, 0)
kinematicEulerRotation: root.jointRotation
isKinematic: true
scale: Qt.vector3d(2, 0.5, 0.5)
collisionShapes: BoxShape {}
Model {
source: "#Cube"
materials: PrincipledMaterial {
baseColor: "yellow"
}
}
}
DynamicRigidBody {
id: revoluteBoxB
position: Qt.vector3d(0, 100, -100)
eulerRotation: Qt.vector3d(0, 90, -90)
scale: Qt.vector3d(2, 0.5, 0.5)
collisionShapes: BoxShape {}
Model {
source: "#Cube"
materials: PrincipledMaterial {
baseColor: "blue"
}
}
}
}Going back to the main scene there is a FrameAnimation object that rotates the kinematic prismatic and revolute joints.
FrameAnimation {
id: animator
running: true
onTriggered: {
prismatic.jointRotation.z += 1
revolute.jointRotation.x += 0.95
}
}With all these moving parts we can see how the different joints interact in a physics scene.
Files:
© 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.