diff --git a/src/core/graph/nodes/data/GetWorldPosition.ts b/src/core/graph/nodes/data/GetWorldPosition.ts new file mode 100644 index 00000000..a2a9cbd0 --- /dev/null +++ b/src/core/graph/nodes/data/GetWorldPosition.ts @@ -0,0 +1,19 @@ +import { worldPositionOf } from '../../NodeContext'; +import type { NodeDef } from '../../NodeRegistry'; +import { asEntity } from '../../values'; +import { num, obj } from '../shared'; + +export const GetWorldPosition: NodeDef = { + type: 'GetWorldPosition', + label: 'Get world position', + category: 'data', + description: 'The position of an object in world units, with every parent added in.', + inputs: [obj('object')], + outputs: [num('x'), num('y')], + params: [], + run: (_ctx, inputs) => { + const target = asEntity(inputs.object); + const world = target ? worldPositionOf(target) : { x: 0, y: 0 }; + return { outputs: { x: world.x, y: world.y } }; + }, +}; diff --git a/src/core/graph/nodes/index.ts b/src/core/graph/nodes/index.ts index 7e2754b1..216b1ebe 100644 --- a/src/core/graph/nodes/index.ts +++ b/src/core/graph/nodes/index.ts @@ -44,6 +44,7 @@ import { FindText } from './data/FindText'; import { FirstNotEmpty } from './data/FirstNotEmpty'; import { Floor } from './data/Floor'; import { GetPosition } from './data/GetPosition'; +import { GetWorldPosition } from './data/GetWorldPosition'; import { GetZ } from './data/GetZ'; import { ChildByName } from './data/ChildByName'; import { Children } from './data/Children'; @@ -201,6 +202,7 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [ IsEnabled, Properties, GetPosition, + GetWorldPosition, GetZ, TextureSize, AnimationPlaying, diff --git a/tests/core/node-catalog.test.ts b/tests/core/node-catalog.test.ts index da103638..fa80a379 100644 --- a/tests/core/node-catalog.test.ts +++ b/tests/core/node-catalog.test.ts @@ -752,6 +752,19 @@ const CASES: Record = { outputs: { x: 0, y: 0, worldX: 0, worldY: 0 }, }, ], + GetWorldPosition: [ + { + name: 'a top-level object is at its own position', + inputs: { object: at('A', 10, 20) }, + outputs: { x: 10, y: 20 }, + }, + { + name: 'a child is at the summed position of its parents', + inputs: { object: { ...at('child', 10, 20), parent: at('parent', 100, 200) } }, + outputs: { x: 110, y: 220 }, + }, + { name: 'no object is the origin', inputs: { object: null }, outputs: { x: 0, y: 0 } }, + ], GetZ: [ { name: 'a child reports its own z and the z summed up with its parents',