Revision control
++ // Copyright (C) 2026 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
++ import QtQuick
++ import QtQuick3D
++ import QtQuick3D.Physics
++ import QtQuick3D.Physics.Helpers
++
++ //! [full]
++ Node {
++ id: root
++
++ SphericalJoint {
++ bodyB: shape0
++ positionA: root.position
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ SphericalJoint {
++ bodyA: shape0
++ bodyB: shape1
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ SphericalJoint {
++ bodyA: shape1
++ bodyB: shape2
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ SphericalJoint {
++ bodyA: shape2
++ bodyB: shape3
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ SphericalJoint {
++ bodyA: shape3
++ bodyB: shape4
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ SphericalJoint {
++ bodyA: shape4
++ bodyB: shape5
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(-25, 0, 0)
++ }
++
++ FixedJoint {
++ bodyA: shape5
++ bodyB: sphere
++ positionA: Qt.vector3d(25, 0, 0)
++ positionB: Qt.vector3d(0, 0, 0)
++ }
++
++ // Neighboring links touch exactly at their joints, so each body ignores collisions
++ // with its immediate neighbors to avoid fighting the joint with contact forces.
++ DynamicRigidBody {
++ id: shape0
++ position: Qt.vector3d(25, 0, 0)
++ filterGroup: 0
++ filterIgnoreGroups: 0b0000010
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: shape1
++ position: Qt.vector3d(75, 0, 0)
++ filterGroup: 1
++ filterIgnoreGroups: 0b0000101
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: shape2
++ position: Qt.vector3d(125, 0, 0)
++ filterGroup: 2
++ filterIgnoreGroups: 0b0001010
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: shape3
++ position: Qt.vector3d(175, 0, 0)
++ filterGroup: 3
++ filterIgnoreGroups: 0b0010100
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: shape4
++ position: Qt.vector3d(225, 0, 0)
++ filterGroup: 4
++ filterIgnoreGroups: 0b0101000
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: shape5
++ position: Qt.vector3d(275, 0, 0)
++ filterGroup: 5
++ filterIgnoreGroups: 0b1010000
++ collisionShapes: CapsuleShape {
++ diameter: 10
++ height: 40
++ }
++ Model {
++ geometry: CapsuleGeometry {
++ diameter: 10
++ height: 40
++ }
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++
++ DynamicRigidBody {
++ id: sphere
++ position: Qt.vector3d(300, 0, 0)
++ scale: Qt.vector3d(0.5, 0.5, 0.5)
++ filterGroup: 6
++ filterIgnoreGroups: 0b0100000
++ collisionShapes: SphereShape {}
++ Model {
++ source: "#Sphere"
++ materials: PrincipledMaterial {
++ baseColor: "blue"
++ }
++ }
++ }
++ }
++ //! [full]