Qt Quick 3D Physics - 叶轮示例

演示如何使用触发体和碰撞信息。

本例演示了如何使用触发体和碰撞信息。场景由一个绿色静态平面、一个红色动态球体、一个粉色方框触发器和一个蓝色静态球体组成。当红色球体与触发体重叠时,它将变成黄色,而当它与蓝色球体碰撞时,它将被排斥开。

设置

像往常一样,我们需要添加PhysicsWorld

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

我们还需要在View3D 中添加场景对象。在这里,我们对视觉环境进行了一些设置:

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
}

物理对象

我们有常规的静态平面:

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

我们的动态球体就是这样定义的:

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

属性inArea 是一个自定义属性,用于跟踪球体何时与盒体触发器重叠。然后,baseColor 属性将使用该属性使球体在与方框重叠时为黄色,否则为红色。由于我们希望球体参与接触报告,因此需要将sendContactReports 属性设置为true 。由于我们还希望球体在进入和离开TriggerBody 时获得回调,因此还需要将receiveContactReports 属性设置为true 。我们在球体上实现了enteredTriggerBodyexitedTriggerBody 信号方法,在进入或离开触发体时,我们将inArea 属性设置为truefalse

现在让我们来看看触发体:

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

qml 类型是TriggerBody ,它的作用与静态体类似,只是它的碰撞不是活动的。相反,它会触发球体上的enteredTriggerBodyexitedTriggerBody 方法调用。

最后,让我们看看叶轮:

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

这是一个静态体,我们将receiveContactReports 设置为true ,以启用碰撞回调。每当有碰撞报告时,就会调用回调bodyContact 。在该方法中,我们调用setLinearVelocity ,将线速度设置为碰撞法向量的相反方向,以模拟叶轮。

文件:

© 2025 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.