babylon.quarks-editor 0.26.0 → 0.28.0

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 (211) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +69 -9
  3. package/dist/core/assetDragSession.d.ts +1 -1
  4. package/dist/core/assetTree.d.ts +6 -1
  5. package/dist/core/assets.d.ts +7 -0
  6. package/dist/core/assets.js +11 -7
  7. package/dist/core/binding.d.ts +11 -2
  8. package/dist/core/binding.js +9 -1
  9. package/dist/core/collision.d.ts +4 -0
  10. package/dist/core/collision.js +4 -0
  11. package/dist/core/colors.d.ts +16 -0
  12. package/dist/core/colors.js +8 -0
  13. package/dist/core/defaultEffect.d.ts +5 -4
  14. package/dist/core/defaultEffect.js +4 -4
  15. package/dist/core/editorScene.d.ts +1 -1
  16. package/dist/core/editorSession.d.ts +229 -0
  17. package/dist/core/editorSession.js +983 -0
  18. package/dist/core/effectTree.d.ts +6 -1
  19. package/dist/core/effectTree.js +13 -88
  20. package/dist/core/emitterShapeWireframe.d.ts +2 -2
  21. package/dist/core/emitterShapeWireframe.js +45 -13
  22. package/dist/core/galleryDropMarker.d.ts +2 -2
  23. package/dist/core/galleryDropMarker.js +6 -6
  24. package/dist/core/galleryLayout.d.ts +3 -3
  25. package/dist/core/galleryLayout.js +1 -1
  26. package/dist/core/galleryPlayback.d.ts +1 -1
  27. package/dist/core/galleryPlayback.js +2 -1
  28. package/dist/core/galleryScene.d.ts +4 -4
  29. package/dist/core/galleryScene.js +3 -3
  30. package/dist/core/gallerySelectionMarker.d.ts +4 -4
  31. package/dist/core/gallerySelectionMarker.js +5 -5
  32. package/dist/core/groups.d.ts +1 -1
  33. package/dist/core/groups.js +1 -1
  34. package/dist/core/history.d.ts +7 -1
  35. package/dist/core/history.js +4 -0
  36. package/dist/core/indexedDbProjectStore.d.ts +14 -1
  37. package/dist/core/indexedDbProjectStore.js +13 -0
  38. package/dist/core/lineShaders.d.ts +2 -2
  39. package/dist/core/lineShaders.js +2 -2
  40. package/dist/core/loadEffect.d.ts +2 -2
  41. package/dist/core/loadEffect.js +1 -1
  42. package/dist/core/material.d.ts +12 -2
  43. package/dist/core/pickAssetFiles.js +1 -1
  44. package/dist/core/playback.d.ts +6 -0
  45. package/dist/core/projectStore.d.ts +26 -0
  46. package/dist/core/projectStore.js +1 -0
  47. package/dist/core/sceneEntries.d.ts +7 -4
  48. package/dist/core/sceneEntries.js +2 -2
  49. package/dist/core/scrub.d.ts +2 -2
  50. package/dist/core/scrub.js +2 -2
  51. package/dist/core/shapes.d.ts +25 -1
  52. package/dist/core/shapes.js +5 -0
  53. package/dist/core/systems.d.ts +4 -2
  54. package/dist/core/systems.js +3 -1
  55. package/dist/core/textureExport.d.ts +1 -1
  56. package/dist/core/timeline.d.ts +25 -5
  57. package/dist/core/transport.d.ts +3 -3
  58. package/dist/core/transport.js +2 -2
  59. package/dist/core/values.d.ts +21 -4
  60. package/dist/core/values.js +5 -0
  61. package/dist/core/viewportPicker.d.ts +4 -4
  62. package/dist/core/viewportPicker.js +8 -7
  63. package/dist/index.d.ts +25 -21
  64. package/dist/index.js +12 -12
  65. package/dist/react/AssetsPanel.d.ts +9 -2
  66. package/dist/react/AssetsPanel.js +6 -6
  67. package/dist/react/ChoiceDialog.d.ts +7 -0
  68. package/dist/react/ChoiceDialog.js +1 -1
  69. package/dist/react/ContextMenu.d.ts +10 -1
  70. package/dist/react/ContextMenu.js +1 -1
  71. package/dist/react/CurveEditor.d.ts +1 -1
  72. package/dist/react/CurveEditor.js +2 -2
  73. package/dist/react/EditorWorkspace.d.ts +9 -2
  74. package/dist/react/EditorWorkspace.js +10 -7
  75. package/dist/react/EffectEditor.d.ts +11 -5
  76. package/dist/react/EffectEditor.js +7 -7
  77. package/dist/react/EffectEditorHost.d.ts +33 -29
  78. package/dist/react/EffectEditorHost.js +247 -1674
  79. package/dist/react/EffectTreeView.d.ts +4 -1
  80. package/dist/react/EffectTreeView.js +3 -3
  81. package/dist/react/GradientEditor.d.ts +1 -1
  82. package/dist/react/GradientEditor.js +3 -3
  83. package/dist/react/InspectorInfoIcon.js +3 -3
  84. package/dist/react/InspectorLabel.js +3 -3
  85. package/dist/react/MessageDialog.d.ts +5 -0
  86. package/dist/react/MessageDialog.js +1 -1
  87. package/dist/react/ModuleSection.d.ts +10 -0
  88. package/dist/react/ModuleSection.js +8 -5
  89. package/dist/react/ObjectModule.d.ts +1 -1
  90. package/dist/react/ObjectModule.js +4 -4
  91. package/dist/react/ProjectsPage.d.ts +7 -1
  92. package/dist/react/ProjectsPage.js +33 -17
  93. package/dist/react/PromptDialog.d.ts +7 -0
  94. package/dist/react/PromptDialog.js +1 -1
  95. package/dist/react/ScenePanel.d.ts +9 -2
  96. package/dist/react/ScenePanel.js +12 -10
  97. package/dist/react/SubEmittersModule.d.ts +1 -1
  98. package/dist/react/SubEmittersModule.js +5 -5
  99. package/dist/react/TextureSelect.d.ts +24 -0
  100. package/dist/react/TextureSelect.js +74 -0
  101. package/dist/react/TextureUVField.d.ts +14 -0
  102. package/dist/react/TextureUVField.js +23 -0
  103. package/dist/react/TimelinePanel.d.ts +20 -7
  104. package/dist/react/TimelinePanel.js +21 -15
  105. package/dist/react/TimelineTrackRow.d.ts +13 -3
  106. package/dist/react/TimelineTrackRow.js +6 -6
  107. package/dist/react/TransportBar.d.ts +13 -4
  108. package/dist/react/TransportBar.js +3 -3
  109. package/dist/react/ValueField.d.ts +32 -5
  110. package/dist/react/ValueField.js +22 -11
  111. package/dist/react/behaviorModules.d.ts +19 -6
  112. package/dist/react/behaviorModules.js +68 -17
  113. package/dist/react/fields.d.ts +9 -0
  114. package/dist/react/fields.js +6 -3
  115. package/dist/react/host/BottomDocks.d.ts +36 -0
  116. package/dist/react/host/BottomDocks.js +63 -0
  117. package/dist/react/host/HostDialogs.d.ts +50 -0
  118. package/dist/react/host/HostDialogs.js +113 -0
  119. package/dist/react/host/InspectorSidebar.d.ts +32 -0
  120. package/dist/react/host/InspectorSidebar.js +59 -0
  121. package/dist/react/host/SceneSidebar.d.ts +53 -0
  122. package/dist/react/host/SceneSidebar.js +62 -0
  123. package/dist/react/host/ViewportPane.d.ts +56 -0
  124. package/dist/react/host/ViewportPane.js +91 -0
  125. package/dist/react/host/hostHooks.d.ts +44 -0
  126. package/dist/react/host/hostHooks.js +164 -0
  127. package/dist/react/host/hostStyles.d.ts +21 -0
  128. package/dist/react/host/hostStyles.js +57 -0
  129. package/dist/react/index.d.ts +42 -38
  130. package/dist/react/index.js +25 -23
  131. package/dist/react/inspectorHints.js +31 -0
  132. package/dist/react/modules.d.ts +19 -6
  133. package/dist/react/modules.js +134 -117
  134. package/dist/react/theme.d.ts +15 -0
  135. package/dist/react/theme.js +15 -0
  136. package/dist/session.d.ts +9 -0
  137. package/dist/session.js +8 -0
  138. package/package.json +18 -11
  139. package/src/core/assetDragSession.ts +1 -1
  140. package/src/core/assetTree.ts +15 -2
  141. package/src/core/assets.ts +25 -10
  142. package/src/core/binding.ts +12 -3
  143. package/src/core/collision.ts +4 -0
  144. package/src/core/colors.ts +21 -1
  145. package/src/core/defaultEffect.ts +8 -7
  146. package/src/core/editorScene.ts +1 -1
  147. package/src/core/editorSession.ts +1299 -0
  148. package/src/core/effectTree.ts +18 -101
  149. package/src/core/emitterShapeWireframe.ts +48 -16
  150. package/src/core/galleryDropMarker.ts +8 -8
  151. package/src/core/galleryLayout.ts +4 -4
  152. package/src/core/galleryPlayback.ts +3 -2
  153. package/src/core/galleryScene.ts +5 -5
  154. package/src/core/gallerySelectionMarker.ts +7 -7
  155. package/src/core/groups.ts +1 -1
  156. package/src/core/history.ts +7 -1
  157. package/src/core/indexedDbProjectStore.ts +14 -1
  158. package/src/core/lineShaders.ts +2 -2
  159. package/src/core/loadEffect.ts +4 -4
  160. package/src/core/material.ts +14 -4
  161. package/src/core/pickAssetFiles.ts +2 -2
  162. package/src/core/playback.ts +6 -0
  163. package/src/core/projectStore.ts +26 -0
  164. package/src/core/sceneEntries.ts +8 -5
  165. package/src/core/scrub.ts +3 -3
  166. package/src/core/shapes.ts +29 -2
  167. package/src/core/systems.ts +11 -4
  168. package/src/core/textureExport.ts +1 -1
  169. package/src/core/timeline.ts +43 -18
  170. package/src/core/transport.ts +4 -4
  171. package/src/core/values.ts +20 -4
  172. package/src/core/viewportPicker.ts +12 -11
  173. package/src/index.ts +25 -21
  174. package/src/react/AssetsPanel.tsx +13 -6
  175. package/src/react/ChoiceDialog.tsx +8 -1
  176. package/src/react/ContextMenu.tsx +11 -2
  177. package/src/react/CurveEditor.tsx +2 -2
  178. package/src/react/EditorWorkspace.tsx +16 -10
  179. package/src/react/EffectEditor.tsx +17 -9
  180. package/src/react/EffectEditorHost.tsx +415 -2354
  181. package/src/react/EffectTreeView.tsx +7 -4
  182. package/src/react/GradientEditor.tsx +3 -3
  183. package/src/react/InspectorInfoIcon.tsx +3 -3
  184. package/src/react/InspectorLabel.tsx +3 -3
  185. package/src/react/MessageDialog.tsx +6 -1
  186. package/src/react/ModuleSection.tsx +15 -4
  187. package/src/react/ObjectModule.tsx +5 -5
  188. package/src/react/ProjectsPage.tsx +44 -17
  189. package/src/react/PromptDialog.tsx +8 -1
  190. package/src/react/ScenePanel.tsx +21 -12
  191. package/src/react/SubEmittersModule.tsx +6 -6
  192. package/src/react/TextureSelect.tsx +118 -0
  193. package/src/react/TextureUVField.tsx +62 -0
  194. package/src/react/TimelinePanel.tsx +40 -21
  195. package/src/react/TimelineTrackRow.tsx +19 -9
  196. package/src/react/TransportBar.tsx +16 -7
  197. package/src/react/ValueField.tsx +60 -16
  198. package/src/react/behaviorModules.tsx +240 -55
  199. package/src/react/fields.tsx +22 -4
  200. package/src/react/host/BottomDocks.tsx +178 -0
  201. package/src/react/host/HostDialogs.tsx +228 -0
  202. package/src/react/host/InspectorSidebar.tsx +147 -0
  203. package/src/react/host/SceneSidebar.tsx +227 -0
  204. package/src/react/host/ViewportPane.tsx +300 -0
  205. package/src/react/host/hostHooks.ts +198 -0
  206. package/src/react/host/hostStyles.ts +65 -0
  207. package/src/react/index.ts +43 -38
  208. package/src/react/inspectorHints.ts +40 -0
  209. package/src/react/modules.tsx +440 -170
  210. package/src/react/theme.ts +15 -0
  211. package/src/session.ts +17 -0
