File size: 3,961 Bytes
e6b949c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import * as SPLAT from "gsplat";
import { InputMode } from "./InputMode";
import { Engine } from "./Engine";
import { ModeManager } from "./ModeManager";
import { SelectionManager } from "./SelectionManager";
import { UndoManager } from "./UndoManager";
import { MoveAction } from "./MoveAction";

class GrabMode implements InputMode {
    exit: () => void;

    constructor(engine: Engine) {
        const splat = SelectionManager.selectedSplat as SPLAT.Splat;
        const initialMousePosition = engine.mouseManager.currentMousePosition.clone();
        const initialPosition = splat.position.clone();

        let axis: "x" | "y" | "z" | null = null;

        const handleClick = () => {
            const action = new MoveAction(splat, initialPosition, splat.position);
            UndoManager.do(action);
            ModeManager.enterMode("default");
        };

        const handleCancel = () => {
            splat.position = initialPosition;
            ModeManager.enterMode("default");
        };

        const handleMouseMove = () => {
            const plane = new SPLAT.Plane(engine.camera.forward, initialPosition);
            const initialDirection = engine.camera.screenPointToRay(initialMousePosition.x, initialMousePosition.y);
            const newDirection = engine.camera.screenPointToRay(
                engine.mouseManager.currentMousePosition.x,
                engine.mouseManager.currentMousePosition.y,
            );
            const initialIntersection = plane.intersect(engine.camera.position, initialDirection);
            const newIntersection = plane.intersect(engine.camera.position, newDirection);
            if (initialIntersection && newIntersection) {
                let delta = newIntersection.subtract(initialIntersection);
                switch (axis) {
                    case "x":
                        delta = new SPLAT.Vector3(delta.x, 0, 0);
                        break;
                    case "y":
                        delta = new SPLAT.Vector3(0, delta.y, 0);
                        break;
                    case "z":
                        delta = new SPLAT.Vector3(0, 0, delta.z);
                        break;
                }
                splat.position = initialPosition.add(delta);
            }
        };

        const handleAxisX = () => {
            if (axis === "x") {
                axis = null;
            } else {
                axis = "x";
            }
            handleMouseMove();
        };

        const handleAxisY = () => {
            if (axis === "y") {
                axis = null;
            } else {
                axis = "y";
            }
            handleMouseMove();
        };

        const handleAxisZ = () => {
            if (axis === "z") {
                axis = null;
            } else {
                axis = "z";
            }
            handleMouseMove();
        };

        engine.mouseManager.registerMouse("click", handleClick);
        engine.mouseManager.registerMouse("contextmenu", handleCancel);
        engine.mouseManager.registerMouse("mousemove", handleMouseMove);
        engine.keyboardManager.registerKey("Escape", handleCancel);
        engine.keyboardManager.registerKey("g", handleCancel);
        engine.keyboardManager.registerKey("x", handleAxisX);
        engine.keyboardManager.registerKey("y", handleAxisY);
        engine.keyboardManager.registerKey("z", handleAxisZ);

        this.exit = () => {
            engine.mouseManager.unregisterMouse("click");
            engine.mouseManager.unregisterMouse("contextmenu");
            engine.mouseManager.unregisterMouse("mousemove");
            engine.keyboardManager.unregisterKey("Escape");
            engine.keyboardManager.unregisterKey("g");
            engine.keyboardManager.unregisterKey("x");
            engine.keyboardManager.unregisterKey("y");
            engine.keyboardManager.unregisterKey("z");
        };
    }
}

export { GrabMode };