@needle-tools/engine 3.2.8-alpha → 3.2.10-alpha

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 (36) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/needle-engine.js +8757 -8712
  3. package/dist/needle-engine.min.js +165 -127
  4. package/dist/needle-engine.umd.cjs +175 -137
  5. package/lib/engine/engine_addressables.d.ts +1 -0
  6. package/lib/engine/engine_addressables.js +14 -9
  7. package/lib/engine/engine_addressables.js.map +1 -1
  8. package/lib/engine/engine_element_loading.js +7 -0
  9. package/lib/engine/engine_element_loading.js.map +1 -1
  10. package/lib/engine/engine_license.js +69 -24
  11. package/lib/engine/engine_license.js.map +1 -1
  12. package/lib/engine/engine_serialization_builtin_serializer.js +1 -1
  13. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  14. package/lib/engine-components/Animator.js +2 -1
  15. package/lib/engine-components/Animator.js.map +1 -1
  16. package/lib/engine-components/Component.js +2 -2
  17. package/lib/engine-components/Component.js.map +1 -1
  18. package/lib/engine-components/GroundProjection.js +1 -1
  19. package/lib/engine-components/ScreenCapture.d.ts +2 -0
  20. package/lib/engine-components/ScreenCapture.js +6 -0
  21. package/lib/engine-components/ScreenCapture.js.map +1 -1
  22. package/lib/engine-components/VideoPlayer.d.ts +8 -6
  23. package/lib/engine-components/VideoPlayer.js +59 -31
  24. package/lib/engine-components/VideoPlayer.js.map +1 -1
  25. package/lib/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +1 -1
  27. package/plugins/vite/license.js +5 -2
  28. package/src/engine/engine_addressables.ts +13 -9
  29. package/src/engine/engine_element_loading.ts +10 -1
  30. package/src/engine/engine_license.ts +71 -25
  31. package/src/engine/engine_serialization_builtin_serializer.ts +1 -1
  32. package/src/engine-components/Animator.ts +1 -1
  33. package/src/engine-components/Component.ts +2 -2
  34. package/src/engine-components/GroundProjection.ts +1 -1
  35. package/src/engine-components/ScreenCapture.ts +7 -0
  36. package/src/engine-components/VideoPlayer.ts +58 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "3.2.8-alpha",
3
+ "version": "3.2.10-alpha",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in",
5
5
  "main": "dist/needle-engine.umd.cjs",
6
6
  "type": "module",
