Qt Quick 3D 物理定律 - 简单示例

演示如何设置一个简单的物理场景。

本示例通过一个简单示例的代码来概述基本的 Quick 3D 物理特性。请注意,这个介绍假设用户对 Qt Quick 3D 模块有一定了解。

设置

整个示例都包含在 main.qml 文件中。让我们首先看看创建物理世界的对象。这个节点称为 PhysicsWorld

PhysicsWorld {
    scene: viewport.scene
}

我们将 scene 属性设置为我们 View3D 的场景。 scene 属性定义了模拟将寻找物理节点的位置。任何放置在场景节点之外的物理节点都不会成为模拟的一部分。

场景

让我们看看场景。

View3D {
    id: viewport
    anchors.fill: parent

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

    PerspectiveCamera {
        position: Qt.vector3d(-200, 100, 500)
        eulerRotation: Qt.vector3d(-20, -20, 0)
        clipFar: 5000
        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(10, 10, 1)
            materials: DefaultMaterial {
                diffuseColor: "green"
            }
            castsShadows: false
            receivesShadows: true
        }
    }

    DynamicRigidBody {
        position: Qt.vector3d(-100, 100, 0)
        collisionShapes: BoxShape {
            id: boxShape
        }
        Model {
            source: "#Cube"
            materials: PrincipledMaterial {
                baseColor: "yellow"
            }
        }
    }

    DynamicRigidBody {
        position: Qt.vector3d(0, 100, 0)
        collisionShapes: SphereShape {
            id: sphereShape
        }
        Model {
            source: "#Sphere"
            materials: PrincipledMaterial {
                baseColor: "blue"
            }
        }
    }

    DynamicRigidBody {
        position: Qt.vector3d(75, 200, 0)
        collisionShapes: CapsuleShape {
            id: capsuleShape
        }

        Model {
            geometry: CapsuleGeometry {}
            materials: PrincipledMaterial {
                baseColor: "red"
            }
        }
    }
}

我们的场景仅仅是一个 View3D,因为我们想绘制物理对象。它包含了一个 PerspectiveCamera 和一个 DirectionalLight 以进行渲染,但更重要的是它包含了一个 StaticRigidBody 和三个 DynamicRigidBody 节点。在物理学中,刚体是一个非可变形、均匀密度的固体体。我们有两种类型的刚体可供使用; StaticRigidBodyDynamicRigidBody。一个 StaticRigidBody 是一个包含静态(不可移动)刚体的 QML 节点。技术上可以移动该体,但这将导致性能 penalties。另一方面,DynamicRigidBody 用于可以移动的对象。一个 DynamicRigidBody 有一个 isKinematic 属性,当它设置为 true 时,刚体将不会被外部力影响,可以从脚本和动画中控制。例如,足球不会是运动学的,而电梯或移动平台通常是。这也意味着,如果您更新足球的 position 属性,它不会移动到该位置,而电梯会。

要与其他物理对象交互,需要设置碰撞形状属性。碰撞形状属性是一个列表,可以包含一个或多个形状,并将作为单个刚体单元共同作用。您可以相对这些形状放置并旋转它们。请注意,平面、三角形网格和高度图形状仅在刚体是静力的动态体时适用。

形状

我们的场景包含四个物理对象(平面、盒子、球、胶囊)。我们将逐一介绍它们。

平面
StaticRigidBody {
    position: Qt.vector3d(0, -100, 0)
    eulerRotation: Qt.vector3d(-90, 0, 0)
    collisionShapes: PlaneShape {}
    Model {
        source: "#Rectangle"
        scale: Qt.vector3d(10, 10, 1)
        materials: DefaultMaterial {
            diffuseColor: "green"
        }
        castsShadows: false
        receivesShadows: true
    }
}

我们通过创建一个StaticRigidBody节点创建一个平面。在这个节点中,我们将碰撞形状属性设置为包含一个平面形状。平面将空间划分为“在上方”和“在下方”它们之间。所有“在下方”平面的东西都会与其碰撞并被推到上方。平面位于YZ平面,上方指向正X。我们在StaticRigidBody节点内放置一个模型以渲染平面。这是一个常见的模式,确保当物理对象在场景中相互作用时模型也以相同的方式移动和旋转。由于我们想使平面位于XY平面,因此我们使用eulerRotation属性来旋转它。我们以类似的方式旋转模型。

盒子
DynamicRigidBody {
    position: Qt.vector3d(-100, 100, 0)
    collisionShapes: BoxShape {
        id: boxShape
    }
    Model {
        source: "#Cube"
        materials: PrincipledMaterial {
            baseColor: "yellow"
        }
    }
}

我们通过创建一个DynamicRigidBody节点和一个单个的BoxShape碰撞形状中创建球体。由于这是一个动态节点,所以盒子将以自由对象的方式通过碰撞和移动与场景交互。由于立方体模型比单位立方体大一百倍,因此我们需要相应地进行缩放。由于这是一个具有物理重量的动态体,因此我们设置了密度属性。

球体
DynamicRigidBody {
    position: Qt.vector3d(0, 100, 0)
    collisionShapes: SphereShape {
        id: sphereShape
    }
    Model {
        source: "#Sphere"
        materials: PrincipledMaterial {
            baseColor: "blue"
        }
    }
}

我们通过创建一个DynamicRigidBody节点和一个单个的SphereShape碰撞形状中创建球体。

胶囊
DynamicRigidBody {
    position: Qt.vector3d(75, 200, 0)
    collisionShapes: CapsuleShape {
        id: capsuleShape
    }

    Model {
        geometry: CapsuleGeometry {}
        materials: PrincipledMaterial {
            baseColor: "red"
        }
    }
}

我们通过创建一个DynamicRigidBody节点和一个单个的CapsuleShape碰撞形状中创建胶囊。我们使用Qt Quick 3D物理提供的内置CapsuleGeometry构建胶囊模型。

文件

© 2024 Qt公司有限公司。本文档中的文档贡献归属其各自的版权所有者。提供在此的文档受自由软件基金会发布的GNU自由文档许可证版本1.3的条款许可。Qt及其相关徽标为芬兰及其它国家的Qt公司有限公司的商标。所有其他商标均为其各自所有者的财产。