@needle-tools/engine 3.0.0-alpha → 3.0.1-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 (75) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/needle-engine.js +9552 -9570
  3. package/dist/needle-engine.min.js +4812 -0
  4. package/dist/needle-engine.umd.cjs +279 -279
  5. package/lib/engine/engine_addressables.js +1 -1
  6. package/lib/engine/engine_addressables.js.map +1 -1
  7. package/lib/engine/engine_assetdatabase.js +24 -17
  8. package/lib/engine/engine_assetdatabase.js.map +1 -1
  9. package/lib/engine/engine_context.d.ts +0 -1
  10. package/lib/engine/engine_context.js +15 -17
  11. package/lib/engine/engine_context.js.map +1 -1
  12. package/lib/engine/engine_context_registry.d.ts +2 -1
  13. package/lib/engine/engine_context_registry.js +6 -1
  14. package/lib/engine/engine_context_registry.js.map +1 -1
  15. package/lib/engine/engine_element.js +1 -1
  16. package/lib/engine/engine_element.js.map +1 -1
  17. package/lib/engine/engine_gltf.d.ts +2 -2
  18. package/lib/engine/engine_mainloop_utils.js +13 -11
  19. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  20. package/lib/engine/engine_networking_files.js +4 -3
  21. package/lib/engine/engine_networking_files.js.map +1 -1
  22. package/lib/engine/engine_patcher.d.ts +4 -3
  23. package/lib/engine/engine_patcher.js +61 -44
  24. package/lib/engine/engine_patcher.js.map +1 -1
  25. package/lib/engine/engine_scenetools.d.ts +4 -4
  26. package/lib/engine/engine_scenetools.js +5 -5
  27. package/lib/engine/engine_scenetools.js.map +1 -1
  28. package/lib/engine/engine_time.d.ts +2 -1
  29. package/lib/engine/engine_time.js.map +1 -1
  30. package/lib/engine/engine_types.d.ts +5 -0
  31. package/lib/engine/engine_types.js.map +1 -1
  32. package/lib/engine-components/Animation.d.ts +1 -1
  33. package/lib/engine-components/Animation.js +3 -3
  34. package/lib/engine-components/Animation.js.map +1 -1
  35. package/lib/engine-components/Renderer.d.ts +1 -1
  36. package/lib/engine-components/Renderer.js +15 -4
  37. package/lib/engine-components/Renderer.js.map +1 -1
  38. package/lib/engine-components/api.d.ts +1 -0
  39. package/lib/engine-components/api.js +2 -0
  40. package/lib/engine-components/api.js.map +1 -0
  41. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.d.ts +2 -0
  42. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js +18 -1
  43. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js.map +1 -1
  44. package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +3 -0
  45. package/lib/engine-components/postprocessing/PostProcessingHandler.js +1 -1
  46. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
  47. package/lib/engine-components/ui/Text.d.ts +1 -1
  48. package/lib/engine-components/ui/Text.js +42 -17
  49. package/lib/engine-components/ui/Text.js.map +1 -1
  50. package/lib/needle-engine.d.ts +1 -0
  51. package/lib/needle-engine.js +1 -0
  52. package/lib/needle-engine.js.map +1 -1
  53. package/lib/tsconfig.tsbuildinfo +1 -1
  54. package/package.json +3 -4
  55. package/plugins/vite/copyfiles.js +37 -10
  56. package/plugins/vite/reload.js +2 -1
  57. package/src/engine/engine_addressables.ts +1 -1
  58. package/src/engine/engine_assetdatabase.ts +29 -18
  59. package/src/engine/engine_context.ts +15 -18
  60. package/src/engine/engine_context_registry.ts +7 -1
  61. package/src/engine/engine_element.ts +1 -1
  62. package/src/engine/engine_gltf.ts +2 -2
  63. package/src/engine/engine_mainloop_utils.ts +12 -10
  64. package/src/engine/engine_networking_files.ts +5 -4
  65. package/src/engine/engine_patcher.ts +104 -47
  66. package/src/engine/engine_scenetools.ts +7 -7
  67. package/src/engine/engine_time.ts +2 -1
  68. package/src/engine/engine_types.ts +6 -0
  69. package/src/engine-components/Animation.ts +3 -3
  70. package/src/engine-components/Renderer.ts +19 -5
  71. package/src/engine-components/api.ts +1 -0
  72. package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +15 -1
  73. package/src/engine-components/postprocessing/PostProcessingHandler.ts +1 -1
  74. package/src/engine-components/ui/Text.ts +41 -17
  75. package/src/needle-engine.ts +1 -0