@@ -7,10 +7,13 @@ export const needleLicense = (command, config, userSettings) => {
7
7
  name: "needle-license",
8
8
  enforce: 'pre',
9
9
  async transform(src, id) {
10
- if (id.includes("engine/engine_license") || id.includes("needle-tools_engine.js")) {
10
+ const isNeedleEngineFile = id.includes("engine/engine_license") || id.includes("needle-tools_engine.js");
11
+ // sometimes the actual license parameter is in a unnamed chunk file
12
+ const isViteChunkFile = id.includes("chunk") && id.includes(".vite");
13
+ if (isNeedleEngineFile || isViteChunkFile) {
11
14
  const needleConfig = await loadConfig();
12
15
  if (needleConfig) {
13
- if (needleConfig.hasProLicense !== undefined && typeof needleConfig.hasProLicense === "boolean") {
16
+ if (needleConfig.hasProLicense === true) {
14
17
  src = src.replace("NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE = false;", "NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE = " + needleConfig.hasProLicense + ";");
15
18
  return { code: src, map: null }
16
19
  }
@@ -1,7 +1,7 @@
1
1
  import { getParam, resolveUrl } from "../engine/engine_utils";
2
2
  import { SerializationContext, TypeSerializer } from "./engine_serialization_core";
3
3
  import { Context } from "./engine_setup";
4
- import { Group, Object3D, Texture } from "three";
4
+ import { Group, Object3D, Texture, TextureLoader } from "three";
5
5
  import { processNewScripts } from "./engine_mainloop_utils";
6
6
  import { registerPrefabProvider, syncInstantiate } from "./engine_networking_instantiate";
7
7
  import { download } from "./engine_web_api";
@@ -372,15 +372,19 @@ export class ImageReference {
372
372
  return img;
373
373
  }
374
374
 
375
+ private loader: TextureLoader | null = null;
375
376
  createTexture(): Promise<Texture | null> {
376
- return this.getBitmap().then((bitmap) => {
377
- if (bitmap) {
378
- const texture = new Texture(bitmap);
379
- texture.needsUpdate = true;
380
- return texture;
381
- }
382
- return null;
383
- });
377
+ if (!this.loader) this.loader = new TextureLoader();
378
+ this.loader.setCrossOrigin("anonymous");
379
+ return this.loader.loadAsync(this.url);
380
+ // return this.getBitmap().then((bitmap) => {
381
+ // if (bitmap) {
382
+ // const texture = new Texture(bitmap);
383
+ // texture.needsUpdate = true;
384
+ // return texture;
385
+ // }
386
+ // return null;
387
+ // });
384
388
  }
385
389
 
386
390
  /** Loads the bitmap data of the image */
@@ -253,13 +253,14 @@ export class EngineLoadingView implements ILoadingViewHandler {
253
253
  }
254
254
  loadingBarContainer.appendChild(logo);
255
255
 
256
+
256
257
  this._loadingBar = document.createElement("div");
257
258
  loadingBarContainer.appendChild(this._loadingBar);
258
259
  const getGradientPos = function (t: number): string {
259
260
  return Mathf.lerp(maxWidth * .5, 100 - maxWidth * .5, t) + "%";
260
261
  }
261
262
  this._loadingBar.style.background =
262
- `linear-gradient(90deg, #02022B ${getGradientPos(0)}, #0BA398 ${getGradientPos(.4)}, #99CC33 ${getGradientPos(.5)}, #D7DB0A ${getGradientPos(1)})`;
263
+ `linear-gradient(90deg, #02022B ${getGradientPos(0)}, #0BA398 ${getGradientPos(.4)}, #99CC33 ${getGradientPos(.5)}, #D7DB0A ${getGradientPos(1)})`;
263
264
  this._loadingBar.style.backgroundAttachment = "fixed";
264
265
  this._loadingBar.style.width = "0%";
265
266
  this._loadingBar.style.height = "100%";
@@ -301,6 +302,14 @@ export class EngineLoadingView implements ILoadingViewHandler {
301
302
  }
302
303
  }
303
304
 
305
+ if (!hasLicense) {
306
+ const nonCommercialContainer = document.createElement("div");
307
+ nonCommercialContainer.style.paddingTop = ".6em";
308
+ nonCommercialContainer.style.fontSize = ".8em";
309
+ nonCommercialContainer.innerText = "NON COMMERCIAL";
310
+ this._loadingElement.appendChild(nonCommercialContainer);
311
+ }
312
+
304
313
  return this._loadingElement;
305
314
  }
306
315
  }
@@ -30,22 +30,18 @@ async function showLicenseInfo(ctx: IContext) {
30
30
  }
31
31
 
32
32
 
33
- const _licenseText = "🌵 <span class=\"text\">Made with <a href=\"https://needle.tools\" target=\"_blank\">Needle</a></span>";
34
33
  const licenseElementIdentifier = "needle-license-element";
35
- const licenseDuration = 30000;
36
- const licenseDelay = 600;
34
+ const licenseDuration = 15000;
35
+ const licenseDelay = 500;
37
36
 
38
37
  function onNonCommercialVersionDetected(ctx: IContext) {
39
- insertNonCommercialUseHint(ctx);
40
- sendNonCommercialUsageMessageToAnalyticsBackend();
38
+ setTimeout(() => insertNonCommercialUseHint(ctx), 2000);
39
+ sendUsageMessageToAnalyticsBackend();
41
40
  }
42
41
 
43
42
  function insertNonCommercialUseHint(ctx: IContext) {
44
43
 
45
- let licenseText = _licenseText;
46
44
  const licenseElement = createLicenseElement();
47
- licenseElement.innerHTML = licenseText;
48
-
49
45
  const style = createLicenseStyle();
50
46
 
51
47
  const interval = setInterval(() => {
@@ -59,9 +55,20 @@ function insertNonCommercialUseHint(ctx: IContext) {
59
55
  logNonCommercialUse();
60
56
 
61
57
  let svg = `<img class="logo" src="${logoSVG}" style="width: 40px; height: 40px; margin-right: 2px; vertical-align: middle; margin-bottom: 2px;"/>`;
62
- svg = "<a href=\"https://needle.tools\" target=\"_blank\">" + svg + "</a>";
63
- licenseText = svg; //licenseText.replace("🌵", svg);
64
- licenseElement.innerHTML = licenseText;
58
+ const logoElement = document.createElement("div");
59
+ logoElement.innerHTML = svg;
60
+ logoElement.classList.add("logo");
61
+ licenseElement.appendChild(logoElement);
62
+
63
+ const textElement = document.createElement("div");
64
+ textElement.classList.add("text");
65
+ textElement.innerHTML = "Needle Engine<br/><span class=\"non-commercial\">Non Commercial</span>";
66
+ licenseElement.appendChild(textElement);
67
+
68
+ licenseElement.title = "Needle Engine — non commercial version";
69
+ licenseElement.addEventListener("click", () => {
70
+ globalThis.open("https://needle.tools", "_blank");
71
+ });
65
72
 
66
73
  const removeDelay = licenseDuration + licenseDelay;
67
74
  setTimeout(() => {
@@ -110,6 +117,13 @@ function createLicenseStyle() {
110
117
  ${selector} {
111
118
  font-family: 'Roboto', sans-serif !important;
112
119
  font-weight: 300;
120
+ transition: all 0.1s ease-in-out !important;
121
+ pointer-events: all;
122
+ }
123
+
124
+ ${selector}:hover {
125
+ cursor: pointer;
126
+ transition: all 0.1s ease-in-out !important;
113
127
  }
114
128
 
115
129
  ${selector}, ${selector} > * {
@@ -118,22 +132,52 @@ function createLicenseStyle() {
118
132
  background: none !important;
119
133
  border: none !important;
120
134
  text-decoration: none !important;
135
+ vertical-align: middle !important;
136
+ }
137
+
138
+ @keyframes license-animation {
139
+ 1% {
140
+ opacity: 0;
141
+ }
142
+ 2.5% {
143
+ opacity: 1;
144
+ }
145
+ 98% {
146
+ opacity: 1;
147
+ }
148
+ 99% {
149
+ opacity: 0;
150
+ }
151
+ }
152
+ ${selector} .text {
153
+ opacity: 0;
154
+ animation: license-animation;
155
+ animation-iteration-count: 1;
156
+ animation-duration: ${(licenseDuration / 1000)}s;
157
+ animation-delay: ${licenseDelay / 1000}s;
158
+ animation-easing: ease-in-out;
159
+ mix-blend-mode: difference;
160
+ color: rgb(40, 40, 40);
161
+ mix-blend-mode: difference;
162
+ line-height: 1em;
163
+ margin-left: -3px;
164
+ text-shadow: 0 0 2px rgba(200,200,200, .3);
121
165
  }
122
166
 
123
- ${selector} a {
124
- color: black !important;
125
- font-weight: 500 !important;
167
+ ${selector} .text .non-commercial {
168
+ font-size: 0.8em;
169
+ font-weight: 600;
170
+ text-transform: uppercase;
126
171
  }
127
172
 
128
- @keyframes append-animate {
173
+ @keyframes logo-animation {
129
174
  0% {
130
175
  transform: translate(0px, 10px);
131
- opacity: 0;
132
176
  pointer-events: none;
133
177
  }
134
178
  1% {
135
179
  transform: translate(0, -5px);
136
- opacity: .9;
180
+ opacity: 1;
137
181
  }
138
182
  2% {
139
183
  transform: translate(0, 2.5px);
@@ -141,7 +185,6 @@ function createLicenseStyle() {
141
185
  3% {
142
186
  transform: translate(0, 0px);
143
187
  pointer-events: all;
144
- opacity: 1;
145
188
  }
146
189
  4% {
147
190
  transform: scale(1)
@@ -161,14 +204,15 @@ function createLicenseStyle() {
161
204
  transform: scale(1)
162
205
  }
163
206
  100% {
164
- opacity: 0;
165
207
  pointer-events: none;
208
+ opacity: 0;
166
209
  }
167
210
  }
168
- ${selector} {
211
+
212
+ ${selector} .logo {
169
213
  opacity: 0;
170
214
  pointer-events: none;
171
- animation: append-animate;
215
+ animation: logo-animation;
172
216
  animation-iteration-count: 1;
173
217
  animation-duration: ${(licenseDuration / 1000)}s;
174
218
  animation-delay: ${licenseDelay / 1000}s;
@@ -184,8 +228,9 @@ function createLicenseStyle() {
184
228
  transition: all 0.1s ease-in-out !important;
185
229
  }
186
230
 
187
- ${selector} .logo:hover {
188
- transform: scale(1.3) !important;
231
+ ${selector}:hover .logo {
232
+ transition: all 0.1s ease-in-out !important;
233
+ transform: scale(1.1) !important;
189
234
  cursor: pointer !important;
190
235
  }
191
236
  `
@@ -193,7 +238,7 @@ function createLicenseStyle() {
193
238
  }
194
239
 
195
240
 
196
- async function sendNonCommercialUsageMessageToAnalyticsBackend() {
241
+ async function sendUsageMessageToAnalyticsBackend() {
197
242
  try {
198
243
  const analyticsBackendUrlForward = "https://urls.needle.tools/analytics-endpoint";
199
244
  const res = await fetch(analyticsBackendUrlForward);
@@ -207,7 +252,8 @@ async function sendNonCommercialUsageMessageToAnalyticsBackend() {
207
252
 
208
253
  let endpoint = "api/v1/register/web-request";
209
254
  if (!analyticsUrl.endsWith("/")) endpoint = "/" + endpoint;
210
- const finalUrl = `${analyticsUrl}${endpoint}?type=non-commercial&url=${encodeURIComponent(currentUrl)}&hostname=${encodeURIComponent(window.location.hostname)}&pathname=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}&hash=${encodeURIComponent(window.location.hash)}`;
255
+ const type = hasProLicense() ? "commercial" : "non-commercial";
256
+ const finalUrl = `${analyticsUrl}${endpoint}?type=${type}&url=${encodeURIComponent(currentUrl)}&hostname=${encodeURIComponent(window.location.hostname)}&pathname=${encodeURIComponent(window.location.pathname)}&search=${encodeURIComponent(window.location.search)}&hash=${encodeURIComponent(window.location.hash)}`;
211
257
  if (debug) console.log("Sending non-commercial usage message to analytics backend", finalUrl);
212
258
 
213
259
 
@@ -362,7 +362,7 @@ export class UriSerializer extends TypeSerializer {
362
362
  }
363
363
 
364
364
  onDeserialize(data: string, _context: SerializationContext) {
365
- if (typeof data === "string") {
365
+ if (typeof data === "string" && data.length > 0) {
366
366
  return resolveUrl(_context.gltfId, data);
367
367
  }
368
368
  return undefined;
@@ -102,7 +102,7 @@ export class Animator extends Behaviour {
102
102
  /**@deprecated use setTrigger */
103
103
  SetTrigger(name: string | number) { this.setTrigger(name); }
104
104
  setTrigger(name: string | number) {
105
- console.log("name", name);
105
+ if(debug) console.log("SetTrigger", name);
106
106
  this.runtimeAnimatorController?.setTrigger(name);
107
107
  }
108
108
 
@@ -486,8 +486,8 @@ export class Component implements IComponent, EventTarget {
486
486
  }
487
487
  // console.trace("INTERNAL ENABLE");
488
488
  this.__didEnable = true;
489
- this.onEnable();
490
489
  this.__isEnabled = true;
490
+ this.onEnable();
491
491
  return true;
492
492
  }
493
493
 
@@ -501,8 +501,8 @@ export class Component implements IComponent, EventTarget {
501
501
  return;
502
502
  }
503
503
  this.__didEnable = false;
504
- this.onDisable();
505
504
  this.__isEnabled = false;
505
+ this.onDisable();
506
506
  }
507
507
 
508
508
  /** @internal */
@@ -24,7 +24,7 @@ export class GroundProjectedEnv extends Behaviour {
24
24
  set radius(val: number) {
25
25
  this._radius = val;
26
26
  if (this.env)
27
- this.env.height = val;
27
+ this.env.radius = val;
28
28
  }
29
29
  get radius(): number { return this._radius; }
30
30
  private _radius: number = 100;
@@ -40,6 +40,13 @@ declare type ScreenCaptureOptions = {
40
40
 
41
41
  export class ScreenCapture extends Behaviour implements IPointerClickHandler {
42
42
 
43
+ onPointerEnter() {
44
+ this.context.input.setCursorPointer();
45
+ }
46
+ onPointerExit() {
47
+ this.context.input.setCursorNormal();
48
+ }
49
+
43
50
  onPointerClick(evt : PointerEventData) {
44
51
  if(evt && evt.pointerId !== 0) return;
45
52
  if(this.context.connection.isInRoom === false) return;
@@ -1,13 +1,13 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
- import * as THREE from "three";
3
2
  import { serializable } from "../engine/engine_serialization_decorator";
4
- import { LinearFilter, Material, Mesh, Object3D, RawShaderMaterial, ShaderMaterial, Texture, TextureLoader, Vector2, Vector4, VideoTexture } from "three";
3
+ import { Material, Mesh, Object3D, ShaderMaterial, sRGBEncoding, Texture, Vector2, Vector4, VideoTexture } from "three";
5
4
  import { awaitInput } from "../engine/engine_input_utils";
6
- import { getParam, resolveUrl } from "../engine/engine_utils";
5
+ import { getParam } from "../engine/engine_utils";
7
6
  import { Renderer } from "./Renderer";
8
7
  import { getWorldScale } from "../engine/engine_three_utils";
9
8
  import { ObjectUtils, PrimitiveType } from "../engine/engine_create_objects";
10
9
  import { Context } from "../engine/engine_setup";
10
+ import { isDevEnvironment } from "../engine/debug";
11
11
 
12
12
  const debug = getParam("debugvideo");
13
13
 
@@ -46,7 +46,7 @@ export enum VideoRenderMode {
46
46
  export class VideoPlayer extends Behaviour {
47
47
 
48
48
  @serializable(Object3D)
49
- renderer: THREE.Object3D | null = null;
49
+ renderer: Object3D | null = null;
50
50
  @serializable()
51
51
  playOnAwake: boolean = true;
52
52
 
@@ -149,18 +149,29 @@ export class VideoPlayer extends Behaviour {
149
149
  }
150
150
  private _muted: boolean = false;
151
151
 
152
+ @serializable()
153
+ private set audioOutputMode(mode: VideoAudioOutputMode) {
154
+ if (mode !== this._audioOutputMode) {
155
+ if (mode === VideoAudioOutputMode.AudioSource && isDevEnvironment()) console.warn("VideoAudioOutputMode.AudioSource is not yet implemented");
156
+ this._audioOutputMode = mode;
157
+ this.updateVideoElementSettings();
158
+ }
159
+ }
160
+ private get audioOutputMode() { return this._audioOutputMode; }
161
+
162
+ private _audioOutputMode: VideoAudioOutputMode = VideoAudioOutputMode.Direct;
163
+
152
164
  /** Set this to false to pause video playback while the tab is not active */
153
165
  playInBackground: boolean = true;
154
166
 
155
167
  private _crossOrigin: string | null = "anonymous";
156
168
 
157
- private audioOutputMode: VideoAudioOutputMode = VideoAudioOutputMode.AudioSource;
158
169
 
159
170
  private source!: VideoSource;
160
171
  private url?: string | null = null;
161
172
 
162
173
  private _videoElement: HTMLVideoElement | null = null;
163
- private _videoTexture: THREE.VideoTexture | null = null;
174
+ private _videoTexture: VideoTexture | null = null;
164
175
  private _videoMaterial: Material | null = null;
165
176
 
166
177
  private _isPlaying: boolean = false;
@@ -195,27 +206,11 @@ export class VideoPlayer extends Behaviour {
195
206
  }
196
207
  }
197
208
 
198
- awake(): void {
199
- this.create(this.playOnAwake);
200
-
201
- window.addEventListener('visibilitychange', _evt => {
202
- switch (document.visibilityState) {
203
- case "hidden":
204
- if(!this.playInBackground){
205
- this.wasPlaying = this._isPlaying;
206
- this.pause();
207
- }
208
- break;
209
- case "visible":
210
- if (this.wasPlaying && !this._isPlaying) this.play();
211
- break;
212
- }
213
- });
214
- }
215
-
216
209
  onEnable(): void {
210
+ window.addEventListener('visibilitychange', this.visibilityChanged);
211
+
217
212
  if (this.playOnAwake === true) {
218
- this.handleBeginPlaying(true);
213
+ this.create(true);
219
214
  }
220
215
  if (this.screenspace) {
221
216
  this._overlay?.start();
@@ -224,9 +219,24 @@ export class VideoPlayer extends Behaviour {
224
219
  }
225
220
 
226
221
  onDisable(): void {
222
+ window.removeEventListener('visibilitychange', this.visibilityChanged);
227
223
  this.pause();
228
224
  }
229
225
 
226
+ private visibilityChanged = (_: Event) => {
227
+ switch (document.visibilityState) {
228
+ case "hidden":
229
+ if (!this.playInBackground) {
230
+ this.wasPlaying = this._isPlaying;
231
+ this.pause();
232
+ }
233
+ break;
234
+ case "visible":
235
+ if (this.wasPlaying && !this._isPlaying) this.play();
236
+ break;
237
+ }
238
+ }
239
+
230
240
  onDestroy(): void {
231
241
  if (this._videoElement) {
232
242
  this._videoElement.parentElement?.removeChild(this._videoElement);
@@ -258,12 +268,15 @@ export class VideoPlayer extends Behaviour {
258
268
  }
259
269
 
260
270
  play() {
271
+ if (!this._videoElement) this.create(false);
261
272
  if (!this._videoElement) return;
262
273
  if (this._isPlaying && !this._videoElement?.ended && !this._videoElement?.paused) return;
263
274
  this._isPlaying = true;
264
275
  if (!this._receivedInput) this._videoElement.muted = true;
265
276
  this.updateVideoElementSettings();
266
- this._videoElement?.play().catch(err => {
277
+ this._videoElement.currentTime = this.time;
278
+ this._videoElement.play().catch(err => {
279
+ console.log(err);
267
280
  // https://developer.chrome.com/blog/play-request-was-interrupted/
268
281
  if (debug)
269
282
  console.error("Error playing video", err, "CODE=" + err.code, this.videoElement?.src, this);
@@ -272,19 +285,23 @@ export class VideoPlayer extends Behaviour {
272
285
  this.play();
273
286
  }, 1000);
274
287
  });
275
- if (debug) console.log("play", this._videoElement);
288
+ if (debug) console.log("play", this._videoElement, this.time);
276
289
  }
277
290
 
278
291
  stop() {
279
292
  this._isPlaying = false;
293
+ this.time = 0;
280
294
  if (!this._videoElement) return;
281
295
  this._videoElement.currentTime = 0;
282
296
  this._videoElement.pause();
297
+ if (debug) console.log("STOP", this);
283
298
  }
284
299
 
285
300
  pause(): void {
301
+ this.time = this._videoElement?.currentTime ?? 0;
286
302
  this._isPlaying = false;
287
303
  this._videoElement?.pause();
304
+ if (debug) console.log("PAUSE", this, this.currentTime);
288
305
  }
289
306
 
290
307
 
@@ -301,30 +318,36 @@ export class VideoPlayer extends Behaviour {
301
318
 
302
319
  if (!src) return;
303
320
 
304
- // console.log(src, this);
305
321
 
306
322
  if (!this._videoElement) {
323
+ if (debug)
324
+ console.warn("Create VideoElement", this);
307
325
  this._videoElement = this.createVideoElement();
308
326
  this.context.domElement?.prepend(this._videoElement);
309
327
  // hide it because otherwise it would overlay the website with default css
310
328
  this.updateVideoElementStyles();
311
329
  }
330
+
312
331
  if (typeof src === "string") {
332
+ if (debug) console.log("Set Video src", src);
313
333
  this._videoElement.src = src;
314
- const str = this._videoElement["captureStream"]?.call(this._videoElement);
315
- this.clip = str;
334
+ // Nor sure why we did this here, but with this code the video does not restart when being paused / enable toggled
335
+ // const str = this._videoElement["captureStream"]?.call(this._videoElement);
336
+ // this.clip = str;
316
337
  }
317
- else
338
+ else {
339
+ if (debug) console.log("Set Video srcObject", src);
318
340
  this._videoElement.srcObject = src;
341
+ }
319
342
 
320
343
 
321
344
  if (!this._videoTexture)
322
- this._videoTexture = new THREE.VideoTexture(this._videoElement);
345
+ this._videoTexture = new VideoTexture(this._videoElement);
323
346
  this._videoTexture.flipY = false;
324
- this._videoTexture.encoding = THREE.sRGBEncoding;
347
+ this._videoTexture.encoding = sRGBEncoding;
325
348
  this.handleBeginPlaying(playAutomatically);
326
349
  if (debug)
327
- console.log(this);
350
+ console.log(this, playAutomatically);
328
351
  }
329
352
 
330
353
  updateAspect() {
@@ -354,7 +377,7 @@ export class VideoPlayer extends Behaviour {
354
377
  const video = document.createElement("video") as HTMLVideoElement;
355
378
  if (this._crossOrigin)
356
379
  video.setAttribute("crossorigin", this._crossOrigin);
357
- if (debug) console.log("create video elment", video);
380
+ if (debug) console.log("created video element", video);
358
381
  return video;
359
382
  }
360
383