RaycastReporter.re.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import * as RE from 'rogue-engine';
  2. import * as THREE from 'three'
  3. import { Vector2 } from 'three';
  4. import RaycastReceiver from './RaycastReceiver.re';
  5. export default class RaycastReporter extends RE.Component {
  6. // @RE.Prop("Select") something;
  7. // somethingOptions = ["One", "Two"]
  8. @RE.PropList("String") receiverClass = ["RaycastReceiver"]
  9. allHovered = []
  10. awake() {
  11. }
  12. start() {
  13. this.mouse = new THREE.Vector2(0, 0)
  14. this.raycaster = new THREE.Raycaster()
  15. this.updated = false
  16. RE.Input.touch.enabled = true
  17. }
  18. normalizeScreenInput(browserVector, gameVector) {
  19. const bounds = RE.Runtime.rogueDOMContainer.getBoundingClientRect();
  20. gameVector.x = ((browserVector.x - bounds.left) / bounds.width) * 2 - 1;
  21. gameVector.y = -((browserVector.y - bounds.top) / bounds.height) * 2 + 1
  22. }
  23. getMouseInput() {
  24. if (!RE.Input.mouse.isMoving) {
  25. return
  26. }
  27. this.normalizeScreenInput(RE.Input.mouse, this.mouse)
  28. this.updated = true
  29. }
  30. getTouchInput() {
  31. if (RE.Input.touch.touches.length == 0) {
  32. return
  33. }
  34. this.normalizeScreenInput(RE.Input.touch.touches[0], this.mouse)
  35. this.updated = true
  36. }
  37. update() {
  38. this.updated = false
  39. this.getMouseInput()
  40. this.getTouchInput()
  41. if (!this.updated) {
  42. return
  43. }
  44. this.raycaster.setFromCamera(this.mouse, this.object3d)
  45. let intersects = this.raycaster.intersectObjects(RE.App.currentScene.children)
  46. let listeningComponents = []
  47. intersects.forEach(intersect => {
  48. let object3d = RE.App.currentScene.getObjectByProperty('uuid', intersect.object.uuid)
  49. let component = RE.getComponent(RaycastReceiver, object3d)
  50. while (component == null && object3d.parent != null) {
  51. object3d = object3d.parent
  52. component = RE.getComponent(RaycastReceiver, object3d)
  53. }
  54. if (component != null) {
  55. listeningComponents = listeningComponents.filter((dataThing) => {
  56. dataThing.component.object3d.uuid != component.object3d.uuid
  57. })
  58. listeningComponents.push({ component: component, intersect: intersect })
  59. }
  60. })
  61. for (let i = 0; i < this.allHovered.length; i++) {
  62. let dataThing = this.allHovered[i]
  63. if (!listeningComponents.includes(dataThing)) {
  64. dataThing.component.onMouseOut()
  65. }
  66. }
  67. this.allHovered = []
  68. for (let i = 0; i < listeningComponents.length; i++) {
  69. let dataThing = listeningComponents[i]
  70. this.allHovered.push(dataThing)
  71. if (dataThing.component.onMouseOver(dataThing.intersect) === false) {
  72. break;
  73. }
  74. }
  75. }
  76. }
  77. RE.registerComponent(RaycastReporter);