@scenoco-three/editor 0.5.4 → 0.7.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.
Files changed (47) hide show
  1. package/README.md +31 -106
  2. package/bin/serve.js +37 -0
  3. package/dist/editor.js +12521 -0
  4. package/package.json +29 -41
  5. package/app/cameraRig.ts +0 -118
  6. package/app/commands.ts +0 -78
  7. package/app/desktopControls.ts +0 -47
  8. package/app/document.ts +0 -547
  9. package/app/editLog.ts +0 -127
  10. package/app/editor.css +0 -51
  11. package/app/gizmo.ts +0 -169
  12. package/app/globals.d.ts +0 -9
  13. package/app/index.html +0 -14
  14. package/app/main.ts +0 -546
  15. package/app/meta.ts +0 -24
  16. package/app/picking.ts +0 -47
  17. package/app/session.ts +0 -612
  18. package/app/touchControls.ts +0 -127
  19. package/app/ui-react/AddMemberPopup.tsx +0 -114
  20. package/app/ui-react/BottomLauncher.tsx +0 -15
  21. package/app/ui-react/EditorUI.tsx +0 -22
  22. package/app/ui-react/FilePicker.tsx +0 -80
  23. package/app/ui-react/HeadBtn.tsx +0 -21
  24. package/app/ui-react/InspectorSheet.tsx +0 -475
  25. package/app/ui-react/NodeListSheet.tsx +0 -56
  26. package/app/ui-react/TopBar.tsx +0 -137
  27. package/app/ui-react/Tree.tsx +0 -106
  28. package/app/ui-react/cx.ts +0 -4
  29. package/app/ui-react/fields.tsx +0 -407
  30. package/app/ui-react/format.ts +0 -30
  31. package/app/ui-react/mount.tsx +0 -31
  32. package/app/ui-react/store.ts +0 -80
  33. package/app/ui-react/types.ts +0 -88
  34. package/app/ui-react/ui.module.css +0 -250
  35. package/app/ui-react/useSize.ts +0 -20
  36. package/app/values.ts +0 -137
  37. package/app/vite-env.d.ts +0 -7
  38. package/dist/cli/index.d.ts +0 -2
  39. package/dist/cli/index.js +0 -122
  40. package/dist/index.d.ts +0 -10
  41. package/dist/index.js +0 -10
  42. package/dist/mcp.d.ts +0 -32
  43. package/dist/mcp.js +0 -191
  44. package/dist/protocol.d.ts +0 -170
  45. package/dist/protocol.js +0 -22
  46. package/dist/server.d.ts +0 -124
  47. package/dist/server.js +0 -440