@@ -7,7 +7,9 @@ import {QuarksLoader} from 'babylon.quarks';
7
7
  * fresh, independent copy (see `instantiateSceneEntry`).
8
8
  */
9
9
  export interface EffectAsset {
10
+ /** The asset's id in this session; scene entries made from it keep it. */
10
11
  id: number;
12
+ /** The asset's display name, its file name without `.json`. */
11
13
  name: string;
12
14
  /** Relative path inside the imported folder (preserves subfolders). */
13
15
  path: string;
@@ -17,10 +19,15 @@ export interface EffectAsset {
17
19
  missingFiles: string[];
18
20
  }
19
21
 
22
+ /** How far an asset import got. */
20
23
  export interface AssetLoadProgress {
24
+ /** JSON files read so far. */
21
25
  done: number;
26
+ /** JSON files in the import. */
22
27
  total: number;
28
+ /** Effects found so far. */
23
29
  loaded: number;
30
+ /** Files that could not be read. */
24
31
  failed: number;
25
32
  }
26
33
 
@@ -75,6 +82,13 @@ function readAsDataUrl(file: File): Promise<string> {
75
82
  });
76
83
  }
77
84
 
85
+ /** An object with fields of unknown types, as an imported file's JSON may hold anywhere. */
86
+ type JSONRecord = {[key: string]: unknown};
87
+
88
+ function isRecord(value: unknown): value is JSONRecord {
89
+ return value !== null && typeof value === 'object';
90
+ }
91
+
78
92
  /** True for a Quarks effect envelope with at least one particle emitter. */
