이 페이지에서

Qt Quick 3D Physics - 임펠러 예제

트리거 바디와 충돌 정보를 사용하는 방법을 보여줍니다.

초록색 표면 위에 파란색 구체가 있고, 그 위에 분홍색 직사각형 블록이 놓여 있으며, 그 위에는 빨간색 구체가 떠 있는 모습을 보여주는 3D 렌더링 스크린샷

이 예제는 트리거 바디와 충돌 정보를 사용하는 방법을 보여줍니다. 이 씬은 녹색 정적 평면, 빨간색 동적 구체, 분홍색 박스 트리거, 파란색 정적 구체로 구성되어 있습니다. 빨간색 구체가 트리거 바디와 겹치면 노란색으로 변하고, 파란색 구체와 충돌하면 밀려나갑니다.

설정

평소와 마찬가지로 ‘ PhysicsWorld ’를 추가해야 합니다:

PhysicsWorld {
    gravity: Qt.vector3d(0, -490, 0)
    scene: viewport.scene
}

또한 장면 오브젝트를 배치할 View3D 도 추가합니다. 여기에는 시각적 환경을 위한 몇 가지 설정이 있습니다:

environment: SceneEnvironment {
    clearColor: "#d6dbdf"
    backgroundMode: SceneEnvironment.Color
}

PerspectiveCamera {
    position: Qt.vector3d(0, 200, 1000)
    clipFar: 2000
    clipNear: 1
}

DirectionalLight {
    eulerRotation.x: -45
    eulerRotation.y: 45
    castsShadow: true
    brightness: 1
    shadowFactor: 50
}

물리적 오브젝트

일반적인 정적 평면이 있습니다:

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

동적 구체는 다음과 같이 정의됩니다:

DynamicRigidBody {
    id: sphere
    massMode: DynamicRigidBody.CustomDensity
    density: 0.00001
    position: Qt.vector3d(0, 600, 0)
    property bool inArea: false
    sendContactReports: true
    receiveTriggerReports: true

    onEnteredTriggerBody: {
        inArea = true
    }
    onExitedTriggerBody: {
        inArea = false
    }

    collisionShapes: SphereShape {}
    Model {
        source: "#Sphere"
        materials: PrincipledMaterial {
            baseColor: sphere.inArea ? "yellow" : "red"
        }
    }
}

inArea 속성은 구체가 박스 트리거 바디와 겹치는 시점을 추적하기 위해 사용하는 사용자 정의 속성입니다. 이 값은 baseColor 속성에 활용되어, 구체가 박스와 겹칠 때는 노란색으로, 그렇지 않을 때는 빨간색으로 표시됩니다. 구체가 접촉 보고에 참여하도록 하려면 ` sendContactReports ` 속성을 ` true`로 설정해야 합니다. 또한 구체가 트리거 영역( TriggerBody)에 진입하거나 이탈할 때 콜백을 수신하도록 하려면 ` receiveContactReports ` 속성도 ` true`로 설정해야 합니다. 구체에 ` enteredTriggerBody ` 및 ` exitedTriggerBody ` 신호 메서드를 구현하여, 트리거 영역에 진입하거나 이탈할 때 ` inArea ` 속성을 ` true ` 또는 ` false `로 설정합니다.

이제 트리거 바디를 살펴보겠습니다:

TriggerBody {
    position: Qt.vector3d(0, 350, 0)
    scale: Qt.vector3d(1, 2, 1)

    collisionShapes: BoxShape {
        id: boxShape
    }
    Model {
        source: "#Cube"
        materials: PrincipledMaterial {
            baseColor: Qt.rgba(1, 0, 1, 0.2)
            alphaMode: PrincipledMaterial.Blend
        }
    }
}

qml 타입은 TriggerBody 이며, 충돌 기능이 비활성화되어 있다는 점을 제외하면 정적 바디와 동일하게 작동합니다. 대신 구체에서 enteredTriggerBody 및 exitedTriggerBody 메서드 호출을 트리거합니다.

마지막으로 임펠러를 살펴보겠습니다:

StaticRigidBody {
    position: Qt.vector3d(0, 0, 0)
    scale: Qt.vector3d(2, 2, 2)
    receiveContactReports: true

    collisionShapes: SphereShape {}

    Model {
        source: "#Sphere"
        materials: PrincipledMaterial {
            baseColor: "blue"
        }
    }

    onBodyContact: (body, positions, impulses, normals) => {
        for (let normal of normals) {
            let velocity = normal.times(-700)
            if (body instanceof DynamicRigidBody) {
                (body as DynamicRigidBody).setLinearVelocity(velocity)
            }
        }
    }
}

이것은 정적 바디이며, 충돌 콜백을 활성화하기 위해 ` receiveContactReports `을 ` true `로 설정했습니다. 콜백 ` bodyContact `은 충돌이 보고될 때마다 호출됩니다. 이 메서드 내에서 ` setLinearVelocity `를 호출하여 충돌 법선 벡터의 반대 방향으로 선형 속도를 설정함으로써 임펠러를 시뮬레이션합니다.

파일:

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