Qt Quick Physique 3D - Exemple de masse
Démontre différentes façons de définir la masse et l'inertie d'un corps.

Cet exemple présente trois façons différentes de définir la masse et l'inertie d'un corps. La scène comprend trois corps constitués de trois sphères empilées verticalement. Ces corps ont tous la même masse mais des centres de masse et des tenseurs d'inertie différents, ce qui leur confère un comportement différent en cas de collision.
Configuration
Nous commençons par ajouter notre site PhysicsWorld:
PhysicsWorld { running: true gravity: Qt.vector3d(0, -9.81, 0) typicalLength: 1 typicalSpeed: 10 scene: viewport.scene }
Nous procédons à l'installation habituelle d'un environnement, d'une caméra et de lumières :
environment: SceneEnvironment { clearColor: "lightblue" backgroundMode: SceneEnvironment.Color } PerspectiveCamera { id: camera position: Qt.vector3d(0, 2, 5) eulerRotation: Qt.vector3d(-10, 0, 0) clipFar: 100 clipNear: 0.01 } DirectionalLight { eulerRotation.x: -45 eulerRotation.y: 45 castsShadow: true brightness: 1 shadowFactor: 50 shadowBias: 0.1 pcfFactor: 0.01 }
Objets physiques
Nous avons notre plan statique habituel :
StaticRigidBody { position: Qt.vector3d(0, 0, 0) eulerRotation: Qt.vector3d(-90, 0, 0) collisionShapes: PlaneShape {} Model { source: "#Rectangle" materials: PrincipledMaterial { baseColor: "green" } castsShadows: false receivesShadows: true } }
Nous définissons une classe QML personnalisée pour notre corps que nous appelons RolyPoly car ils se comportent comme des jouets roly-poly. Le RolyPoly est un DynamicRigidBody avec trois formes de collision sphériques :
DynamicRigidBody { property string color: "blue" collisionShapes: [ SphereShape { id: sphere0 diameter: 1 }, SphereShape { id: sphere1 diameter: 0.8 position: Qt.vector3d(0, 0.6, 0) }, SphereShape { id: sphere2 diameter: 0.6 position: Qt.vector3d(0, 1.1, 0) } ] Model { source: "#Sphere" position: sphere0.position scale: Qt.vector3d(1,1,1).times(sphere0.diameter*0.01) materials: PrincipledMaterial { baseColor: color } } Model { source: "#Sphere" position: sphere1.position scale: Qt.vector3d(1,1,1).times(sphere1.diameter*0.01) materials: PrincipledMaterial { baseColor: color } } Model { source: "#Sphere" position: sphere2.position scale: Qt.vector3d(1,1,1).times(sphere2.diameter*0.01) materials: PrincipledMaterial { baseColor: color } } }
Nous ajoutons ensuite trois roly-polys à notre scène :
RolyPoly { position: Qt.vector3d(-2, 0.5, 0) color: "blue" mass: 0.9 centerOfMassPosition: Qt.vector3d(0, -0.5, 0) inertiaTensor: Qt.vector3d(0.217011, 0.0735887, 0.217011) massMode: DynamicRigidBody.MassAndInertiaTensor } RolyPoly { position: Qt.vector3d(0, 0.5, 0) color: "purple" mass: 0.9 centerOfMassPosition: Qt.vector3d(0, -0.5, 0) inertiaTensor: Qt.vector3d(0.05, 100, 100) massMode: DynamicRigidBody.MassAndInertiaTensor } RolyPoly { position: Qt.vector3d(2, 0.5, 0) color: "red" mass: 0.9 massMode: DynamicRigidBody.Mass }
Le roly-poly violet et bleu a un centre de masse et un tenseur d'inertie personnalisés. Puisque les corps utilisent une densité uniforme par défaut et calculent automatiquement la masse et l'inertie, nous définissons massMode sur DynamicRigidBody.MassAndInertiaTensor dans nos corps violet et bleu pour utiliser les tenseurs de masse et d'inertie que nous avons fournis à la place. Le centre de masse étant plus bas, les corps se redresseront toujours après avoir été poussés. Le tenseur d'inertie du corps violet fait en sorte qu'il oscille facilement dans une direction, mais difficilement dans l'autre. Le corps rouge a un centre de masse calculé automatiquement et restera donc couché après avoir été renversé.
Tirer des balles
Pour tester le comportement des différents corps, nous ajoutons un nœud pour tirer des balles :
Node { id: shapeSpawner property var spheres: [] property var sphereComponent: Qt.createComponent("Sphere.qml") function createBall(position, forward) { let diameter = 0.2 let speed = 20 let sphere = sphereComponent.createObject(shapeSpawner, { "position": position, "sphereDiameter": diameter }) sphere.setLinearVelocity(forward.times(speed)) var pair = { "sphere": sphere, "date": Date.now() } spheres.push(pair) if (sphere === null) { console.log("Error creating object") } } function clean() { spheres = spheres.filter(sphere => { let diff = Date.now() - sphere['date']; if (diff > 5000) { sphere['sphere'].destroy(); return false; } return true; }); } Timer { interval: 200 running: true repeat: true onTriggered: shapeSpawner.clean() } }
Nous ajoutons ensuite un WasdController pour pouvoir déplacer la caméra et viser et tirer des balles sur les corps :
WasdController { speed: 0.01 shiftSpeed: 0.1 controlledObject: camera Keys.onPressed: (event) => { handleKeyPress(event); if (event.key === Qt.Key_Space) { shapeSpawner.createBall(camera.position, camera.forward); } } Keys.onReleased: (event) => { handleKeyRelease(event) } }
Fichiers :
© 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.