Qt Quick 3D物理-复合形状示例

Qt Quick 3D Physics - Compound Shapes Example

Qt Quick 3D物理-复合形状示例

Demonstrates using complex collision shapes.

演示如何使用复杂碰撞形状。

This example demonstrates how to use more than one collision shape to create complex objects for collision detection. The scene consists of a green static plane and a series of links connected to each other. At the beginning, the simulation is disabled. After some time or when the user press the space key, the simulation will start. An animation will start that causes the leftmost link to move horizontally. Since the leftmost link is purely controlled by animation, the isKinematic property is set to true.

​此示例演示如何使用多个碰撞形状创建复杂对象以进行碰撞检测。场景由一个绿色静态平面和一系列相互连接的链组成。开始时,模拟被禁用。一段时间后或当用户按空格键时,模拟将开始。将启动一个动画,使最左侧的链水平移动。由于最左侧的链接完全由动画控制,因此isKinematic属性设置为true。

Setup

设置

As usual we need to add our DynamicsWorld:

​像往常一样,我们需要添加DynamicsWorld:

DynamicsWorld {
    id: physicsWorld
    running: false
    enableCCD: true
}

We do the usual setup where we have an environment, camera and lights:

我们通常设置环境、摄像机和灯光:

environment: SceneEnvironment {
    antialiasingMode: SceneEnvironment.MSAA
    backgroundMode: SceneEnvironment.Color
    clearColor: "lightblue"
}

focus: true

PerspectiveCamera {
    id: camera
    position: Qt.vector3d(-200, 900, 1300)
    eulerRotation: Qt.vector3d(-10, 0, 0)
    clipFar: 15500
    clipNear: 1
}

DirectionalLight {
    eulerRotation.x: -45
    eulerRotation.y: 45
    castsShadow: true
    brightness: 1.5
    shadowFactor: 15
    shadowFilter: 10
    shadowMapFar: 100
    shadowBias: -0.01
    shadowMapQuality: Light.ShadowMapQualityVeryHigh
}

Physical objects

物体

We have our regular static plane:

我们有常规的静态平面:

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

Then we make instances of our links.

然后我们创建链的实例。

