feat(picking)!: sprite & billboard picking (pickSprite2D + pickBillboardSprite)#341
feat(picking)!: sprite & billboard picking (pickSprite2D + pickBillboardSprite)#341VicenteCartas wants to merge 12 commits into
pickSprite2D + pickBillboardSprite)#341Conversation
API ChangesAPI Extractor detected public API changes for No removed public API lines were detected; this appears to be additive. API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 873e78f3..68e1a7b1 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -586,6 +586,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3615,6 +3623,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3660,6 +3671,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5269,6 +5283,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
There was a problem hiding this comment.
Pull request overview
This PR adds sprite picking to Babylon Lite for both sprite families: a CPU-based pickSprite2D for Sprite2DLayer HUD/pure-2D sprites and a GPU-based pickBillboardSprite that integrates billboard picking into the existing 1×1 mesh picking pass (respecting occlusion). It also wires the Freeciv demo to use the new 2D picker, adds new parity scenes (117/118), and introduces unit/plumbing tests plus supporting lab/docs updates.
Changes:
- Add
pickSprite2D(CPU) +pickBillboardSprite(GPU) and export them from the package root. - Integrate billboard systems into
gpu-pickervia a dynamically importedbillboard-pick-pipeline. - Add new test coverage (unit + Playwright plumbing + parity scenes) and update lab/demo/docs/bundle manifests accordingly.
Reviewed changes
Copilot reviewed 62 out of 64 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/lite/unit/picking-discard-api.test.ts | Updates picker scene stub to include _billboardSystems. |
| tests/lite/unit/pick-sprite-2d.test.ts | Unit tests for pickSprite2D behavior (pivot/rotation/ordering/visibility). |
| tests/lite/unit/billboard-pick.test.ts | Unit tests for UBO packing and billboard-system scene registry behavior. |
| tests/lite/plumbing/billboard-pick.spec.ts | Playwright GPU plumbing test for billboard picking hit/occlusion/miss. |
| tests/lite/parity/scenes/scene118-billboard-picking.spec.ts | Parity test for billboard picking scene 118. |
| tests/lite/parity/scenes/scene117-sprite-2d-picking.spec.ts | Parity test for 2D sprite picking scene 117. |
| tests/lite/parity/bundle-size.spec.ts | Adds 117/118 to sprite-using allowlist for bundle-size validation. |
| scene-config.json | Adds scenes 117/118 and updates bundle ceilings for select scenes. |
| packages/babylon-lite/src/sprite/sprite-2d.ts | Clarifies pickable doc comment (API compat; not yet used by picker). |
| packages/babylon-lite/src/sprite/picking/pick-sprite-2d.ts | Implements CPU hit-testing for 2D sprites (reverse draw order, pivot/rotation inversion). |
| packages/babylon-lite/src/sprite/picking/pick-billboard.ts | Adds public async wrapper to pick billboard sprites via the GPU picker. |
| packages/babylon-lite/src/sprite/billboard-scene.ts | Registers billboard systems on the scene for picker iteration. |
| packages/babylon-lite/src/scene/scene-core.ts | Adds _billboardSystems to SceneContext lifecycle (init/dispose). |
| packages/babylon-lite/src/picking/picking-info.ts | Extends PickingInfo with internal _spritePick payload. |
| packages/babylon-lite/src/picking/gpu-picker.ts | Integrates billboard picking into the shared GPU pick pass + disposal path. |
| packages/babylon-lite/src/picking/billboard-pick-pipeline.ts | Implements dynamic-imported billboard GPU picking pipeline (draw/resolve/resources). |
| packages/babylon-lite/src/index.ts | Exports new picking APIs and result types from package root. |
| lab/vite.config.ts | Serves new billboard-pick test HTML and sets MIME types for .spec/.tilespec. |
| lab/public/bundle/manifest/scene86.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene72.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene59.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene49.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene48.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene43.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene244.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene240.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene224.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene222.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene221.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene216.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene206.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene201.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene2.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene19.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene177.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene158.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene147.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene129.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene118.json | Adds new scene 118 bundle manifest. |
| lab/public/bundle/manifest/scene117.json | Adds new scene 117 bundle manifest. |
| lab/public/bundle/manifest/scene115.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene114.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene113.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene110.json | Updates measured bundle runtime sizes/chunks. |
| lab/public/bundle/manifest/scene100.json | Updates measured bundle runtime sizes/chunks. |
| lab/lite/src/lite/scene118.ts | New Lite parity scene implementing billboard sprite picking visualization. |
| lab/lite/src/lite/scene117.ts | New Lite parity scene implementing 2D sprite picking visualization. |
| lab/lite/src/demos/freeciv/live.ts | Adds hitScout using pickSprite2D for unit selection hit-testing. |
| lab/lite/src/demos/freeciv.ts | Uses sprite picking for scout selection and passes world coords through controls. |
| lab/lite/src/bjs/scene118.ts | Babylon.js oracle for scene 118 using scene.pickSprite. |
| lab/lite/src/bjs/scene117.ts | Babylon.js oracle for scene 117 rendering deterministic highlight (no 2D pick API). |
| lab/lite/src/billboard-pick-test.ts | Standalone GPU billboard picking test harness for plumbing spec. |
| lab/lite/scene118.html | Adds lab HTML entry for scene 118. |
| lab/lite/scene117.html | Adds lab HTML entry for scene 117. |
| lab/lite/bundle-scene118.html | Adds bundle HTML entry for scene 118. |
| lab/lite/bundle-scene117.html | Adds bundle HTML entry for scene 117. |
| lab/lite/bundle-bjs-scene118.html | Adds Babylon.js bundle HTML entry for scene 118. |
| lab/lite/bundle-bjs-scene117.html | Adds Babylon.js bundle HTML entry for scene 117. |
| lab/lite/billboard-pick-test.html | Adds lab HTML entry for GPU billboard pick plumbing test. |
| lab/lite/babylon-ref-scene118.html | Adds Babylon.js reference HTML entry for scene 118. |
| lab/lite/babylon-ref-scene117.html | Adds Babylon.js reference HTML entry for scene 117. |
| docs/lite/architecture/32-sprites.md | Updates sprite architecture docs to reflect exported picking APIs and design. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
Lab - Static SiteBuild 20260630.3 - merge @ b838194 |
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 873e78f3..21e45470 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -586,6 +586,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3615,6 +3623,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3660,6 +3671,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5127,7 +5141,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5269,6 +5282,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
pickSprite2D + pickBillboardSprite)pickSprite2D + pickBillboardSprite)
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 873e78f3..21e45470 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -586,6 +586,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3615,6 +3623,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3660,6 +3671,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5127,7 +5141,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5269,6 +5282,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
pickSprite2D + pickBillboardSprite)pickSprite2D + pickBillboardSprite)
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 873e78f3..21e45470 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -586,6 +586,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3615,6 +3623,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3660,6 +3671,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5127,7 +5141,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5269,6 +5282,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
Lab - Static SiteBuild 20260630.7 - merge @ fc28ed4 |
sebavan
left a comment
There was a problem hiding this comment.
0.3k in quite a few scenes sounds like a meaningfull change ?
I was thinking the same. Generally speaking, any time we have entity type specific code (e.g. code to deal with billboards) inside code that needs to deal with many entity types (scene-core.ts or gpu-picker.ts), then that code will grow in size with the number of entities. I think usually we want to avoid this, and we often do through light weight abstractions like RenderContext. Can we do something similar here? Like don't force new billboard specific code into gpu-picker for example, but instead have some kind of light weight abstraction, and only when you are actually using billboards would a handler for that entity type be added? |
|
Chatted with Ryan, moving to draft until we can figure out a better way to handle the multiple different entities that may require picking but may not be in the scene in a better way than adding ifs. |
noUncheckedIndexedAccess flags a[i]/b[i] as possibly undefined; the tuple elements are always defined for i in [0,3). Add non-null assertions so the lint gate (tsc) passes.
…ypes gpu-picker.ts and scene-core.ts no longer contain billboard- or GS-specific code. Optional pickable entities (billboard systems, GS meshes) register a PickContributor (draw + resolve) when added to the scene; the picker draws meshes itself, then iterates scene._pickContributors with no entity-type knowledge. A single _pickContributors array replaces the _billboardSystems and _gsMeshes registries; per-picker GPU pick state is cached on picker._contributorState (GUIDANCE forbids module-level maps) and disposed generically. Heavy pick pipelines stay behind lazy imports registered by the lightweight scene-wiring modules, so pay-for-use is preserved and the shared picker shrank for every picker scene (mesh -0.5 to -0.6 KB, billboard -0.5 KB; 2D/GS neutral). Behaviour-preserving: all picking parity tests unchanged (MAD identical). Ceilings 115/118 re-tightened to the new sizes.
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index b97f112d..0a05cd23 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -589,6 +589,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3649,6 +3657,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3694,6 +3705,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5166,7 +5180,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5308,6 +5321,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index e50c3542..ee876d48 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -589,6 +589,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3658,6 +3666,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3703,6 +3714,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5185,7 +5199,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5327,6 +5340,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index e50c3542..ee876d48 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -589,6 +589,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3658,6 +3666,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3703,6 +3714,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5185,7 +5199,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5327,6 +5340,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
…ick code Register a lazy factory thunk at entity-add time instead of an eager contributor. The thunk reaches the pick pipeline only through a dynamic import, so billboard and GS rendering pull zero pick-pipeline bytes; the picker builds and caches each contributor on the first pick. Restores pay-for-use: billboard/GS render scenes drop back to master sizes (reverts the 4 GS ceiling bumps) while gpu-picker stays entity-type-agnostic. draw() is now sync and the factory async, with an optional dispose(); gs-pick-contributor.ts folded into gs-picking-pipeline. Regenerated 26 manifests. Addresses ryantrem and sebavan review feedback.
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 1042a4ff..b7919f2d 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -589,6 +589,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3666,6 +3674,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3711,6 +3722,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5196,7 +5210,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5338,6 +5351,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
API ChangesAPI Extractor detected public API changes for Potentially breaking changes detected. Removed or changed public API lines:
API Extractor diffdiff --git a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
index 1042a4ff..b7919f2d 100644
--- a/home/vsts/work/1/s/test-results/api-report/target/temp/babylon-lite.api.md
+++ b/home/vsts/work/1/s/test-results/api-report/current/temp/babylon-lite.api.md
@@ -589,6 +589,14 @@ export type BillboardDepthMode = "transparent" | "cutout";
// @public
export type BillboardOrientation = "facing" | "axis-locked";
+// @public
+export interface BillboardPickInfo {
+ distance: number;
+ pickedPoint: [number, number, number] | null;
+ spriteIndex: number;
+ system: BillboardSpriteSystem;
+}
+
// @public
export interface BillboardSpriteHandle {
// (undocumented)
@@ -3666,6 +3674,9 @@ export interface PhysicsWorld {}
// @public
export function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
+// @public
+export function pickBillboardSprite(scene: SceneContext, x: number, y: number): Promise<BillboardPickInfo | null>;
+
// @public
export interface PickDiscardRule {
readonly key: string;
@@ -3711,6 +3722,9 @@ export interface PickOptions {
filter?: (mesh: Mesh) => boolean;
}
+// @public
+export function pickSprite2D(layers: ReadonlyArray<Sprite2DLayer>, xPx: number, yPx: number): SpritePickInfo | null;
+
// @public
export interface PixelsTexture2DOptions {
addressModeU?: GPUAddressMode;
@@ -5196,7 +5210,6 @@ export interface Sprite2DProps {
flipY?: boolean;
// (undocumented)
frame?: number;
- pickable?: boolean;
// (undocumented)
positionPx: [number, number];
// (undocumented)
@@ -5338,6 +5351,15 @@ export interface SpriteFrameAnimation {
to: number;
}
+// @public
+export interface SpritePickInfo {
+ layer: Sprite2DLayer;
+ spriteIndex: number;
+ u: number;
+ // (undocumented)
+ v: number;
+}
+
// @public
export interface SpriteRenderer extends RenderingContext_2 {
readonly layers: readonly Sprite2DLayer[]; |
Bundle Size ChangesIncreases
Sizes rounded to nearest KB. Run |
Summary
Adds picking for both sprite families, bringing Lite to parity with Babylon's
scene.pickSprite(x, y):pickSprite2D(layers, xPx, yPx)— a pure-CPU hit test forSprite2DLayersprites (HUD / pure-2D). Walks layers in reverse draw order and inverts each sprite's pivot + rotation, so it reports exactly the sprite the GPU drew underthe point. No GPU pass, no scene/camera required.
pickBillboardSprite(scene, xPx, yPx)— a GPU picker for world-space*BillboardSpriteSystemsprites. Billboards are drawn into the same 1×1 depth-sorted pass the mesh picker uses, so a billboard occluded by a mesh (or a nearer billboard) correctly loses the pick.Previously the engine had no sprite-picking primitive at all — the Freeciv demo had to hand-roll tile selection from analytic grid math. This ships the real primitive and wires the demo to it.
Public API
Design
be picked in the shared GPU pass to respect occlusion.
picking/billboard-pick-pipeline.ts.gpu-picker.tskeeps only a thin guarded dispatch (if (scene._billboardSystems.length) …), exactly like the existing Gaussian-splatting picking path. A mesh-only or billboard-free picker scene fetches zero billboard-pick bytes (verified: the chunk is built but never inruntimeChunks). 2DpickSprite2Dlives in its own folder and tree-shakes away unless called.scene._billboardSystemsregistry (mirroring_gsMeshes), so visual parity cannot move.Demo
The Freeciv demo now selects the scout via
pickSprite2Dagainst its sprite (which overhangs its tile and slides between tiles mid-hop), while the move destination keeps the analytic tile inversion — each technique used where it fits. Also fixes the lab dev server serving.spec/.tilespectileset files (they were falling through to the SPA HTML fallback).Lab scenes
Two new parity scenes alongside the existing picking scenes (113–115):
pickSprite2D, MAD 0.005)pickBillboardSpritevs BJSscene.pickSprite, MAD 0.041)Tests
pick-sprite-2d.test.ts(11),billboard-pick.test.ts(5).billboard-pick.spec.ts— real-WebGPU hit / occlusion / miss.gpu-pickerrefactor is non-regressing.Bundle size
The shared
gpu-pickerdispatch glue grows picker scenes by ~+0.3 KB raw / +0.1 KB gzip (consistent with the existing GS-picking pattern; billboard code itself is 0 bytes unless a scene uses billboards). Three picker-scene ceilings bumped to absorb this natural growth.bundle-size.spec.ts'sSPRITE_USING_IDSallowlist gains 117 / 118 (they legitimately load sprite modules).Notes / follow-ups
Sprite2DProps.pickableis accepted for API compatibility but not yet consultedby
pickSprite2D(every visible sprite is pickable) — a future enhancement.scene.pickSpriteremains a separate follow-up.BillboardPickInfo).BREAKING CHANGE: removed the unused optional
pickablefield fromSprite2DProps. It was accepted but never read (every visible sprite is pickable); delete it from any call sites.