@qispace/vue3-player 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +18 -0
  2. package/dist/components/apartmentChooser/QiApartmentChooser.vue.d.ts +4 -0
  3. package/dist/components/apartmentChooser/QiApartmentChooser.vue.d.ts.map +1 -0
  4. package/dist/components/apartmentChooser/QiApartmentChooserNavigation.vue.d.ts +4 -0
  5. package/dist/components/apartmentChooser/QiApartmentChooserNavigation.vue.d.ts.map +1 -0
  6. package/dist/components/apartmentChooser/QiApartmentChooserRaster.vue.d.ts +4 -0
  7. package/dist/components/apartmentChooser/QiApartmentChooserRaster.vue.d.ts.map +1 -0
  8. package/dist/components/apartmentChooser/QiApartmentChooserRotator.vue.d.ts +4 -0
  9. package/dist/components/apartmentChooser/QiApartmentChooserRotator.vue.d.ts.map +1 -0
  10. package/dist/components/apartmentChooser/QiApartmentChooserSvg.vue.d.ts +4 -0
  11. package/dist/components/apartmentChooser/QiApartmentChooserSvg.vue.d.ts.map +1 -0
  12. package/dist/components/buildingPicker/QiBuildingChooser.vue.d.ts +3 -0
  13. package/dist/components/buildingPicker/QiBuildingChooser.vue.d.ts.map +1 -0
  14. package/dist/components/buildingPicker/QiBuildingChooserRaster.vue.d.ts +4 -0
  15. package/dist/components/buildingPicker/QiBuildingChooserRaster.vue.d.ts.map +1 -0
  16. package/dist/components/buildingPicker/QiBuildingChooserRasterOverlay.vue.d.ts +4 -0
  17. package/dist/components/buildingPicker/QiBuildingChooserRasterOverlay.vue.d.ts.map +1 -0
  18. package/dist/components/buildingPicker/QiBuildingChooserSceneImageStack.vue.d.ts +4 -0
  19. package/dist/components/buildingPicker/QiBuildingChooserSceneImageStack.vue.d.ts.map +1 -0
  20. package/dist/components/buildingPicker/QiBuildingChooserSunSimControl.vue.d.ts +5 -0
  21. package/dist/components/buildingPicker/QiBuildingChooserSunSimControl.vue.d.ts.map +1 -0
  22. package/dist/components/buildingPicker/QiBuildingChooserSvg.vue.d.ts +4 -0
  23. package/dist/components/buildingPicker/QiBuildingChooserSvg.vue.d.ts.map +1 -0
  24. package/dist/components/index.d.ts +4 -0
  25. package/dist/components/shared/QiFloatingCard.vue.d.ts +4 -0
  26. package/dist/components/shared/QiFloatingCard.vue.d.ts.map +1 -0
  27. package/dist/components/shared/QiHoverProbe.vue.d.ts +4 -0
  28. package/dist/components/shared/QiHoverProbe.vue.d.ts.map +1 -0
  29. package/dist/components/shared/QiNorthDirection.vue.d.ts +3 -0
  30. package/dist/components/shared/QiNorthDirection.vue.d.ts.map +1 -0
  31. package/dist/components/shared/QiZoomBox.vue.d.ts +4 -0
  32. package/dist/components/shared/QiZoomBox.vue.d.ts.map +1 -0
  33. package/dist/components/virtualTourV2/Disclaimer.vue.d.ts +4 -0
  34. package/dist/components/virtualTourV2/Disclaimer.vue.d.ts.map +1 -0
  35. package/dist/components/virtualTourV2/FullScreenButton.vue.d.ts +3 -0
  36. package/dist/components/virtualTourV2/FullScreenButton.vue.d.ts.map +1 -0
  37. package/dist/components/virtualTourV2/ManualSlideShow.vue.d.ts +4 -0
  38. package/dist/components/virtualTourV2/ManualSlideShow.vue.d.ts.map +1 -0
  39. package/dist/components/virtualTourV2/ManualSlideShowPlayer.vue.d.ts +4 -0
  40. package/dist/components/virtualTourV2/ManualSlideShowPlayer.vue.d.ts.map +1 -0
  41. package/dist/components/virtualTourV2/SingleImage.vue.d.ts +4 -0
  42. package/dist/components/virtualTourV2/SingleImage.vue.d.ts.map +1 -0
  43. package/dist/components/virtualTourV2/SocialShare.vue.d.ts +4 -0
  44. package/dist/components/virtualTourV2/SocialShare.vue.d.ts.map +1 -0
  45. package/dist/components/virtualTourV2/WaypointCarousel.vue.d.ts +4 -0
  46. package/dist/components/virtualTourV2/WaypointCarousel.vue.d.ts.map +1 -0
  47. package/dist/lib/virtualTour__/ApartmentConfig.d.ts +27 -0
  48. package/dist/lib/virtualTour__/ApartmentFiles.d.ts +7 -0
  49. package/dist/lib/virtualTour__/MinimapConfig.d.ts +23 -0
  50. package/dist/lib/virtualTour__/impl/HttpApartmentFiles.d.ts +19 -0
  51. package/dist/vue3-player.cjs.js +2 -0
  52. package/dist/vue3-player.esm.js +2992 -0
  53. package/dist/vue3-player.iife.js +3 -0
  54. package/dist/vue3-player.umd.js +3 -0
  55. package/package.json +65 -0
  56. package/src/components/apartmentChooser/QiApartmentChooser.vue +319 -0
  57. package/src/components/apartmentChooser/QiApartmentChooserNavigation.vue +88 -0
  58. package/src/components/apartmentChooser/QiApartmentChooserRaster.vue +408 -0
  59. package/src/components/apartmentChooser/QiApartmentChooserRotator.vue +202 -0
  60. package/src/components/apartmentChooser/QiApartmentChooserSvg.vue +257 -0
  61. package/src/components/apartmentChooser/index.js +5 -0
  62. package/src/components/buildingPicker/QiBuildingChooser.vue +61 -0
  63. package/src/components/buildingPicker/QiBuildingChooserRaster.vue +312 -0
  64. package/src/components/buildingPicker/QiBuildingChooserRasterOverlay.vue +96 -0
  65. package/src/components/buildingPicker/QiBuildingChooserSceneImageStack.vue +89 -0
  66. package/src/components/buildingPicker/QiBuildingChooserSunSimControl.vue +257 -0
  67. package/src/components/buildingPicker/QiBuildingChooserSvg.vue +414 -0
  68. package/src/components/buildingPicker/index.js +6 -0
  69. package/src/components/index.ts +4 -0
  70. package/src/components/shared/QiFloatingCard.vue +76 -0
  71. package/src/components/shared/QiHoverProbe.vue +22 -0
  72. package/src/components/shared/QiNorthDirection.vue +27 -0
  73. package/src/components/shared/QiZoomBox.vue +322 -0
  74. package/src/components/shared/index.js +4 -0
  75. package/src/components/virtualTourV2/Compass.vue +37 -0
  76. package/src/components/virtualTourV2/Disclaimer.vue +41 -0
  77. package/src/components/virtualTourV2/FloorLevel.vue +73 -0
  78. package/src/components/virtualTourV2/FullScreenButton.vue +23 -0
  79. package/src/components/virtualTourV2/InteriorSelector.vue +90 -0
  80. package/src/components/virtualTourV2/ManualSlideShow.vue +198 -0
  81. package/src/components/virtualTourV2/ManualSlideShowPlayer.vue +159 -0
  82. package/src/components/virtualTourV2/PlayerV2.vue +300 -0
  83. package/src/components/virtualTourV2/ScrollHelper.vue +74 -0
  84. package/src/components/virtualTourV2/SettingsUI.vue +355 -0
  85. package/src/components/virtualTourV2/SingleImage.vue +36 -0
  86. package/src/components/virtualTourV2/SocialShare.vue +163 -0
  87. package/src/components/virtualTourV2/TimeOfDay.vue +50 -0
  88. package/src/components/virtualTourV2/Tutorial.vue +690 -0
  89. package/src/components/virtualTourV2/ViewModeToggle.vue +24 -0
  90. package/src/components/virtualTourV2/VirtualTourV2.vue +876 -0
  91. package/src/components/virtualTourV2/WaypointCarousel.vue +162 -0
  92. package/src/components/virtualTourV2/index.js +1 -0
  93. package/src/components/virtualTourV2/minimapv2/MiniMapMap.vue +262 -0
  94. package/src/components/virtualTourV2/minimapv2/MiniMapV2.vue +110 -0
  95. package/src/components/virtualTourV2/minimapv2/MinimapCompass.vue +39 -0
  96. package/src/components/virtualTourV2/minimapv2/Moveable.vue +208 -0
  97. package/src/components/virtualTourV2/minimapv2/RotationMarkerV2.vue +79 -0
  98. package/src/components/virtualTourV2/minimapv2/SunsimulationSlider.vue +203 -0
  99. package/src/components/virtualTourV2/minimapv2/index.js +1 -0
  100. package/src/entry.esm.js +17 -0
  101. package/src/entry.js +13 -0
  102. package/src/entry.ts_ +17 -0
  103. package/src/lib/apartmentChooser/BuildingViewerModel.js +60 -0
  104. package/src/lib/apartmentChooser/CircularSlideshow.js +66 -0
  105. package/src/lib/apartmentChooser/RotationStep.js +31 -0
  106. package/src/lib/apartmentChooser/SceneRotator.js +25 -0
  107. package/src/lib/apartmentChooser/index.js +3 -0
  108. package/src/lib/apartmentChooser/throttle.js +15 -0
  109. package/src/lib/buildingPicker/BuildingMap.js +24 -0
  110. package/src/lib/buildingPicker/BuildingPickerResourceProvider.js +97 -0
  111. package/src/lib/buildingPicker/CanvasRaster.js +29 -0
  112. package/src/lib/buildingPicker/DayOfYearSelector.js +36 -0
  113. package/src/lib/buildingPicker/SampleRaster.js +14 -0
  114. package/src/lib/buildingPicker/index.js +5 -0
  115. package/src/lib/index.js +4 -0
  116. package/src/lib/shared/BatchLoadTracker.js +52 -0
  117. package/src/lib/shared/I18N.js +65 -0
  118. package/src/lib/shared/ResourceLoader.js +33 -0
  119. package/src/lib/shared/index.js +3 -0
  120. package/src/lib/virtualTour/CameraSnapshot.js +42 -0
  121. package/src/lib/virtualTour/FullscreenModel.js +69 -0
  122. package/src/lib/virtualTour/textures/arrow.png +0 -0
  123. package/src/lib/virtualTour/textures/compass-bg.png +0 -0
  124. package/src/lib/virtualTour/textures/compass-needle.png +0 -0
  125. package/src/lib/virtualTour/textures/compass-north.png +0 -0
  126. package/src/lib/virtualTour/textures/floor-1.svg +4 -0
  127. package/src/lib/virtualTour/textures/floor-2.svg +4 -0
  128. package/src/lib/virtualTour/textures/marker.png +0 -0
  129. package/src/lib/virtualTour/textures/tod-sun.png +0 -0
  130. package/src/lib/virtualTour__/ApartmentConfig.ts +80 -0
  131. package/src/lib/virtualTour__/ApartmentFiles.ts +8 -0
  132. package/src/lib/virtualTour__/CameraNavigator.js_ +74 -0
  133. package/src/lib/virtualTour__/CameraSnapshot.js +42 -0
  134. package/src/lib/virtualTour__/CoordConversions.js +43 -0
  135. package/src/lib/virtualTour__/FullscreenModel.js +69 -0
  136. package/src/lib/virtualTour__/MinimapConfig.ts +46 -0
  137. package/src/lib/virtualTour__/PlayerViewModel.js +423 -0
  138. package/src/lib/virtualTour__/config/ApartmentConfig.js +92 -0
  139. package/src/lib/virtualTour__/config/CameraConfig.js +97 -0
  140. package/src/lib/virtualTour__/config/Interaction.js +393 -0
  141. package/src/lib/virtualTour__/config/Panorama.js +78 -0
  142. package/src/lib/virtualTour__/config/PlayerConfig.js +812 -0
  143. package/src/lib/virtualTour__/config/rawinflate.export.js +833 -0
  144. package/src/lib/virtualTour__/config/shaders.js +24 -0
  145. package/src/lib/virtualTour__/impl/HttpApartmentFiles.ts +57 -0
  146. package/src/lib/virtualTour__/index.js +1 -0
  147. package/src/lib/virtualTour__/textures/arrow.png +0 -0
  148. package/src/lib/virtualTour__/textures/compass-bg.png +0 -0
  149. package/src/lib/virtualTour__/textures/compass-needle.png +0 -0
  150. package/src/lib/virtualTour__/textures/compass-north.png +0 -0
  151. package/src/lib/virtualTour__/textures/floor-1.svg +4 -0
  152. package/src/lib/virtualTour__/textures/floor-2.svg +4 -0
  153. package/src/lib/virtualTour__/textures/marker.png +0 -0
  154. package/src/lib/virtualTour__/textures/tod-sun.png +0 -0
  155. package/src/main.ts_ +24 -0
  156. package/src/shims-png.d.ts +4 -0
  157. package/src/shims-tsx.d.ts +11 -0
  158. package/src/shims-vue.d.ts +4 -0
  159. package/src/style.css +0 -0
  160. package/src/vite-env.d.ts +5 -0
