@needle-tools/engine 4.8.8-next.aa09526 → 4.8.8-next.db5fdbd

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 (35) hide show
  1. package/README.md +50 -45
  2. package/dist/{needle-engine.bundle-DDQrIop6.min.js → needle-engine.bundle-BtPGFT7e.min.js} +6 -6
  3. package/dist/{needle-engine.bundle-xO7DnXAE.js → needle-engine.bundle-COsyGTEY.js} +42 -24
  4. package/dist/{needle-engine.bundle-C5WmZ20c.umd.cjs → needle-engine.bundle-IiODerFA.umd.cjs} +53 -53
  5. package/dist/needle-engine.js +2 -2
  6. package/dist/needle-engine.min.js +1 -1
  7. package/dist/needle-engine.umd.cjs +1 -1
  8. package/lib/engine/engine_camera.d.ts +15 -2
  9. package/lib/engine/engine_camera.js +9 -2
  10. package/lib/engine/engine_camera.js.map +1 -1
  11. package/lib/engine/engine_context.d.ts +8 -2
  12. package/lib/engine/engine_context.js +21 -3
  13. package/lib/engine/engine_context.js.map +1 -1
  14. package/lib/engine/engine_create_objects.d.ts +3 -3
  15. package/lib/engine/engine_create_objects.js +5 -4
  16. package/lib/engine/engine_create_objects.js.map +1 -1
  17. package/lib/engine/extensions/NEEDLE_lighting_settings.js +5 -2
  18. package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
  19. package/lib/engine-components/Camera.d.ts +1 -1
  20. package/lib/engine-components/Camera.js.map +1 -1
  21. package/lib/engine-components/ContactShadows.d.ts +12 -2
  22. package/lib/engine-components/ContactShadows.js +24 -4
  23. package/lib/engine-components/ContactShadows.js.map +1 -1
  24. package/lib/engine-components/OrbitControls.js +4 -6
  25. package/lib/engine-components/OrbitControls.js.map +1 -1
  26. package/lib/engine-components/api.d.ts +1 -1
  27. package/package.json +2 -2
  28. package/src/engine/engine_camera.ts +15 -3
  29. package/src/engine/engine_context.ts +22 -4
  30. package/src/engine/engine_create_objects.ts +8 -7
  31. package/src/engine/extensions/NEEDLE_lighting_settings.ts +5 -2
  32. package/src/engine-components/Camera.ts +1 -1
  33. package/src/engine-components/ContactShadows.ts +27 -6
  34. package/src/engine-components/OrbitControls.ts +4 -11
  35. package/src/engine-components/api.ts +1 -1
