Qt Quick 3D物理-简单示例

Qt Quick 3D Physics - Simple Example

Qt Quick 3D物理-简单示例

Demonstrates setting up a simple physics scene.

This example gives an introductory overview of the basic Quick 3D Physics features by going through the code of a simple example. Note that this introduction assumes a familiarity with the Qt Quick 3D module.

本示例通过简单示例的代码,对Quick 3D Physics的基本功能进行了介绍性概述。请注意,本介绍假定您熟悉Qt Quick 3D模块。

Setup

设置

The whole example is contained and set up in the main.qml file. Let's first look at the object that creates the physical world. This node is called DynamicsWorld:

​整个示例包含在main.qml文件中并在其中进行设置。让我们首先看看创建物理世界的对象。此节点称为DynamicsWorld:

DynamicsWorld {
    running: true
}

We set the gravity property to point downwards in the y-direction with a magnitude that matches the gravity on earth. Note that all physical properties are unit-less so the magnitude could be -981 instead if we scaled the scene accordingly. It is possible to (un)pause the simulation by setting running to false.

​我们将重力属性设置为沿y方向向下,其大小与地球上的重力相匹配。请注意,所有物理特性都无单位,因此如果相应缩放场景,幅值可能为-981。可以通过将running设置为false来(取消)暂停模拟。

Scene

场景

Let's have a look at the 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, 10)
            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"
            }
        }
    }
}

Our scene is just a View3D since we want to draw our physical objects. It contains a PerspectiveCamera and a DirectionalLight for rendering, but more importantly it contains a StaticRigidBody and three DynamicRigidBody nodes. In physics, a rigid body is a non-deformable, solid body with uniform density. We have two types of rigid bodies available; StaticRigidBody and DynamicRigidBody. A StaticRigidBody is a QML node which contains a static (immovable) rigid body. It is technically possible to move the body but it will incur a performance penalty. A DynamicRigidBody on the other hand is used for objects that can move. A DynamicRigidBody has a isKinematic property, when it is set to true the rigid body will not be influenced by external forces and can be controlled from scripts and animations. For instance a football would not be kinematic but an elevator or a moving platform typically would. This also means that if you update the position property of the football it would not move to that position whereas the elevator would.

​我们的场景只是一个View3D,因为我们想要绘制物理对象。它包含用于渲染的透视摄影机和平行光,但更重要的是,它包含一个StaticRigidBody和三个DynamicRigidBody节点。在物理学中,刚体是密度均匀的不可变形的固体。我们有两种类型的刚体可用;静态刚体和动态刚体。StaticRigidBody是包含静态(不可移动)刚体的QML节点。从技术上讲,可以移动本身,但会导致性能损失。另一方面,DynamicRigidBody用于可以移动的对象。DynamicRigidBody具有isKinematic特性,当它设置为true时,刚体将不受外力影响,并且可以通过脚本和动画进行控制。例如,足球不是运动的,但电梯或移动平台通常是运动的。这也意味着,如果更新足球的位置属性,它将不会移动到该位置,而电梯会。

To be able to interact with other physical objects the collisionShapes property needs to be set. The collisionShapes property is a list that can contain one or more shapes and will act as one rigid unit combined. You can position and rotate these shapes in relation to each other. Note that plane, triangle mesh and heightmap shapes only work with dynamic bodies if the body is kinematic.

​为了能够与其他物理对象交互,需要设置collisionShapes属性。collisionShapes属性是一个列表,可以包含一个或多个形状,并将作为一个组合的刚性单元。您可以相对地定位和旋转这些形状。请注意,如果实体是运动学的,则平面、三角形网格和高度贴图形状仅适用于动力学实体。

Shapes

形状

Our scene contains four physical objects (plane, box, ball, capsule). We will go through them one at a time.

我们的场景包含四个物理对象(平面、盒、球、胶囊)。我们将一次检查一个。

Plane

平面

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

We create a plane by making a StaticRigidBody node. In this node we set the collisionShapes property to contain a PlaneShape. Planes divide space into "above" and "below" them. Everything "below" the plane will collide with it and be pushed above it. The Plane lies on the YZ plane with "above" pointing towards positive X. We put a Model inside our StaticRigidBody node to render the plane. This is a common pattern which makes sure that the model also moves and rotates in the same way when the physical object interacts in the scene. Since we want the plane to lie on the XY plane we rotate it using the eulerRotation property. We rotate the model in a similar way.

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

Box

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

We create a sphere by making a DynamicRigidBody node and a single BoxShape in collisionShapes. Since this is a dynamic node the box will interact with the scene by colliding and moving like a free object. Since the cube model is a hundred times bigger than a unit cube we need to scale it accordingly. Since this is a dynamic body and thus have a physical weight we set the density property.

​我们通过在collisionShapes中创建DynamicRigidBody节点和单个BoxShape来创建球体。因为这是一个动态节点,所以盒会像自由对象一样碰撞和移动,从而与场景交互。由于立方体模型比单位立方体大一百倍,我们需要相应地对其进行缩放。由于这是一个动态物体,因此具有物理重量,因此我们设置密度特性。

Sphere

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

We create a sphere by making a DynamicRigidBody node and a single SphereShape in collisionShapes.

​我们通过在collisionShapes中创建DynamicRigidBody节点和单个SphereShape来创建球体。

Capsule

胶囊

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

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

We create a capsule by making a DynamicRigidBody node and a single CapsuleShape in collisionShapes. We build a capsule model by using the built-in CapsuleGeometry provided by Qt Quick 3D Physics.

​我们通过在collisionShapes中创建DynamicRigidBody节点和单个CapsuleShape来创建胶囊。我们使用Qt Quick 3D Physics提供的内置CapsuleGeometry构建胶囊模型。

Files:

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值