WasdController.qml 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2019 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of Qt Quick 3D.
  7. **
  8. ** $QT_BEGIN_LICENSE:GPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see https://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at https://www.qt.io/contact-us.
  16. **
  17. ** GNU General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU
  19. ** General Public License version 3 or (at your option) any later version
  20. ** approved by the KDE Free Qt Foundation. The licenses are as published by
  21. ** the Free Software Foundation and appearing in the file LICENSE.GPL3
  22. ** included in the packaging of this file. Please review the following
  23. ** information to ensure the GNU General Public License requirements will
  24. ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
  25. **
  26. ** $QT_END_LICENSE$
  27. **
  28. ****************************************************************************/
  29. import QtQuick
  30. import QtQuick3D
  31. Item {
  32. id: root
  33. property Node controlledObject: undefined
  34. property real speed: 1
  35. property real shiftSpeed: 3
  36. property real forwardSpeed: 5
  37. property real backSpeed: 5
  38. property real rightSpeed: 5
  39. property real leftSpeed: 5
  40. property real upSpeed: 5
  41. property real downSpeed: 5
  42. property real xSpeed: 0.1
  43. property real ySpeed: 0.1
  44. property bool xInvert: false
  45. property bool yInvert: true
  46. property bool mouseEnabled: true
  47. property bool keysEnabled: true
  48. readonly property bool inputsNeedProcessing: status.moveForward | status.moveBack
  49. | status.moveLeft | status.moveRight
  50. | status.moveUp | status.moveDown
  51. | status.useMouse
  52. property alias acceptedButtons: dragHandler.acceptedButtons
  53. implicitWidth: parent.width
  54. implicitHeight: parent.height
  55. focus: keysEnabled
  56. DragHandler {
  57. id: dragHandler
  58. target: null
  59. enabled: mouseEnabled
  60. onCentroidChanged: {
  61. mouseMoved(Qt.vector2d(centroid.position.x, centroid.position.y));
  62. }
  63. onActiveChanged: {
  64. if (active)
  65. mousePressed(Qt.vector2d(centroid.position.x, centroid.position.y));
  66. else
  67. mouseReleased(Qt.vector2d(centroid.position.x, centroid.position.y));
  68. }
  69. }
  70. TapHandler {
  71. onTapped: root.forceActiveFocus()
  72. }
  73. Keys.onPressed: (event)=> { if (keysEnabled) handleKeyPress(event) }
  74. Keys.onReleased: (event)=> { if (keysEnabled) handleKeyRelease(event) }
  75. function mousePressed(newPos) {
  76. root.forceActiveFocus()
  77. status.currentPos = newPos
  78. status.lastPos = newPos
  79. status.useMouse = true;
  80. }
  81. function mouseReleased(newPos) {
  82. status.useMouse = false;
  83. }
  84. function mouseMoved(newPos) {
  85. status.currentPos = newPos;
  86. }
  87. function forwardPressed() {
  88. status.moveForward = true
  89. status.moveBack = false
  90. }
  91. function forwardReleased() {
  92. status.moveForward = false
  93. }
  94. function backPressed() {
  95. status.moveBack = true
  96. status.moveForward = false
  97. }
  98. function backReleased() {
  99. status.moveBack = false
  100. }
  101. function rightPressed() {
  102. status.moveRight = true
  103. status.moveLeft = false
  104. }
  105. function rightReleased() {
  106. status.moveRight = false
  107. }
  108. function leftPressed() {
  109. status.moveLeft = true
  110. status.moveRight = false
  111. }
  112. function leftReleased() {
  113. status.moveLeft = false
  114. }
  115. function upPressed() {
  116. status.moveUp = true
  117. status.moveDown = false
  118. }
  119. function upReleased() {
  120. status.moveUp = false
  121. }
  122. function downPressed() {
  123. status.moveDown = true
  124. status.moveUp = false
  125. }
  126. function downReleased() {
  127. status.moveDown = false
  128. }
  129. function shiftPressed() {
  130. status.shiftDown = true
  131. }
  132. function shiftReleased() {
  133. status.shiftDown = false
  134. }
  135. function handleKeyPress(event)
  136. {
  137. switch (event.key) {
  138. case Qt.Key_W:
  139. case Qt.Key_Up:
  140. forwardPressed();
  141. break;
  142. case Qt.Key_S:
  143. case Qt.Key_Down:
  144. backPressed();
  145. break;
  146. case Qt.Key_A:
  147. case Qt.Key_Left:
  148. leftPressed();
  149. break;
  150. case Qt.Key_D:
  151. case Qt.Key_Right:
  152. rightPressed();
  153. break;
  154. case Qt.Key_R:
  155. case Qt.Key_PageUp:
  156. upPressed();
  157. break;
  158. case Qt.Key_F:
  159. case Qt.Key_PageDown:
  160. downPressed();
  161. break;
  162. case Qt.Key_Shift:
  163. shiftPressed();
  164. break;
  165. }
  166. }
  167. function handleKeyRelease(event)
  168. {
  169. switch (event.key) {
  170. case Qt.Key_W:
  171. case Qt.Key_Up:
  172. forwardReleased();
  173. break;
  174. case Qt.Key_S:
  175. case Qt.Key_Down:
  176. backReleased();
  177. break;
  178. case Qt.Key_A:
  179. case Qt.Key_Left:
  180. leftReleased();
  181. break;
  182. case Qt.Key_D:
  183. case Qt.Key_Right:
  184. rightReleased();
  185. break;
  186. case Qt.Key_R:
  187. case Qt.Key_PageUp:
  188. upReleased();
  189. break;
  190. case Qt.Key_F:
  191. case Qt.Key_PageDown:
  192. downReleased();
  193. break;
  194. case Qt.Key_Shift:
  195. shiftReleased();
  196. break;
  197. }
  198. }
  199. Timer {
  200. id: updateTimer
  201. interval: 16
  202. repeat: true
  203. running: root.inputsNeedProcessing
  204. onTriggered: {
  205. processInputs();
  206. }
  207. }
  208. function processInputs()
  209. {
  210. if (root.inputsNeedProcessing)
  211. status.processInput();
  212. }
  213. QtObject {
  214. id: status
  215. property bool moveForward: false
  216. property bool moveBack: false
  217. property bool moveLeft: false
  218. property bool moveRight: false
  219. property bool moveUp: false
  220. property bool moveDown: false
  221. property bool shiftDown: false
  222. property bool useMouse: false
  223. property vector2d lastPos: Qt.vector2d(0, 0)
  224. property vector2d currentPos: Qt.vector2d(0, 0)
  225. function updatePosition(vector, speed, position)
  226. {
  227. if (shiftDown)
  228. speed *= shiftSpeed;
  229. else
  230. speed *= root.speed
  231. var direction = vector;
  232. var velocity = Qt.vector3d(direction.x * speed,
  233. direction.y * speed,
  234. direction.z * speed);
  235. controlledObject.position = Qt.vector3d(position.x + velocity.x,
  236. position.y + velocity.y,
  237. position.z + velocity.z);
  238. }
  239. function negate(vector) {
  240. return Qt.vector3d(-vector.x, -vector.y, -vector.z)
  241. }
  242. function processInput() {
  243. if (controlledObject == undefined)
  244. return;
  245. if (moveForward)
  246. updatePosition(controlledObject.forward, forwardSpeed, controlledObject.position);
  247. else if (moveBack)
  248. updatePosition(negate(controlledObject.forward), backSpeed, controlledObject.position);
  249. if (moveRight)
  250. updatePosition(controlledObject.right, rightSpeed, controlledObject.position);
  251. else if (moveLeft)
  252. updatePosition(negate(controlledObject.right), leftSpeed, controlledObject.position);
  253. if (moveDown)
  254. updatePosition(negate(controlledObject.up), downSpeed, controlledObject.position);
  255. else if (moveUp)
  256. updatePosition(controlledObject.up, upSpeed, controlledObject.position);
  257. if (useMouse) {
  258. // Get the delta
  259. var rotationVector = controlledObject.eulerRotation;
  260. var delta = Qt.vector2d(lastPos.x - currentPos.x,
  261. lastPos.y - currentPos.y);
  262. // rotate x
  263. var rotateX = delta.x * xSpeed
  264. if (xInvert)
  265. rotateX = -rotateX;
  266. rotationVector.y += rotateX;
  267. // rotate y
  268. var rotateY = delta.y * -ySpeed
  269. if (yInvert)
  270. rotateY = -rotateY;
  271. rotationVector.x += rotateY;
  272. controlledObject.setEulerRotation(rotationVector);
  273. lastPos = currentPos;
  274. }
  275. }
  276. }
  277. }