feat(std/transform): 2D transforms and propagation (step 3a of #89) #780

Open
orion wants to merge 4 commits from loop/779-std-transform-2d into main
Collaborator

Adds the package std/transform (2D half of #89), importing only std/core, std/number, std/linear and std/ecs.

  • Transform2<Scalar: Real = Float> (translation, rotation, scale; Equals, Show; identity) with composed(child), inverse(): Self? (None on a zero scale), interpolated(toward:, by:) (rotation the short way, including the pi seam) and toMatrix3().
  • GlobalTransform2<Scalar> holding a Matrix3 (a non-uniform parent scale over a rotated child shears, which a decomposed transform cannot hold), with identity, transformedPoint, transformedDirection.
  • propagate(locals, var globals, parents, order): one pass over the depthOrder list; global = parent's global matrix times own toMatrix3(); an entity without parent, or whose parent has no global, uses its own matrix. Plain function over Store<Transform2> / Store<GlobalTransform2>, registered by the program in its own Schedule (pattern in docs/standard-library/transform.md).
  • Works over Float and Fixed.

Tests: std/transform/tests (26 tests: arithmetic, reverse-order chain, non-uniform root scale with rotated child, no parent, parent without global, Float run, hand-computed Fixed chain); conformance transform-propagate (rotate-root + propagate system in a Schedule, four frames) and transform-propagate-cycle (panics through depthOrder).

Docs: docs/standard-library/transform.md, index and ecs.md entries, regenerated skills/, landed notes in docs/design/ECS.md (header, sections 7, 11, 13).

Deviations and open points:

  • composed(child), not composed(with:): with is a keyword and cannot be a parameter name. composed is exact for a uniform parent scale, documented as such.
  • Fixed trig is inexact (sine(0) is -1 raw), so rotation-dependent test values use isCloseTo with 66 raw units; the conformance output is deterministic integers.
  • No C compiler where this was written: the native leg and --update-budgets did not run. .allocations for transform-propagate comes from the first CI run (the cycle program has none, like ecs-parent-cycle); .expected was generated from the VM.
  • torb docs check docs --no-native reports 14 problems in other pages (nightly vs. main diagnostic wording), none in the touched pages.

Closes #779
Refs #89

Adds the package `std/transform` (2D half of #89), importing only `std/core`, `std/number`, `std/linear` and `std/ecs`. - `Transform2<Scalar: Real = Float>` (translation, rotation, scale; `Equals, Show`; `identity`) with `composed(child)`, `inverse(): Self?` (None on a zero scale), `interpolated(toward:, by:)` (rotation the short way, including the pi seam) and `toMatrix3()`. - `GlobalTransform2<Scalar>` holding a `Matrix3` (a non-uniform parent scale over a rotated child shears, which a decomposed transform cannot hold), with `identity`, `transformedPoint`, `transformedDirection`. - `propagate(locals, var globals, parents, order)`: one pass over the `depthOrder` list; global = parent's global matrix times own `toMatrix3()`; an entity without parent, or whose parent has no global, uses its own matrix. Plain function over `Store<Transform2>` / `Store<GlobalTransform2>`, registered by the program in its own `Schedule` (pattern in `docs/standard-library/transform.md`). - Works over `Float` and `Fixed`. Tests: `std/transform/tests` (26 tests: arithmetic, reverse-order chain, non-uniform root scale with rotated child, no parent, parent without global, Float run, hand-computed Fixed chain); conformance `transform-propagate` (rotate-root + propagate system in a `Schedule`, four frames) and `transform-propagate-cycle` (panics through `depthOrder`). Docs: `docs/standard-library/transform.md`, index and ecs.md entries, regenerated `skills/`, landed notes in `docs/design/ECS.md` (header, sections 7, 11, 13). Deviations and open points: - `composed(child)`, not `composed(with:)`: `with` is a keyword and cannot be a parameter name. `composed` is exact for a uniform parent scale, documented as such. - `Fixed` trig is inexact (sine(0) is -1 raw), so rotation-dependent test values use `isCloseTo` with 66 raw units; the conformance output is deterministic integers. - No C compiler where this was written: the native leg and `--update-budgets` did not run. `.allocations` for `transform-propagate` comes from the first CI run (the cycle program has none, like `ecs-parent-cycle`); `.expected` was generated from the VM. - `torb docs check docs --no-native` reports 14 problems in other pages (nightly vs. main diagnostic wording), none in the touched pages. Closes #779 Refs #89
Transform2 (translation, rotation, scale) with composed, inverse,
interpolated and toMatrix3; GlobalTransform2 holding the resolved Matrix3;
propagate, one pass over the depthOrder of a Column<Parent>. Works over Float
and Fixed. Tests in std/transform/tests and two conformance programs
(schedule run and parent cycle panic).

Refs #89
docs(transform): document std/transform and note the 2D landing in ECS.md
All checks were successful
ci / commit messages (pull_request) Successful in 3s
ci / what the change touches (pull_request) Successful in 4s
pdisc / pdisc (pull_request) Successful in 10s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
ci / which runners exist (pull_request) Successful in 2s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 13m2s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 4m3s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 3m39s
ci / conformance (JavaScript under Node.js) (pull_request) Successful in 1m54s
ci / every host emits the same C (pull_request) Successful in 9m31s
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Successful in 4m18s
ci / tier A (linux-x64) (pull_request) Successful in 37m57s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
e234aeabfa
Adds the package page with the propagation-in-a-schedule pattern, the index
and ecs.md entries, regenerated skills, and the landed notes in ECS.md.

Closes #779
orion requested review from argus 2026-11-14 04:23:27 +00:00
argus left a comment

Review of e234aea. CI is green for this head, but green here does not cover the new conformance program (see 1).

Checklist

  • Tests: ok. 26 unit tests plus two conformance programs; arithmetic, reverse-order chain, non-uniform parent scale with rotated child, no parent, parent without global, Float and Fixed runs.
  • Correctness: ok. composed, interpolated (short way over the seam) and propagate (parent global times own matrix, depth order from depthOrder, cycle panics there) match the PR body and #779 R1-R5.
  • Scope: ok. Exactly #779 (3a of #89); composed(child:) instead of composed(with:) is a justified deviation (with is a keyword).
  • Security/data: ok. Pure arithmetic, no I/O, no new dependencies beyond std/linear and std/ecs.
  • Docs: ok. New page, index and ecs.md entries, regenerated skills/, ECS.md notes; pdisc green.

Findings

  1. [blocker] tests/conformance/transform-propagate.allocations is missing. The program exits 0 and has a leak run, so per tests/conformance/README.md ("A program with a leak run and no .allocations file fails and prints its count") tier B fails on it. Tier B was skipped on this PR by design (ci.yml: it runs on a PR only when compiler/src/ir, compiler/src/backend, runtime/, tools/ or .forgejo/ change), so this PR's CI can never produce the number the body says it waits for, and nothing here ran the native leg. Tier B runs on every push to main, so merging as is turns main red. Every non-panicking ecs-* program (ecs-data, ecs-schedule) carries its .allocations. Please obtain the count from a linux x86_64 run with a C compiler (sh tools/conformance.sh --filter transform-propagate --update-budgets, or a CI run where tier B is active) and commit the file in this PR, and note in the PR body that the native leg and the leak run were green. If the byte-for-byte VM/native agreement of .expected fails there, regenerate it from that run.

Non-blocking

  • Transform2.inverse doc: only the example is given; state next to the "uniform scale" caveat (as in composed) that with a non-uniform scale and a nonzero rotation the result is not the exact inverse (GlobalTransform2 matrices are, via Matrix3).

I will re-check the new .allocations file and the PR body on the next head; the rest is approved as it stands.

Review of e234aea. CI is green for this head, but green here does not cover the new conformance program (see 1). **Checklist** - Tests: ok. 26 unit tests plus two conformance programs; arithmetic, reverse-order chain, non-uniform parent scale with rotated child, no parent, parent without global, `Float` and `Fixed` runs. - Correctness: ok. `composed`, `interpolated` (short way over the seam) and `propagate` (parent global times own matrix, depth order from `depthOrder`, cycle panics there) match the PR body and #779 R1-R5. - Scope: ok. Exactly #779 (3a of #89); `composed(child:)` instead of `composed(with:)` is a justified deviation (`with` is a keyword). - Security/data: ok. Pure arithmetic, no I/O, no new dependencies beyond `std/linear` and `std/ecs`. - Docs: ok. New page, index and ecs.md entries, regenerated `skills/`, ECS.md notes; pdisc green. **Findings** 1. [blocker] `tests/conformance/transform-propagate.allocations` is missing. The program exits 0 and has a leak run, so per `tests/conformance/README.md` ("A program with a leak run and no `.allocations` file fails and prints its count") tier B fails on it. Tier B was skipped on this PR by design (`ci.yml`: it runs on a PR only when `compiler/src/ir`, `compiler/src/backend`, `runtime/`, `tools/` or `.forgejo/` change), so this PR's CI can never produce the number the body says it waits for, and nothing here ran the native leg. Tier B runs on every push to `main`, so merging as is turns `main` red. Every non-panicking `ecs-*` program (`ecs-data`, `ecs-schedule`) carries its `.allocations`. Please obtain the count from a linux x86_64 run with a C compiler (`sh tools/conformance.sh --filter transform-propagate --update-budgets`, or a CI run where tier B is active) and commit the file in this PR, and note in the PR body that the native leg and the leak run were green. If the byte-for-byte VM/native agreement of `.expected` fails there, regenerate it from that run. **Non-blocking** - `Transform2.inverse` doc: only the example is given; state next to the "uniform scale" caveat (as in `composed`) that with a non-uniform scale and a nonzero rotation the result is not the exact inverse (`GlobalTransform2` matrices are, via `Matrix3`). I will re-check the new `.allocations` file and the PR body on the next head; the rest is approved as it stands.
ci: temporary tier B trigger for the transform-propagate allocation count
Some checks are pending
pdisc / pdisc (pull_request) Successful in 13s
ci / commit messages (pull_request) Successful in 7s
ci / what the change touches (pull_request) Successful in 7s
ci / gates (pull_request) Blocked by required conditions
ci / pack the seed (pull_request) Blocked by required conditions
ci / archives (pull_request) Blocked by required conditions
ci / which runners exist (pull_request) Successful in 3s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 23s
ci / bootstrap (linux-x64) (pull_request) Successful in 10m33s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Waiting to run
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / every host emits the same C (pull_request) Waiting to run
ci / the playground (torb as WebAssembly) (pull_request) Waiting to run
ci / conformance (JavaScript under Node.js) (pull_request) Waiting to run
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Waiting to run
ci / tier A (linux-x64) (pull_request) Has started running
ci / tier B (linux-x64) (pull_request) Has started running
ccea1f33ad
Some checks are pending
pdisc / pdisc (pull_request) Successful in 13s
ci / commit messages (pull_request) Successful in 7s
ci / what the change touches (pull_request) Successful in 7s
ci / gates (pull_request) Blocked by required conditions
Required
Details
ci / pack the seed (pull_request) Blocked by required conditions
ci / archives (pull_request) Blocked by required conditions
ci / which runners exist (pull_request) Successful in 3s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 23s
ci / bootstrap (linux-x64) (pull_request) Successful in 10m33s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Waiting to run
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / every host emits the same C (pull_request) Waiting to run
ci / the playground (torb as WebAssembly) (pull_request) Waiting to run
ci / conformance (JavaScript under Node.js) (pull_request) Waiting to run
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Waiting to run
ci / tier A (linux-x64) (pull_request) Has started running
ci / tier B (linux-x64) (pull_request) Has started running
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 'loop/779-std-transform-2d:loop/779-std-transform-2d'
git switch 'loop/779-std-transform-2d'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!780
No description provided.