Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Qt Quick 3D Physics - Cannon Example

Demonstrates how to spawn physical objects.

This example demonstrates how to create and delete physical objects on demand. The scene consists of a number of stacks of boxes. You can move around by using WASD and the mouse and shoot a ball by pressing space.

The scene is setup with the usual Qt Quick 3D objects like view, camera and light:

PerspectiveCamera {
    id: camera
    position: Qt.vector3d(-4000, 5000, 10000)
    eulerRotation : Qt.vector3d(-20, -20, 0)
    clipFar: 500000
    clipNear: 100
}
DirectionalLight {
    eulerRotation: Qt.vector3d(-45, 45, 0)
    castsShadow: true
    brightness: 1
    shadowMapQuality: Light.ShadowMapQualityVeryHigh
    shadowFactor: 100
}

We also add a static floor:

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

We create a Node we use as the spawner of objects and put inside our view:

Node {
    id: shapeSpawner
    property var instancesBoxes: []
    property var instancesSpheres: []
    property int stackCount: 0

    function createStack(stackZ) {
        var size = 10;
        var extents = 400;

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

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

    function createBall(position, forward) {
        var diameter = 600;
        var speed = 20000;
        var component = Qt.createComponent("sphere.qml");
        let sphere = component.createObject(shapeSpawner, {position: position, linearVelocity: forward.times(speed), sphereDiameter: diameter});
        instancesSpheres.push(sphere);

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

    function reset() {
        instancesSpheres.forEach(sphere => { sphere.destroy(); });
        instancesBoxes.forEach(boxes => { boxes.destroy(); });
        instancesSpheres = [];
        instancesBoxes = [];

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

We have three methods: createStack for creating a stack, createBall for creating a ball with velocity and reset for resetting the scene. The actual box and sphere that is spawn is stored in their own qml files (box.qml and sphere.qml).

Files:

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded