mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
PageScene: move change_mode + toggleTransformSpace into GizmoController
GizmoController now reads/writes the store's transformSpace through a new GizmoControllerDeps surface that Editor wires up in initialize(). - changeMode(type) reads the desired space from the store internally (forces local for scale), so callers don't plumb space through. - toggleTransformSpace() owns the read/flip/write/apply loop that used to live on Editor.toggleTransformSpace. Editor.change_mode and Editor.toggleTransformSpace are deleted. Callers updated: - actions/setTransformMode.ts → editor.gizmo.changeMode(...) - Controls3D.tsx → editorEngine?.gizmo.toggleTransformSpace() - keymap.ts → editor.gizmo.changeMode + .toggleTransformSpace; the inline setGizmoMode body shrinks to one line and the duplicate toggleTransformSpace helper is gone.
This commit is contained in:
1 parent
89ac302392
commit
5ec73e362d
5 files changed
+40
-41
No files matched your search
@@ -8,7 +8,7 @@ const ENGINE_MODE: Record<TransformMode, "translate" | "rotate" | "scale"> = {
|
||||
};
|
||||
|
||||
export function setTransformMode(editor: Editor, mode: TransformMode): void {
|
||||
editor.change_mode(ENGINE_MODE[mode]);
|
||||
editor.gizmo.changeMode(ENGINE_MODE[mode]);
|
||||
const store = usePageSceneStore.getState();
|
||||
store.setTransformMode(mode);
|
||||
store.setSelectedMode(mode);
|
||||
|
||||
@@ -318,7 +318,7 @@ export const Controls3D = () => {
|
||||
>
|
||||
<button
|
||||
className="h-9 rounded-[10px] px-2.5 text-[10px] font-semibold font-mono bg-white/15 hover:bg-white/25 transition-colors uppercase tracking-wide"
|
||||
onClick={() => editorEngine?.toggleTransformSpace()}
|
||||
onClick={() => editorEngine?.gizmo.toggleTransformSpace()}
|
||||
>
|
||||
{transformSpace === "world" ? "World" : "Local"}
|
||||
</button>
|
||||
|
||||
@@ -136,7 +136,11 @@ class Editor {
|
||||
// PostProcessingPipeline must exist before Scene because Scene's
|
||||
// load paths invoke updateSurfaceIdAttributeToMesh as a callback.
|
||||
this.postProcessing = new PostProcessingPipeline();
|
||||
this.gizmo = new GizmoController();
|
||||
this.gizmo = new GizmoController({
|
||||
getTransformSpace: () => usePageSceneStore.getState().transformSpace,
|
||||
setTransformSpace: (space) =>
|
||||
usePageSceneStore.getState().setTransformSpace(space),
|
||||
});
|
||||
this.cameraController = new CameraController({
|
||||
getThreeScene: () => this.activeScene.scene,
|
||||
getHotItems: () => this.activeScene.hot_items ?? null,
|
||||
@@ -823,24 +827,6 @@ class Editor {
|
||||
console.log("3D Editor Engine unmounted");
|
||||
}
|
||||
|
||||
// Facade for actions/setTransformMode + keymap dispatch. Reads the
|
||||
// store's current transform space and forwards to the gizmo.
|
||||
change_mode(type: "translate" | "rotate" | "scale") {
|
||||
const space =
|
||||
type === "scale" ? "local" : usePageSceneStore.getState().transformSpace;
|
||||
this.gizmo.changeMode(type, space);
|
||||
}
|
||||
|
||||
// Facade for Controls3D button + keymap. Toggles the store's
|
||||
// transform space and pushes the new value into the gizmo.
|
||||
toggleTransformSpace() {
|
||||
if (!this.gizmo.canToggleSpace()) return;
|
||||
const store = usePageSceneStore.getState();
|
||||
const next = store.transformSpace === "world" ? "local" : "world";
|
||||
store.setTransformSpace(next);
|
||||
this.gizmo.setSpace(next);
|
||||
}
|
||||
|
||||
// Facades — external callers in actions/* and helper.ts target these
|
||||
// names. Internals reach the bridge directly via this.selection.*.
|
||||
updateOutliner() {
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
// on Editor), then `configure()` wires it to the camera/renderer once
|
||||
// initialize() has produced them.
|
||||
//
|
||||
// No `editor` reference, no `import type Editor`. Store access stays on
|
||||
// Editor's facades (change_mode, toggleTransformSpace); this module only
|
||||
// translates them into TransformControls calls.
|
||||
// Store access for the transform-space pref is injected via Deps so the
|
||||
// controller doesn't import the Zustand store directly.
|
||||
|
||||
import type * as THREE from "three";
|
||||
import { TransformControls } from "../TransformControls.js";
|
||||
@@ -22,9 +21,23 @@ export type GizmoCallbacks = {
|
||||
onDraggingChanged: (dragging: boolean) => void;
|
||||
};
|
||||
|
||||
// Capabilities the gizmo needs from outside its own state.
|
||||
// Editor wires these in initialize() so GizmoController never imports
|
||||
// the store directly.
|
||||
export type GizmoControllerDeps = {
|
||||
getTransformSpace: () => TransformSpace;
|
||||
setTransformSpace: (space: TransformSpace) => void;
|
||||
};
|
||||
|
||||
export class GizmoController {
|
||||
control: TransformControls | undefined;
|
||||
|
||||
private deps: GizmoControllerDeps;
|
||||
|
||||
constructor(deps: GizmoControllerDeps) {
|
||||
this.deps = deps;
|
||||
}
|
||||
|
||||
configure(
|
||||
camera: THREE.PerspectiveCamera | null,
|
||||
domElement: HTMLElement,
|
||||
@@ -45,8 +58,11 @@ export class GizmoController {
|
||||
scene.add(this.control);
|
||||
}
|
||||
|
||||
changeMode(type: TransformMode, space: TransformSpace) {
|
||||
// Apply a transform mode. Reads the desired space from the store so
|
||||
// callers don't need to plumb it through. Scale is always local.
|
||||
changeMode(type: TransformMode) {
|
||||
if (this.control == undefined) return;
|
||||
const space = type === "scale" ? "local" : this.deps.getTransformSpace();
|
||||
this.control.mode = type;
|
||||
this.control.space = space;
|
||||
}
|
||||
@@ -56,6 +72,17 @@ export class GizmoController {
|
||||
this.control.space = space;
|
||||
}
|
||||
|
||||
// Flip the store's transform-space preference and push the new value
|
||||
// into the live gizmo. No-op when the gizmo is in scale mode (scale
|
||||
// is always local).
|
||||
toggleTransformSpace() {
|
||||
if (!this.canToggleSpace()) return;
|
||||
const next =
|
||||
this.deps.getTransformSpace() === "world" ? "local" : "world";
|
||||
this.deps.setTransformSpace(next);
|
||||
this.setSpace(next);
|
||||
}
|
||||
|
||||
// True when the gizmo exists and is in a mode where toggling between
|
||||
// world/local space is meaningful (scale is always local).
|
||||
canToggleSpace(): boolean {
|
||||
|
||||
@@ -26,25 +26,11 @@ const setGizmoMode = (
|
||||
gizmoMode: "translate" | "rotate" | "scale",
|
||||
storeMode: "move" | "rotate" | "scale",
|
||||
) => {
|
||||
editor.mouse_controls?.control?.setMode(gizmoMode);
|
||||
const space = usePageSceneStore.getState().transformSpace;
|
||||
if (editor.mouse_controls?.control) {
|
||||
editor.mouse_controls.control.space = space;
|
||||
}
|
||||
editor.gizmo.changeMode(gizmoMode);
|
||||
usePageSceneStore.getState().setTransformMode(storeMode);
|
||||
usePageSceneStore.getState().setSelectedMode(storeMode);
|
||||
};
|
||||
|
||||
const toggleTransformSpace = (editor: Editor) => {
|
||||
if (editor.mouse_controls?.control?.mode === "scale") return;
|
||||
const next =
|
||||
usePageSceneStore.getState().transformSpace === "world" ? "local" : "world";
|
||||
usePageSceneStore.getState().setTransformSpace(next);
|
||||
if (editor.mouse_controls?.control) {
|
||||
editor.mouse_controls.control.space = next;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteSelected = (editor: Editor) => {
|
||||
const mc = editor.mouse_controls;
|
||||
if (!mc?.selected) return;
|
||||
@@ -108,7 +94,7 @@ export const buildKeymap = (): KeyBinding[] => [
|
||||
{ code: "KeyG", label: "Scale", group: "Transform",
|
||||
run: (e) => setGizmoMode(e, "scale", "scale") },
|
||||
{ code: "KeyX", label: "Toggle local/world", group: "Transform",
|
||||
run: toggleTransformSpace },
|
||||
run: (e) => e.gizmo.toggleTransformSpace() },
|
||||
{ code: "KeyK", label: "Toggle pose (FK)", group: "Transform",
|
||||
run: (e) => e.mouse_controls?.toggleFKMode() },
|
||||
|
||||
|
||||
Reference in new issue
Block a user