package/app/editor.css DELETED
@@ -1,51 +0,0 @@
1
- /*
2
- * The page shell and the theme.
3
- *
4
- * `ui.module.css` styles the chrome and reads these three variables for every panel — so they
5
- * have to be defined here, on `:root`, not inside the module: a CSS Module hashes class names but
6
- * a custom property still resolves through the cascade, and an undefined `var(--line)` is not an
7
- * error. It silently paints nothing, which is exactly how every panel border went missing.
8
- */
9
- :root {
10
- color-scheme: dark;
11
- /* Translucent, because a panel floats over the viewport and the scene behind it is context. */
12
- --panel: rgba(20, 24, 32, 0.92);
13
- --line: #2a3344;
14
- /* A panel floats over the scene, so its outline has to hold against whatever is behind it —
15
- brighter than `--line`, which divides rows *inside* a panel and should stay quiet. */
16
- --edge: #3d4b64;
17
- --accent: #4af0e0;
18
- }
19
-
20
- * { box-sizing: border-box; }
21
-
22
- html,
23
- body {
24
- margin: 0;
25
- height: 100%;
26
- overflow: hidden;
27
- background: #15181f;
28
- color: #d6e2f0;
29
- font: 13px/1.5 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
30
- }
31
-
32
- #viewport {
33
- position: fixed;
34
- inset: 0;
35
- width: 100%;
36
- height: 100%;
37
- display: block;
38
- touch-action: none;
39
- }
40
-
41
- /*
42
- * The chrome overlays the viewport but lets pointer events fall through to the canvas; each
43
- * panel re-enables them on its own surface. Otherwise an invisible full-screen div would eat
44
- * every click meant for the scene.
45
- */
46
- #sc-ui {
47
- position: fixed;
48
- inset: 0;
49
- z-index: 5;
50
- pointer-events: none;
51
- }
package/app/gizmo.ts DELETED
@@ -1,169 +0,0 @@
1
- import { Quaternion, Vector3, type Camera, type Object3D, type Scene } from 'three';
2
- import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
3
-
4
- export type GizmoMode = 'translate' | 'rotate' | 'scale';
5
-
6
- /** Which axes the handles follow: the world's, or the object's own. */
7
- export type GizmoSpace = 'world' | 'local';
8
-
9
- /**
10
- * How far the pointer must travel before a press on a handle counts as a drag.
11
- *
12
- * No click is perfectly still — a real mouse moves a pixel or two between down and up — and
13
- * `TransformControls` applies every one of those pixels. Without a threshold, clicking an object
14
- * in scale mode quietly resizes it by a fraction of a percent, which is invisible on screen and
15
- * permanent in the document: the file gains a `scale` attribute nobody asked for.
16
- */
17
- const DRAG_THRESHOLD = 3;
18
-
19
- export interface GizmoOptions {
20
- /** Live refresh while dragging (e.g. update the inspector numbers). */
21
- onObjectChange?: () => void;
22
- /** Drag finished — commit the object's new transform as one undoable edit. */
23
- onCommit?: (object: Object3D) => void;
24
- }
25
-
26
- /**
27
- * Thin wrapper over three's `TransformControls` (translate/rotate/scale handles).
28
- * The control mutates the attached `Object3D` directly during a drag; on drag end
29
- * we hand the object to `onCommit`, which records a single undoable edit (the
30
- * compiled scene was untouched during the drag, so it still holds the pre-drag
31
- * value — exactly the right "before" for undo).
32
- *
33
- * Camera controls read `dragging` to stand down while a handle is being dragged,
34
- * so the fly camera and the gizmo never fight over the same pointer/touch.
35
- */
36
- export class Gizmo {
37
- private readonly controls: TransformControls;
38
- private readonly helper: Object3D;
39
-
40
- private readonly scene: Scene;
41
-
42
- /** Where the press started, while one is in progress. */
43
- private pressedAt: { x: number; y: number } | null = null;
44
- /** True once a press has travelled far enough to be a drag. */
45
- private travelled = false;
46
- /** The attached object's transform at the moment of the press, to put back after a click. */
47
- private readonly grabbed = {
48
- position: new Vector3(),
49
- quaternion: new Quaternion(),
50
- scale: new Vector3(),
51
- /** Kept alongside the quaternion because it is the form the document writes. */
52
- eulerAngles: new Vector3(),
53
- };
54
-
55
- constructor(
56
- camera: Camera,
57
- domElement: HTMLElement,
58
- scene: Scene,
59
- touch: boolean,
60
- opts: GizmoOptions = {},
61
- ) {
62
- this.scene = scene;
63
- this.controls = new TransformControls(camera, domElement);
64
- this.controls.setSize(touch ? 1.4 : 1); // fat-finger handles on touch
65
- this.helper = this.controls.getHelper();
66
- this.helper.userData.scenocoEditorOnly = true; // keep it out of the Hierarchy + picking
67
- scene.add(this.helper);
68
-
69
- domElement.addEventListener('pointerdown', (event) => {
70
- this.pressedAt = { x: event.clientX, y: event.clientY };
71
- this.travelled = false;
72
- });
73
- domElement.addEventListener('pointermove', (event) => {
74
- if (!this.pressedAt || this.travelled) return;
75
- this.travelled = Math.hypot(event.clientX - this.pressedAt.x, event.clientY - this.pressedAt.y) > DRAG_THRESHOLD;
76
- });
77
-
78
- // A press that never travelled changed nothing the user meant to change, so the object goes
79
- // back to where it was grabbed and the document never hears about it.
80
- this.controls.addEventListener('objectChange', () => {
81
- if (this.travelled) opts.onObjectChange?.();
82
- });
83
- this.controls.addEventListener('dragging-changed', (e) => {
84
- // Fired true at drag start, false at drag end.
85
- const object = this.controls.object;
86
- if (!object) return;
87
- if (e.value) {
88
- this.grabbed.position.copy(object.position);
89
- this.grabbed.quaternion.copy(object.quaternion);
90
- this.grabbed.scale.copy(object.scale);
91
- this.grabbed.eulerAngles.copy(object.eulerAngles);
92
- return;
93
- }
94
- this.pressedAt = null;
95
- if (this.travelled) opts.onCommit?.(object);
96
- else {
97
- object.position.copy(this.grabbed.position);
98
- object.quaternion.copy(this.grabbed.quaternion);
99
- object.scale.copy(this.grabbed.scale);
100
- }
101
- });
102
- }
103
-
104
- /**
105
- * The attached object's value for one channel as it was when the drag began.
106
- *
107
- * Undo needs this and cannot work it out later. By the time the first edit is recorded the
108
- * object has already moved — the write happens *because* it moved — so a "before" captured
109
- * there is a frame late. For a channel the document writes, undo restores the text and the
110
- * error never shows; for one it does not write (a rotation left at zero, a scale left at one,
111
- * which is most of them) there is nothing to restore from, and the object is left wherever
112
- * that first frame put it.
113
- */
114
- grabbedValue(channel: 'position' | 'eulerAngles' | 'scale'): Vector3 {
115
- return this.grabbed[channel];
116
- }
117
-
118
- /** True while a handle is being dragged — camera controls check this to yield. */
119
- get dragging(): boolean {
120
- return this.controls.dragging;
121
- }
122
-
123
- setMode(mode: GizmoMode): void {
124
- this.controls.setMode(mode);
125
- }
126
- get mode(): GizmoMode {
127
- return this.controls.mode as GizmoMode;
128
- }
129
-
130
- /**
131
- * Whether the handles line up with the world's axes or the object's own — Unity's
132
- * Global/Local button.
133
- *
134
- * It changes what a drag means, not just how it looks: dragging the green arrow moves a node
135
- * along world Y in one space and along its own up in the other, and for anything rotated the
136
- * two are different edits.
137
- */
138
- setSpace(space: GizmoSpace): void {
139
- this.controls.setSpace(space);
140
- }
141
- get space(): GizmoSpace {
142
- return this.controls.space as GizmoSpace;
143
- }
144
-
145
- /**
146
- * Point the handles at an object — never at the handles themselves.
147
- *
148
- * Attaching the control to its own helper makes the helper its own parent's target: three walks
149
- * `updateMatrixWorld` between the two for ever and the page dies on a stack overflow. It is one
150
- * mis-routed pick away, and there is no legitimate reason to aim a gizmo at a gizmo, so it is
151
- * refused here rather than trusted to every caller.
152
- */
153
- attach(object: Object3D | null): void {
154
- if (object && !this.contains(object)) this.controls.attach(object);
155
- else this.controls.detach();
156
- }
157
-
158
- /** True if `object` is part of the gizmo's own helper. */
159
- contains(object: Object3D): boolean {
160
- for (let o: Object3D | null = object; o; o = o.parent) if (o === this.helper) return true;
161
- return false;
162
- }
163
-
164
- dispose(): void {
165
- this.controls.detach();
166
- this.scene.remove(this.helper);
167
- this.controls.dispose();
168
- }
169
- }
package/app/globals.d.ts DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * The websocket path, substituted into the page at serve time by the editor's Vite config.
3
- *
4
- * A constant rather than an import because the page and the server share `src/protocol.ts`, and
5
- * `src/` is not published — the package ships `dist` and `app`. Everything else the page borrows
6
- * from that module is a type, which erases; this was the only value, so it comes in through
7
- * `define` and the import can be type-only.
8
- */
9
- declare const __SCENOCO_WS_PATH__: string;
package/app/index.html DELETED
@@ -1,14 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
- <title>SceNoCo editor</title>
7
- <link rel="stylesheet" href="./editor.css" />
8
- </head>
9
- <body>
10
- <canvas id="viewport"></canvas>
11
- <div id="sc-ui"></div>
12
- <script type="module" src="./main.ts"></script>
13
- </body>
14
- </html>