babylon.quarks-editor 0.18.0 → 0.19.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 (83) hide show
  1. package/README.md +6 -6
  2. package/dist/core/binding.d.ts +1 -1
  3. package/dist/core/colors.d.ts +1 -1
  4. package/dist/core/defaultEffect.d.ts +1 -1
  5. package/dist/core/effectTree.d.ts +1 -1
  6. package/dist/core/effectTree.js +18 -4
  7. package/dist/core/emitterShapeWireframe.d.ts +1 -1
  8. package/dist/core/emitterShapeWireframe.js +1 -1
  9. package/dist/core/galleryDropMarker.js +1 -1
  10. package/dist/core/galleryScene.d.ts +1 -1
  11. package/dist/core/galleryTree.js +4 -1
  12. package/dist/core/loadEffect.d.ts +2 -2
  13. package/dist/core/loadEffect.js +1 -1
  14. package/dist/core/loadEffectGallery.d.ts +2 -2
  15. package/dist/core/shapes.d.ts +1 -1
  16. package/dist/core/shapes.js +35 -8
  17. package/dist/core/systems.d.ts +1 -1
  18. package/dist/core/systems.js +3 -1
  19. package/dist/core/timeline.d.ts +1 -2
  20. package/dist/core/values.d.ts +1 -1
  21. package/dist/index.d.ts +11 -11
  22. package/dist/index.js +6 -6
  23. package/dist/react/CurveEditor.d.ts +1 -2
  24. package/dist/react/CurveEditor.js +14 -3
  25. package/dist/react/EffectEditor.d.ts +2 -2
  26. package/dist/react/EffectEditor.js +2 -2
  27. package/dist/react/EffectEditorHost.d.ts +1 -1
  28. package/dist/react/EffectEditorHost.js +123 -33
  29. package/dist/react/GalleryPanel.d.ts +1 -1
  30. package/dist/react/GalleryPanel.js +14 -7
  31. package/dist/react/GradientEditor.d.ts +1 -2
  32. package/dist/react/GradientEditor.js +8 -1
  33. package/dist/react/MessageDialog.js +7 -1
  34. package/dist/react/ModuleSection.js +10 -3
  35. package/dist/react/ObjectModule.d.ts +1 -2
  36. package/dist/react/ObjectModule.js +1 -1
  37. package/dist/react/SubEmittersModule.d.ts +1 -2
  38. package/dist/react/TimelinePanel.d.ts +3 -3
  39. package/dist/react/TimelinePanel.js +55 -9
  40. package/dist/react/TimelineTrackRow.d.ts +1 -1
  41. package/dist/react/TimelineTrackRow.js +20 -6
  42. package/dist/react/ValueField.d.ts +1 -2
  43. package/dist/react/behaviorModules.js +19 -5
  44. package/dist/react/index.d.ts +17 -17
  45. package/dist/react/index.js +11 -11
  46. package/dist/react/modules.js +55 -25
  47. package/package.json +68 -68
  48. package/src/core/binding.ts +2 -2
  49. package/src/core/colors.ts +1 -1
  50. package/src/core/defaultEffect.ts +1 -1
  51. package/src/core/effectTree.ts +22 -7
  52. package/src/core/emitterShapeWireframe.ts +8 -4
  53. package/src/core/galleryDropMarker.ts +6 -2
  54. package/src/core/galleryPlayback.ts +1 -1
  55. package/src/core/galleryScene.ts +3 -7
  56. package/src/core/gallerySelectionMarker.ts +5 -1
  57. package/src/core/galleryTree.ts +8 -5
  58. package/src/core/loadEffect.ts +3 -3
  59. package/src/core/loadEffectGallery.ts +7 -3
  60. package/src/core/pickGalleryFiles.ts +4 -1
  61. package/src/core/shapes.ts +48 -10
  62. package/src/core/systems.ts +9 -3
  63. package/src/core/timeline.ts +8 -8
  64. package/src/core/values.ts +1 -1
  65. package/src/core/viewportPicker.ts +1 -1
  66. package/src/index.ts +18 -18
  67. package/src/react/CurveEditor.tsx +40 -10
  68. package/src/react/EffectEditor.tsx +14 -13
  69. package/src/react/EffectEditorHost.tsx +239 -64
  70. package/src/react/GalleryPanel.tsx +56 -12
  71. package/src/react/GradientEditor.tsx +21 -4
  72. package/src/react/InspectorInfoIcon.tsx +6 -2
  73. package/src/react/MessageDialog.tsx +9 -1
  74. package/src/react/ModuleSection.tsx +12 -3
  75. package/src/react/ObjectModule.tsx +36 -15
  76. package/src/react/PromptDialog.tsx +5 -1
  77. package/src/react/SubEmittersModule.tsx +1 -2
  78. package/src/react/TimelinePanel.tsx +94 -21
  79. package/src/react/TimelineTrackRow.tsx +71 -18
  80. package/src/react/ValueField.tsx +0 -1
  81. package/src/react/behaviorModules.tsx +143 -29
  82. package/src/react/index.ts +33 -33
  83. package/src/react/modules.tsx +173 -57
