mirror of https://github.com/qt/qtdoc.git
328 lines
9.3 KiB
QML
328 lines
9.3 KiB
QML
// Copyright (C) 2024 The Qt Company Ltd.
|
||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||
import QtQuick
|
||
import QtQuick3D
|
||
import QtQuick3D.Helpers
|
||
import QtQuick3D.Physics
|
||
import QtQuick3D.Physics.Helpers as Helpers
|
||
import QtQuick3D.Xr
|
||
import QtQuick3D.Particles3D
|
||
|
||
XrView {
|
||
id: xrView
|
||
XrErrorDialog { id: err }
|
||
onInitializeFailed: (errorString) => err.run("XR physics-base teleportation", errorString)
|
||
referenceSpace: XrView.ReferenceSpaceStage
|
||
|
||
environment: ExtendedSceneEnvironment {
|
||
id: extendedSceneEnvironment
|
||
backgroundMode: SceneEnvironment.Color
|
||
probeExposure: 0.7
|
||
lightProbe: Texture {
|
||
source: "media/textures/OpenfootageNET_lowerAustria01-1024.hdr"
|
||
}
|
||
skyboxBlurAmount: 0.0
|
||
specularAAEnabled: true
|
||
clearColor: theFog.color
|
||
exposure: teleporter.screenVisibility
|
||
|
||
fog: Fog {
|
||
id: theFog
|
||
color:"gray"
|
||
enabled: true
|
||
depthEnabled: true
|
||
depthNear: 1500
|
||
depthFar: 3000
|
||
}
|
||
}
|
||
|
||
Component.onCompleted: {
|
||
ParticleResources.init(xrView)
|
||
}
|
||
|
||
xrOrigin: XrOrigin {
|
||
id: xrOrigin
|
||
|
||
camera: XrCamera {
|
||
id: trackingCamera
|
||
Prompter {
|
||
id: prompter
|
||
}
|
||
}
|
||
|
||
XrController {
|
||
id: xrLeftController
|
||
controller: XrController.ControllerLeft
|
||
poseSpace: XrController.AimPose
|
||
|
||
TorchGripper {
|
||
hand: XrInputAction.LeftHand
|
||
}
|
||
}
|
||
|
||
XrController {
|
||
id: xrRightController
|
||
controller: XrController.ControllerRight
|
||
poseSpace: XrController.AimPose
|
||
|
||
XrInputAction {
|
||
id: thumbstickX
|
||
hand: XrInputAction.RightHand
|
||
actionId: [XrInputAction.ThumbstickX]
|
||
}
|
||
|
||
XrInputAction {
|
||
id: thumbstickY
|
||
hand: XrInputAction.RightHand
|
||
actionId: [XrInputAction.ThumbstickY]
|
||
}
|
||
|
||
XrInputAction {
|
||
id: trackpadX
|
||
hand: XrInputAction.RightHand
|
||
actionId: [XrInputAction.TrackpadX]
|
||
}
|
||
|
||
XrInputAction {
|
||
id: trackpadY
|
||
hand: XrInputAction.RightHand
|
||
actionId: [XrInputAction.TrackpadY]
|
||
}
|
||
|
||
XrInputAction {
|
||
id: trackpadPressed
|
||
hand: XrInputAction.RightHand
|
||
actionId: [XrInputAction.TrackpadPressed]
|
||
}
|
||
|
||
TorchGripper {
|
||
hand: XrInputAction.RightHand
|
||
}
|
||
|
||
property real xValue: trackpadPressed.pressed ? trackpadX.value : thumbstickX.value
|
||
property real yValue: trackpadPressed.pressed ? trackpadY.value : thumbstickY.value
|
||
}
|
||
}
|
||
|
||
PhysicsbaseTeleporter {
|
||
id: teleporter
|
||
rayPicker: xrView
|
||
cameraOrigin: xrOrigin
|
||
camera: xrOrigin.camera
|
||
beamHandle: xrRightController
|
||
characterController: character
|
||
xStickValue: xrRightController.xValue
|
||
yStickValue: xrRightController.yValue
|
||
onDoTeleportation: (cameraOriginPosition, characterControllerPosition)=> {
|
||
xrOrigin.position = cameraOriginPosition
|
||
character.teleport(characterControllerPosition)
|
||
}
|
||
onDoRotation: (cameraOriginRotation, cameraOriginPosition)=> {
|
||
xrOrigin.rotation = cameraOriginRotation
|
||
xrOrigin.position = cameraOriginPosition
|
||
}
|
||
}
|
||
|
||
PhysicsWorld {
|
||
id: physicsWorld
|
||
running: true
|
||
scene: xrView
|
||
gravity: Qt.vector3d(0, -981, 0)
|
||
}
|
||
|
||
CharacterController {
|
||
id: character
|
||
property bool inTheHouse: true
|
||
signal enteredTheHouse
|
||
signal leftTheHouse
|
||
|
||
onEnteredTheHouse: {
|
||
inTheHouse = true
|
||
}
|
||
onLeftTheHouse: {
|
||
inTheHouse = false
|
||
}
|
||
|
||
property vector3d startPos: Qt.vector3d(0, 200, 0)
|
||
scale: Qt.vector3d(0.5, 1.75, 0.5)
|
||
Component.onCompleted: {
|
||
prompter.prompt = Prompter.DarknessFalling
|
||
prompter.prompt = Prompter.PickupTorch
|
||
teleporter.teleportTo(character.startPos)
|
||
}
|
||
|
||
collisionShapes: CapsuleShape {
|
||
id: capsuleShape
|
||
}
|
||
|
||
onShapeHit: (body, position, impulse, normal)=>{
|
||
if (body.objectName === "Ground")
|
||
leftTheHouse()
|
||
else if (body.objectName === "HouseFloor")
|
||
enteredTheHouse()
|
||
}
|
||
|
||
enableShapeHitCallback: true
|
||
sendTriggerReports: true
|
||
gravity: physicsWorld.gravity.times(10) //make it fall faster
|
||
}
|
||
|
||
Ground {
|
||
|
||
}
|
||
|
||
Fence {
|
||
|
||
}
|
||
|
||
House {
|
||
|
||
}
|
||
|
||
Chair {
|
||
eulerRotation: Qt.vector3d(0, -45, 0)
|
||
position: Qt.vector3d(-200, 200, -300)
|
||
}
|
||
|
||
Table {
|
||
position: Qt.vector3d(-30, 200, -300)
|
||
}
|
||
|
||
Torch {
|
||
id: torch
|
||
position: Qt.vector3d(0, 350, -300)
|
||
eulerRotation: Qt.vector3d(-90, 0, 0)
|
||
windEnabled: !character.inTheHouse
|
||
|
||
onAttachedToChanged: {
|
||
if (attachedTo)
|
||
prompter.prompt = Prompter.LightupTorch
|
||
}
|
||
|
||
onIsOnChanged: {
|
||
prompter.prompt = Prompter.DefendCrop
|
||
}
|
||
}
|
||
|
||
Grass {
|
||
id: field
|
||
z: -1200
|
||
}
|
||
|
||
Stands {
|
||
|
||
}
|
||
|
||
Campfire {
|
||
id: campFire1
|
||
position: Qt.vector3d(1000, 185 ,1000)
|
||
function updateColors(){
|
||
if (campFire1.isOn && campFire2.isOn &&
|
||
campFire3.isOn && campFire4.isOn) {
|
||
campFire1.fireColor = "white"
|
||
campFire1.lightColor = Qt.lighter("orange", 1.5)
|
||
enemy.run = true
|
||
}else {
|
||
campFire1.fireColor = "orange"
|
||
campFire1.lightColor = "orange"
|
||
enemy.run = false
|
||
}
|
||
|
||
campFire2.fireColor = campFire1.fireColor
|
||
campFire2.lightColor = campFire1.lightColor
|
||
campFire3.fireColor = campFire1.fireColor
|
||
campFire3.lightColor = campFire1.lightColor
|
||
campFire4.fireColor = campFire1.fireColor
|
||
campFire4.lightColor = campFire1.lightColor
|
||
}
|
||
onIsOnChanged: {
|
||
campFire1.updateColors()
|
||
}
|
||
}
|
||
|
||
Campfire {
|
||
id: campFire2
|
||
position: Qt.vector3d(1000, 185 ,-1000)
|
||
onIsOnChanged: {
|
||
campFire1.updateColors()
|
||
}
|
||
}
|
||
|
||
Campfire {
|
||
id: campFire3
|
||
position: Qt.vector3d(-1000, 185 ,1000)
|
||
onIsOnChanged: {
|
||
campFire1.updateColors()
|
||
}
|
||
}
|
||
|
||
Campfire {
|
||
id: campFire4
|
||
position: Qt.vector3d(-1000, 185 ,-1000)
|
||
onIsOnChanged: {
|
||
campFire1.updateColors()
|
||
}
|
||
}
|
||
|
||
Smoke {
|
||
id: enemy
|
||
readonly property real maxY: 5000
|
||
readonly property real startY: 40000
|
||
property bool run: false
|
||
position: Qt.vector3d(0, startY, 0)
|
||
color: "black"
|
||
colorVariation: 0.0
|
||
size: run ? 6.0 : 4.0
|
||
|
||
FrameAnimation {
|
||
running: true
|
||
property real time: 0
|
||
property real fieldEncounterTime: 0
|
||
onTriggered: {
|
||
time += 0.5 * frameTime
|
||
let enemyLinearY = enemy.scenePosition.y / enemy.maxY
|
||
let enemyOffset = enemyLinearY * 5000 + 200
|
||
let targetBase = field.scenePosition
|
||
let enemyMovementSpeed = 20.
|
||
let chaseTheCamera = false
|
||
|
||
if (fieldEncounterTime > 0.99 && !character.inTheHouse && !enemy.run) {
|
||
targetBase = xrOrigin.camera.scenePosition
|
||
enemyOffset = 20
|
||
chaseTheCamera = true
|
||
enemyMovementSpeed = 5
|
||
}
|
||
|
||
let target = Qt.vector3d(targetBase.x + Math.cos(time) * enemyOffset ,
|
||
targetBase.y + Math.abs(Math.cos(time)) * 100,
|
||
targetBase.z + Math.sin(time) * enemyOffset)
|
||
if (torch.isOn) {
|
||
let enemyToTorchDir = torch.scenePosition.minus(enemy.position)
|
||
let enemyToTorchLen = enemyToTorchDir.length()
|
||
let dis = Math.max(0, 500 - enemyToTorchLen)
|
||
target.y += dis * dis * dis
|
||
}
|
||
|
||
if (enemy.run)
|
||
target.y += enemy.maxY
|
||
|
||
if (!chaseTheCamera) {
|
||
field.baseColor = ""
|
||
|
||
if (field.scenePosition.minus(enemy.scenePosition).length() < 500)
|
||
fieldEncounterTime += frameTime * 0.02
|
||
else
|
||
fieldEncounterTime -= frameTime * 0.01
|
||
|
||
fieldEncounterTime = Math.min(Math.max(fieldEncounterTime, 0), 1.)
|
||
|
||
field.baseColor = Qt.darker("white", Math.exp(fieldEncounterTime))
|
||
}
|
||
|
||
let enemyToTargetDir = target.minus(enemy.scenePosition).normalized().times(enemyMovementSpeed)
|
||
enemy.position = enemy.scenePosition.plus(enemyToTargetDir)
|
||
}
|
||
}
|
||
}
|
||
}
|