Qt Quick 3D Physics - 캐논 예제

물리적 오브젝트를 생성하는 방법을 보여줍니다.

푸른 풍경 속 여러 개의 빨간 상자가 피라미드 모양을 이루고 있으며, 상자를 조절할 수 있는 슬라이더가 있는 화면 캡처

이 예제는 필요에 따라 물리적 객체를 생성하고 삭제하는 방법을 보여줍니다. 이 장면은 여러 개의 상자 더미로 구성되어 있습니다. WASD 와 마우스를 사용하여 이동할 수 있으며, space 를 눌러 공을 쏠 수 있습니다.

이 장면은 뷰, 카메라, 조명과 같은 일반적인 Qt Quick 3D 객체들로 구성되어 있습니다:

PerspectiveCamera {
    id: camera
    position: Qt.vector3d(-4000, 5000, 10000)
    eulerRotation: Qt.vector3d(-20, -20, 0)
    clipFar: 200000
    clipNear: 100
}
DirectionalLight {
    eulerRotation: Qt.vector3d(-45, 45, 0)
    castsShadow: true
    brightness: 1
    shadowMapQuality: Light.ShadowMapQualityVeryHigh
    shadowMapFar: camera.clipFar
    shadowFactor: 50
    csmNumSplits: 2
    csmSplit1: 0.1
    csmSplit2: 0.3
    softShadowQuality: Light.PCF4
}

또한 정적 바닥을 추가합니다:

StaticRigidBody {
    eulerRotation: Qt.vector3d(-90, 0, 0)
    collisionShapes: PlaneShape {}
    Model {
        source: "#Rectangle"
        scale: Qt.vector3d(2000, 2000, 1)
        materials: PrincipledMaterial {
            baseColor: "green"
        }
        castsShadows: false
        receivesShadows: true
    }
}

오브젝트를 생성하는 스포너로 사용할 노드를 생성하고 뷰 안에 배치합니다:

Node {
    id: shapeSpawner
    property var instancesBoxes: []
    property var instancesSpheres: []
    property int stackCount: 0
    property var boxComponent: Qt.createComponent("Box.qml")
    property var sphereComponent: Qt.createComponent("Sphere.qml")

    function createStack(stackZ, numStacks) {
        let size = 10
        let extents = 400

        for (let i = 0; i < size; i++) {
            for (let j = 0; j < size - i; j++) {
                let x = j * 2 - size + i
                let y = i * 2 + 1
                let z = 5 * (stackZ - numStacks)
                let center = Qt.vector3d(x, y, z).times(0.5 * extents)
                let box = boxComponent.incubateObject(shapeSpawner, {
                                                          "position": center,
                                                          "xyzExtents": extents
                                                      })
                instancesBoxes.push(box)
            }
        }
    }

    function createBall(position, forward) {
        const diameter = 600
        const speed = 20000
        let settings = {
            "position": position,
            "sphereDiameter": diameter
        }
        let sphere = sphereComponent.createObject(shapeSpawner, settings)
        sphere.setLinearVelocity(forward.times(speed))
        instancesSpheres.push(sphere)

        if (sphere === null) {
            console.log("Error creating object")
        }
    }

    function reset() {
        // Only run method if previous stack has been created fully
        for (let i = 0; i < instancesBoxes.length; i++)
            if (!instancesBoxes[i].object)
                return

        instancesSpheres.forEach(sphere => {
                                     sphere.collisionShapes = []
                                     sphere.destroy()
                                 })
        instancesBoxes.forEach(box => {
                                   box.object.collisionShapes = []
                                   box.object.destroy()
                               })
        instancesSpheres = []
        instancesBoxes = []

        for (let stackI = 0; stackI < stackSlider.value; stackI++) {
            shapeSpawner.createStack(stackI, stackSlider.value)
        }
    }
}

세 가지 메서드가 있습니다: 스택을 생성하는 ` createStack `, 속도를 가진 공을 생성하는 ` createBall `, 그리고 씬을 초기화하는 ` reset `입니다. 실제로 스폰되는 상자와 구체는 각각의 QML 파일(`box.qml ` 및 ` sphere.qml`)에 저장되어 있습니다.

파일:

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