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: 50
shadowBias: 0.1
pcfFactor: 0.01
}物理对象
我们有一个常规的静态平面:
StaticRigidBody {
position: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(-90, 0, 0)
collisionShapes: PlaneShape {}
Model {
source: "#Rectangle"
materials: PrincipledMaterial {
baseColor: "green"
}
castsShadows: false
receivesShadows: true
}
}我们为身体定义了一个自定义的QML类,命名为RolyPoly,因为它们的行为就像所谓的“滚滚球”玩具。RolyPoly是一个DynamicRigidBody ,带有三个球形碰撞形状:
DynamicRigidBody {
id: body
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: body.color
}
}
Model {
source: "#Sphere"
position: sphere1.position
scale: Qt.vector3d(1,1,1).times(sphere1.diameter*0.01)
materials: PrincipledMaterial {
baseColor: body.color
}
}
Model {
source: "#Sphere"
position: sphere2.position
scale: Qt.vector3d(1,1,1).times(sphere2.diameter*0.01)
materials: PrincipledMaterial {
baseColor: body.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具有自定义质心和惯性张量。由于物体默认使用均匀密度,并会自动计算质量和惯性,因此我们将紫色和蓝色物体的`massMode`设置为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
shiftSpeed: 0.1
controlledObject: camera
Keys.onPressed: (event) => {
handleKeyPress(event);
if (event.key === Qt.Key_Space) {
shapeSpawner.createBall(camera.position, camera.forward);
}
}
Keys.onReleased: (event) => { handleKeyRelease(event) }
}文件:
© 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.