package/README.md CHANGED
@@ -13,17 +13,17 @@ npm install babylon.quarks-editor babylon.quarks @babylonjs/core react @heroicon
13
13
  ## Usage
14
14
 
15
15
  ```tsx
16
- import {EffectBinding, EffectHistory} from "babylon.quarks-editor";
17
- import {EffectEditor} from "babylon.quarks-editor/react";
16
+ import {EffectBinding, EffectHistory} from 'babylon.quarks-editor';
17
+ import {EffectEditor} from 'babylon.quarks-editor/react';
18
18
 
19
- const binding = new EffectBinding(particleSystem); // your babylon.quarks ParticleSystem
19
+ const binding = new EffectBinding(particleSystem); // your babylon.quarks ParticleSystem
20
20
  const history = new EffectHistory();
21
21
  history.attach(binding);
22
22
 
23
23
  <EffectEditor binding={binding} />;
24
24
 
25
25
  // Serialize to Quarks JSON (round-trips through QuarksLoader):
26
- const json = binding.exportJSON("MyEffect");
26
+ const json = binding.exportJSON('MyEffect');
27
27
  ```
28
28
 
29
29
  Modules: Main, Emission (bursts), Shape (7 emitter types), Speed/Limit Speed/Force/Rotation over Lifetime, Gravity, Color over Lifetime (gradient), Size over Lifetime (curve), Noise, Sub Emitters, Texture Sheet Animation, Renderer. Multi-system hierarchy with add/remove/rename, undo/redo via `EffectHistory`.
@@ -39,9 +39,9 @@ an opinion on your CDN, asset pipeline, or loader (`@babylonjs/loaders`, your ow
39
39
  "Load from file…" in the Renderer module) into whatever object you assign as `system.texture`.
