@needle-tools/engine 5.1.0-experimental.3 → 5.1.0-experimental.4

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 (38) hide show
  1. package/dist/generateMeshBVH.worker-DT9A2Hrc.js +1 -0
  2. package/dist/{needle-engine.bundle-Cp6RtfsD.js → needle-engine.bundle-BAe6Zbj9.js} +4224 -4218
  3. package/dist/{needle-engine.bundle-DQE5rl-V.umd.cjs → needle-engine.bundle-BYO243m2.umd.cjs} +125 -125
  4. package/dist/{needle-engine.bundle-EFFJgRPu.min.js → needle-engine.bundle-DRun3Rri.min.js} +125 -125
  5. package/dist/needle-engine.d.ts +12 -0
  6. package/dist/needle-engine.js +2 -2
  7. package/dist/needle-engine.min.js +1 -1
  8. package/dist/needle-engine.umd.cjs +1 -1
  9. package/lib/engine/engine_three_utils.js +4 -2
  10. package/lib/engine/engine_three_utils.js.map +1 -1
  11. package/lib/engine/js-extensions/three.d.ts +40 -0
  12. package/lib/engine/js-extensions/three.js +52 -0
  13. package/lib/engine/js-extensions/three.js.map +1 -0
  14. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +3 -12
  15. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  16. package/lib/engine/webcomponents/icons.js.map +1 -1
  17. package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
  18. package/lib/engine-components/export/usdz/extensions/Animation.js +0 -1
  19. package/lib/engine-components/export/usdz/extensions/Animation.js.map +1 -1
  20. package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
  21. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  22. package/lib/engine-components/postprocessing/PostProcessingHandler.js +1 -1
  23. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
  24. package/lib/engine-components/timeline/TimelineTracks.js +2 -2
  25. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  26. package/lib/engine-components/ui/Image.js +3 -1
  27. package/lib/engine-components/ui/Image.js.map +1 -1
  28. package/package.json +1 -2
  29. package/src/engine/engine_three_utils.ts +7 -5
  30. package/src/engine/js-extensions/three.ts +72 -0
  31. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +3 -11
  32. package/src/engine/webcomponents/icons.ts +1 -1
  33. package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +1 -1
  34. package/src/engine-components/export/usdz/extensions/Animation.ts +3 -4
  35. package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +1 -1
  36. package/src/engine-components/postprocessing/PostProcessingHandler.ts +1 -1
  37. package/src/engine-components/timeline/TimelineTracks.ts +2 -2
  38. package/src/engine-components/ui/Image.ts +3 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Type augmentations and utilities for three.js r183.
