mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
PageScene: SceneUtils takes Deps, no Editor reference (P2)
Closes the last "subsystem holds an Editor ref" holdout. SceneUtils now takes a SceneUtilsDeps surface (Phase 2 idiom — same shape as SaveManagerDeps, CameraControllerDeps, SelectionBridgeDeps, GizmoControllerDeps) instead of the full Editor. Deps surface — 9 single-purpose getters/callbacks for the cross- subsystem reaches the methods need: - Gizmo lifecycle (getGizmoControl/detachGizmo/removeGizmoFromScene) used by removeTransformControls - Outline pass (getOutlinePass) used by removeTransformControls - Selection (publishSelect/clearSelected) used by deleteObject and removeTransformControls - Camera name (getCameraName) used by deleteObject's ::CAM:: guard - Selected object lookup (getSelectedObject) used by getSelectedSum - Three scene root (getThreeScene) — provided for future use; the current deleteObject still goes through this.scene.scene since Scene is an injected primitive, not a subsystem Editor wires deps inline at SceneUtils construction. Constructor signature flips: was (editor, scene); now (scene, deps). Re P2 holdouts: ViewportController already used Deps (ViewportEngineRefs); roadmap memory was stale. PostProcessingPipeline and GizmoController.configure only take primitives (renderer/scene/ camera/dom), no subsystem coupling — converting them to options objects would be pure style and was deferred.
This commit is contained in:
1 parent
72071c0066
commit
c6c0b193eb
2 files changed
+59
-31
No files matched your search
@@ -195,7 +195,20 @@ class Editor {
|
||||
this.renderEventToken = -1;
|
||||
this.shouldRender = false;
|
||||
|
||||
this.utils = new SceneUtils(this, this.activeScene);
|
||||
this.utils = new SceneUtils(this.activeScene, {
|
||||
getGizmoControl: () => this.gizmo.control,
|
||||
detachGizmo: () => this.gizmo.detach(),
|
||||
removeGizmoFromScene: () =>
|
||||
this.gizmo.removeFromScene(this.activeScene.scene),
|
||||
getOutlinePass: () => this.postProcessing.outlinePass,
|
||||
publishSelect: () => this.selection.publishSelect(),
|
||||
clearSelected: () => {
|
||||
this.selection.selected = undefined;
|
||||
},
|
||||
getCameraName: () => this.cameraController.camera_name,
|
||||
getSelectedObject: () => this.sceneManager?.selected_objects?.[0],
|
||||
getThreeScene: () => this.activeScene.scene,
|
||||
});
|
||||
this.save_manager = new SaveManager({
|
||||
getVersion: () => this.version,
|
||||
setVersion: (v) => {
|
||||
|
||||
@@ -1,14 +1,40 @@
|
||||
import Scene from "./scene";
|
||||
import Editor from "./editor";
|
||||
import * as THREE from "three";
|
||||
import type { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";
|
||||
import type { TransformControls } from "./TransformControls.js";
|
||||
|
||||
import Scene from "./scene";
|
||||
import { usePageSceneStore } from "../PageSceneStore";
|
||||
|
||||
// Capabilities SceneUtils needs from outside its own state. Editor
|
||||
// wires these in inline at construction (Phase 2 idiom — same shape
|
||||
// as CameraControllerDeps, SaveManagerDeps, etc.). SceneUtils does
|
||||
// NOT import Editor — every cross-subsystem reach is a callback or
|
||||
// getter on this object.
|
||||
export type SceneUtilsDeps = {
|
||||
// Gizmo lifecycle (used by removeTransformControls)
|
||||
getGizmoControl: () => TransformControls | undefined;
|
||||
detachGizmo: () => void;
|
||||
removeGizmoFromScene: () => void;
|
||||
// Outline pass (used by removeTransformControls)
|
||||
getOutlinePass: () => OutlinePass | undefined;
|
||||
// Selection sync (used by removeTransformControls + deleteObject)
|
||||
publishSelect: () => void;
|
||||
clearSelected: () => void;
|
||||
// Camera identity (used by deleteObject — protects ::CAM:: from delete)
|
||||
getCameraName: () => string;
|
||||
// Selected object lookup (used by getSelectedSum)
|
||||
getSelectedObject: () => THREE.Object3D | undefined;
|
||||
// Three scene root (used by deleteObject + removeTransformControls)
|
||||
getThreeScene: () => THREE.Scene;
|
||||
};
|
||||
|
||||
export class SceneUtils {
|
||||
scene: Scene;
|
||||
editor: Editor;
|
||||
constructor(editor: Editor, scene: Scene) {
|
||||
private deps: SceneUtilsDeps;
|
||||
|
||||
constructor(scene: Scene, deps: SceneUtilsDeps) {
|
||||
this.scene = scene;
|
||||
this.editor = editor;
|
||||
this.deps = deps;
|
||||
}
|
||||
|
||||
// If string is empty.
|
||||
@@ -52,42 +78,31 @@ export class SceneUtils {
|
||||
|
||||
// Removes transform controls and publishes selected.
|
||||
removeTransformControls(remove_outline: boolean = true) {
|
||||
if (this.editor.gizmo.control == undefined) {
|
||||
if (this.deps.getGizmoControl() == undefined) {
|
||||
return;
|
||||
}
|
||||
const outlinePass = this.editor.postProcessing.outlinePass;
|
||||
const outlinePass = this.deps.getOutlinePass();
|
||||
if (outlinePass == undefined) {
|
||||
return;
|
||||
}
|
||||
if (remove_outline) {
|
||||
outlinePass.selectedObjects = [];
|
||||
this.editor.selection.publishSelect();
|
||||
this.deps.publishSelect();
|
||||
}
|
||||
this.editor.gizmo.detach();
|
||||
this.editor.gizmo.removeFromScene(this.editor.activeScene.scene);
|
||||
this.deps.detachGizmo();
|
||||
this.deps.removeGizmoFromScene();
|
||||
if (remove_outline) outlinePass.selectedObjects = [];
|
||||
}
|
||||
|
||||
// Returns the "check sum" of the editors selected object.
|
||||
// Returns the "check sum" of the editor's selected object.
|
||||
getSelectedSum(): number {
|
||||
if (this.editor.sceneManager?.selected_objects === undefined) {
|
||||
return 0;
|
||||
}
|
||||
if (this.editor.sceneManager?.selected_objects.length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const selected = this.deps.getSelectedObject();
|
||||
if (selected === undefined) return 0;
|
||||
const posCombo =
|
||||
this.editor.sceneManager?.selected_objects[0].position.x +
|
||||
this.editor.sceneManager?.selected_objects[0].position.y +
|
||||
this.editor.sceneManager?.selected_objects[0].position.z;
|
||||
selected.position.x + selected.position.y + selected.position.z;
|
||||
const rotCombo =
|
||||
this.editor.sceneManager?.selected_objects[0].rotation.x +
|
||||
this.editor.sceneManager?.selected_objects[0].rotation.y +
|
||||
this.editor.sceneManager?.selected_objects[0].rotation.z;
|
||||
const sclCombo =
|
||||
this.editor.sceneManager?.selected_objects[0].scale.x +
|
||||
this.editor.sceneManager?.selected_objects[0].scale.y +
|
||||
this.editor.sceneManager?.selected_objects[0].scale.z;
|
||||
selected.rotation.x + selected.rotation.y + selected.rotation.z;
|
||||
const sclCombo = selected.scale.x + selected.scale.y + selected.scale.z;
|
||||
return posCombo + rotCombo + sclCombo;
|
||||
}
|
||||
|
||||
@@ -123,7 +138,7 @@ function removeObject3D(object3D) {
|
||||
}
|
||||
|
||||
this.removeTransformControls();
|
||||
if (obj.name === this.editor.cameraController.camera_name) {
|
||||
if (obj.name === this.deps.getCameraName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,8 +177,8 @@ function removeObject3D(object3D) {
|
||||
}
|
||||
|
||||
usePageSceneStore.getState().removeSceneObject(uuid);
|
||||
this.editor.selection.selected = undefined;
|
||||
this.editor.selection.publishSelect();
|
||||
this.deps.clearSelected();
|
||||
this.deps.publishSelect();
|
||||
usePageSceneStore.getState().hideObjectPanel();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user