40
40
  - `resolveGeometry(file) => Promise<GeometryData>` — turns a picked file (from "Load from file…"
41
41
  in the Mesh render mode's geometry dropdown) into vertex buffers: `{positions, indices?, uvs?,
42
- normals?}` (typed arrays or plain number arrays).
42
+ normals?}` (typed arrays or plain number arrays).
43
43
  - `textureOptions?: {label, url}[]` / `geometryOptions?: {label, positions, indices?, uvs?,
44
- normals?}[]` — preset lists shown alongside "Custom URL…" / "Load from file…".
44
+ normals?}[]` — preset lists shown alongside "Custom URL…" / "Load from file…".
45
45
 
46
46
  **Signature differs by entry point** — a common source of "works in the demo, throws in my
47
47
  host" bugs:
@@ -1,5 +1,5 @@
1
- import type { ParticleSystem } from 'babylon.quarks';
2
1
  import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { ParticleSystem } from 'babylon.quarks';
3
3
  import type { EffectTreeNode } from './effectTree';
4
4
  export type EditorListener = () => void;
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { ColorOverLife, Gradient, Vector4 } from 'babylon.quarks';
2
1
  import type { Behavior } from 'babylon.quarks';
2
+ import { ColorOverLife, Gradient, Vector4 } from 'babylon.quarks';
3
3
  /** One RGBA stop of the editable gradient (all channels 0..1, pos 0..1). */
4
4
  export interface GradientStop {
5
5
  pos: number;
@@ -1,5 +1,5 @@
1
- import type { Scene } from '@babylonjs/core/scene';
2
1
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { Scene } from '@babylonjs/core/scene';
3
3
  import { ParticleSystem } from 'babylon.quarks';
4
4
  import type { GalleryEntry } from './loadEffectGallery';
5
5
  export interface CreateGalleryDefaultOptions {
@@ -1,5 +1,5 @@
1
- import type { ParticleSystem } from 'babylon.quarks';
2
1
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { ParticleSystem } from 'babylon.quarks';
3
3
  /** A node in the editor's effect hierarchy: a Group (organizational) or a ParticleEmitter. */
4
4
  export interface EffectTreeNode {
5
5
  node: TransformNode;
@@ -1,6 +1,6 @@
1
- import { ParticleEmitter } from 'babylon.quarks';
2
- import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
3
1
  import { Matrix, Quaternion } from '@babylonjs/core/Maths/math.vector';
2
+ import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
3
+ import { ParticleEmitter } from 'babylon.quarks';
4
4
  import { isEditorSceneNode } from './editorScene';
5
5
  /** Walks a loaded root TransformNode into the editor tree (groups + emitters). */
6
6
  export function buildEffectTree(root, depth = 0) {
@@ -51,7 +51,11 @@ function serializeNode(tree, meta, fallbackUuid) {
51
51
  children: children.length > 0 ? children : undefined,
52
52
  };
53
53
  if (tree.system) {
54
- return { ...base, type: 'ParticleEmitter', ps: tree.system.toJSON(meta, { useUrlForImage: true }) };
54
+ return {
55
+ ...base,
56
+ type: 'ParticleEmitter',
57
+ ps: tree.system.toJSON(meta, { useUrlForImage: true }),
58
+ };
55
59
  }
56
60
  return { ...base, type: 'Group' };
57
61
  }
@@ -92,10 +96,20 @@ function finishEnvelope(object, meta) {
92
96
  const textures = [];
93
97
  for (const [uuid, tex] of Object.entries(meta.textures)) {
94
98
  const url = tex?.url ?? tex?.name;
99
+ const invertY = typeof tex?.invertY === 'boolean' ? tex.invertY : undefined;
100
+ const isEnvAtlas = tex?.name === 'quarksEnvAtlas' || (typeof tex?.name === 'string' && tex.name.endsWith('_envAtlas'));
95
101
  if (url) {
96
102
  const imageUuid = `${uuid}-image`;
97
103
  images.push({ uuid: imageUuid, url });
98
- textures.push({ uuid, image: imageUuid });
104
+ const entry = {
105
+ uuid,
106
+ image: imageUuid,
107
+ };
108
+ if (invertY === false || isEnvAtlas) {
109
+ entry.invertY = false;
110
+ entry.noMipmap = true;
111
+ }
112
+ textures.push(entry);
99
113
  }
100
114
  else {
101
115
  textures.push({ uuid });
@@ -1,5 +1,5 @@
1
- import type { ParticleSystem } from 'babylon.quarks';
2
1
  import type { Scene } from '@babylonjs/core/scene';
2
+ import type { ParticleSystem } from 'babylon.quarks';
3
3
  /**
4
4
  * Optional wireframe overlays for every emitter shape in the current effect.
5
5
  * Geometry follows quarks.core spawn math (local XY spawn plane, +Z emit axis).
@@ -2,8 +2,8 @@ import { Color3 } from '@babylonjs/core/Maths/math.color';
2
2
  import { Vector3 } from '@babylonjs/core/Maths/math.vector';
3
3
  import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
4
4
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
5
- import { getShapeType, readShapeParams } from './shapes';
6
5
  import { EDITOR_SCENE_NODE_METADATA } from './editorScene';
6
+ import { getShapeType, readShapeParams } from './shapes';
7
7
  const LINE_COLOR = new Color3(0.45, 0.82, 1);
8
8
  const DIRECTION_COLOR = new Color3(0.75, 0.92, 1);
9
9
  /**
@@ -1,5 +1,5 @@
1
- import { Color3 } from '@babylonjs/core/Maths/math.color';
2
1
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
2
+ import { Color3 } from '@babylonjs/core/Maths/math.color';
3
3
  import { Mesh } from '@babylonjs/core/Meshes/mesh';
4
4
  import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
5
5
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
@@ -1,6 +1,6 @@
1
1
  import { Vector3 } from '@babylonjs/core/Maths/math.vector';
2
- import type { Scene } from '@babylonjs/core/scene';
3
2
  import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
3
+ import type { Scene } from '@babylonjs/core/scene';
4
4
  import type { BatchedRenderer } from 'babylon.quarks';
5
5
  import type { GalleryEntry } from './loadEffectGallery';
6
6
  /** Clears live particles and freezes simulation for one placed catalog entry. */
@@ -9,7 +9,10 @@ export function buildGalleryTree(entries) {
9
9
  const roots = [];
10
10
  for (const entry of entries) {
11
11
  const normalized = entry.path.replace(/\\/g, '/');
12
- const segments = normalized.replace(/\.json$/i, '').split('/').filter(Boolean);
12
+ const segments = normalized
13
+ .replace(/\.json$/i, '')
14
+ .split('/')
15
+ .filter(Boolean);
13
16
  const fileName = segments.pop() ?? entry.name;
14
17
  let level = roots;
15
18
  let pathSoFar = '';
@@ -1,6 +1,6 @@
1
- import type { BatchedRenderer, ParticleSystem } from 'babylon.quarks';
2
- import type { Scene } from '@babylonjs/core/scene';
3
1
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { Scene } from '@babylonjs/core/scene';
3
+ import type { BatchedRenderer, ParticleSystem } from 'babylon.quarks';
4
4
  export interface LoadEffectOptions {
5
5
  /** Registers systems with the batched renderer (default true). */
6
6
  registerRenderer?: boolean;
@@ -1,5 +1,5 @@
1
- import { ParticleEmitter, QuarksLoader, QuarksUtil } from 'babylon.quarks';
2
1
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import { ParticleEmitter, QuarksLoader, QuarksUtil } from 'babylon.quarks';
3
3
  /** `ParticleEmitter`'s constructor default (see babylon.quarks/src/ParticleEmitter.ts) — the
4
4
  * name every emitter gets when the source JSON didn't give it one of its own. */
5
5
  const DEFAULT_EMITTER_NAME = 'particleEmitter';
@@ -1,6 +1,6 @@
1
- import type { ParticleSystem } from 'babylon.quarks';
2
- import type { Scene } from '@babylonjs/core/scene';
3
1
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { Scene } from '@babylonjs/core/scene';
3
+ import type { ParticleSystem } from 'babylon.quarks';
4
4
  import { EffectBinding } from './binding';
5
5
  export interface GalleryEntry {
6
6
  name: string;
@@ -1,6 +1,6 @@
1
+ import type { Mesh } from '@babylonjs/core/Meshes/mesh';
1
2
  import type { EmitterShape } from 'babylon.quarks';
2
3
  import { EmitterMode } from 'babylon.quarks';
3
- import type { Mesh } from '@babylonjs/core/Meshes/mesh';
4
4
  export type ShapeType = 'point' | 'sphere' | 'hemisphere' | 'cone' | 'circle' | 'donut' | 'rectangle' | 'grid' | 'mesh_surface';
5
5
  export declare const SHAPE_TYPES: Array<{
6
6
  value: ShapeType;
@@ -1,5 +1,4 @@
1
- import { CircleEmitter, ConeEmitter, DonutEmitter, GridEmitter, HemisphereEmitter, MeshSurfaceEmitter, PointEmitter, RectangleEmitter, SphereEmitter, } from 'babylon.quarks';
2
- import { EmitterMode } from 'babylon.quarks';
1
+ import { CircleEmitter, ConeEmitter, DonutEmitter, EmitterMode, GridEmitter, HemisphereEmitter, MeshSurfaceEmitter, PointEmitter, RectangleEmitter, SphereEmitter, } from 'babylon.quarks';
3
2
  export const SHAPE_TYPES = [
4
3
  { value: 'cone', label: 'Cone' },
5
4
  { value: 'sphere', label: 'Sphere' },
@@ -31,7 +30,7 @@ export function getShapeType(shape) {
31
30
  }
32
31
  export function readShapeParams(shape) {
33
32
  const anyShape = shape;
34
- const num = (key, fallback) => (typeof anyShape[key] === 'number' ? anyShape[key] : fallback);
33
+ const num = (key, fallback) => typeof anyShape[key] === 'number' ? anyShape[key] : fallback;
35
34
  return {
36
35
  radius: num('radius', DEFAULT_SHAPE_PARAMS.radius),
37
36
  mode: num('mode', DEFAULT_SHAPE_PARAMS.mode),
@@ -65,9 +64,21 @@ export function createShape(type, params) {
65
64
  case 'point':
66
65
  return new PointEmitter();
67
66
  case 'sphere':
68
- return new SphereEmitter({ radius: params.radius, arc: params.arc, thickness: params.thickness, mode: params.mode, spread: params.spread });
67
+ return new SphereEmitter({
68
+ radius: params.radius,
69
+ arc: params.arc,
70
+ thickness: params.thickness,
71
+ mode: params.mode,
72
+ spread: params.spread,
73
+ });
69
74
  case 'hemisphere':
70
- return new HemisphereEmitter({ radius: params.radius, arc: params.arc, thickness: params.thickness, mode: params.mode, spread: params.spread });
75
+ return new HemisphereEmitter({
76
+ radius: params.radius,
77
+ arc: params.arc,
78
+ thickness: params.thickness,
79
+ mode: params.mode,
80
+ spread: params.spread,
81
+ });
71
82
  case 'cone':
72
83
  return new ConeEmitter({
73
84
  radius: params.radius,
@@ -78,7 +89,13 @@ export function createShape(type, params) {
78
89
  spread: params.spread,
79
90
  });
80
91
  case 'circle':
81
- return new CircleEmitter({ radius: params.radius, arc: params.arc, thickness: params.thickness, mode: params.mode, spread: params.spread });
92
+ return new CircleEmitter({
93
+ radius: params.radius,
94
+ arc: params.arc,
95
+ thickness: params.thickness,
96
+ mode: params.mode,
97
+ spread: params.spread,
98
+ });
82
99
  case 'donut':
83
100
  return new DonutEmitter({
84
101
  radius: params.radius,
@@ -89,9 +106,19 @@ export function createShape(type, params) {
89
106
  spread: params.spread,
90
107
  });
91
108
  case 'rectangle':
92
- return new RectangleEmitter({ width: params.width, height: params.height, mode: params.mode, spread: params.spread });
109
+ return new RectangleEmitter({
110
+ width: params.width,
111
+ height: params.height,
112
+ mode: params.mode,
113
+ spread: params.spread,
114
+ });
93
115
  case 'grid':
94
- return new GridEmitter({ width: params.width, height: params.height, column: params.column, row: params.row });
116
+ return new GridEmitter({
117
+ width: params.width,
118
+ height: params.height,
119
+ column: params.column,
120
+ row: params.row,
121
+ });
95
122
  case 'mesh_surface':
96
123
  return new MeshSurfaceEmitter(params.mesh);
97
124
  }
@@ -1,5 +1,5 @@
1
- import { ParticleSystem } from 'babylon.quarks';
2
1
  import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import { ParticleSystem } from 'babylon.quarks';
3
3
  import type { EffectBinding } from './binding';
4
4
  export interface ChildSystemOptions {
5
5
  name?: string;
@@ -15,7 +15,9 @@ export function createChildSystem(parent, options = {}) {
15
15
  startSize: new IntervalValue(0.05, 0.2),
16
16
  startColor: new ConstantColor(new Vector4(1, 0.9, 0.6, 1)),
17
17
  emissionOverTime: new ConstantValue(oneShot ? 0 : 30),
18
- emissionBursts: oneShot ? [{ time: 0, count: new ConstantValue(8), cycle: 1, interval: 0.01, probability: 1 }] : [],
18
+ emissionBursts: oneShot
19
+ ? [{ time: 0, count: new ConstantValue(8), cycle: 1, interval: 0.01, probability: 1 }]
20
+ : [],
19
21
  shape: new ConeEmitter({ radius: 0.1, angle: Math.PI / 3 }),
20
22
  renderMode: RenderMode.BillBoard,
21
23
  texture: parent.texture ?? undefined,
@@ -1,6 +1,5 @@
1
- import type { ParticleSystem } from 'babylon.quarks';
2
- import type { FunctionValueGenerator, ValueGenerator } from 'babylon.quarks';
3
1
  import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { FunctionValueGenerator, ParticleSystem, ValueGenerator } from 'babylon.quarks';
4
3
  import type { EffectBinding } from './binding';
5
4
  export type TimelineRow = {
6
5
  kind: 'group';
@@ -1,5 +1,5 @@
1
- import { PiecewiseBezier } from 'babylon.quarks';
2
1
  import type { FunctionValueGenerator, ValueGenerator } from 'babylon.quarks';
2
+ import { PiecewiseBezier } from 'babylon.quarks';
3
3
  export type ScalarGenerator = ValueGenerator | FunctionValueGenerator;
4
4
  export type ScalarMode = 'constant' | 'random' | 'curve';
5
5
  /** Editable snapshot of a scalar value generator. */
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  export { EffectBinding } from './core/binding';
2
2
  export type { EditorListener } from './core/binding';
3
- export { EffectHistory } from './core/history';
4
- export { createChildSystem } from './core/systems';
5
- export { buildEffectTree, collectSystems, serializeEffectTree, serializeEffectForest } from './core/effectTree';
6
- export type { EffectTreeNode } from './core/effectTree';
7
- export type { ChildSystemOptions } from './core/systems';
8
- export { readScalar, buildScalar, sampleCurve, readPieces, buildCurve, splitPieces, mergePieces } from './core/values';
9
- export type { ScalarGenerator, ScalarMode, ScalarValueState, CurvePiece } from './core/values';
10
- export { DEFAULT_GRADIENT_STOPS, buildGradient, buildColorOverLife, rgbaToVector4, stopToCss, stopsToCssGradient, hexToRgb, rgbToHex, findBehavior, } from './core/colors';
11
- export type { GradientStop } from './core/colors';
12
- export { SHAPE_TYPES, SHAPE_PARAM_KEYS, DEFAULT_SHAPE_PARAMS, getShapeType, readShapeParams, createShape, } from './core/shapes';
13
- export type { ShapeType, ShapeParams } from './core/shapes';
14
3
  export { GroundPlaneResolver, ensureGroundResolver } from './core/collision';
4
+ export { DEFAULT_GRADIENT_STOPS, buildColorOverLife, buildGradient, findBehavior, hexToRgb, rgbToHex, rgbaToVector4, stopToCss, stopsToCssGradient, } from './core/colors';
5
+ export type { GradientStop } from './core/colors';
6
+ export { buildEffectTree, collectSystems, serializeEffectForest, serializeEffectTree } from './core/effectTree';
7
+ export type { EffectTreeNode } from './core/effectTree';
8
+ export { EffectHistory } from './core/history';
15
9
  export { applyRendererMaterial, getMaterialLabel } from './core/material';
16
10
  export type { RendererMaterialPatch } from './core/material';
11
+ export { DEFAULT_SHAPE_PARAMS, SHAPE_PARAM_KEYS, SHAPE_TYPES, createShape, getShapeType, readShapeParams, } from './core/shapes';
12
+ export type { ShapeParams, ShapeType } from './core/shapes';
13
+ export { createChildSystem } from './core/systems';
14
+ export type { ChildSystemOptions } from './core/systems';
17
15
  export { ensurePortableTextureUrl } from './core/textureExport';
16
+ export { buildCurve, buildScalar, mergePieces, readPieces, readScalar, sampleCurve, splitPieces } from './core/values';
17
+ export type { CurvePiece, ScalarGenerator, ScalarMode, ScalarValueState } from './core/values';
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  export { EffectBinding } from './core/binding';
2
- export { EffectHistory } from './core/history';
3
- export { createChildSystem } from './core/systems';
4
- export { buildEffectTree, collectSystems, serializeEffectTree, serializeEffectForest } from './core/effectTree';
5
- export { readScalar, buildScalar, sampleCurve, readPieces, buildCurve, splitPieces, mergePieces } from './core/values';
6
- export { DEFAULT_GRADIENT_STOPS, buildGradient, buildColorOverLife, rgbaToVector4, stopToCss, stopsToCssGradient, hexToRgb, rgbToHex, findBehavior, } from './core/colors';
7
- export { SHAPE_TYPES, SHAPE_PARAM_KEYS, DEFAULT_SHAPE_PARAMS, getShapeType, readShapeParams, createShape, } from './core/shapes';
8
2
  export { GroundPlaneResolver, ensureGroundResolver } from './core/collision';
3
+ export { DEFAULT_GRADIENT_STOPS, buildColorOverLife, buildGradient, findBehavior, hexToRgb, rgbToHex, rgbaToVector4, stopToCss, stopsToCssGradient, } from './core/colors';
4
+ export { buildEffectTree, collectSystems, serializeEffectForest, serializeEffectTree } from './core/effectTree';
5
+ export { EffectHistory } from './core/history';
9
6
  export { applyRendererMaterial, getMaterialLabel } from './core/material';
7
+ export { DEFAULT_SHAPE_PARAMS, SHAPE_PARAM_KEYS, SHAPE_TYPES, createShape, getShapeType, readShapeParams, } from './core/shapes';
8
+ export { createChildSystem } from './core/systems';
10
9
  export { ensurePortableTextureUrl } from './core/textureExport';
10
+ export { buildCurve, buildScalar, mergePieces, readPieces, readScalar, sampleCurve, splitPieces } from './core/values';
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { CurvePiece } from '../core/values';
3
2
  /**
4
3
  * Multi-segment piecewise-bezier curve editor. Drag keys/handles vertically,
@@ -9,4 +8,4 @@ export declare function CurveEditor(props: {
9
8
  pieces: CurvePiece[];
10
9
  onChange: (pieces: CurvePiece[]) => void;
11
10
  maxValue?: number;
12
- }): React.JSX.Element;
11
+ }): import("react").JSX.Element;
@@ -70,8 +70,16 @@ export function CurveEditor(props) {
70
70
  }
71
71
  props.onChange(next);
72
72
  };
73
- const selectedPoint = selected ? points.find((pt) => pt.ref.piece === selected.piece && pt.ref.idx === selected.idx) : null;
74
- return (_jsxs("div", { children: [_jsxs("svg", { ref: svgRef, width: WIDTH, height: HEIGHT, style: { background: 'rgba(5, 8, 18, 0.85)', border: `1px solid ${theme.border}`, borderRadius: 8, touchAction: 'none', display: 'block' }, onPointerMove: (e) => applyDrag(e.clientX, e.clientY), onPointerUp: (e) => {
73
+ const selectedPoint = selected
74
+ ? points.find((pt) => pt.ref.piece === selected.piece && pt.ref.idx === selected.idx)
75
+ : null;
76
+ return (_jsxs("div", { children: [_jsxs("svg", { ref: svgRef, width: WIDTH, height: HEIGHT, style: {
77
+ background: 'rgba(5, 8, 18, 0.85)',
78
+ border: `1px solid ${theme.border}`,
79
+ borderRadius: 8,
80
+ touchAction: 'none',
81
+ display: 'block',
82
+ }, onPointerMove: (e) => applyDrag(e.clientX, e.clientY), onPointerUp: (e) => {
75
83
  drag.current = null;
76
84
  e.target.releasePointerCapture?.(e.pointerId);
77
85
  }, onDoubleClick: (e) => {
@@ -95,7 +103,10 @@ export function CurveEditor(props) {
95
103
  if (Number.isNaN(parsed)) {
96
104
  return;
97
105
  }
98
- const next = pieces.map((piece) => ({ start: piece.start, p: [...piece.p] }));
106
+ const next = pieces.map((piece) => ({
107
+ start: piece.start,
108
+ p: [...piece.p],
109
+ }));
99
110
  const { piece, idx } = selectedPoint.ref;
100
111
  if (idx === 0 && piece > 0) {
101
112
  next[piece - 1].p[3] = parsed;
@@ -1,8 +1,8 @@
1
- import React from 'react';
2
1
  import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
2
+ import type { ParticleSystem } from 'babylon.quarks';
3
+ import React from 'react';
3
4
  import { EffectBinding } from '../core/binding';
4
5
  import type { GeometryData, GeometryOption, TextureOption } from './modules';
5
- import type { ParticleSystem } from 'babylon.quarks';
6
6
  export interface EffectEditorProps {
7
7
  binding: EffectBinding;
8
8
  /** Currently selected system, lifted up so the timeline panel and this module stack agree. */
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useSyncExternalStore } from 'react';
3
3
  import { EffectBinding } from '../core/binding';
4
- import { ObjectModule } from './ObjectModule';
5
- import { ColorOverLifeModule, EmissionModule, MainModule, RendererModule, ShapeModule, SizeOverLifeModule, } from './modules';
6
4
  import { CollisionModule, ColorBySpeedModule, EmitDirectionModule, ForceOverLifeModule, GravityModule, InheritVelocityModule, LimitSpeedOverLifeModule, NoiseModule, OrbitOverLifeModule, RotationBySpeedModule, RotationOverLifeModule, SizeBySpeedModule, SpeedOverLifeModule, TextureSheetModule, TurbulenceModule, VelocityOverLifeModule, WidthOverTrailModule, } from './behaviorModules';
5
+ import { ColorOverLifeModule, EmissionModule, MainModule, RendererModule, ShapeModule, SizeOverLifeModule, } from './modules';
6
+ import { ObjectModule } from './ObjectModule';
7
7
  import { SubEmittersModule } from './SubEmittersModule';
8
8
  import { theme } from './theme';
9
9
  /**
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
1
  import { Scene } from '@babylonjs/core/scene';
3
2
  import { BatchedRenderer } from 'babylon.quarks';
3
+ import React from 'react';
4
4
  import { EffectBinding } from '../core/binding';
5
5
  import { EffectHistory } from '../core/history';
6
6
  import type { GeometryData, GeometryOption, TextureOption } from './modules';