MeshLink {
    isKinematic: true
    position: Qt.vector3d(-6 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
    color: "red"

    SequentialAnimation on x {
        running: physicsWorld.running
        PauseAnimation {
            duration: 7000
        }
        NumberAnimation {
            from: -6 * viewport.ringDistance
            to: -9 * viewport.ringDistance
            duration: 3000
            easing.type: Easing.InOutQuad
        }

        SequentialAnimation {
            NumberAnimation {
                from: -9 * viewport.ringDistance
                to: 3 * viewport.ringDistance
                easing.type: Easing.InOutCubic
                duration: 8000
            }
            NumberAnimation {
                to: -9 * viewport.ringDistance
                from: 3 * viewport.ringDistance
                easing.type: Easing.InOutCubic
                duration: 8000
            }
            loops: Animation.Infinite
        }
    }
}

CapsuleLink {
    position: Qt.vector3d(-5 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

MeshLink {
    position: Qt.vector3d(-4 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

MeshLink {
    position: Qt.vector3d(-3 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(0, 90, 0)
}

MeshLink {
    position: Qt.vector3d(-2 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

MeshLink {
    position: Qt.vector3d(-1 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(0, 90, 0)
}

CapsuleLink {
    position: Qt.vector3d(0, viewport.ringY, 0)
}

MeshLink {
    position: Qt.vector3d(1 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(0, 90, 0)
}

MeshLink {
    position: Qt.vector3d(2 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

MeshLink {
    position: Qt.vector3d(3 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(0, 90, 0)
}

MeshLink {
    position: Qt.vector3d(4 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

CapsuleLink {
    position: Qt.vector3d(5 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
}

MeshLink {
    isKinematic: true
    position: Qt.vector3d(6 * viewport.ringDistance, viewport.ringY, 0)
    eulerRotation: Qt.vector3d(90, 0, 0)
    color: "red"
}

The first link which is on the left has its isKinematic property set to true so that we can control it via animation. The other links are instanced with some spacing between them.

​左侧的第一个链的isKinematic属性设置为true,以便我们可以通过动画控制它。其他链是实例化的,它们之间有一些间距。

The interesting part is what is happening inside the Mesh and Capsule Links files. Let's take a look at each one of them.

有趣的是网格和胶囊链文件中发生的事情。让我们看一看其中的每一个。

Mesh Link

网格链

DynamicRigidBody {
    scale: Qt.vector3d(100, 100, 100)
    property color color: "white"
    PrincipledMaterial {
        id: _material
        baseColor: color
        metalness: 1.0
        roughness: 0.5
    }

    Model {
        source: "meshes/ring.mesh"
        materials: [
            _material
        ]
    }

    collisionShapes: [
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_001.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_002.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_003.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_004.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_005.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_006.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_007.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_008.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_009.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_010.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_011.mesh"
        },
        ConvexMeshShape {
            meshSource: "meshes/segmentedRing_012.mesh"
        }
    ]
}

The Mesh Link is a Dynamic Rigid Body with a model and a material. The model loads the mesh from a mesh file. We also have a list of collision shapes that together are combined and form a compound shape for collision detection. Each shape is a Convex Mesh shape which loads the mesh from a source file. A convex shape is basically a shape where the line between any two points within the shape is always inside the shape.

网格链是具有模型和材质的动态刚体。模型从网格文件加载网格。我们还有一个碰撞形状列表,这些碰撞形状组合在一起形成一个用于碰撞检测的复合形状。每个形状都是从源文件加载网格的“凸面网格”形状。凸形基本上是一种形状,其中形状内任意两点之间的线始终位于形状内。

If we take a closer look when the debug mode is enabled, this is how the collision shapes form the compound collision shape:

如果我们仔细观察启用调试模式时,碰撞形状是如何形成复合碰撞形状的:

Capsule Link

胶囊链

DynamicRigidBody {
    property real len: 170
    property real w: 17
    PrincipledMaterial {
        id: material3
        baseColor: "yellow"
        metalness: 1.0
        roughness: 0.5
    }
    Node {
        opacity: 1
        Model {
            materials: material3
            source: "#Cylinder"
            scale: Qt.vector3d(w/100, len/100, w/100)
            eulerRotation.z: 90
            y: -len/2
        }
        Model {
            materials: material3
            source: "#Cylinder"
            scale: Qt.vector3d(w/100, len/100, w/100)
            eulerRotation.z: 90
            y: len/2
        }
        Model {
            materials: material3
            source: "#Cylinder"
            scale: Qt.vector3d(w/100, len/100, w/100)
            x: len/2
        }
        Model {
            materials: material3
            source: "#Cylinder"
            scale: Qt.vector3d(w/100, len/100, w/100)
            x: -len/2
        }
        Model {
            materials: material3
            source: "#Sphere"
            scale: Qt.vector3d(w/100, w/100, w/100)
            x: -len/2
            y: -len/2
        }
        Model {
            materials: material3
            source: "#Sphere"
            scale: Qt.vector3d(w/100, w/100, w/100)
            x: -len/2
            y: len/2
        }
        Model {
            materials: material3
            source: "#Sphere"
            scale: Qt.vector3d(w/100, w/100, w/100)
            x: len/2
            y: -len/2
        }
        Model {
            materials: material3
            source: "#Sphere"
            scale: Qt.vector3d(w/100, w/100, w/100)
            x: len/2
            y: len/2
        }
    }
    collisionShapes: [
        CapsuleShape {
            y: -len/2
            height: len
            diameter: w
        },
        CapsuleShape {
            y: len/2
            height: len
            diameter: w
        },
        CapsuleShape {
            x: -len/2
            eulerRotation.z: 90
            height: len
            diameter: w
        },
        CapsuleShape {
            x: len/2
            eulerRotation.z: 90
            height: len
            diameter: w
        }
    ]
}

The Capsule Link is a Dynamic Rigid Body with some models that share the same material. This link is formed from several cylinders and spheres. Like the Mesh Link we have a list of collision shapes. This time each shape is a Capsule Shape.

胶囊链是具有共享相同材质的某些模型的动态刚体。该连杆由几个圆柱体和球体组成。像网格链接一样,我们有一个碰撞形状列表。这次每个形状都是胶囊形状。

If we take a closer look when the debug mode is enabled, this is how the collision shapes form the compound collision shape.

如果我们仔细观察一下启用调试模式时,碰撞形状是如何形成复合碰撞形状的。

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值