@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,812 @@
1
+ /* eslint-disable */
2
+
3
+ /**
4
+ * Putting global variables (shared between qi.js, transition.js, etc)
5
+ */
6
+ import * as THREE from 'three'
7
+ import { isBrowser } from 'browser-or-node'
8
+ import { Panorama } from './Panorama'
9
+ import { ApartmentConfig } from './ApartmentConfig'
10
+ import { inflate } from './rawinflate.export'
11
+ import { vertexShader, fragmentShader } from './shaders'
12
+ import arrowTexture from '../textures/arrow.png'
13
+ import { clampAngle } from '../CoordConversions'
14
+
15
+ function deg2rad(degAngle) {
16
+ return (degAngle * Math.PI) / 180.0
17
+ }
18
+
19
+ export class RenderLoop {
20
+ constructor(renderFn) {
21
+ this._clock = new THREE.Clock(false)
22
+ this._listeners = [renderFn]
23
+ }
24
+
25
+ addListener(l) {
26
+ this._listeners.push(l)
27
+ }
28
+
29
+ removeListener(l) {
30
+ this._listeners = this._listeners.filter((each) => each !== l)
31
+ }
32
+
33
+ start() {
34
+ this._clock.start()
35
+ this._animate()
36
+ }
37
+
38
+ stop() {
39
+ this._clock.stop()
40
+ this._listeners = []
41
+ }
42
+
43
+ _animate() {
44
+ if (this._clock.running) {
45
+ window.requestAnimationFrame(() => this._animate())
46
+ this._notifyListeners(this._clock.elapsedTime, this._clock.getDelta())
47
+ }
48
+ }
49
+
50
+ _notifyListeners(elapsedTime, timeDelta) {
51
+ this._listeners.forEach((l) => l(elapsedTime, timeDelta))
52
+ }
53
+ }
54
+
55
+ class Consts {
56
+ constructor() {
57
+ this._isMobile =
58
+ /Android|webOS|iPhone|iPad|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(
59
+ navigator.userAgent
60
+ )
61
+ this._build = '123' // TODO fix
62
+ }
63
+
64
+ get isMobile() {
65
+ return this._isMobile
66
+ }
67
+
68
+ get build() {
69
+ return this._build
70
+ }
71
+ }
72
+
73
+ // TODO 1: Move all constants to Consts class
74
+ // TODO 2: Move all url stuff to URL class
75
+ // TODO 3: Move all
76
+ export default class Player {
77
+ constructor(settings) {
78
+ // Constants class
79
+ this._consts = new Consts()
80
+
81
+ // Settings
82
+ this._target = settings.target
83
+ this._fileResolver = settings.fileResolver
84
+ this._onPlayerCameraChanged = settings.onPlayerCameraChanged
85
+ this._addBuildVersionToUrls =
86
+ settings.addBuildVersionToUrls !== undefined
87
+ ? settings.addBuildVersionToUrls
88
+ : true
89
+ this._panoramaOrientation = settings.panoramaOrientation
90
+
91
+ // Dimensions
92
+ this._height = this._target.clientHeight
93
+ this._width = this._target.clientWidth
94
+
95
+ // Player components
96
+ this._panoramaSphere = null
97
+ this._adornments = new THREE.Group()
98
+ this._scene = new THREE.Scene()
99
+ this._scene.add(this._adornments)
100
+ this._renderer = new THREE.WebGLRenderer({ preserveDrawingBuffer: true })
101
+ this._camera = new THREE.PerspectiveCamera(
102
+ 70,
103
+ this._width / this._height,
104
+ 0.01,
105
+ 1100
106
+ )
107
+ this._camera.target = new THREE.Vector3(0, 0, 0)
108
+
109
+ this._arrowMesh = null
110
+
111
+ this._raycaster = new THREE.Raycaster()
112
+
113
+ // Player settings
114
+ // fov, width, height, near, far
115
+
116
+ // Apartment
117
+ this._apartmentConfig = null
118
+ // Other stuff
119
+ this._currentPanorama = null
120
+ this._isUserInteracting = false
121
+
122
+ // Panorama
123
+ this._isLoadingPanorama = false
124
+ this._panoramaCameraID = null
125
+
126
+ // Mouse interaction
127
+
128
+ this.mouseSensitivityFactor = settings.mouseSensitivityFactor
129
+ this._mouse = new THREE.Vector2()
130
+ this._mouseFloorHitpoint = new THREE.Vector3()
131
+ this._mouseSensitivity = this.mouseSensitivityFactor * (120.0 / Math.min(screen.width, screen.height))
132
+
133
+ // Positions
134
+ this._isMouseMoved = false
135
+ this._nMouseMove = 0
136
+ this._onMouseDownMouseX = 0
137
+ this._onMouseDownMouseY = 0
138
+ this._onMouseDownLon = 0
139
+ this._onMouseDownLat = 0
140
+ ; (this._lon = 0), (this._lat = 0)
141
+ this._isMouseDown = false
142
+ ; (this._speedLon = 0), (this._speedLat = 0)
143
+ ; (this._oldLon = 0), (this._oldLat = 0)
144
+
145
+ // Transitions
146
+ this._isTransition = false
147
+ this._transitionScene1 = null
148
+ this._transitionScene2 = null
149
+ this._panoramaSphere1 = null
150
+ this._panoramaSphere2 = null
151
+ this._compositeCamera = null
152
+ this._panoramaSphereTemplate = null
153
+ this._transitionRotateCamera = false
154
+ this._lat1, this._lon1
155
+ this._lat2, this._lon2
156
+ this._panorama1
157
+ this._panorama2
158
+ this._panoramaSphere1
159
+ this._panoramaSphere2
160
+ this._transition
161
+ this._bufferTexture1
162
+ this._bufferTexture2
163
+ this._compositeCamera
164
+ this._targetMesh
165
+ this._shaderMaterial
166
+ this._transitionScene1
167
+ this._transitionScene2
168
+ this._compositeScene
169
+
170
+ // Fixing this in callback functions
171
+ this.onPanoramaLoaded = this.onPanoramaLoaded.bind(this)
172
+ }
173
+
174
+ start(apartmentData, cameraId, startedCb) {
175
+ this._apartmentConfig = new ApartmentConfig(apartmentData, this._adornments)
176
+ const onLoaded = (panorama) => {
177
+ this.onFirstPanoramaLoaded(panorama)
178
+ if (startedCb) startedCb(this)
179
+ }
180
+ this.initializeTransitions()
181
+ this.loadPanorama(cameraId, onLoaded, false)
182
+ }
183
+
184
+ newPanorama(apartmentConfig, panoramaData) {
185
+ const panorama = new Panorama(
186
+ panoramaData.texture,
187
+ panoramaData.depth,
188
+ apartmentConfig.cameras[this._panoramaCameraID.toUpperCase()],
189
+ apartmentConfig._version
190
+ )
191
+ return panorama
192
+ }
193
+
194
+ takeCameraSnapshot() {
195
+ this._adornments.visible = false
196
+ try {
197
+ this.renderScene()
198
+ return this._renderer.domElement.toDataURL()
199
+ } finally {
200
+ this._adornments.visible = true
201
+ }
202
+ }
203
+
204
+ createDepthSphere(panorama, sphere) {
205
+ const positionAttributeTemplate =
206
+ this._panoramaSphereTemplate.geometry.attributes.position
207
+ const positionAttribute = sphere.geometry.attributes.position
208
+ for (let i = 0; i < positionAttribute.count; i++) {
209
+ // Read the position from the original sphere shape, to avoid any inaccuracies over time
210
+ let x = positionAttributeTemplate.getX(i)
211
+ let y = positionAttributeTemplate.getY(i)
212
+ let z = positionAttributeTemplate.getZ(i)
213
+ // Normalize
214
+ const length = Math.sqrt(x * x + y * y + z * z)
215
+ if (length > 0) {
216
+ x /= length
217
+ y /= length
218
+ z /= length
219
+ }
220
+ const d = panorama.getDepth(x, y, z)
221
+ positionAttribute.setXYZ(i, x * d, y * d, z * d)
222
+ }
223
+ sphere.geometry.attributes.position.needsUpdate = true
224
+ }
225
+
226
+ createPanoramaSphere(radius, resolution) {
227
+ const sphereGeometry = new THREE.SphereBufferGeometry(
228
+ radius,
229
+ resolution,
230
+ resolution
231
+ )
232
+
233
+ const material = new THREE.MeshBasicMaterial({
234
+ side: THREE.DoubleSide,
235
+ })
236
+
237
+ const panoramaSphere = new THREE.Mesh(sphereGeometry, material)
238
+
239
+ // Remap UV coordinates
240
+ const uvAttribute = panoramaSphere.geometry.attributes.uv
241
+
242
+ for (var i = 0; i < uvAttribute.count; i++) {
243
+ const u = uvAttribute.getX(i)
244
+ const v = uvAttribute.getY(i)
245
+ uvAttribute.setXY(i, u, v)
246
+ }
247
+ return panoramaSphere
248
+ }
249
+
250
+ init() {
251
+ // Sphere
252
+ this._panoramaSphere = this.createPanoramaSphere(1000, 120)
253
+ this._panoramaSphere.material.map = this._currentPanorama.texture
254
+
255
+ // Scene
256
+ this._scene.add(this._panoramaSphere)
257
+
258
+ // Renderer
259
+ if (isBrowser) {
260
+ this._renderer.setPixelRatio(window.devicePixelRatio)
261
+ }
262
+ this._renderer.setSize(this._width, this._height)
263
+
264
+ // Add to DOM
265
+ this._target.innerHTML = ''
266
+ this._target.appendChild(this._renderer.domElement)
267
+
268
+ // Set camera position
269
+ const pos = this._currentPanorama.cameraConfig.position
270
+ this._panoramaSphere.position.set(pos.x, pos.y, pos.z)
271
+ this._camera.position.set(pos.x, pos.y, pos.z)
272
+
273
+ // Create arrow
274
+ if (!this._isMobile) this._arrowMesh = this.createPointer(arrowTexture)
275
+ }
276
+
277
+ resize(element) {
278
+ this._width = element.clientWidth
279
+ this._height = element.clientHeight
280
+
281
+ this.camera.aspect = this._width / this._height
282
+ this.camera.updateProjectionMatrix()
283
+ this.renderer.setSize(this._width, this._height)
284
+ }
285
+
286
+ setCamera(cameraID) {
287
+ if (cameraID !== this._panoramaCameraID) {
288
+ if (!this.isLoadingPanorama && !this.isTransition)
289
+ this.loadPanorama(cameraID, this.onPanoramaLoaded, true)
290
+ }
291
+ }
292
+
293
+ onPanoramaLoaded(panorama) {
294
+ this.startTransition(this, panorama)
295
+ }
296
+
297
+ onFirstPanoramaLoaded(panorama) {
298
+ this._currentPanorama = panorama
299
+ this.init()
300
+ this.lat = this.clampAngle(panorama.cameraConfig.rotation.x)
301
+ this.lon = this.clampAngle(panorama.cameraConfig.rotation.y)
302
+ }
303
+
304
+ incomingPanoramaData(callback, loadedData) {
305
+ if (loadedData.texture && loadedData.depth) {
306
+ const newPanorama = this.newPanorama(this._apartmentConfig, loadedData)
307
+ if (callback) callback(newPanorama)
308
+ this._apartmentConfig.updateVisible(newPanorama)
309
+ this._isLoadingPanorama = false
310
+ }
311
+ }
312
+
313
+ loadPanorama(cameraID, callback, rotateCamera) {
314
+ this._isLoadingPanorama = true
315
+ this._panoramaCameraID = cameraID
316
+ this._transitionRotateCamera = rotateCamera
317
+
318
+ const loadedData = { texture: null, depth: null }
319
+
320
+ if (this._arrowMesh) this._arrowMesh.visible = false
321
+
322
+ // Load 360 image
323
+ const loader = new THREE.TextureLoader()
324
+ const self = this
325
+ loader.load(
326
+ this.getTextureName(cameraID),
327
+ function (texture) {
328
+ loadedData.texture = texture
329
+ self.incomingPanoramaData(callback, loadedData)
330
+ },
331
+ undefined,
332
+ function (err) {
333
+ try {
334
+ console.error(this.getTextureName(cameraID) + ' : ' + err)
335
+ } catch (e) {
336
+ console.error(e)
337
+ }
338
+ }
339
+ )
340
+
341
+ // Load depth data
342
+ const oReq = new XMLHttpRequest()
343
+ oReq.open('GET', this.getDepthName(cameraID), true)
344
+ oReq.responseType = 'arraybuffer'
345
+
346
+ oReq.onload = () => {
347
+ const arrayBuffer = oReq.response // Note: not oReq.responseText
348
+ if (!arrayBuffer) return false
349
+ const byteArray = new Uint8Array(arrayBuffer)
350
+ loadedData.depth = inflate(byteArray)
351
+ this.incomingPanoramaData(callback, loadedData)
352
+ }
353
+ oReq.send(null)
354
+ }
355
+
356
+ startTransition(player, _panorama2) {
357
+ this._panorama1 = player.currentPanorama
358
+ this._panorama2 = _panorama2
359
+
360
+ this._panoramaSphere1.position.set(
361
+ this._panorama1.cameraConfig.position.x,
362
+ this._panorama1.cameraConfig.position.y,
363
+ this._panorama1.cameraConfig.position.z
364
+ )
365
+ this._panoramaSphere2.position.set(
366
+ this._panorama2.cameraConfig.position.x,
367
+ this._panorama2.cameraConfig.position.y,
368
+ this._panorama2.cameraConfig.position.z
369
+ )
370
+ this._panoramaSphere1.material.map = this._panorama1.texture
371
+ this._panoramaSphere2.material.map = this._panorama2.texture
372
+
373
+ this.createDepthSphere(this._panorama1, this._panoramaSphere1)
374
+ this.createDepthSphere(this._panorama2, this._panoramaSphere2)
375
+
376
+ if (player.transitionRotateCamera) {
377
+ this._lat1 = player.clampAngle(player._lat)
378
+ this._lon1 = player.clampAngle(player._lon)
379
+ this._lat2 = player.clampAngle(this._panorama2.cameraConfig.rotation.x)
380
+ this._lon2 = player.clampAngle(this._panorama2.cameraConfig.rotation.y)
381
+ }
382
+
383
+ this._transition = 0
384
+ player._isTransition = true
385
+ }
386
+
387
+ handleTransition(deltaTime) {
388
+ this._transition += Math.min(0.1, deltaTime * 1.5)
389
+
390
+ if (this._transition > 1) this._transition = 1
391
+
392
+ const s = (Math.sin(this._transition * Math.PI - Math.PI / 2) + 1) / 2
393
+
394
+ this.setCameraPosition(this._panorama1, this._panorama2, s)
395
+ this.rotateCamera(this._lat1, this._lat2, this._lon1, this._lon2, s)
396
+ this._renderer.setRenderTarget(this._bufferTexture1)
397
+ this._renderer.render(this._transitionScene1, this._camera)
398
+ this._renderer.setRenderTarget(this._bufferTexture2)
399
+ this._renderer.render(this._transitionScene2, this._camera)
400
+ this._renderer.setRenderTarget(null)
401
+
402
+ if (this._transition == 1) {
403
+ this._currentPanorama.dispose()
404
+ this._currentPanorama = this._panorama2
405
+ this._panoramaSphere.material.map = this._currentPanorama.texture
406
+ this._isTransition = false
407
+ this._transitionRotateCamera = false
408
+
409
+ // Tell host about new cameraID
410
+ this._onPlayerCameraChanged(this._currentPanorama.cameraConfig.cameraID)
411
+ }
412
+
413
+ // Render composited rendertextures to screen
414
+ this._shaderMaterial.uniforms.blend.value = s
415
+ this._renderer.render(this._compositeScene, this._compositeCamera)
416
+ }
417
+
418
+ initializeTransitions() {
419
+ this._transitionScene1 = new THREE.Scene()
420
+ this._transitionScene2 = new THREE.Scene()
421
+ this._compositeScene = new THREE.Scene()
422
+ const resolution = 400
423
+
424
+ this._panoramaSphere1 = this.createPanoramaSphere(1, resolution)
425
+ this._panoramaSphere2 = this.createPanoramaSphere(1, resolution)
426
+ this._panoramaSphereTemplate = this.createPanoramaSphere(1, resolution)
427
+ this._transitionScene1.add(this._panoramaSphere1)
428
+ this._transitionScene2.add(this._panoramaSphere2)
429
+
430
+ this._compositeCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 1, 1000)
431
+
432
+ const width = this._width / 2
433
+ const height = this._height / 2
434
+
435
+ this._bufferTexture1 = new THREE.WebGLRenderTarget(width, height, {
436
+ minFilter: THREE.LinearFilter,
437
+ magFilter: THREE.NearestFilter,
438
+ })
439
+
440
+ this._bufferTexture2 = new THREE.WebGLRenderTarget(width, height, {
441
+ minFilter: THREE.LinearFilter,
442
+ magFilter: THREE.NearestFilter,
443
+ })
444
+
445
+ const uniforms = {
446
+ tex1: { value: this._bufferTexture1.texture },
447
+ tex2: { value: this._bufferTexture2.texture },
448
+ blend: { value: 0 },
449
+ }
450
+ const geometry = new THREE.PlaneGeometry(2, 2, 1, 1)
451
+ this._shaderMaterial = new THREE.ShaderMaterial({
452
+ uniforms,
453
+ vertexShader,
454
+ fragmentShader,
455
+ })
456
+ this._targetMesh = new THREE.Mesh(geometry, this._shaderMaterial)
457
+ this._targetMesh.position.set(0, 0, -1)
458
+ this._compositeScene.add(this._targetMesh)
459
+ }
460
+
461
+ getDepthName(cameraID) {
462
+ const url =
463
+ this._fileResolver('/data/' + cameraID + '_depth.raw.z') +
464
+ (this._addBuildVersionToUrls ? '?v=' + window.BUILD : '')
465
+ return url
466
+ }
467
+
468
+ getTextureName(cameraID) {
469
+ const url =
470
+ this._fileResolver('/360/4096x2048/' + cameraID + '_high.jpg') +
471
+ (this._addBuildVersionToUrls ? '?v=' + window.BUILD : '')
472
+ return url
473
+ }
474
+
475
+ // Initializing /creating stuff
476
+
477
+ update(elapsedTime, timeDelta) {
478
+ timeDelta = Math.min(timeDelta, 0.1)
479
+ this.handleAnimationEasing(timeDelta)
480
+
481
+ this.lat = Math.max(-85, Math.min(85, this.lat))
482
+ const phi = deg2rad(90 - this.lat)
483
+ const theta = deg2rad(this.lon)
484
+
485
+ this._camera.target.x =
486
+ 500 * Math.sin(phi) * Math.cos(theta) + this._camera.position.x
487
+ this._camera.target.y = 500 * Math.cos(phi) + this._camera.position.y
488
+ this._camera.target.z =
489
+ 500 * Math.sin(phi) * Math.sin(theta) + this._camera.position.z
490
+ this._camera.lookAt(this._camera.target)
491
+
492
+ if (this._isTransition) {
493
+ this.handleTransition(timeDelta)
494
+ } else {
495
+ this.renderScene()
496
+ }
497
+
498
+ if (this.apartmentConfig)
499
+ this.apartmentConfig.animateMarkers(this._currentPanorama, elapsedTime)
500
+ }
501
+
502
+ renderScene() {
503
+ this._renderer.render(this._scene, this._camera)
504
+ }
505
+
506
+ createPointer(loaderUrl) {
507
+ const arrowTexture = new THREE.TextureLoader().load(loaderUrl)
508
+
509
+ const geometry = new THREE.PlaneGeometry(0.5, 0.5, 1, 1)
510
+ const material = new THREE.MeshBasicMaterial({
511
+ map: arrowTexture,
512
+ transparent: true,
513
+ opacity: 0.4,
514
+ color: 0xffffff,
515
+ polygonOffset: true,
516
+ polygonOffsetFactor: -1.0,
517
+ polygonOffsetUnits: 4.0,
518
+ })
519
+
520
+ const mesh = new THREE.Mesh(geometry, material)
521
+
522
+ mesh.rotation.x = deg2rad(-90)
523
+ mesh.renderOrder = 1
524
+
525
+ this._adornments.add(mesh)
526
+ return mesh
527
+ }
528
+
529
+ // Animations
530
+ handleAnimationEasing(deltaTime) {
531
+ if (this._isMouseDown) {
532
+ this._speedLon = this.lon - this._oldLon
533
+ this._speedLat = this.lat - this._oldLat
534
+ this._oldLon = this.lon
535
+ this._oldLat = this.lat
536
+ } else {
537
+ this.lon += this._speedLon
538
+ this.lat += this._speedLat
539
+
540
+ // Stop gradually. TODO: Tweak
541
+ this._speedLon *= 0.97 * (1 - deltaTime)
542
+ this._speedLat *= 0.92 * (1 - deltaTime)
543
+ }
544
+ }
545
+
546
+ getX(event) {
547
+ if (event.touches) return event.touches[0].clientX
548
+ return event.clientX
549
+ }
550
+
551
+ getY(event) {
552
+ if (event.touches) return event.touches[0].clientY
553
+ return event.clientY
554
+ }
555
+
556
+ lerp(value1, value2, amount) {
557
+ amount = amount < 0 ? 0 : amount
558
+ amount = amount > 1 ? 1 : amount
559
+ return value1 + (value2 - value1) * amount
560
+ }
561
+
562
+ clampAngle(angle) {
563
+ return clampAngle(angle)
564
+ }
565
+
566
+ clamp(value, min, max) {
567
+ if (value < min) value = min
568
+ else if (value > max) value = max
569
+ return value
570
+ }
571
+
572
+ rotateCamera(lat1, lat2, lon1, lon2, s) {
573
+ if (!this._transitionRotateCamera) return false
574
+ const lat = this.lerp(lat1, lat2, s)
575
+ const lon = this.lerp(lon1, lon2, s)
576
+ this.lat = lat
577
+ this.lon = lon
578
+ }
579
+
580
+ setCameraPosition(panorama1, panorama2, s) {
581
+ const posPano1 = panorama1.cameraConfig.position
582
+ const posPano2 = panorama2.cameraConfig.position
583
+ this._camera.position.set(
584
+ this.lerp(posPano1.x, posPano2.x, s),
585
+ this.lerp(posPano1.y, posPano2.y, s),
586
+ this.lerp(posPano1.z, posPano2.z, s)
587
+ )
588
+ }
589
+
590
+ get consts() {
591
+ return this._consts
592
+ }
593
+
594
+ get height() {
595
+ return this._height
596
+ }
597
+
598
+ get width() {
599
+ return this._width
600
+ }
601
+
602
+ // Player components
603
+ get panoramaSphere() {
604
+ return this._panoramaSphere
605
+ }
606
+
607
+ set panoramaSphere(panoramaSphere) {
608
+ this._panoramaSphere = panoramaSphere
609
+ }
610
+
611
+ get scene() {
612
+ return this._scene
613
+ }
614
+
615
+ get renderer() {
616
+ return this._renderer
617
+ }
618
+
619
+ get camera() {
620
+ return this._camera
621
+ }
622
+
623
+ get arrowMesh() {
624
+ return this._arrowMesh
625
+ }
626
+
627
+ get raycaster() {
628
+ return this._raycaster
629
+ }
630
+
631
+ get isTransition() {
632
+ return this._isTransition
633
+ }
634
+
635
+ get apartmentConfig() {
636
+ return this._apartmentConfig
637
+ }
638
+
639
+ // Panoramas and Spheres
640
+ get isLoadingPanorama() {
641
+ return this._isLoadingPanorama
642
+ }
643
+
644
+ get currentPanorama() {
645
+ return this._currentPanorama
646
+ }
647
+
648
+ get panoramaSphere1() {
649
+ return this._panoramaSphere1
650
+ }
651
+
652
+ get panoramaSphere2() {
653
+ return this._panoramaSphere2
654
+ }
655
+
656
+ set currentPanorama(panorama) {
657
+ this._currentPanorama = panorama
658
+ }
659
+
660
+ set isTransition(isTransition) {
661
+ this._isTransition = isTransition
662
+ }
663
+
664
+ set isMouseDown(val) {
665
+ this._isMouseDown = val
666
+ }
667
+
668
+ // Lat longs
669
+ get lon() {
670
+ return this._lon
671
+ }
672
+
673
+ get lat() {
674
+ return this._lat
675
+ }
676
+
677
+ get isMouseDown() {
678
+ return this._isMouseDown
679
+ }
680
+
681
+ get speedLon() {
682
+ return this._speedLon
683
+ }
684
+
685
+ get speedLat() {
686
+ return this._speedLat
687
+ }
688
+
689
+ get oldLon() {
690
+ return this._oldLon
691
+ }
692
+
693
+ get oldLat() {
694
+ return this._oldLat
695
+ }
696
+
697
+ set oldLat(val) {
698
+ this._oldLat = val
699
+ }
700
+
701
+ set oldLon(val) {
702
+ this._oldLon = val
703
+ }
704
+
705
+ set lon(lon) {
706
+ this._lon = lon
707
+ this._panoramaOrientation.lon = lon
708
+ }
709
+
710
+ set lat(lat) {
711
+ this._lat = lat
712
+ this._panoramaOrientation.lat = lat
713
+ }
714
+
715
+ set speedLon(speedLon) {
716
+ this._speedLon = speedLon
717
+ }
718
+
719
+ set speedLat(speedLat) {
720
+ this._speedLat = speedLat
721
+ }
722
+
723
+ set isUserInteracting(isInteracting) {
724
+ this._isUserInteracting = isInteracting
725
+ }
726
+
727
+ // Movement
728
+ get isMouseMoved() {
729
+ return this._isMouseMoved
730
+ }
731
+
732
+ get nMouseMove() {
733
+ return this._nMouseMove
734
+ }
735
+
736
+ get onMouseDownMouseX() {
737
+ return this._onMouseDownMouseX
738
+ }
739
+
740
+ get onMouseDownMouseY() {
741
+ return this._onMouseDownMouseY
742
+ }
743
+
744
+ get onMouseDownLon() {
745
+ return this._onMouseDownLon
746
+ }
747
+
748
+ get onMouseDownLat() {
749
+ return this._onMouseDownLat
750
+ }
751
+
752
+ get mouseFloorHitpoint() {
753
+ return this._mouseFloorHitpoint
754
+ }
755
+
756
+ get mouse() {
757
+ return this._mouse
758
+ }
759
+
760
+ get isUserInteracting() {
761
+ return this._isUserInteracting
762
+ }
763
+
764
+ get mouseSensitivity() {
765
+ return this._mouseSensitivity
766
+ }
767
+
768
+ set isMouseMoved(val) {
769
+ this._isMouseMoved = val
770
+ }
771
+
772
+ set nMouseMove(val) {
773
+ this._nMouseMove = val
774
+ }
775
+
776
+ set onMouseDownMouseX(val) {
777
+ this._onMouseDownMouseX = val
778
+ }
779
+
780
+ set onMouseDownMouseY(val) {
781
+ this._onMouseDownMouseY = val
782
+ }
783
+
784
+ set onMouseDownLon(val) {
785
+ this._onMouseDownLon = val
786
+ }
787
+
788
+ set onMouseDownLat(val) {
789
+ this._onMouseDownLat = val
790
+ }
791
+
792
+ // Camera position and rotation
793
+ get transitionScene1() {
794
+ return (this._transitionScene1 = null)
795
+ }
796
+
797
+ get transitionScene2() {
798
+ return (this._transitionScene2 = null)
799
+ }
800
+
801
+ get transitionRotateCamera() {
802
+ return this._transitionRotateCamera
803
+ }
804
+
805
+ get compositeCamera() {
806
+ return this._compositeCamera
807
+ }
808
+
809
+ set transitionRotateCamera(rotateCamera) {
810
+ this._transitionRotateCamera = rotateCamera
811
+ }
812
+ }