@@ -24,11 +24,11 @@ export class NeedleGltfLoader implements INeedleGltfLoader {
24
24
  return writeBuiltinComponentData(comp, context);
25
25
  }
26
26
 
27
- parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
27
+ parseSync(context: Context, data : string | ArrayBuffer, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
28
28
  return parseSync(context, data, path, seed);
29
29
  }
30
- loadSync(context: Context, url: string, seed: number | UIDProvider | null, _allowAddingAnimator: boolean, prog?: ((ProgressEvent: any) => void) | undefined): Promise<GLTF | undefined> {
31
- return loadSync(context, url, seed, _allowAddingAnimator, prog);
30
+ loadSync(context: Context, url: string, sourceId:string, seed: number | UIDProvider | null, prog?: ((ProgressEvent: any) => void) | undefined): Promise<GLTF | undefined> {
31
+ return loadSync(context, url, sourceId, seed, prog);
32
32
  }
33
33
  }
34
34
 
@@ -87,7 +87,7 @@ function invokeEvents(type: GltfLoadEventType, event: GltfLoadEvent) {
87
87
 
88
88
  async function handleLoadedGltf(context: Context, gltfId: string, gltf, seed: number | null | UIDProvider, componentsExtension) {
89
89
  if (printGltf)
90
- console.log(gltf);
90
+ console.warn("glTF", gltfId, gltf);
91
91
  await getLoader().createBuiltinComponents(context, gltfId, gltf, seed, componentsExtension);
92
92
 
93
93
  // load and assign animation
@@ -102,7 +102,7 @@ export function createGLTFLoader(url: string, context: Context) {
102
102
  return loader;
103
103
  }
104
104
 
105
- export function parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
105
+ export function parseSync(context: Context, data : string | ArrayBuffer, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
106
106
  if (typeof path !== "string") {
107
107
  console.warn("Parse gltf binary without path, this might lead to errors in resolving extensions. Please provide the source path of the gltf/glb file", path, typeof path);
108
108
  }
@@ -131,7 +131,7 @@ export function parseSync(context: Context, data, path: string, seed: number | U
131
131
  });
132
132
  }
133
133
 
134
- export function loadSync(context: Context, url: string, seed: number | UIDProvider | null, _allowAddingAnimator: boolean = false, prog?: (ProgressEvent) => void): Promise<GLTF | undefined> {
134
+ export function loadSync(context: Context, url: string, sourceId:string, seed: number | UIDProvider | null, prog?: (ProgressEvent) => void): Promise<GLTF | undefined> {
135
135
  // better to create new loaders every time
136
136
  // (maybe we can cache them...)
137
137
  // but due to the async nature and potentially triggering multiple loads at the same time
@@ -145,7 +145,7 @@ export function loadSync(context: Context, url: string, seed: number | UIDProvid
145
145
  invokeEvents(GltfLoadEventType.BeforeLoad, new GltfLoadEvent(context, url, loader));
146
146
  loader.load(url, async data => {
147
147
  invokeEvents(GltfLoadEventType.AfterLoaded, new GltfLoadEvent(context, url, loader, data));
148
- await handleLoadedGltf(context, url, data, seed, componentsExtension);
148
+ await handleLoadedGltf(context, sourceId, data, seed, componentsExtension);
149
149
  invokeEvents(GltfLoadEventType.FinishedSetup, new GltfLoadEvent(context, url, loader, data));
150
150
  registerPrewarmObject(data.scene, context);
151
151
  resolve(data);
@@ -1,11 +1,12 @@
1
1
  import { Clock } from 'three'
2
2
  import { getParam } from './engine_utils';
3
+ import { ITime } from './engine_types';
3
4
 
4
5
  const timescaleUrl = getParam("timescale");
5
6
  let timeScale = 1;
6
7
  if (typeof timescaleUrl === "number") timeScale = timescaleUrl;
7
8
 
8
- export class Time {
9
+ export class Time implements ITime {
9
10
 
10
11
  deltaTime = 0;
11
12
  time = 0;
@@ -27,9 +27,13 @@ export declare type CoroutineData = {
27
27
  chained?: Array<Generator>
28
28
  }
29
29
 
30
+ export interface ITime {
31
+ get time(): number;
32
+ }
30
33
 
31
34
  export interface IContext {
32
35
  alias?: string | null;
36
+ hash?:string;
33
37
 
34
38
  scene: Scene;
35
39
  renderer: WebGLRenderer;
@@ -37,6 +41,8 @@ export interface IContext {
37
41
  mainCameraComponent: ICamera | undefined;
38
42
  domElement: HTMLElement;
39
43
 
44
+ time: ITime;
45
+
40
46
  scripts: IComponent[];
41
47
  scripts_pausedChanged: IComponent[];
42
48
  // scripts with update event
@@ -145,7 +145,7 @@ export class Animation extends Behaviour {
145
145
  return false;
146
146
  }
147
147
 
148
- play(clipOrNumber: AnimationClip | number | string | undefined, options?: PlayOptions): Promise<AnimationAction> | void {
148
+ play(clipOrNumber: AnimationClip | number | string | undefined = 0, options?: PlayOptions): Promise<AnimationAction> | void {
149
149
  if (debug) console.log("PLAY", clipOrNumber)
150
150
  this.init();
151
151
  if (!this.mixer) {
@@ -171,8 +171,8 @@ export class Animation extends Behaviour {
171
171
  if (!options) options = {};
172
172
  if (!options.minMaxOffsetNormalized) options.minMaxOffsetNormalized = this.minMaxOffsetNormalized;
173
173
  if (!options.minMaxSpeed) options.minMaxSpeed = this.minMaxSpeed;
174
- if (!options.loop) options.loop = this.loop;
175
- if (!options.clampWhenFinished) options.clampWhenFinished = this.clampWhenFinished;
174
+ if (options.loop === undefined) options.loop = this.loop;
175
+ if (options.clampWhenFinished === undefined) options.clampWhenFinished = this.clampWhenFinished;
176
176
  for (const act of this.actions) {
177
177
  if (act.getClip() === clip) {
178
178
  return this.internalOnPlay(act, options);
@@ -639,7 +639,7 @@ export class Renderer extends Behaviour implements IRenderer {
639
639
  }
640
640
  }
641
641
 
642
- private applySettings(go: THREE.Object3D) {
642
+ applySettings(go: THREE.Object3D) {
643
643
  go.receiveShadow = this.receiveShadows;
644
644
  if (this.shadowCastingMode == ShadowCastingMode.On) {
645
645
  go.castShadow = true;
@@ -734,15 +734,16 @@ class InstancingHandler {
734
734
  public setup(renderer: Renderer, obj: THREE.Object3D, context: Context, handlesArray: InstanceHandle[] | null, args: InstancingSetupArgs, level: number = 0)
735
735
  : InstanceHandle[] | null {
736
736
 
737
+ // make sure setting casting settings are applied so when we add the mesh to the InstancedMesh we can ask for the correct cast shadow setting
738
+ renderer.applySettings(obj);
737
739
  const res = this.tryCreateOrAddInstance(obj, context, args);
738
740
  if (res) {
739
741
  renderer.loadProgressiveTextures(res.instancer.material);
740
742
  if (handlesArray === null) handlesArray = [];
741
743
  handlesArray.push(res);
742
- return handlesArray;
743
744
  }
744
745
 
745
- if (level <= 0 && obj.type !== "Mesh") {
746
+ else if (level <= 0 && obj.type !== "Mesh") {
746
747
  const nextLevel = level + 1;
747
748
  for (const ch of obj.children) {
748
749
  handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
@@ -799,10 +800,8 @@ class InstancingHandler {
799
800
  let previousMatrix: THREE.Matrix4 = obj.matrixWorld.clone();
800
801
  const matrixChangeWrapper = (a: Matrix4, b: Matrix4) => {
801
802
  const newMatrixWorld = original(a, b);
802
- // console.warn("MULT", obj.matrixWorldNeedsUpdate);
803
803
  if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
804
804
  previousMatrix.copy(newMatrixWorld)
805
- // handle.setMatrix(newMatrixWorld);
806
805
  obj[NEED_UPDATE_INSTANCE_KEY] = true;
807
806
  }
808
807
  return newMatrixWorld;
@@ -865,6 +864,13 @@ class InstanceHandle {
865
864
 
866
865
  class InstancedMeshRenderer {
867
866
 
867
+ set castShadow(val: boolean) {
868
+ this.inst.castShadow = val;
869
+ }
870
+ set receiveShadow(val: boolean) {
871
+ this.inst.receiveShadow = val;
872
+ }
873
+
868
874
  public name: string = "";
869
875
  public geo: THREE.BufferGeometry;
870
876
  public material: THREE.Material;
@@ -915,6 +921,14 @@ class InstancedMeshRenderer {
915
921
  return null;
916
922
  }
917
923
  const handle = new InstanceHandle(-1, obj, this);
924
+
925
+ if (obj.castShadow === true && this.inst.castShadow === false) {
926
+ this.inst.castShadow = true;
927
+ }
928
+ if (obj.receiveShadow === true && this.inst.receiveShadow === false) {
929
+ this.inst.receiveShadow = true;
930
+ }
931
+
918
932
  this.add(handle);
919
933
  return handle;
920
934
  }
@@ -0,0 +1 @@
1
+ export * from "./ui/PointerEvents"
@@ -1,5 +1,5 @@
1
1
  import { BlendFunction, DepthDownsamplingPass, Effect, NormalPass, SSAOEffect } from "postprocessing";
2
- import { NeverDepth, PerspectiveCamera } from "three";
2
+ import { Color, NeverDepth, PerspectiveCamera } from "three";
3
3
  import { serializable } from "../../../engine/engine_serialization";
4
4
  import { EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect";
5
5
  import { VolumeParameter } from "../VolumeParameter";
@@ -21,6 +21,12 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
21
21
  @serializable(VolumeParameter)
22
22
  samples!: VolumeParameter;
23
23
 
24
+ @serializable(VolumeParameter)
25
+ color!: VolumeParameter;
26
+
27
+ @serializable(VolumeParameter)
28
+ luminanceInfluence!: VolumeParameter;
29
+
24
30
  onBeforeRender() {
25
31
  if (this._ssao && this.context.mainCamera instanceof PerspectiveCamera) {
26
32
  const fadeDistance = this.context.mainCamera.far - this.context.mainCamera.near;
@@ -48,6 +54,7 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
48
54
  worldProximityFalloff: 2,
49
55
  intensity: 1,
50
56
  blendFunction: BlendFunction.MULTIPLY,
57
+ luminanceInfluence: .5,
51
58
  });
52
59
 
53
60
  this.intensity.onValueChanged = newValue => {
@@ -59,6 +66,13 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
59
66
  this.samples.onValueChanged = newValue => {
60
67
  ssao.samples = newValue;
61
68
  }
69
+ this.color.onValueChanged = newValue => {
70
+ if (!ssao.color) ssao.color = new Color();
71
+ ssao.color.copy(newValue);
72
+ }
73
+ this.luminanceInfluence.onValueChanged = newValue => {
74
+ ssao.luminanceInfluence = newValue;
75
+ }
62
76
 
63
77
  const arr = new Array();
64
78
  arr.push(normalPass);
@@ -193,7 +193,7 @@ export class PostProcessingHandler {
193
193
  }
194
194
 
195
195
 
196
- const effectsOrder: Array<Constructor<Effect | Pass>> = [
196
+ export const effectsOrder: Array<Constructor<Effect | Pass>> = [
197
197
  NormalPass,
198
198
  DepthDownsamplingPass,
199
199
  SSAOEffect,
@@ -466,7 +466,7 @@ export class Text extends Graphic {
466
466
  }
467
467
 
468
468
  private setFont(opts: any, fontStyle: FontStyle) {
469
- const name = this.getFontName(fontStyle);
469
+ const name = this.getFontStyleName(fontStyle);
470
470
  let family = name;
471
471
  if (!family?.endsWith("-msdf.json")) family += "-msdf.json";
472
472
  opts.fontFamily = family;
@@ -476,23 +476,47 @@ export class Text extends Graphic {
476
476
  opts.fontTexture = texture;
477
477
  }
478
478
 
479
- private getFontName(_fontStyle: FontStyle): string | null {
479
+ private getFontStyleName(style: FontStyle): string | null {
480
480
  if (!this.font) return null;
481
- // switch (fontStyle) {
482
- // case FontStyle.Normal:
483
- // return this.font;
484
- // case FontStyle.Bold:
485
- // if (!this.font.includes("-bold"))
486
- // return this.font + "-bold";
487
- // case FontStyle.Italic:
488
- // if (!this.font.includes("-italic"))
489
- // return this.font + "-italic";
490
- // case FontStyle.BoldAndItalic:
491
- // if (!this.font.includes("-bold-italic"))
492
- // return this.font + "-bold-italic";
493
- // }
494
- this.font = getPath(this.sourceId, this.font);
495
- return this.font;
481
+ let fontName = this.font;
482
+
483
+ // if a font path has a known suffix we remove it
484
+ if (fontName.endsWith("-regular")) {
485
+ if (style === FontStyle.Normal) return getPath(this.sourceId, fontName);
486
+ fontName = fontName.substring(0, fontName.length - "-regular".length);
487
+ }
488
+ else if (fontName.endsWith("-bold")) {
489
+ if (style === FontStyle.Bold)return getPath(this.sourceId, fontName);
490
+ fontName = fontName.substring(0, fontName.length - "-bold".length);
491
+ }
492
+ else if (fontName.endsWith("-italic")) {
493
+ if (style === FontStyle.Italic)return getPath(this.sourceId, fontName);
494
+ fontName = fontName.substring(0, fontName.length - "-italic".length);
495
+ }
496
+ else if (fontName.endsWith("-bolditalic")) {
497
+ if (style === FontStyle.BoldAndItalic)return getPath(this.sourceId, fontName);
498
+ fontName = fontName.substring(0, fontName.length - "-bolditalic".length);
499
+ }
500
+ else
501
+ // If a font does not have a specific style suffic we dont support getting the correct font style
502
+ return getPath(this.sourceId, fontName);
503
+
504
+ switch (style) {
505
+ case FontStyle.Normal:
506
+ fontName += "-regular";
507
+ break;
508
+ case FontStyle.Bold:
509
+ fontName += "-bold";
510
+ break;
511
+ case FontStyle.Italic:
512
+ fontName += "-italic";
513
+ break;
514
+ case FontStyle.BoldAndItalic:
515
+ fontName += "-bolditalic";
516
+ break;
517
+ }
518
+
519
+ return getPath(this.sourceId, fontName);
496
520
  }
497
521
  }
498
522
 
@@ -11,6 +11,7 @@ export { GameObject, Behaviour } from "./engine-components/Component";
11
11
  export { serializable, serializeable } from "./engine/engine_serialization_decorator";
12
12
  export { Collision } from "./engine/engine_types";
13
13
  export * from "./engine/api";
14
+ export * from "./engine-components/api";
14
15
  export * from "./engine-components/codegen/components";
15
16
  export * from "./engine-components/js-extensions/Object3D";
16
17