@@ -0,0 +1,92 @@
1
+ /* eslint-disable */
2
+
3
+ import { CameraConfig } from './CameraConfig'
4
+
5
+ class ApartmentConfig {
6
+ constructor(json, scene) {
7
+ this._cameras = {}
8
+ this._apartmentID = json.id
9
+ this._version = json.version
10
+ for (let i = 0; i < json.cameras.length; i++) {
11
+ const camera = json.cameras[i]
12
+ this._cameras[camera.id.toUpperCase()] = new CameraConfig(
13
+ camera.id,
14
+ camera,
15
+ scene
16
+ )
17
+ }
18
+ }
19
+
20
+ get apartmentID() {
21
+ return this._apartmentID
22
+ }
23
+
24
+ get cameras() {
25
+ return this._cameras
26
+ }
27
+
28
+ findClosestVisibleCamera(point, ignoreCamera) {
29
+ let closestCamera = null
30
+ let minDistance = 10000
31
+ for (const key in this._cameras) {
32
+ const c = this._cameras[key]
33
+ if (c.isVisible && c != ignoreCamera) {
34
+ const dx = c.position.x - point.x
35
+ const dz = c.position.z - point.z
36
+ const distance = Math.sqrt(dx * dx + dz * dz)
37
+ if (distance < minDistance) {
38
+ minDistance = distance
39
+ closestCamera = c
40
+ }
41
+ }
42
+ }
43
+ return closestCamera
44
+ }
45
+
46
+ findClosestVisibleCameraInDirection(dx, dz, v, currentPanorama) {
47
+ for (let dist = 0; dist < 10; dist += 0.1) {
48
+ v.x = currentPanorama.cameraConfig.position.x + dx * dist
49
+ v.y = currentPanorama.cameraConfig.position.y
50
+ v.z = currentPanorama.cameraConfig.position.z + dz * dist
51
+ const c = this.findClosestVisibleCamera(v, null)
52
+ if (c != currentPanorama.cameraConfig) return c
53
+ }
54
+ return null
55
+ }
56
+
57
+ updateVisible(panorama) {
58
+ for (const key in this._cameras) {
59
+ // Check if something is in front of the given camera (at camera level), in that case it is invisible
60
+ const c = this._cameras[key]
61
+ var dx = c.position.x - panorama.cameraConfig.position.x
62
+ var dy = c.position.y - panorama.cameraConfig.position.y
63
+ var dz = c.position.z - panorama.cameraConfig.position.z
64
+ var distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
65
+ c.isVisible = panorama.getDepth(dx, dy, dz) > distance
66
+ c.mesh.visible = c.isVisible
67
+
68
+ // Check if the visible camera positions are obstructed at slightly above ground level
69
+ if (c.isVisible) {
70
+ var dx = c.position.x - panorama.cameraConfig.position.x
71
+ const floorOffset = c._floor_vertical_position + 0.2
72
+ var dy = floorOffset - panorama.cameraConfig.position.y
73
+ var dz = c.position.z - panorama.cameraConfig.position.z
74
+ var distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
75
+ c.isObstructed = panorama.getDepth(dx, dy, dz) <= distance
76
+ }
77
+ }
78
+ }
79
+
80
+ animateMarkers(panorama, elapsedTime) {
81
+ if (!panorama) return false
82
+ for (const key in this._cameras) {
83
+ const c = this._cameras[key]
84
+ const dist = c.position.distanceTo(panorama.cameraConfig.position)
85
+ const baseOpacityModifier = c.isObstructed ? 0.1 : 0.2
86
+ c.mesh.material.opacity =
87
+ (Math.sin(-elapsedTime * 3 + dist * 0.5) + 1) *
88
+ baseOpacityModifier
89
+ }
90
+ }
91
+ }
92
+ export { ApartmentConfig }
@@ -0,0 +1,97 @@
1
+ /* eslint-disable */
2
+ import * as THREE from 'three'
3
+ import markerTexture from '../textures/marker.png'
4
+ import { stringToVector3ConvertPositionFromUnity, stringToVector3ConvertRotationFromUnity } from '../CoordConversions'
5
+
6
+ function stringToVector3(str) {
7
+ const split = str.split(',', 3)
8
+ const v = new THREE.Vector3(
9
+ parseFloat(split[0]),
10
+ parseFloat(split[1]),
11
+ parseFloat(split[2])
12
+ )
13
+ return v
14
+ }
15
+
16
+ function stringToVector3ConvertPositionFromBlender(str) {
17
+ const split = str.split(',', 3)
18
+ const v = new THREE.Vector3(
19
+ -parseFloat(split[0]),
20
+ parseFloat(split[2]),
21
+ parseFloat(split[1])
22
+ )
23
+ return v
24
+ }
25
+
26
+ class CameraConfig {
27
+ constructor(
28
+ cameraID,
29
+ camera,
30
+ scene
31
+ ) {
32
+ this._cameraID = cameraID //.toUpperCase()
33
+ this._floor_vertical_position = parseFloat(camera.floor_vertical_position)
34
+ if (camera.uposition && camera.urotation) {
35
+ this._position = stringToVector3ConvertPositionFromUnity(
36
+ camera.uposition
37
+ )
38
+ this._rotation = stringToVector3ConvertRotationFromUnity(
39
+ camera.urotation
40
+ )
41
+ } else {
42
+ this._position = stringToVector3ConvertPositionFromBlender(
43
+ camera.position
44
+ )
45
+ this._rotation = stringToVector3(camera.rotation) // "90.00,180.00,41.59"
46
+ }
47
+
48
+ this._isVisible = true
49
+
50
+ const geometry = new THREE.PlaneGeometry(0.35, 0.35, 1, 1)
51
+ const material = new THREE.MeshBasicMaterial({
52
+ map: new THREE.TextureLoader().load(markerTexture),
53
+ transparent: true,
54
+ opacity: 0.0,
55
+ color: 0xffffff,
56
+ })
57
+
58
+ this._mesh = new THREE.Mesh(geometry, material)
59
+ this._mesh.rotation.x = -Math.PI / 2
60
+ scene.add(this._mesh)
61
+
62
+ this._mesh.position.set(
63
+ this._position.x,
64
+ this._floor_vertical_position,
65
+ this._position.z
66
+ )
67
+ }
68
+
69
+ get cameraID() {
70
+ return this._cameraID
71
+ }
72
+
73
+ get floor_vertical_position() {
74
+ return this._floor_vertical_position
75
+ }
76
+
77
+ get position() {
78
+ return this._position
79
+ }
80
+
81
+ get mesh() {
82
+ return this._mesh
83
+ }
84
+
85
+ get rotation() {
86
+ return this._rotation
87
+ }
88
+
89
+ get isVisible() {
90
+ return this._isVisible
91
+ }
92
+
93
+ set isVisible(v) {
94
+ this._isVisible = v
95
+ }
96
+ }
97
+ export { CameraConfig }
@@ -0,0 +1,393 @@
1
+ /* eslint-disable */
2
+ import * as THREE from 'three'
3
+
4
+ const DOM_KEY_LOCATION_STANDARD = 0
5
+ const DOM_KEY_LOCATION_LEFT = 1
6
+ const DOM_KEY_LOCATION_RIGHT = 2
7
+ const DOM_KEY_LOCATION_NUMPAD = 3
8
+
9
+ const NUMPAD_KEYS = [
10
+ 'ArrowDown',
11
+ 'ArrowUp',
12
+ 'ArrowLeft',
13
+ 'ArrowRight',
14
+ 'Home',
15
+ 'PageUp',
16
+ ]
17
+
18
+ class Interaction {
19
+ constructor(eventTarget, player) {
20
+ this._player = player
21
+ this.scaling = false
22
+ this.prevDist = NaN
23
+
24
+ if (!eventTarget || !player) return false
25
+
26
+ if (!player.consts.isMobile) {
27
+ eventTarget.addEventListener(
28
+ 'pointerleave',
29
+ () => {
30
+ player.isUserInteracting = false
31
+ },
32
+ { passive: false }
33
+ )
34
+ }
35
+
36
+ // Mouse events
37
+ eventTarget.addEventListener('mousedown', (e) => this.onMouseDown(e))
38
+ eventTarget.addEventListener('wheel', (e) => this.onDocumentMouseWheel(e))
39
+ eventTarget.addEventListener(
40
+ 'mousemove',
41
+ (e) => {
42
+ this.onMouseMove(e)
43
+ },
44
+ { passive: false }
45
+ )
46
+ eventTarget.addEventListener(
47
+ 'mouseup',
48
+ (e) => {
49
+ this.onMouseUp(e)
50
+ },
51
+ { passive: false }
52
+ )
53
+
54
+ // Touch events
55
+ eventTarget.addEventListener('touchstart', (e) => this.onTouchStart(e), {
56
+ passive: false,
57
+ })
58
+ eventTarget.addEventListener('touchmove', (e) => this.onTouchMove(e), {
59
+ passive: false,
60
+ })
61
+
62
+ // Use same handler for pointer{up,cancel,out,leave} events since
63
+ // the semantics for these events - in this app - are the same.
64
+ eventTarget.addEventListener('touchend', (e) => this.onTouchEnd(e), {
65
+ passive: false,
66
+ })
67
+ eventTarget.addEventListener('touchcancel', (e) => this.onTouchEnd(e), {
68
+ passive: false,
69
+ })
70
+
71
+ // Key events
72
+ window.addEventListener(
73
+ 'keydown',
74
+ (e) => {
75
+ this.onKeyDown(e)
76
+ },
77
+ { passive: false }
78
+ )
79
+ }
80
+
81
+ onTouchStart(e) {
82
+ if (e.touches.length === 2) {
83
+ this.scaling = true
84
+ } else {
85
+ this.onMouseDown(e)
86
+ }
87
+ }
88
+
89
+ onTouchMove(e) {
90
+ if (this.scaling) {
91
+ const dist = Math.hypot(
92
+ e.touches[0].pageX - e.touches[1].pageX,
93
+ e.touches[0].pageY - e.touches[1].pageY
94
+ )
95
+ if (!Number.isNaN(this.prevDist)) {
96
+ const currDist = this.prevDist - dist
97
+ const camera = this._player.camera
98
+ const fov = camera.fov + currDist * 0.2
99
+ camera.fov = THREE.MathUtils.clamp(fov, 35, 90)
100
+ camera.updateProjectionMatrix()
101
+ }
102
+ this.prevDist = dist
103
+ } else {
104
+ if (e.scale !== 1) {
105
+ e.preventDefault()
106
+ }
107
+ this.onMouseMove(e)
108
+ }
109
+ }
110
+
111
+ onTouchEnd(e) {
112
+ if (this.scaling) {
113
+ this.scaling = false
114
+ this.prevDist = NaN
115
+ } else {
116
+ this.onMouseUp(e)
117
+ }
118
+ }
119
+
120
+ removeEvent(ev) {
121
+ // Remove this event from the target's cache
122
+ const index = this.evCache.findIndex(
123
+ (cachedEv) => cachedEv.pointerId === ev.pointerId
124
+ )
125
+ this.evCache.splice(index, 1)
126
+ }
127
+
128
+ onDocumentMouseWheel(event) {
129
+ const camera = this._player.camera
130
+ const fov = camera.fov + event.deltaY * 0.05
131
+ camera.fov = THREE.MathUtils.clamp(fov, 35, 90)
132
+ camera.updateProjectionMatrix()
133
+ }
134
+
135
+ onMouseDown(event) {
136
+ if (this._player.isTransition) return false
137
+ this._player.transitionRotateCamera = true
138
+ this._player.isMouseDown = true
139
+ this._player.isUserInteracting = true
140
+ this._player.isMouseMoved = false
141
+
142
+ this._player.nMouseMove = 0
143
+
144
+ const clientX = this._player.getX(event)
145
+ const clientY = this._player.getY(event)
146
+
147
+ this._player.onMouseDownMouseX = clientX
148
+ this._player.onMouseDownMouseY = clientY
149
+ this._player.onMouseDownLon = this._player.lon
150
+ this._player.onMouseDownLat = this._player.lat
151
+ this._player.oldLon = this._player.lon
152
+ this._player.oldLat = this._player.lat
153
+ this._player.speedLon = 0
154
+ this._player.speedLat = 0
155
+ }
156
+
157
+ onMouseMove(event) {
158
+ if (!this._player.currentPanorama) return false
159
+ if (this._player.isUserInteracting === true) {
160
+ this._player.nMouseMove = this._player.nMouseMove + 1
161
+ this._player.isMouseMoved = this._player.nMouseMove > 4
162
+ const clientX = this._player.getX(event)
163
+ const clientY = this._player.getY(event)
164
+
165
+ this._player.lon =
166
+ (this._player.onMouseDownMouseX - clientX) *
167
+ this._player.mouseSensitivity +
168
+ this._player.onMouseDownLon
169
+ this._player.lat =
170
+ (clientY - this._player.onMouseDownMouseY) *
171
+ this._player.mouseSensitivity +
172
+ this._player.onMouseDownLat
173
+ }
174
+ const gamecontainer = document.getElementById('gameinstance')
175
+
176
+ if (!gamecontainer) return false
177
+
178
+ const rect = gamecontainer.getBoundingClientRect()
179
+
180
+ // Map to -1 to 1
181
+ this._player.mouse.x =
182
+ ((event.clientX - rect.left) / this._player.width) * 2 - 1
183
+ this._player.mouse.y =
184
+ -((event.clientY - rect.top) / this._player.height) * 2 + 1
185
+
186
+ this._player.raycaster.setFromCamera(
187
+ this._player.mouse,
188
+ this._player.camera
189
+ )
190
+ const t =
191
+ (this._player.currentPanorama.cameraConfig.floor_vertical_position -
192
+ this._player.raycaster.ray.origin.y) /
193
+ this._player.raycaster.ray.direction.y
194
+ this._player.mouseFloorHitpoint.set(
195
+ this._player.raycaster.ray.origin.x +
196
+ this._player.raycaster.ray.direction.x * t,
197
+ this._player.raycaster.ray.origin.y +
198
+ this._player.raycaster.ray.direction.y * t,
199
+ this._player.raycaster.ray.origin.z +
200
+ this._player.raycaster.ray.direction.z * t
201
+ )
202
+
203
+ // Handle arrow
204
+ if (this._player.arrowMesh) {
205
+ this._player.arrowMesh.position.set(
206
+ this._player.mouseFloorHitpoint.x,
207
+ this._player.mouseFloorHitpoint.y + 0.04,
208
+ this._player.mouseFloorHitpoint.z
209
+ )
210
+
211
+ const deltaZ =
212
+ this._player.arrowMesh.position.z -
213
+ this._player.currentPanorama.cameraConfig.position.z
214
+ const deltaX =
215
+ this._player.arrowMesh.position.x -
216
+ this._player.currentPanorama.cameraConfig.position.x
217
+ this._player.arrowMesh.rotation.z =
218
+ -Math.atan2(deltaZ, deltaX) - Math.PI / 2
219
+
220
+ this._player.arrowMesh.visible =
221
+ !this._player.isUserInteracting &&
222
+ !this._player.isLoadingPanorama &&
223
+ !this._player.isTransition
224
+ }
225
+ }
226
+
227
+ onMouseUp() {
228
+ this._player.isMouseDown = false
229
+ if (!this._player.isMouseMoved && !this._player.isTransition)
230
+ this.onMouseClick()
231
+ this._player.isUserInteracting = false
232
+ }
233
+
234
+ onMouseClick() {
235
+ const camera = this._player.apartmentConfig.findClosestVisibleCamera(
236
+ this._player.mouseFloorHitpoint,
237
+ null
238
+ )
239
+ if (camera && camera != this._player.currentPanorama.cameraConfig) {
240
+ this._player.loadPanorama(
241
+ camera.cameraID,
242
+ this._player.onPanoramaLoaded,
243
+ false
244
+ )
245
+ }
246
+ }
247
+
248
+ debugDepth(pointsTotal = 1000) {
249
+ for (let n = 0; n < pointsTotal; n++) {
250
+ const ray = new THREE.Vector3(
251
+ Math.random() * 2 - 1,
252
+ Math.random() * 2 - 1,
253
+ Math.random() * 2 - 1
254
+ )
255
+
256
+ ray.normalize()
257
+
258
+ const d = this._player.currentPanorama.getDepth(ray.x, ray.y, ray.z)
259
+
260
+ let gray = d * 0.1
261
+
262
+ if (gray > 1) gray = 1
263
+
264
+ if (gray < 0) gray = 0
265
+
266
+ gray = 1 - gray
267
+
268
+ const col = new THREE.Color(gray, gray, gray)
269
+
270
+ const geometry = new THREE.BoxGeometry(0.005, 0.005, 0.005)
271
+ const material = new THREE.MeshBasicMaterial({
272
+ color: col,
273
+ opacity: 0.2,
274
+ transparent: true,
275
+ })
276
+
277
+ const cube = new THREE.Mesh(geometry, material)
278
+
279
+ const x = this._player.currentPanorama.cameraConfig.position.x + ray.x * d
280
+ const y = this._player.currentPanorama.cameraConfig.position.y + ray.y * d
281
+ const z = this._player.currentPanorama.cameraConfig.position.z + ray.z * d
282
+
283
+ cube.position.set(x, y, z)
284
+ this._player.scene.add(cube)
285
+ }
286
+ }
287
+
288
+ isNumpadMoveKey(event) {
289
+ if (event.location === DOM_KEY_LOCATION_NUMPAD) {
290
+ if (NUMPAD_KEYS.includes(event.key || event.code)) {
291
+ return true
292
+ }
293
+ }
294
+ return false
295
+ }
296
+
297
+ debugCameraMovement(key, camera, amount = 0.1) {
298
+ switch (key) {
299
+ case 'ArrowUp':
300
+ camera.translateZ(-amount)
301
+ break
302
+ case 'ArrowDown':
303
+ camera.translateZ(amount)
304
+ break
305
+ case 'ArrowLeft':
306
+ camera.translateX(-amount)
307
+ break
308
+ case 'ArrowRight':
309
+ camera.translateX(amount)
310
+ break
311
+ case 'PageUp':
312
+ camera.translateY(amount)
313
+ break
314
+ case 'Home':
315
+ camera.translateY(-amount)
316
+ break
317
+ }
318
+ }
319
+
320
+ onKeyDown(event) {
321
+ if (this._player.isLoadingPanorama || this._player.isTransition) return
322
+ let dx = 0
323
+ let dz = 0
324
+
325
+ const key = event.key || event.code
326
+
327
+ if (window._debug && this.isNumpadMoveKey(event)) {
328
+ this.debugCameraMovement(key, this._player.camera)
329
+ return
330
+ }
331
+
332
+ switch (key) {
333
+ case 'a':
334
+ case 'A':
335
+ case 'KeyA':
336
+ case 'ArrowLeft':
337
+ dx = -1
338
+ break
339
+ case 'd':
340
+ case 'D':
341
+ case 'KeyD':
342
+ case 'ArrowRight':
343
+ dx = 1
344
+ break
345
+ case 'w':
346
+ case 'W':
347
+ case 'KeyW':
348
+ case 'ArrowUp':
349
+ dz = 1
350
+ break
351
+ case 's':
352
+ case 'S':
353
+ case 'KeyS':
354
+ case 'ArrowDown':
355
+ dz = -1
356
+ break
357
+ case 'q':
358
+ window._debug && this.debugDepth()
359
+ break
360
+ }
361
+
362
+ const v = new THREE.Vector3()
363
+ if (dz != 0 || dx != 0) {
364
+ v.y = 0
365
+ v.normalize()
366
+
367
+ this._player.camera.getWorldDirection(v)
368
+
369
+ if (dx != 0) {
370
+ dz = dx
371
+ const swap = v.x
372
+ v.x = -v.z
373
+ v.z = swap
374
+ }
375
+ const c =
376
+ this._player.apartmentConfig.findClosestVisibleCameraInDirection(
377
+ v.x * dz,
378
+ v.z * dz,
379
+ v,
380
+ this._player.currentPanorama
381
+ )
382
+
383
+ if (c) {
384
+ this._player.loadPanorama(
385
+ c.cameraID,
386
+ this._player.onPanoramaLoaded,
387
+ false
388
+ )
389
+ }
390
+ }
391
+ }
392
+ }
393
+ export { Interaction }
@@ -0,0 +1,78 @@
1
+ /* eslint-disable */
2
+ // We load three.min.js in index.html instead because importing it here gives error in IE11,
3
+ // using global commen instead
4
+
5
+ import * as THREE from 'three'
6
+ class Panorama {
7
+ constructor(texture, rawDepth, cameraConfig, version) {
8
+ texture.wrapS = THREE.RepeatWrapping
9
+ texture.wrapT = THREE.RepeatWrapping
10
+ this._texture = texture
11
+ this._version = version
12
+
13
+ console.log('QiSpace data version: ' + this._version)
14
+ if (this._version > 1.0) {
15
+ texture.repeat.set(-1, 1)
16
+ texture.offset.set(0.25, 0)
17
+ }
18
+
19
+ this._cameraConfig = cameraConfig
20
+ this._depth = new Float32Array(512 * 256)
21
+ let o = 4 // Skip 4 bytes header
22
+ for (let i = 0; i < this._depth.byteLength; i++)
23
+ this._depth[i] = (rawDepth[o++] | (rawDepth[o++] << 8)) / 512 // 512 samples per meter, max 128 meter
24
+ }
25
+
26
+ get texture() {
27
+ return this._texture
28
+ }
29
+
30
+ get depth() {
31
+ return this._depth
32
+ }
33
+
34
+ get cameraConfig() {
35
+ return this._cameraConfig
36
+ }
37
+
38
+ // Assumes the ray is cast from the middle of the panorama sphere
39
+ getDepth(rayX, rayY, rayZ) {
40
+ // Normalize
41
+ const length = Math.sqrt(rayX * rayX + rayY * rayY + rayZ * rayZ)
42
+ if (length > 0) {
43
+ rayX /= length
44
+ rayY /= length
45
+ rayZ /= length
46
+ }
47
+
48
+ // Invert
49
+ rayX *= -1
50
+ rayY *= -1
51
+ rayZ *= -1
52
+
53
+ const u = (Math.atan2(rayX, rayZ) / (2 * Math.PI) + 0.75) % 1
54
+ const v = 0.5 - Math.asin(rayY) / Math.PI
55
+
56
+ return this.getDepthTexture(u, v)
57
+ }
58
+
59
+ getDepthTexture(u, v) {
60
+ if (this._version > 1.0) {
61
+ //2.0+ format
62
+ u = -u + 0.25
63
+ const i = parseInt(u * 511) & 0x1ff
64
+ const j = parseInt(v * 255) & 0xff
65
+ return this._depth[i + j * 512]
66
+ } else {
67
+ //Legacy format
68
+ const i = parseInt(u * 511) & 0x1ff
69
+ const j = parseInt(v * 255) & 0xff
70
+ return this._depth[i + j * 512]
71
+ }
72
+ }
73
+
74
+ dispose() {
75
+ this._texture.dispose()
76
+ }
77
+ }
78
+ export { Panorama }