@@ -1765,9 +1765,9 @@ fo('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUIL
1765
1765
  fo('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";');
1766
1766
  fo('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.8.8";');
1767
1767
  fo('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";');
1768
- fo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Thu Sep 04 2025 07:54:57 GMT+0000 (Coordinated Universal Time)";');
1768
+ fo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Fri Sep 05 2025 14:22:32 GMT+0000 (Coordinated Universal Time)";');
1769
1769
  fo('globalThis["__NEEDLE_PUBLIC_KEY__"] = "' + NEEDLE_PUBLIC_KEY + '";');
1770
- const En = "4.8.8", Cm = "undefined", Gb = "Thu Sep 04 2025 07:54:57 GMT+0000 (Coordinated Universal Time)";
1770
+ const En = "4.8.8", Cm = "undefined", Gb = "Fri Sep 05 2025 14:22:32 GMT+0000 (Coordinated Universal Time)";
1771
1771
  Hb && console.log(`Engine version: ${En} (generator: ${Cm})
1772
1772
  Project built at ${Gb}`);
1773
1773
  const bl = NEEDLE_PUBLIC_KEY, oo = "needle_isActiveInHierarchy", Br = "builtin_components", Mh = "needle_editor_guid";
@@ -4240,7 +4240,7 @@ class Oa {
4240
4240
  return this.applyDefaultObjectOptions(n, e), n;
4241
4241
  }
4242
4242
  static applyDefaultObjectOptions(e, t) {
4243
- e.receiveShadow = !0, e.castShadow = !0, t?.name && (e.name = t.name), t?.position && (Array.isArray(t.position) ? e.position.set(t.position[0], t.position[1], t.position[2]) : e.position.set(t.position.x, t.position.y, t.position.z)), t?.rotation && (Array.isArray(t.rotation) ? e.rotation.set(t.rotation[0], t.rotation[1], t.rotation[2]) : e.rotation.set(t.rotation.x, t.rotation.y, t.rotation.z)), t?.scale && (typeof t.scale == "number" ? e.scale.set(t.scale, t.scale, t.scale) : Array.isArray(t.scale) ? e.scale.set(t.scale[0], t.scale[1], t.scale[2]) : e.scale.set(t.scale.x, t.scale.y, t.scale.z)), t?.receiveShadow != null && (e.receiveShadow = t.receiveShadow), t?.castShadow != null && (e.castShadow = t.castShadow), t?.parent && t.parent.add(e);
4243
+ e.receiveShadow = !0, e.castShadow = !0, t?.name && (e.name = t.name), t?.position && (Array.isArray(t.position) ? e.position.set(t.position[0], t.position[1], t.position[2]) : e.position.set(t.position.x || 0, t.position.y || 0, t.position.z || 0)), t?.rotation && (Array.isArray(t.rotation) ? e.rotation.set(t.rotation[0], t.rotation[1], t.rotation[2]) : e.rotation.set(t.rotation.x || 0, t.rotation.y || 0, t.rotation.z || 0)), t?.scale && (typeof t.scale == "number" ? e.scale.set(t.scale, t.scale, t.scale) : Array.isArray(t.scale) ? e.scale.set(t.scale[0], t.scale[1], t.scale[2]) : e.scale.set(t.scale.x || 1, t.scale.y || 1, t.scale.z || 1)), t?.receiveShadow != null && (e.receiveShadow = t.receiveShadow), t?.castShadow != null && (e.castShadow = t.castShadow), t?.parent && t.parent.add(e);
4244
4244
  }
4245
4245
  }
