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.
- package/CHANGELOG.md +134 -0
- package/README.md +69 -9
- package/dist/core/assetDragSession.d.ts +1 -1
- package/dist/core/assetTree.d.ts +6 -1
- package/dist/core/assets.d.ts +7 -0
- package/dist/core/assets.js +11 -7
- package/dist/core/binding.d.ts +11 -2
- package/dist/core/binding.js +9 -1
- package/dist/core/collision.d.ts +4 -0
- package/dist/core/collision.js +4 -0
- package/dist/core/colors.d.ts +16 -0
- package/dist/core/colors.js +8 -0
- package/dist/core/defaultEffect.d.ts +5 -4
- package/dist/core/defaultEffect.js +4 -4
- package/dist/core/editorScene.d.ts +1 -1
- package/dist/core/editorSession.d.ts +229 -0
- package/dist/core/editorSession.js +983 -0
- package/dist/core/effectTree.d.ts +6 -1
- package/dist/core/effectTree.js +13 -88
- package/dist/core/emitterShapeWireframe.d.ts +2 -2
- package/dist/core/emitterShapeWireframe.js +45 -13
- package/dist/core/galleryDropMarker.d.ts +2 -2
- package/dist/core/galleryDropMarker.js +6 -6
- package/dist/core/galleryLayout.d.ts +3 -3
- package/dist/core/galleryLayout.js +1 -1
- package/dist/core/galleryPlayback.d.ts +1 -1
- package/dist/core/galleryPlayback.js +2 -1
- package/dist/core/galleryScene.d.ts +4 -4
- package/dist/core/galleryScene.js +3 -3
- package/dist/core/gallerySelectionMarker.d.ts +4 -4
- package/dist/core/gallerySelectionMarker.js +5 -5
- package/dist/core/groups.d.ts +1 -1
- package/dist/core/groups.js +1 -1
- package/dist/core/history.d.ts +7 -1
- package/dist/core/history.js +4 -0
- package/dist/core/indexedDbProjectStore.d.ts +14 -1
- package/dist/core/indexedDbProjectStore.js +13 -0
- package/dist/core/lineShaders.d.ts +2 -2
- package/dist/core/lineShaders.js +2 -2
- package/dist/core/loadEffect.d.ts +2 -2
- package/dist/core/loadEffect.js +1 -1
- package/dist/core/material.d.ts +12 -2
- package/dist/core/pickAssetFiles.js +1 -1
- package/dist/core/playback.d.ts +6 -0
- package/dist/core/projectStore.d.ts +26 -0
- package/dist/core/projectStore.js +1 -0
- package/dist/core/sceneEntries.d.ts +7 -4
- package/dist/core/sceneEntries.js +2 -2
- package/dist/core/scrub.d.ts +2 -2
- package/dist/core/scrub.js +2 -2
- package/dist/core/shapes.d.ts +25 -1
- package/dist/core/shapes.js +5 -0
- package/dist/core/systems.d.ts +4 -2
- package/dist/core/systems.js +3 -1
- package/dist/core/textureExport.d.ts +1 -1
- package/dist/core/timeline.d.ts +25 -5
- package/dist/core/transport.d.ts +3 -3
- package/dist/core/transport.js +2 -2
- package/dist/core/values.d.ts +21 -4
- package/dist/core/values.js +5 -0
- package/dist/core/viewportPicker.d.ts +4 -4
- package/dist/core/viewportPicker.js +8 -7
- package/dist/index.d.ts +25 -21
- package/dist/index.js +12 -12
- package/dist/react/AssetsPanel.d.ts +9 -2
- package/dist/react/AssetsPanel.js +6 -6
- package/dist/react/ChoiceDialog.d.ts +7 -0
- package/dist/react/ChoiceDialog.js +1 -1
- package/dist/react/ContextMenu.d.ts +10 -1
- package/dist/react/ContextMenu.js +1 -1
- package/dist/react/CurveEditor.d.ts +1 -1
- package/dist/react/CurveEditor.js +2 -2
- package/dist/react/EditorWorkspace.d.ts +9 -2
- package/dist/react/EditorWorkspace.js +10 -7
- package/dist/react/EffectEditor.d.ts +11 -5
- package/dist/react/EffectEditor.js +7 -7
- package/dist/react/EffectEditorHost.d.ts +33 -29
- package/dist/react/EffectEditorHost.js +247 -1674
- package/dist/react/EffectTreeView.d.ts +4 -1
- package/dist/react/EffectTreeView.js +3 -3
- package/dist/react/GradientEditor.d.ts +1 -1
- package/dist/react/GradientEditor.js +3 -3
- package/dist/react/InspectorInfoIcon.js +3 -3
- package/dist/react/InspectorLabel.js +3 -3
- package/dist/react/MessageDialog.d.ts +5 -0
- package/dist/react/MessageDialog.js +1 -1
- package/dist/react/ModuleSection.d.ts +10 -0
- package/dist/react/ModuleSection.js +8 -5
- package/dist/react/ObjectModule.d.ts +1 -1
- package/dist/react/ObjectModule.js +4 -4
- package/dist/react/ProjectsPage.d.ts +7 -1
- package/dist/react/ProjectsPage.js +33 -17
- package/dist/react/PromptDialog.d.ts +7 -0
- package/dist/react/PromptDialog.js +1 -1
- package/dist/react/ScenePanel.d.ts +9 -2
- package/dist/react/ScenePanel.js +12 -10
- package/dist/react/SubEmittersModule.d.ts +1 -1
- package/dist/react/SubEmittersModule.js +5 -5
- package/dist/react/TextureSelect.d.ts +24 -0
- package/dist/react/TextureSelect.js +74 -0
- package/dist/react/TextureUVField.d.ts +14 -0
- package/dist/react/TextureUVField.js +23 -0
- package/dist/react/TimelinePanel.d.ts +20 -7
- package/dist/react/TimelinePanel.js +21 -15
- package/dist/react/TimelineTrackRow.d.ts +13 -3
- package/dist/react/TimelineTrackRow.js +6 -6
- package/dist/react/TransportBar.d.ts +13 -4
- package/dist/react/TransportBar.js +3 -3
- package/dist/react/ValueField.d.ts +32 -5
- package/dist/react/ValueField.js +22 -11
- package/dist/react/behaviorModules.d.ts +19 -6
- package/dist/react/behaviorModules.js +68 -17
- package/dist/react/fields.d.ts +9 -0
- package/dist/react/fields.js +6 -3
- package/dist/react/host/BottomDocks.d.ts +36 -0
- package/dist/react/host/BottomDocks.js +63 -0
- package/dist/react/host/HostDialogs.d.ts +50 -0
- package/dist/react/host/HostDialogs.js +113 -0
- package/dist/react/host/InspectorSidebar.d.ts +32 -0
- package/dist/react/host/InspectorSidebar.js +59 -0
- package/dist/react/host/SceneSidebar.d.ts +53 -0
- package/dist/react/host/SceneSidebar.js +62 -0
- package/dist/react/host/ViewportPane.d.ts +56 -0
- package/dist/react/host/ViewportPane.js +91 -0
- package/dist/react/host/hostHooks.d.ts +44 -0
- package/dist/react/host/hostHooks.js +164 -0
- package/dist/react/host/hostStyles.d.ts +21 -0
- package/dist/react/host/hostStyles.js +57 -0
- package/dist/react/index.d.ts +42 -38
- package/dist/react/index.js +25 -23
- package/dist/react/inspectorHints.js +31 -0
- package/dist/react/modules.d.ts +19 -6
- package/dist/react/modules.js +134 -117
- package/dist/react/theme.d.ts +15 -0
- package/dist/react/theme.js +15 -0
- package/dist/session.d.ts +9 -0
- package/dist/session.js +8 -0
- package/package.json +18 -11
- package/src/core/assetDragSession.ts +1 -1
- package/src/core/assetTree.ts +15 -2
- package/src/core/assets.ts +25 -10
- package/src/core/binding.ts +12 -3
- package/src/core/collision.ts +4 -0
- package/src/core/colors.ts +21 -1
- package/src/core/defaultEffect.ts +8 -7
- package/src/core/editorScene.ts +1 -1
- package/src/core/editorSession.ts +1299 -0
- package/src/core/effectTree.ts +18 -101
- package/src/core/emitterShapeWireframe.ts +48 -16
- package/src/core/galleryDropMarker.ts +8 -8
- package/src/core/galleryLayout.ts +4 -4
- package/src/core/galleryPlayback.ts +3 -2
- package/src/core/galleryScene.ts +5 -5
- package/src/core/gallerySelectionMarker.ts +7 -7
- package/src/core/groups.ts +1 -1
- package/src/core/history.ts +7 -1
- package/src/core/indexedDbProjectStore.ts +14 -1
- package/src/core/lineShaders.ts +2 -2
- package/src/core/loadEffect.ts +4 -4
- package/src/core/material.ts +14 -4
- package/src/core/pickAssetFiles.ts +2 -2
- package/src/core/playback.ts +6 -0
- package/src/core/projectStore.ts +26 -0
- package/src/core/sceneEntries.ts +8 -5
- package/src/core/scrub.ts +3 -3
- package/src/core/shapes.ts +29 -2
- package/src/core/systems.ts +11 -4
- package/src/core/textureExport.ts +1 -1
- package/src/core/timeline.ts +43 -18
- package/src/core/transport.ts +4 -4
- package/src/core/values.ts +20 -4
- package/src/core/viewportPicker.ts +12 -11
- package/src/index.ts +25 -21
- package/src/react/AssetsPanel.tsx +13 -6
- package/src/react/ChoiceDialog.tsx +8 -1
- package/src/react/ContextMenu.tsx +11 -2
- package/src/react/CurveEditor.tsx +2 -2
- package/src/react/EditorWorkspace.tsx +16 -10
- package/src/react/EffectEditor.tsx +17 -9
- package/src/react/EffectEditorHost.tsx +415 -2354
- package/src/react/EffectTreeView.tsx +7 -4
- package/src/react/GradientEditor.tsx +3 -3
- package/src/react/InspectorInfoIcon.tsx +3 -3
- package/src/react/InspectorLabel.tsx +3 -3
- package/src/react/MessageDialog.tsx +6 -1
- package/src/react/ModuleSection.tsx +15 -4
- package/src/react/ObjectModule.tsx +5 -5
- package/src/react/ProjectsPage.tsx +44 -17
- package/src/react/PromptDialog.tsx +8 -1
- package/src/react/ScenePanel.tsx +21 -12
- package/src/react/SubEmittersModule.tsx +6 -6
- package/src/react/TextureSelect.tsx +118 -0
- package/src/react/TextureUVField.tsx +62 -0
- package/src/react/TimelinePanel.tsx +40 -21
- package/src/react/TimelineTrackRow.tsx +19 -9
- package/src/react/TransportBar.tsx +16 -7
- package/src/react/ValueField.tsx +60 -16
- package/src/react/behaviorModules.tsx +240 -55
- package/src/react/fields.tsx +22 -4
- package/src/react/host/BottomDocks.tsx +178 -0
- package/src/react/host/HostDialogs.tsx +228 -0
- package/src/react/host/InspectorSidebar.tsx +147 -0
- package/src/react/host/SceneSidebar.tsx +227 -0
- package/src/react/host/ViewportPane.tsx +300 -0
- package/src/react/host/hostHooks.ts +198 -0
- package/src/react/host/hostStyles.ts +65 -0
- package/src/react/index.ts +43 -38
- package/src/react/inspectorHints.ts +40 -0
- package/src/react/modules.tsx +440 -170
- package/src/react/theme.ts +15 -0
- package/src/session.ts +17 -0
package/src/core/assets.ts
CHANGED
|
@@ -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:
|
|
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
|
|
267
|
-
const findMaterial = (node:
|
|
268
|
-
if (!node
|
|
269
|
-
if (node.type === 'ParticleEmitter' && node.ps
|
|
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:
|
|
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
|
|
280
|
-
const texture = byUuid(json
|
|
281
|
-
const
|
|
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;
|
package/src/core/binding.ts
CHANGED
|
@@ -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]) {
|
package/src/core/collision.ts
CHANGED
|
@@ -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);
|
package/src/core/colors.ts
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
2
|
-
import
|
|
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) =>
|
|
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) =>
|
|
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:
|
|
39
|
+
texture: textureUrl && resolveTexture ? resolveTexture(textureUrl, scene) : undefined,
|
|
39
40
|
transparent: true,
|
|
40
41
|
blendMode: 1,
|
|
41
42
|
});
|
package/src/core/editorScene.ts
CHANGED
|
@@ -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};
|