79
93
  export function isEffectJson(json: unknown): boolean {
80
94
  const object = (json as {object?: unknown} | null)?.object;
@@ -166,7 +180,7 @@ function createFileResolver(effectPath: string, index: ImportedFileIndex, missin
166
180
  * {@link QuarksLoader.resolveLinkedResources}, so the effect loads (and later exports) as a
167
181
  * self-contained effect. Returns the references that could not be found among the files.
168
182
  */
169
- async function inlineExternalFiles(json: any, effectPath: string, index: ImportedFileIndex): Promise<string[]> {
183
+ async function inlineExternalFiles(json: unknown, effectPath: string, index: ImportedFileIndex): Promise<string[]> {
170
184
  const missing: string[] = [];
171
185
  // baseUrl is the effect file path so resolveRelativePath can walk from its folder; the
172
186
  // File resolver ignores HTTP join and looks up files by path/name instead.
@@ -263,22 +277,23 @@ export function assetIconUrl(asset: EffectAsset): string | null {
263
277
  if (cached !== undefined) {
264
278
  return cached;
265
279
  }
266
- const json = asset.json as any;
267
- const findMaterial = (node: any): string | undefined => {
268
- if (!node || typeof node !== 'object') return undefined;
269
- if (node.type === 'ParticleEmitter' && node.ps?.material) return node.ps.material;
280
+ const json = isRecord(asset.json) ? asset.json : {};
281
+ const findMaterial = (node: unknown): unknown => {
282
+ if (!isRecord(node)) return undefined;
283
+ if (node.type === 'ParticleEmitter' && isRecord(node.ps) && node.ps.material) return node.ps.material;
270
284
  for (const child of Array.isArray(node.children) ? node.children : []) {
271
285
  const found = findMaterial(child);
272
286
  if (found) return found;
273
287
  }
274
288
  return undefined;
275
289
  };
276
- const byUuid = (list: unknown, uuid: unknown) =>
277
- (Array.isArray(list) ? list : []).find((item: any) => item?.uuid === uuid) as any;
290
+ const byUuid = (list: unknown, uuid: unknown): JSONRecord | undefined =>
291
+ (Array.isArray(list) ? list : []).find((item: unknown) => isRecord(item) && item.uuid === uuid);
278
292
 
279
- const material = byUuid(json?.materials, findMaterial(json?.object));
280
- const texture = byUuid(json?.textures, material?.map ?? material?.texture);
281
- const image = byUuid(json?.images, texture?.image) ?? (Array.isArray(json?.images) ? json.images[0] : undefined);
293
+ const material = byUuid(json.materials, findMaterial(json.object));
294
+ const texture = byUuid(json.textures, material?.map ?? material?.texture);
295
+ const firstImage: unknown = Array.isArray(json.images) ? json.images[0] : undefined;
296
+ const image = byUuid(json.images, texture?.image) ?? (isRecord(firstImage) ? firstImage : undefined);
282
297
  const url = typeof image?.url === 'string' && image.url ? image.url : null;
283
298
  iconCache.set(asset, url);
284
299
  return url;
@@ -1,8 +1,9 @@
1
- import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
1
+ import type {TransformNode} from '@babylonjs/core/Meshes/transformNode.js';
2
2
  import type {ParticleSystem} from 'babylon.quarks';
3
- import type {EffectTreeNode} from './effectTree';
4
- import {buildEffectTree, serializeEffectTree} from './effectTree';
3
+ import type {EffectTreeNode} from './effectTree.js';
4
+ import {buildEffectTree, serializeEffectTree} from './effectTree.js';
5
5
 
6
+ /** Called after every change made through an {@link EffectBinding}. */
6
7
  export type EditorListener = () => void;
7
8
 
8
9
  /**
@@ -32,6 +33,7 @@ export class EffectBinding {
32
33
  return buildEffectTree(this.root);
33
34
  }
34
35
 
36
+ /** Calls `listener` after every change; returns the call that stops it. */
35
37
  subscribe(listener: EditorListener): () => void {
36
38
  this.listeners.add(listener);
37
39
  return () => this.listeners.delete(listener);
@@ -42,17 +44,23 @@ export class EffectBinding {
42
44
  return this.revision;
43
45
  }
44
46
 
47
+ /**
48
+ * Changes the main system through `mutate`: takes an undo snapshot first, then notifies
49
+ * subscribers. Every inspector edit goes through here.
50
+ */
45
51
  apply(mutate: (system: ParticleSystem) => void): void {
46
52
  this.onBeforeChange?.();
47
53
  mutate(this.system);
48
54
  this.notify();
49
55
  }
50
56
 
57
+ /** Adds a system to the effect's sub systems. */
51
58
  addSubSystem(sub: ParticleSystem): void {
52
59
  this.subSystems.push(sub);
53
60
  this.notify();
54
61
  }
55
62
 
63
+ /** Removes a system from the effect's sub systems; a system it does not have is ignored. */
56
64
  removeSubSystem(sub: ParticleSystem): void {
57
65
  const index = this.subSystems.indexOf(sub);
58
66
  if (index >= 0) {
@@ -92,6 +100,7 @@ export class EffectBinding {
92
100
  }
93
101
  }
94
102
 
103
+ /** Restarts every system of the effect from time 0. */
95
104
  restart(): void {
96
105
  // onlyUsedByOther systems skip self-emission in update(); play() only unpauses sim.
97
106
  for (const system of [this.system, ...this.subSystems]) {
@@ -8,8 +8,12 @@ import {Vector3, getPhysicsResolver, setPhysicsResolver} from 'babylon.quarks';
8
8
  * which is exactly what ApplyCollision.update reflects the velocity against.
9
9
  */
10
10
  export class GroundPlaneResolver {
11
+ /** @param y - Height of the ground plane. */
11
12
  constructor(public y = 0) {}
12
13
 
14
+ /**
15
+ * True when `position` is at or below the plane, with the plane's normal written to `normal`.
16
+ */
13
17
  resolve(position: Vector3, normal: Vector3): boolean {
14
18
  if (position.y <= this.y) {
15
19
  normal.set(0, 1, 0);
@@ -3,18 +3,25 @@ import {ColorOverLife, Gradient, Vector3, Vector4} from 'babylon.quarks';
3
3
 
4
4
  /** One RGBA stop of the editable gradient (all channels 0..1, pos 0..1). */
5
5
  export interface GradientStop {
6
+ /** Where the stop sits over the particle's life, 0..1. */
6
7
  pos: number;
8
+ /** Red, 0..1. */
7
9
  r: number;
10
+ /** Green, 0..1. */
8
11
  g: number;
12
+ /** Blue, 0..1. */
9
13
  b: number;
14
+ /** Alpha, 0..1. */
10
15
  a: number;
11
16
  }
12
17
 
18
+ /** The gradient a new Color over Lifetime starts with: warm yellow fading out through red. */
13
19
  export const DEFAULT_GRADIENT_STOPS: GradientStop[] = [
14
20
  {pos: 0, r: 1, g: 0.85, b: 0.4, a: 1},
15
21
  {pos: 1, r: 1, g: 0.25, b: 0.05, a: 0},
16
22
  ];
17
23
 
24
+ /** A quarks gradient through `stops`, sorted by position; colour and alpha share the stops. */
18
25
  export function buildGradient(stops: GradientStop[]): Gradient {
19
26
  const sorted = [...stops].sort((a, b) => a.pos - b.pos);
20
27
  return new Gradient(
@@ -23,26 +30,38 @@ export function buildGradient(stops: GradientStop[]): Gradient {
23
30
  );
24
31
  }
25
32
 
33
+ /** A Color over Lifetime behavior through `stops`. */
26
34
  export function buildColorOverLife(stops: GradientStop[]): ColorOverLife {
27
35
  return new ColorOverLife(buildGradient(stops));
28
36
  }
29
37
 
38
+ /** An RGBA colour as a quarks `Vector4`. */
30
39
  export function rgbaToVector4(stop: {r: number; g: number; b: number; a: number}): Vector4 {
31
40
  return new Vector4(stop.r, stop.g, stop.b, stop.a);
32
41
  }
33
42
 
43
+ /** A stop's colour as CSS `rgba()`. */
34
44
  export function stopToCss(stop: GradientStop): string {
35
45
  const c = (v: number) => Math.round(v * 255);
36
46
  return `rgba(${c(stop.r)}, ${c(stop.g)}, ${c(stop.b)}, ${stop.a.toFixed(2)})`;
37
47
  }
38
48
 
49
+ /** The stops as a left-to-right CSS `linear-gradient`, for a gradient preview. */
39
50
  export function stopsToCssGradient(stops: GradientStop[]): string {
40
51
  const sorted = [...stops].sort((a, b) => a.pos - b.pos);
41
52
  const parts = sorted.map((s) => `${stopToCss(s)} ${(s.pos * 100).toFixed(1)}%`);
42
53
  return `linear-gradient(90deg, ${parts.join(', ')})`;
43
54
  }
44
55
 
45
- export function hexToRgb(hex: string): {r: number; g: number; b: number} {
56
+ /** A `#rrggbb` colour as channels 0..1. */
57
+ export function hexToRgb(hex: string): {
58
+ /** Red, 0..1. */
59
+ r: number;
60
+ /** Green, 0..1. */
61
+ g: number;
62
+ /** Blue, 0..1. */
63
+ b: number;
64
+ } {
46
65
  const value = hex.replace('#', '');
47
66
  return {
48
67
  r: parseInt(value.slice(0, 2), 16) / 255,
@@ -51,6 +70,7 @@ export function hexToRgb(hex: string): {r: number; g: number; b: number} {
51
70
  };
52
71
  }
53
72
 
73
+ /** Channels 0..1, clamped, as a `#rrggbb` colour. */
54
74
  export function rgbToHex(r: number, g: number, b: number): string {
55
75
  const c = (v: number) =>
56
76
  Math.round(Math.min(1, Math.max(0, v)) * 255)
@@ -1,5 +1,6 @@
1
- import {TransformNode} from '@babylonjs/core/Meshes/transformNode';
2
- import type {Scene} from '@babylonjs/core/scene';
1
+ import type {Texture} from '@babylonjs/core/Materials/Textures/texture.js';
2
+ import {TransformNode} from '@babylonjs/core/Meshes/transformNode.js';
3
+ import type {Scene} from '@babylonjs/core/scene.js';
3
4
  import {
4
5
  ColorOverLife,
5
6
  ConeEmitter,
@@ -10,18 +11,18 @@ import {
10
11
  RenderMode,
11
12
  Vector4,
12
13
  } from 'babylon.quarks';
13
- import {DEFAULT_GRADIENT_STOPS, buildGradient} from './colors';
14
- import {uniqueEntryName, type SceneEntry} from './sceneEntries';
14
+ import {DEFAULT_GRADIENT_STOPS, buildGradient} from './colors.js';
15
+ import {uniqueEntryName, type SceneEntry} from './sceneEntries.js';
15
16
 
16
17
  export interface CreateSceneDefaultOptions {
17
- resolveTexture?: (url: string, scene: Scene) => unknown;
18
+ resolveTexture?: (url: string, scene: Scene) => Texture | null | undefined;
18
19
  textureUrl?: string;
19
20
  }
20
21
 
21
22
  /** Creates a simple cone burst preset for new editor effects. */
22
23
  export function createDefaultEffect(
23
24
  scene: Scene,
24
- resolveTexture?: (url: string, scene: Scene) => unknown,
25
+ resolveTexture?: (url: string, scene: Scene) => Texture | null | undefined,
25
26
  textureUrl?: string
26
27
  ): ParticleSystem {
27
28
  const system = new ParticleSystem({
@@ -35,7 +36,7 @@ export function createDefaultEffect(
35
36
  emissionOverTime: new ConstantValue(80),
36
37
  shape: new ConeEmitter({radius: 0.3, angle: 0.25}),
37
38
  renderMode: RenderMode.BillBoard,
38
- texture: (textureUrl && resolveTexture ? resolveTexture(textureUrl, scene) : undefined) as never,
39
+ texture: textureUrl && resolveTexture ? resolveTexture(textureUrl, scene) : undefined,
39
40
  transparent: true,
40
41
  blendMode: 1,
41
42
  });
@@ -1,4 +1,4 @@
1
- import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
1
+ import type {TransformNode} from '@babylonjs/core/Meshes/transformNode.js';
2
2
 
3
3
  /** Marks meshes/nodes created only for editor interaction or overlays (not part of the effect). */
4
4
  export const EDITOR_SCENE_NODE_METADATA = {quarksEditorSceneNode: true as const};