Add a Texture tab for defining frames
A new Texture tab next to Scene/Game/Graph shows a texture sheet and lets frames be drawn on it: drag to create, move, resize via eight handles, edit name and rect in the inspector, Delete to remove. Every change is a command, so one gesture is one undo step. "Slice..." cuts a grid from columns and rows with optional offset and spacing, previewing the resulting frame count and cell size live. Sprites pick a frame instead of the whole texture through the same `texture` property: it now holds either a texture id or a frame id. Frame ids come from the same generator and are document-wide unique, so one picker, one property and one set of instance overrides cover both cases, and every sprite written before this still means the same thing. A Graphics fill ignores a Pixi sub-texture's frame and draws the whole image, because it derives its uvs from the shape bounds and the inverted style matrix. The cutout is therefore a matrix (`viewport/textureFill.ts`), which keeps a sheet at a single GPU upload no matter how many of its frames are on screen at once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5a6af74e44
commit
35a1a23af8
29 files changed
+2650
-53
No files matched your search
+12
-3
@@ -1,6 +1,6 @@
|
||||
import { type Application, type Container, Rectangle, Text } from 'pixi.js';
|
||||
import { ui, Widget } from '../ui';
|
||||
import type { Editor } from './Editor';
|
||||
import type { CentreTab, Editor } from './Editor';
|
||||
import type { EditorState } from './state';
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@ import type { EditorState } from './state';
|
||||
* visible text and to read editor state. Read-only access; harmless in production.
|
||||
*/
|
||||
export function installDebugHook(app: Application, state: EditorState, editor: Editor): void {
|
||||
const { viewport, gameView, graphEditor, hierarchy } = editor;
|
||||
const { viewport, gameView, graphEditor, textureEditor, hierarchy } = editor;
|
||||
const centreOf = (widget: { getGlobalPosition(): { x: number; y: number }; w: number; h: number }) => {
|
||||
const p = widget.getGlobalPosition();
|
||||
return { x: p.x + widget.w / 2, y: p.y + widget.h / 2 };
|
||||
@@ -81,6 +81,15 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
nodeAt: (nodeId: string) => graphEditor.nodeGlobal(nodeId),
|
||||
center: () => centreOf(graphEditor),
|
||||
},
|
||||
texture: {
|
||||
current: () => textureEditor.currentAssetId,
|
||||
/**
|
||||
* Where an image pixel of the shown sheet sits on screen. Frames are dragged in image
|
||||
* coordinates, so without this a check could only drag somewhere and hope – it could not
|
||||
* aim at a known part of the picture and then assert which part came out.
|
||||
*/
|
||||
pointAt: (x: number, y: number) => textureEditor.imageToScreen(x, y),
|
||||
},
|
||||
world: () => editor.worldSnapshot(),
|
||||
/** Rows the hierarchy shows – collapsed subtrees are not in here. */
|
||||
hierarchyOrder: () => hierarchy.rowOrder(),
|
||||
@@ -103,6 +112,6 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
},
|
||||
fps: () => editor.fps,
|
||||
tab: () => editor.tab,
|
||||
showTab: (tab: 'scene' | 'graph' | 'game') => editor.showTab(tab),
|
||||
showTab: (tab: CentreTab) => editor.showTab(tab),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user