3
+ *
4
+ * Some properties exist at runtime but were removed or changed in @types/three r183.
5
+ * This module provides type-safe access without `as any` casts.
6
+ */
7
+
8
+ import type { Interpolant, Texture, Source } from 'three';
9
+
10
+ // #region Module augmentation for properties that exist at runtime but are missing from types
11
+
12
+ declare module 'three' {
13
+ interface Material {
14
+ /** Unique ID for this material instance. Exists at runtime via Object.defineProperty. */
15
+ readonly id: number;
16
+ }
17
+
18
+ interface KeyframeTrack {
19
+ /** Creates an interpolant for sampling this track. Exists at runtime. */
20
+ createInterpolant(): Interpolant;
21
+ }
22
+ }
23
+
24
+ // #region Texture image type utilities
25
+ // Texture<TImage = unknown> uses a generic for image data. At runtime this can be
26
+ // ImageBitmap, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement,
27
+ // or a plain object with {width, height, data} (DataTexture/CompressedTexture).
28
+
29
+ /** Checks if a texture image has width/height dimensions (ImageBitmap, HTMLImageElement, HTMLCanvasElement, etc.) */
30
+ export function hasImageDimensions(image: unknown): image is { width: number; height: number } {
31
+ return image != null
32
+ && typeof image === 'object'
33
+ && typeof (image as any).width === 'number'
34
+ && typeof (image as any).height === 'number';
35
+ }
36
+
37
+ /** Get the width/height from a texture, checking image, source.data, and direct properties (e.g. render targets) */
38
+ export function getTextureDimensions(texture: Texture): { width: number; height: number } {
39
+ if (hasImageDimensions(texture.image)) {
40
+ return { width: texture.image.width, height: texture.image.height };
41
+ }
42
+ const srcData = texture.source?.data;
43
+ if (hasImageDimensions(srcData)) {
44
+ return { width: srcData.width, height: srcData.height };
45
+ }
46
+ // RenderTarget textures may have dimensions on the texture itself
47
+ if (hasImageDimensions(texture)) {
48
+ return { width: texture.width, height: texture.height };
49
+ }
50
+ return { width: 0, height: 0 };
51
+ }
52
+
53
+ /** Checks if a texture image has pixel data (typed array from DataTexture) */
54
+ export function hasPixelData(image: unknown): image is { data: ArrayBufferView; width: number; height: number } {
55
+ return hasImageDimensions(image) && (image as any).data != null;
56
+ }
57
+
58
+ /** Get the source data of a texture as a dimension-bearing object, or null */
59
+ export function getSourceDimensions(texture: Texture): { width: number; height: number } | null {
60
+ const data = texture.source?.data;
61
+ if (hasImageDimensions(data)) return data;
62
+ return null;
63
+ }
64
+
65
+ /** Checks if a value is a renderable image (ImageBitmap, HTMLImageElement, HTMLCanvasElement, etc.) */
66
+ export function isTextureImage(image: unknown): image is TexImageSource | OffscreenCanvas {
67
+ return image instanceof ImageBitmap
68
+ || image instanceof HTMLImageElement
69
+ || image instanceof HTMLCanvasElement
70
+ || image instanceof HTMLVideoElement
71
+ || (typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas);
72
+ }
@@ -7,18 +7,10 @@ import { WorkerBase } from "three-mesh-bvh/src/workers/utils/WorkerBase.js";
7
7
  export class GenerateMeshBVHWorker extends WorkerBase {
8
8
 
9
9
  constructor() {
10
- // Worker loading: resolve the worker URL via import.meta.resolve so that bare
11
- // specifiers like 'three-mesh-bvh/...' are correctly resolved through the module
12
- // system (node_modules) rather than relative to this file's location.
13
- // Falls back to new URL() + import.meta.url for environments without import.meta.resolve.
14
10
  // https://linear.app/needle/issue/NE-6572
15
- let workerUrl;
16
- try {
17
- workerUrl = import.meta.resolve('three-mesh-bvh/src/workers/generateMeshBVH.worker.js');
18
- } catch {
19
- workerUrl = new URL('three-mesh-bvh/src/workers/generateMeshBVH.worker.js', import.meta.url);
20
- }
21
- super(new Worker(workerUrl, { type: 'module' }));
11
+ // The URL must start with "/" so the rollupFixWorkerImport plugin rewrites it
12
+ // for production builds. In dev, vite serves /node_modules/ paths directly.
13
+ super(new Worker(new URL("/node_modules/three-mesh-bvh/src/workers/generateMeshBVH.worker.js", import.meta.url), { type: 'module' }));
22
14
  this.name = 'GenerateMeshBVHWorker';
23
15
 
24
16
  }
@@ -62,7 +62,7 @@ export async function getIconTexture(str: string): Promise<Texture | null> {
62
62
  const texture = new Texture();
63
63
  texture.name = str + " icon";
64
64
  const img = new Image();
65
- (texture as any).image = img;
65
+ texture.image = img;
66
66
  img.src = data;
67
67
  texture.needsUpdate = true;
68
68
  textures.set(str, texture);
@@ -1516,7 +1516,7 @@ function getGeometryName(geometry: BufferGeometry, _fallbackName: string) {
1516
1516
  }
1517
1517
 
1518
1518
  function getMaterialName(material: Material) {
1519
- return makeNameSafe(material.name || 'Material') + "_" + (material as any).id;
1519
+ return makeNameSafe(material.name || 'Material') + "_" + material.id;
1520
1520
  }
1521
1521
 
1522
1522
  function getPathToSkeleton(bone: Object3D, assumedRoot: Object3D) {
@@ -218,10 +218,9 @@ export class TransformData {
218
218
  const scale = new Vector3(1, 1, 1);
219
219
  const object = this.target;
220
220
 
221
- // createInterpolant exists at runtime but was removed from types in r183
222
- const positionInterpolant: Interpolant | undefined = generatePos ? (this.pos as any)?.createInterpolant() : undefined;
223
- const rotationInterpolant: Interpolant | undefined = generateRot ? (this.rot as any)?.createInterpolant() : undefined;
224
- const scaleInterpolant: Interpolant | undefined = generateScale ? (this.scale as any)?.createInterpolant() : undefined;
221
+ const positionInterpolant: Interpolant | undefined = generatePos ? this.pos?.createInterpolant() : undefined;
222
+ const rotationInterpolant: Interpolant | undefined = generateRot ? this.rot?.createInterpolant() : undefined;
223
+ const scaleInterpolant: Interpolant | undefined = generateScale ? this.scale?.createInterpolant() : undefined;
225
224
 
226
225
  if (!positionInterpolant) translation.set(object.position.x, object.position.y, object.position.z);
227
226
  if (!rotationInterpolant) rotation.set(object.quaternion.x, object.quaternion.y, object.quaternion.z, object.quaternion.w);
@@ -388,7 +388,7 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
388
388
  }
389
389
 
390
390
  private static getMaterialName(material: Material) {
391
- return makeNameSafeForUSD(material.name || 'Material') + "_" + (material as any).id;
391
+ return makeNameSafeForUSD(material.name || 'Material') + "_" + material.id;
392
392
  }
393
393
 
394
394
  static variantSwitchIndex: number = 0;
@@ -577,7 +577,7 @@ export class PostProcessingHandler {
577
577
  // Assigning a new Source breaks the deduplication so they get separate GL textures.
578
578
  const composerDepthTexture = (composer as any).depthTexture as DepthTexture | null;
579
579
  if (composerDepthTexture) {
580
- composerDepthTexture.source = new Source({ width: 0, height: 0 } as any);
580
+ composerDepthTexture.source = new Source({ width: 0, height: 0, depth: 1 });
581
581
  composerDepthTexture.needsUpdate = true;
582
582
  }
583
583
 
@@ -700,8 +700,8 @@ export class AudioTrackHandler extends TrackHandler {
700
700
  }
701
701
  if (AudioSource.userInteractionRegistered === false) continue;
702
702
  if (audio === null || !audio.buffer) continue;
703
- (audio as any).playbackRate = this.director.context.time.timeScale * this.director.speed;
704
- (audio as any).loop = asset.loop;
703
+ audio.setPlaybackRate(this.director.context.time.timeScale * this.director.speed);
704
+ audio.setLoop(asset.loop);
705
705
  if (time >= model.start && time <= model.end && time < this.director.duration) {
706
706
  if (!audio.isPlaying || !this.director.isPlaying) {
707
707
  // if the timeline is paused we trigger the audio clip once when the model is entered
@@ -1,4 +1,5 @@
1
1
  import { Color, Texture } from 'three';
2
+ import { hasImageDimensions } from '../../engine/js-extensions/three.js';
2
3
 
3
4
  import { serializable } from '../../engine/engine_serialization_decorator.js';
4
5
  import { MaskableGraphic } from './Graphic.js';
@@ -77,7 +78,8 @@ export class Image extends MaskableGraphic {
77
78
  }
78
79
  // this is a hack/workaround for production builds where the name of the sprite is missing
79
80
  // need to remove this!!!!
80
- if (!sprite?.texture?.name?.length && (sprite?.texture?.image as any)?.width === 32 && (sprite?.texture?.image as any)?.height === 32)
81
+ const img = sprite?.texture?.image;
82
+ if (!sprite?.texture?.name?.length && hasImageDimensions(img) && img.width === 32 && img.height === 32)
81
83
  return true;
82
84
  return false;
83
85
  }