Qt Quick 3D 物理引擎 - 叶轮示例

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

此示例演示了如何使用触发体和碰撞信息。场景包括一个绿色静态平面、一个红色动态球体、一个粉色盒子触发体和一个蓝色静态球体。当红色球体与触发体重叠时,它会变成黄色,当它与蓝色球体碰撞时,它将被推开。

设置

像往常一样,我们需要添加我们的 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: 100
}

物理对象

我们有我们的常规静态平面

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

这是一个静态体,我们设置 receiveContactReportstrue 以启用碰撞回调。每当报告碰撞时,回调 bodyContact 会被调用。在方法中,我们调用 setLinearVelocity 来设置线性速度,其方向与碰撞法向量相反,以模拟叶轮。

文件

© 2024 Qt公司有限公司。本文件中包含的文档贡献属于其各自的版权所有者。本文件提供的文档根据自由软件基金会的发布,遵循GNU自由文档许可协议第1.3版的条款进行许可。Qt及其相关标志是芬兰及/或其他国家的Qt公司有限公司的商标。所有其他商标均为其各自所有者的财产。