4246
4246
  function P1(s, e, t, i, n) {
@@ -11184,13 +11184,25 @@ Possible solutions:
11184
11184
  * Set a rect or dom element. The camera center will be moved to the center of the rect.
11185
11185
  * This is useful if you have Needle Engine embedded in a HTML layout and while you want the webgl background to fill e.g. the whole screen you want to move the camera center to free space.
11186
11186
  * For that you can simply pass in the rect or HMTL div that you want the camera to center on.
11187
+ * @param rect The focus rect or null to disable
11188
+ * @param settings Optional settings for the focus rect. These will override the `focusRectSettings` property
11187
11189
  */
11188
- setCameraFocusRect(e) {
11189
- this._focusRect = e;
11190
+ setCameraFocusRect(e, t) {
11191
+ this._focusRect = e, t && Object.assign(this.focusRectSettings, t);
11190
11192
  }
11191
11193
  get focusRect() {
11192
11194
  return this._focusRect;
11193
11195
  }
11196
+ /** Settings when a focus rect is set. Use `setCameraFocusRect(...)` to do so.
11197
+ * This can be used to offset the renderer center e.g. to a specific DOM element.
11198
+ */
11199
+ focusRectSettings = {
11200
+ /** Controls how fast the rect is centered. Smaller values mean the rect is centered faster.
11201
+ * A minimum value of 0 means the rect is centered instantly.
11202
+ * @default .05
11203
+ */
11204
+ damping: 0.05
11205
+ };
11194
11206
  _focusRect = null;
11195
11207
  _lastTimestamp = 0;
11196
11208
  _accumulatedTime = 0;
@@ -11264,7 +11276,11 @@ Possible solutions:
11264
11276
  2
11265
11277
  /* LateUpdate */
11266
11278
  ), this.physicsSteps === void 0 && (this.physicsSteps = 1), this.physics.engine && this.physicsSteps > 0 && this.internalUpdatePhysics(this.physicsSteps), this.isVisibleToUser || this.runInBackground) {
11267
- this._focusRect && this.mainCamera instanceof me && CC(this._focusRect, this.time.deltaTime / 0.05, this.mainCamera, this.renderer), this._currentFrameEvent = 3;
11279
+ if (this._focusRect && this.mainCamera instanceof me) {
11280
+ const n = this.focusRectSettings, o = n.damping > 0 ? this.time.deltaTime / n.damping : 1;
11281
+ CC(this._focusRect, o, this.mainCamera, this.renderer);
11282
+ }
11283
+ this._currentFrameEvent = 3;
11268
11284
  for (let n = 0; n < this.scripts_onBeforeRender.length; n++) {
11269
11285
  const o = this.scripts_onBeforeRender[n];
11270
11286
  o.activeAndEnabled && o.onBeforeRender !== void 0 && (U.Current = this, o.onBeforeRender(t));
@@ -16321,7 +16337,7 @@ class ye extends T {
16321
16337
  return;
16322
16338
  }
16323
16339
  let i;
16324
- if (Array.isArray(e) ? i = e : e && "type" in e ? i = e.children : e && typeof e == "object" && !(e instanceof M) && !Array.isArray(e) && (t = e, i = t.objects), i && !Array.isArray(i) && (i = i.children), (!Array.isArray(i) || i && i.length <= 0) && (i = this.context.scene.children), !Array.isArray(i) || i.length <= 0) {
16340
+ if (Array.isArray(e) || e && "type" in e ? i = e : e && typeof e == "object" && !(e instanceof M) && !Array.isArray(e) && (t = e, i = t.objects), i && !Array.isArray(i) && (i = [i]), (!Array.isArray(i) || i && i.length <= 0) && (i = this.context.scene.children), !Array.isArray(i) || i.length <= 0) {
16325
16341
  console.warn("No objects to fit camera to...");
16326
16342
  return;
16327
16343
  }
@@ -16332,9 +16348,9 @@ class ye extends T {
16332
16348
  }
16333
16349
  t || (t = {});
16334
16350
  const { immediate: r = !1, centerCamera: a, cameraNearFar: l = "auto", fitOffset: c = 1.1, fov: h = n?.fov } = t, d = new b(), f = new b(), p = _i(i, void 0, this._camera?.threeCamera?.layers), g = p.clone();
16335
- n.updateMatrixWorld(), n.updateProjectionMatrix(), p.getCenter(f);
16351
+ p.getCenter(f);
16336
16352
  const _ = new b();
16337
- if (p.getSize(_), p.applyMatrix4(n.matrixWorldInverse), p.getSize(d), p.setFromCenterAndSize(f, d), Number.isNaN(d.x) || Number.isNaN(d.y) || Number.isNaN(d.z)) {
16353
+ if (p.getSize(_), n.updateMatrixWorld(), p.applyMatrix4(n.matrixWorldInverse), p.getSize(d), p.setFromCenterAndSize(f, d), Number.isNaN(d.x) || Number.isNaN(d.y) || Number.isNaN(d.z)) {
16338
16354
  console.warn("Camera fit size resultet in NaN", n, p, [...i]);
16339
16355
  return;
16340
16356
  }
@@ -16347,10 +16363,10 @@ class ye extends T {
16347
16363
  const O = 0.05, k = f.clone();
16348
16364
  if (k.y -= d.y * O, t.targetOffset && (t.targetOffset.x !== void 0 && (k.x += t.targetOffset.x), t.targetOffset.y !== void 0 && (k.y += t.targetOffset.y), t.targetOffset.z !== void 0 && (k.z += t.targetOffset.z)), t.relativeTargetOffset && (t.relativeTargetOffset.x !== void 0 && (k.x += t.relativeTargetOffset.x * d.x), t.relativeTargetOffset.y !== void 0 && (k.y += t.relativeTargetOffset.y * d.y), t.relativeTargetOffset.z !== void 0 && (k.z += t.relativeTargetOffset.z * d.z)), this.setLookTargetPosition(k, r), this.setFieldOfView(t.fov, r), l == null || l == "auto") {
16349
16365
  const W = S.findObjectOfType(Ms), X = W ? W.radius : 0, A = Math.max(_.x, _.y, _.z, X);
16350
- n.near = I / 100, n.far = A + I * 10, W && (this.maxZoom = Math.max(Math.min(this.maxZoom, X * 0.5), I));
16366
+ n.near = I / 100, n.far = A + I * 10, n.updateProjectionMatrix(), W && (this.maxZoom = Math.max(Math.min(this.maxZoom, X * 0.5), I));
16351
16367
  }
16352
16368
  const E = o.getDistance();
16353
- E < this.minZoom && (this.minZoom = E * 0.9), E > this.maxZoom && (this.maxZoom = E * 1.1), n.updateMatrixWorld(), n.updateProjectionMatrix();
16369
+ E < this.minZoom && (this.minZoom = E * 0.9), E > this.maxZoom && (this.maxZoom = E * 1.1);
16354
16370
  const B = f.clone();
16355
16371
  t.fitDirection ? B.sub(new b().copy(t.fitDirection).multiplyScalar(1e6)) : B.sub(n.worldPosition), a === "y" && (B.y = 0), B.normalize(), B.multiplyScalar(I), a === "y" && (B.y += -O * 4 * I);
16356
16372
  let L = f.clone().sub(B);
@@ -18662,18 +18678,18 @@ const vr = class Cl extends T {
18662
18678
  * @param context The context to create the contact shadows in.
18663
18679
  * @returns The instance of the contact shadows.
18664
18680
  */
18665
- static auto(e) {
18681
+ static auto(e, t) {
18666
18682
  if (e || (e = U.Current), !e)
18667
18683
  throw new Error("No context provided and no current context set.");
18668
- let t = this._instances.get(e);
18669
- if (!t || t.destroyed) {
18670
- const i = new M();
18671
- t = An(i, Cl, {
18684
+ let i = this._instances.get(e);
18685
+ if (!i || i.destroyed) {
18686
+ const n = new M();
18687
+ i = An(n, Cl, {
18672
18688
  autoFit: !1,
18673
18689
  occludeBelowGround: !1
18674
- }), this._instances.set(e, t);
18690
+ }), this._instances.set(e, i);
18675
18691
  }
18676
- return e.scene.add(t.gameObject), t.fitShadows(), t;
18692
+ return e.scene.add(i.gameObject), i.fitShadows(t), i;
18677
18693
  }
18678
18694
  autoFit = !1;
18679
18695
  darkness = 0.5;
@@ -18683,11 +18699,13 @@ const vr = class Cl extends T {
18683
18699
  backfaceShadows = !0;
18684
18700
  /**
18685
18701
  * The minimum size of the shadows box
18702
+ * @default undefined
18686
18703
  */
18687
18704
  minSize;
18688
18705
  /**
18689
18706
  * When enabled the shadows will not be updated automatically. Use `needsUpdate()` to update the shadows manually.
18690
18707
  * This is useful when you want to update the shadows only when the scene changes.
18708
+ * @default false
18691
18709
  */
18692
18710
  manualUpdate = !1;
18693
18711
  /**
@@ -18719,12 +18737,12 @@ const vr = class Cl extends T {
18719
18737
  /**
18720
18738
  * Call to fit the shadows to the scene.
18721
18739
  */
18722
- fitShadows() {
18740
+ fitShadows(e = {}) {
18723
18741
  sl && console.warn("Fitting shadows to scene"), hp(this.shadowsRoot, !1);
18724
- const e = _i(this.context.scene.children, [this.shadowsRoot]), t = Math.max(1, this.blur / 32), i = e.max.x - e.min.x, n = e.max.z - e.min.z;
18725
- e.expandByVector(new b(t * i, 0, t * n)), sl && z.DrawWireBox3(e, 16776960, 60), this.gameObject.parent && e.applyMatrix4(this.gameObject.parent.matrixWorld.clone().invert());
18726
- const o = e.min, r = Math.max(1e-5, (e.max.y - o.y) * 2e-3);
18727
- e.max.y += r, this.shadowsRoot.position.set((o.x + e.max.x) / 2, o.y - r, (o.z + e.max.z) / 2), this.shadowsRoot.scale.set(e.max.x - o.x, e.max.y - o.y, e.max.z - o.z), this.applyMinSize(), this.shadowsRoot.matrixWorldNeedsUpdate = !0, sl && console.log("Fitted shadows to scene", this.shadowsRoot.scale.clone());
18742
+ const t = e.object || this.context.scene, i = _i(t, [this.shadowsRoot]), n = Math.max(1, this.blur / 32), o = i.max.x - i.min.x, r = i.max.z - i.min.z;
18743
+ i.expandByVector(new b(n * o, 0, n * r)), sl && z.DrawWireBox3(i, 16776960, 60), this.gameObject.parent && i.applyMatrix4(this.gameObject.parent.matrixWorld.clone().invert());
18744
+ const a = i.min, l = Math.max(1e-5, (i.max.y - a.y) * 2e-3);
18745
+ i.max.y += l, this.shadowsRoot.position.set((a.x + i.max.x) / 2, a.y - l, (a.z + i.max.z) / 2), this.shadowsRoot.scale.set(i.max.x - a.x, i.max.y - a.y, i.max.z - a.z), e.positionOffset && (e.positionOffset.x !== void 0 && (this.shadowsRoot.position.x += e.positionOffset.x), e.positionOffset.y !== void 0 && (this.shadowsRoot.position.y += e.positionOffset.y), e.positionOffset.z !== void 0 && (this.shadowsRoot.position.z += e.positionOffset.z)), e.scaleFactor && (e.scaleFactor.x !== void 0 && (this.shadowsRoot.scale.x *= e.scaleFactor.x), e.scaleFactor.y !== void 0 && (this.shadowsRoot.scale.y *= e.scaleFactor.y), e.scaleFactor.z !== void 0 && (this.shadowsRoot.scale.z *= e.scaleFactor.z)), this.applyMinSize(), this.shadowsRoot.matrixWorldNeedsUpdate = !0, sl && console.log("Fitted shadows to scene", this.shadowsRoot.scale.clone());
18728
18746
  }
18729
18747
  /** @internal */
18730
18748
  awake() {
@@ -20588,7 +20606,7 @@ class Fp extends T {
20588
20606
  }
20589
20607
  } else
20590
20608
  this._ambientLightObj && this._ambientLightObj.removeFromParent(), this._hemisphereLightObj && this._hemisphereLightObj.removeFromParent();
20591
- this.sourceId && this.context.sceneLighting.internalEnableReflection(this.sourceId);
20609
+ this.sourceId && (this.context.domElement.getAttribute("environment-image") || this.context.sceneLighting.internalEnableReflection(this.sourceId));
20592
20610
  }
20593
20611
  onDisable() {
20594
20612
  Nr && console.warn("💡⚫ <<< Disable lighting:", this.sourceId, this), this._ambientLightObj && this._ambientLightObj.removeFromParent(), this._hemisphereLightObj && this._hemisphereLightObj.removeFromParent(), this.sourceId && this.context.sceneLighting.internalDisableReflection(this.sourceId);