Qt Quick 3D 物理力学 - 质量示例
演示设置物体质量和惯性的不同方法。
本示例演示了设置物体质量和惯性的三种不同的方法。场景由三个竖直堆叠的球体组成,这些物体质量相同,但质量中心不同,惯性张量各异,因此在碰撞时表现出不同的行为。
设置
我们首先添加我们的 PhysicsWorld
PhysicsWorld { running: true gravity: Qt.vector3d(0, -9.81, 0) typicalLength: 1 typicalSpeed: 10 scene: viewport.scene }
我们进行通常的设置,包括环境、相机和灯光
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: 100 }
物理对象
我们有我们的常规静态平面
StaticRigidBody { position: Qt.vector3d(0, 0, 0) eulerRotation: Qt.vector3d(-90, 0, 0) collisionShapes: PlaneShape {} Model { source: "#Rectangle" materials: DefaultMaterial { diffuseColor: "green" } castsShadows: false receivesShadows: true } }
我们定义了一个用于我们物体的自定义 QML 类,我们称之为 RolyPoly,因为它们的行为类似于所谓的滚球玩具。RolyPoly 是一个带有三个球形碰撞形状的 DynamicRigidBody
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 } } }
然后,我们将三个 RolyPoly 添加到场景中
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 }
紫色和蓝色 RolyPoly 具有自定义的质量中心和中性张量。由于默认情况下,物体使用均匀密度并会自动计算质量,我们将质量模式设置为DynamicRigidBody.MassAndInertiaTensor,以便紫色和蓝色物体使用我们提供的质量和惯性张量。较低的质量中心将使物体在推动后会始终站立。紫色物体的惯性张量容易在一个方向上晃动,但很难在另一个方向上晃动。红色物体具有自动计算的质量中心,因此在被撞倒后会因此保持平躺。
射击球体
为了测试不同物体的行为,我们添加了一个用于射击球体的节点
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() } }
然后,我们添加了一个 WasdController 来移动相机并瞄准射击球体
WasdController { speed: 0.01 controlledObject: camera Keys.onPressed: (event) => { handleKeyPress(event); if (event.key === Qt.Key_Space) { shapeSpawner.createBall(camera.position, camera.forward); } } Keys.onReleased: (event) => { handleKeyRelease(event) } }
文件
© 2024 Qt 公司。其中包含的文档贡献属于各自的著作权人。本文件中的文档是根据自由软件基金会发布的GNU自由文档许可证版本1.3许可的。Qt及其相关标志是芬兰和/或其他国家/地区的Qt公司的商标。所有其他商标均为其各自所有者的财产。