Sur cette page

Qt Quick 3D Physics - Exemple de roue à aubes

Démonstration de l'utilisation des corps de déclenchement et des informations de collision.

Capture d'écran d'un rendu 3D montrant une sphère bleue sur une surface verte, un bloc rectangulaire rose au-dessus, et une sphère rouge flottant au-dessus.

Cet exemple montre comment utiliser les corps de déclenchement et les informations de collision. La scène se compose d'un plan statique vert, d'une sphère dynamique rouge, d'une boîte de déclenchement rose et d'une sphère statique bleue. Lorsque la sphère rouge chevauche le corps de déclenchement, elle devient jaune et lorsqu'elle entre en collision avec la sphère bleue, elle est repoussée.

Configuration

Comme d'habitude, nous devons ajouter notre PhysicsWorld:

PhysicsWorld {
    gravity: Qt.vector3d(0, -490, 0)
    scene: viewport.scene
}

Nous ajoutons également un View3D où nous plaçons nos objets de scène. Dans celui-ci, nous avons quelques paramètres pour l'environnement visuel :

environment: SceneEnvironment {
    clearColor: "#d6dbdf"
    backgroundMode: SceneEnvironment.Color
}

PerspectiveCamera {
    position: Qt.vector3d(0, 200, 1000)
    clipFar: 2000
    clipNear: 1
}

DirectionalLight {
    eulerRotation.x: -45
    eulerRotation.y: 45
    castsShadow: true
    brightness: 1
    shadowFactor: 50
}

Objets physiques

Nous avons notre plan statique régulier :

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
    }
}

C'est ainsi que notre sphère dynamique est définie :

DynamicRigidBody {
    id: sphere
    massMode: DynamicRigidBody.CustomDensity
    density: 0.00001
    position: Qt.vector3d(0, 600, 0)
    property bool inArea: false
    sendContactReports: true
    receiveTriggerReports: true

    onEnteredTriggerBody: {
        inArea = true
    }
    onExitedTriggerBody: {
        inArea = false
    }

    collisionShapes: SphereShape {}
    Model {
        source: "#Sphere"
        materials: PrincipledMaterial {
            baseColor: sphere.inArea ? "yellow" : "red"
        }
    }
}

La propriété inArea est une propriété personnalisée que nous utilisons pour garder une trace du moment où la sphère chevauche le corps de déclenchement de la boîte. Elle est ensuite utilisée pour la propriété baseColor afin de rendre la sphère jaune lorsqu'elle chevauche la boîte et rouge dans le cas contraire. Puisque nous voulons que la sphère participe au rapport de contact, la propriété sendContactReports doit être définie à true. Puisque nous voulons également que la sphère reçoive des rappels lorsqu'elle entre et quitte un TriggerBody, la propriété receiveContactReports est également définie à true. Nous implémentons les méthodes de signal enteredTriggerBody et exitedTriggerBody sur la sphère où nous définissons la propriété inArea à true ou false lorsqu'elle entre ou quitte le corps de déclenchement.

Examinons maintenant le corps du déclencheur :

TriggerBody {
    position: Qt.vector3d(0, 350, 0)
    scale: Qt.vector3d(1, 2, 1)

    collisionShapes: BoxShape {
        id: boxShape
    }
    Model {
        source: "#Cube"
        materials: PrincipledMaterial {
            baseColor: Qt.rgba(1, 0, 1, 0.2)
            alphaMode: PrincipledMaterial.Blend
        }
    }
}

Le type qml est un TriggerBody qui agit comme un corps statique sauf que ses collisions sont inactives. Au lieu de cela, il déclenchera les appels de méthode enteredTriggerBody et exitedTriggerBody sur la sphère.

Enfin, examinons la roue à aubes :

StaticRigidBody {
    position: Qt.vector3d(0, 0, 0)
    scale: Qt.vector3d(2, 2, 2)
    receiveContactReports: true

    collisionShapes: SphereShape {}

    Model {
        source: "#Sphere"
        materials: PrincipledMaterial {
            baseColor: "blue"
        }
    }

    onBodyContact: (body, positions, impulses, normals) => {
        for (var normal of normals) {
            let velocity = normal.times(-700)
            body.setLinearVelocity(velocity)
        }
    }
}

Il s'agit d'un corps statique et nous avons mis receiveContactReports à true pour activer les rappels de collision. Le callback bodyContact est appelé chaque fois qu'une collision est signalée. Dans la méthode, nous appelons setLinearVelocity pour définir la vitesse linéaire dans la direction opposée au vecteur normal de la collision afin de simuler une roue à aubes.

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.