Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/dev/core/src/Particles/Node/nodeParticleSystemSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export interface INodeParticleEditorOptions {
/** Additional configuration for the NPE */
nodeEditorConfig?: {
backgroundColor?: Color4;
/** If true, the node particle system set will be disposed when the editor is closed (default: true) */
disposeOnClose?: boolean;
};
}

Expand Down
21 changes: 16 additions & 5 deletions packages/dev/core/src/Rendering/utilityLayerRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,26 @@ export class UtilityLayerRenderer implements IDisposable {
*/
public static get DefaultKeepDepthUtilityLayer(): UtilityLayerRenderer {
if (UtilityLayerRenderer._DefaultKeepDepthUtilityLayer == null) {
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = new UtilityLayerRenderer(EngineStore.LastCreatedScene!);
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.originalScene.onDisposeObservable.addOnce(() => {
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = null;
});
return UtilityLayerRenderer._CreateDefaultKeepUtilityLayerFromScene(EngineStore.LastCreatedScene!);
}
return UtilityLayerRenderer._DefaultKeepDepthUtilityLayer;
}

/**
* Creates an utility layer, and set it as a default utility layer (Depth map of the previous scene is not cleared before drawing on top of it)
* @param scene associated scene
* @internal
*/
public static _CreateDefaultKeepUtilityLayerFromScene(scene: Scene): UtilityLayerRenderer {
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = new UtilityLayerRenderer(scene);
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.originalScene.onDisposeObservable.addOnce(() => {
UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = null;
});

return UtilityLayerRenderer._DefaultKeepDepthUtilityLayer;
}

/**
* The scene that is rendered on top of the original scene
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Nullable } from "core/types";
import type { ListItem } from "shared-ui-components/fluent/primitives/list";

import { GizmoManager } from "core/Gizmos/gizmoManager";
import { UtilityLayerRenderer } from "core/Rendering/utilityLayerRenderer";
import { StandardMaterial } from "core/Materials/standardMaterial";
import { Color3 } from "core/Maths/math.color";
import { Attractor } from "core/Particles/attractor";
Expand Down Expand Up @@ -38,7 +39,12 @@ function AttractorsToListItems(attractors: Nullable<Array<Attractor>>) {
}

const CreateGizmoManager = (scene: Scene) => {
const gizmoManager = new GizmoManager(scene);
const gizmoManager = new GizmoManager(
scene,
1,
UtilityLayerRenderer._CreateDefaultUtilityLayerFromScene(scene),
UtilityLayerRenderer._CreateDefaultKeepUtilityLayerFromScene(scene)
);
gizmoManager.positionGizmoEnabled = true;
gizmoManager.attachableMeshes = [];
return gizmoManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
import { Tools } from "core/Misc/tools";
import { ParticleHelper } from "core/Particles/particleHelper";
import { ParticleSystem } from "core/Particles/particleSystem";
import { ConvertToNodeParticleSystemSetAsync } from "core/Particles/Node/nodeParticleSystemSet.helper";
import { BlendModeOptions, ParticleBillboardModeOptions } from "shared-ui-components/constToOptionsMaps";
import { ButtonLine } from "shared-ui-components/fluent/hoc/buttonLine";
import { FileUploadLine } from "shared-ui-components/fluent/hoc/fileUploadLine";
Expand Down Expand Up @@ -246,10 +247,22 @@ export const ParticleSystemGeneralProperties: FunctionComponent<{ particleSystem
<BoundProperty component={NumberInputPropertyLine} label="Update Speed" target={system} propertyKey="updateSpeed" min={0} step={0.01} />

<ButtonLine
label={system.isNodeGenerated ? "Edit in Node Particle Editor (coming soon)" : "View in Node Particle Editor (coming soon)"}
disabled={true}
onClick={() => {
// Hook up once Node Particle Editor UX is wired.
label={system.isNodeGenerated ? "Edit in Node Particle Editor" : "View in Node Particle Editor"}
onClick={async () => {
const scene = system.getScene();
if (!scene) {
return;
}

if (system.isNodeGenerated && system.source) {
await system.source.editAsync({ nodeEditorConfig: { backgroundColor: scene.clearColor, disposeOnClose: false } });
} else {
// View: Convert the particle system to a NodeParticleSystemSet and open editor
const systemSet = await ConvertToNodeParticleSystemSetAsync("source", [system]);
if (systemSet) {
await systemSet.editAsync({ nodeEditorConfig: { backgroundColor: scene.clearColor } });
}
}
}}
/>

Expand Down
2 changes: 2 additions & 0 deletions packages/dev/inspector-v2/test/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { MultiMaterial } from "core/Materials/multiMaterial";
import { Texture } from "core/Materials/Textures/texture";
import { ShowInspector } from "../../src";

import "node-particle-editor/legacy/legacy"; // Ensure node particle editor legacy code is imported
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine for now. I will change it later to not go through the legacy path.


// Register scene loader plugins.
registerBuiltInLoaders();

Expand Down
11 changes: 9 additions & 2 deletions packages/dev/inspector-v2/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = (env) => {
),

resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"],
extensions: [".ts", ".tsx", ".js", ".jsx", ".svg", ".scss"],
alias: {
addons: path.resolve("../../dev/addons/dist"),
core: path.resolve("../../dev/core/dist"),
Expand All @@ -30,13 +30,20 @@ module.exports = (env) => {
"shared-ui-components": path.resolve("../../dev/sharedUiComponents/src"),
"inspector-v2": path.resolve("./src"),
serializers: path.resolve("../../dev/serializers/dist"),
"node-particle-editor": path.resolve("../../tools/nodeParticleEditor/dist"),
},
},

module: {
rules: webpackTools.getRules({
sideEffects: true,
includeCSS: false,
includeCSS: true,
extraRules: [
{
test: /\.svg$/,
type: "asset/inline",
},
],
enableFastRefresh: !production,
tsOptions: {
configFile: "tsconfig.build.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ export class PreviewManager {
}
}

// Only build new systems if we found matching ones to replace
if (map.size === 0) {
return;
}

const newSet = await this._nodeParticleSystemSet.buildAsync(scene);
for (const [reference, emitter] of map) {
const particleSystem = (newSet.systems as ParticleSystem[]).find((ps) => ps._blockReference === reference);
Expand All @@ -180,7 +185,7 @@ export class PreviewManager {
this._particleSystemSet.dispose();
}

if (this._nodeParticleSystemSet) {
if (this._globalState.disposeOnClose && this._nodeParticleSystemSet) {
this._nodeParticleSystemSet.dispose();
}

Expand Down
2 changes: 2 additions & 0 deletions packages/tools/nodeParticleEditor/src/globalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export class GlobalState {
hostDocument: Document;
hostWindow: Window;
stateManager: StateManager;
/** If true, the node particle system set will be disposed when the editor is closed (default: true) */
disposeOnClose: boolean = true;
onBuildRequiredObservable = new Observable<void>();
onResetRequiredObservable = new Observable<boolean>();
onClearUndoStack = new Observable<void>();
Expand Down
3 changes: 3 additions & 0 deletions packages/tools/nodeParticleEditor/src/nodeParticleEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface INodeEditorOptions {
customSave?: { label: string; action: (data: string) => Promise<void> };
customLoadObservable?: Observable<any>;
backgroundColor?: Color4;
/** If true, the node particle system set will be disposed when the editor is closed (default: true) */
disposeOnClose?: boolean;
}

/**
Expand Down Expand Up @@ -65,6 +67,7 @@ export class NodeParticleEditor {
globalState.customSave = options.customSave;
globalState.hostWindow = hostElement.ownerDocument.defaultView!;
globalState.stateManager.hostDocument = globalState.hostDocument;
globalState.disposeOnClose = options.disposeOnClose ?? true;
if (options.backgroundColor) {
globalState.backgroundColor = options.backgroundColor;
}
Expand Down