Files
feuerwerk/src/core/graph/nodes/index.ts
T
adminandClaude Opus 5.5 ef2600493f Read the pixel size of a texture in a graph (#262)
A graph had no way to know how big a picture is. An icon sprite with a
fixed size therefore stretched every icon of another size, an 8x8
pixel-art icon in a 16x16 slot was drawn twice as big.

- New data node Texture size. It takes a texture, a frame or a pixel
  art and hands out width and height in pixels, 0 x 0 for none.
  Wired into a sprite's width and height, the picture shows pixel for
  pixel.
- GraphLookup gets textureSize. The project answers it with the same
  pictureSize rule a sprite uses to size itself.

Tests:

- ./check.sh: 2749 tests, CHECK EXIT 0.
- 2 catalog cases (a picture, no picture) and one test against a real
  project: pixel-art sheet, single frame, missing texture.
- No e2e check and no counter-check for this node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 06:01:27 +02:00

287 lines
7.8 KiB
TypeScript

import { type NodeDef, registerNode } from '../NodeRegistry';
import { Destroy } from './action/Destroy';
import { PauseAnimation, PlayAnimation, StopAnimation } from './action/animationNodes';
import { Emit } from './action/Emit';
import { IsGamePaused, PauseGame, ResumeGame, SetTimeScale, TimeScale } from './action/gameTimeNodes';
import { LoadScene } from './action/LoadScene';
import { Log } from './action/Log';
import { IgnoreOneWay } from './action/IgnoreOneWay';
import { Move } from './action/Move';
import {
ApplyForce,
ApplyImpulse,
GetVelocity,
SetAngularVelocity,
SetGravity,
SetVelocity,
} from './action/physicsNodes';
import { PlaySound } from './action/PlaySound';
import { Raycast } from './action/Raycast';
import { RaycastAll } from './action/RaycastAll';
import { RestartGame } from './action/RestartGame';
import { SetPosition } from './action/SetPosition';
import { Spawn } from './action/Spawn';
import { StopGame } from './action/StopGame';
import { StopSound } from './action/StopSound';
import { CellToWorld, SetTile, TileAt, TileLiteral, WorldToCell } from './action/tileNodes';
import { Abs } from './data/Abs';
import { Add } from './data/Add';
import { And } from './data/And';
import { AxisInput } from './data/AxisInput';
import { Ceil } from './data/Ceil';
import { Clamp } from './data/Clamp';
import { Compare } from './data/Compare';
import { Distance } from './data/Distance';
import { Divide } from './data/Divide';
import { Equals } from './data/Equals';
import { FindText } from './data/FindText';
import { FirstNotEmpty } from './data/FirstNotEmpty';
import { Floor } from './data/Floor';
import { GetPosition } from './data/GetPosition';
import { ChildByName } from './data/ChildByName';
import { Children } from './data/Children';
import { ChildrenByName } from './data/ChildrenByName';
import { IsAsset } from './data/IsAsset';
import { IsEnabled } from './data/IsEnabled';
import { IsHovered } from './data/IsHovered';
import { IsInState } from './data/IsInState';
import { IsTouching } from './data/IsTouching';
import { Join } from './data/Join';
import { KeyIsDown } from './data/KeyIsDown';
import { Length } from './data/Length';
import { Lerp } from './data/Lerp';
import {
AnimationLiteral,
AssetLiteral,
BooleanLiteral,
ListLiteral,
NumberLiteral,
SceneLiteral,
SoundLiteral,
StateMachineLiteral,
StringLiteral,
TextureLiteral,
} from './data/literals';
import { Max } from './data/Max';
import { Min } from './data/Min';
import { Modulo } from './data/Modulo';
import { MouseButton } from './data/MouseButton';
import { MousePosition } from './data/MousePosition';
import { Multiply } from './data/Multiply';
import { NameOf } from './data/NameOf';
import { Normalize } from './data/Normalize';
import { Not } from './data/Not';
import { ObjectByName } from './data/ObjectByName';
import { ObjectsByName } from './data/ObjectsByName';
import { ObjectsOfAsset } from './data/ObjectsOfAsset';
import { Or } from './data/Or';
import { Owner } from './data/Owner';
import { PackStruct } from './data/PackStruct';
import { Properties } from './data/Properties';
import { Parent } from './data/Parent';
import { Random } from './data/Random';
import { Round } from './data/Round';
import { Select } from './data/Select';
import { Self } from './data/Self';
import { Sqrt } from './data/Sqrt';
import { Substring } from './data/Substring';
import { Subtract } from './data/Subtract';
import { Time } from './data/Time';
import { ToNumber } from './data/ToNumber';
import { ToText } from './data/ToText';
import { AddItem } from './data/AddItem';
import { Concat } from './data/Concat';
import { Count } from './data/Count';
import { CurrentState } from './data/CurrentState';
import { ExpandStruct } from './data/ExpandStruct';
import { Fill } from './data/Fill';
import { IndexOf } from './data/IndexOf';
import { ItemAt } from './data/ItemAt';
import { SetItem } from './data/SetItem';
import { SubList } from './data/SubList';
import { TextureSize } from './data/TextureSize';
import { OnAnimationFinished } from './events/OnAnimationFinished';
import { OnClick } from './events/OnClick';
import { OnCollisionEnter } from './events/OnCollisionEnter';
import { OnCollisionExit } from './events/OnCollisionExit';
import { OnCollisionStay } from './events/OnCollisionStay';
import { OnDestroy } from './events/OnDestroy';
import { OnDisable } from './events/OnDisable';
import { OnEnable } from './events/OnEnable';
import { OnKeyDown } from './events/OnKeyDown';
import { OnKeyHeld } from './events/OnKeyHeld';
import { OnKeyUp } from './events/OnKeyUp';
import { OnStart } from './events/OnStart';
import { OnStateEntered } from './events/OnStateEntered';
import { OnStateExited } from './events/OnStateExited';
import { OnTimer } from './events/OnTimer';
import { OnUpdate } from './events/OnUpdate';
import { BehaviorEnd } from './flow/BehaviorEnd';
import { BehaviorStart } from './flow/BehaviorStart';
import { Branch } from './flow/Branch';
import { Find } from './flow/Find';
import { ForEach } from './flow/ForEach';
import { Match } from './flow/Match';
import { Repeat } from './flow/Repeat';
import { RunBehavior } from './flow/RunBehavior';
import { Sequence } from './flow/Sequence';
import { SetState } from './flow/SetState';
import { SetStateByName } from './flow/SetStateByName';
import { StateBranch } from './flow/StateBranch';
import { StateTransition } from './flow/StateTransition';
import { PARTICLE_NODES } from '../../particles/nodes';
import { SHADER_NODES } from '../../shader/nodes';
import { State } from '../stateMachine';
import { Variables } from './variable/Variables';
/**
* Importing this module registers the built-in nodes. The palette sorts by category and label, so
* the order here is documentation only.
*/
export const BUILT_IN_NODES: readonly NodeDef[] = [
OnStart,
OnEnable,
OnUpdate,
OnDisable,
OnDestroy,
OnKeyDown,
OnKeyUp,
OnKeyHeld,
OnTimer,
OnCollisionEnter,
OnCollisionStay,
OnCollisionExit,
OnClick,
OnAnimationFinished,
OnStateEntered,
OnStateExited,
BehaviorStart,
Branch,
Sequence,
Repeat,
ForEach,
Find,
Match,
RunBehavior,
StateBranch,
SetState,
SetStateByName,
StateTransition,
CurrentState,
IsInState,
BehaviorEnd,
Variables,
Self,
Owner,
Parent,
ObjectByName,
ObjectsByName,
ChildByName,
ChildrenByName,
Children,
NameOf,
IsAsset,
ObjectsOfAsset,
IsEnabled,
Properties,
GetPosition,
TextureSize,
NumberLiteral,
BooleanLiteral,
StringLiteral,
TextureLiteral,
StateMachineLiteral,
SoundLiteral,
SceneLiteral,
AnimationLiteral,
AssetLiteral,
Add,
Subtract,
Multiply,
Divide,
Min,
Max,
Abs,
Sqrt,
Clamp,
Lerp,
Floor,
Ceil,
Round,
Modulo,
Random,
Time,
ToText,
ToNumber,
Join,
Substring,
FindText,
Equals,
Compare,
FirstNotEmpty,
Select,
And,
Or,
Not,
ListLiteral,
Fill,
Count,
ItemAt,
SetItem,
AddItem,
SubList,
Concat,
IndexOf,
PackStruct,
ExpandStruct,
Length,
Distance,
Normalize,
AxisInput,
KeyIsDown,
MousePosition,
MouseButton,
IsHovered,
IsTouching,
Move,
SetPosition,
GetVelocity,
ApplyForce,
ApplyImpulse,
SetVelocity,
SetAngularVelocity,
SetGravity,
Raycast,
RaycastAll,
IgnoreOneWay,
TileAt,
SetTile,
WorldToCell,
CellToWorld,
TileLiteral,
Spawn,
Destroy,
Emit,
PlayAnimation,
PauseAnimation,
StopAnimation,
PlaySound,
StopSound,
LoadScene,
Log,
StopGame,
RestartGame,
PauseGame,
ResumeGame,
IsGamePaused,
SetTimeScale,
TimeScale,
];
for (const def of BUILT_IN_NODES) registerNode(def);
// Registered so a machine's, a shader's or a particle graph loads and draws, but not built in: no
// behavior graph offers them.
registerNode(State);
for (const def of SHADER_NODES) registerNode(def);
for (const def of PARTICLE_NODES) registerNode(def);