@babylonjsmarket/arcade 0.3.8 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components/PinballBuilderInput/PinballBuilderInput.d.ts.map +1 -1
- package/dist/Components/PinballBuilderInput/PinballBuilderInput.js +1 -2
- package/dist/Components/PinballBuilderInput/PinballBuilderInput.js.map +1 -1
- package/package.json +1 -1
- package/src/Components/Flipper/Flipper.viz.tsx +34 -55
- package/src/Components/PinballBuilderInput/PinballBuilderInput.test.ts +4 -6
- package/src/Components/PinballBuilderInput/PinballBuilderInput.ts +1 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinballBuilderInput.d.ts","sourceRoot":"","sources":["../../../src/Components/PinballBuilderInput/PinballBuilderInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAMpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"PinballBuilderInput.d.ts","sourceRoot":"","sources":["../../../src/Components/PinballBuilderInput/PinballBuilderInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAMpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;AAIzE,qBAAa,yBAA0B,SAAQ,MAAM;IACnD,SAAS,CAAC,KAAK;;MAA+C;IAC9D,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,iBAAiB,CAAQ;IAEjC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,QAAQ,CAAuB;IAEvC,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,WAAW,CAA2C;gBAElD,QAAQ,EAAE,QAAQ;IAK9B,SAAS,CAAC,YAAY,IAAI,IAAI;IAW9B,SAAS,CAAC,UAAU,IAAI,IAAI;IAI5B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIrC,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,MAAM;IA0Cd,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,OAAO;CAgBhB;AAED,OAAO,EACL,4BAA4B,EAC5B,KAAK,wBAAwB,GAC9B,MAAM,4BAA4B,CAAA"}
|
|
@@ -55,8 +55,7 @@ export class PinballBuilderInputSystem extends System {
|
|
|
55
55
|
getCanvas() {
|
|
56
56
|
if (this.canvas)
|
|
57
57
|
return this.canvas;
|
|
58
|
-
const
|
|
59
|
-
const c = adapter?.scene?.getEngine().getRenderingCanvas() ?? null;
|
|
58
|
+
const c = this.world?.renderer?.getRenderingCanvas() ?? null;
|
|
60
59
|
this.canvas = c;
|
|
61
60
|
return c;
|
|
62
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinballBuilderInput.js","sourceRoot":"","sources":["../../../src/Components/PinballBuilderInput/PinballBuilderInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7C,OAAO,EACL,yBAAyB,GAG1B,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"PinballBuilderInput.js","sourceRoot":"","sources":["../../../src/Components/PinballBuilderInput/PinballBuilderInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7C,OAAO,EACL,yBAAyB,GAG1B,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;AAIzE,MAAM,OAAO,yBAA0B,SAAQ,MAAM;IACzC,KAAK,GAAG,EAAE,QAAQ,EAAE,CAAC,4BAA4B,CAAC,EAAE,CAAA;IACtD,MAAM,GAA6B,IAAI,CAAA;IACvC,iBAAiB,GAAG,KAAK,CAAA;IAEzB,OAAO,GAAG,KAAK,CAAA;IACf,UAAU,GAAkB,EAAE,CAAA;IAC9B,QAAQ,GAAiB,MAAM,CAAA;IAE/B,aAAa,GAAuC,IAAI,CAAA;IACxD,aAAa,GAAuC,IAAI,CAAA;IACxD,WAAW,GAAuC,IAAI,CAAA;IAE9D,YAAY,QAAkB;QAC5B,KAAK,CAAC,QAAQ,CAAC,CAAA;QACf,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;IACzB,CAAC;IAES,YAAY;QACpB,IAAI,CAAC,MAAM,CACT,yBAAyB,CAAC,aAAa,EACvC,CAAC,GAAuB,EAAE,EAAE;YAC1B,IAAI,GAAG,CAAC,IAAI;gBAAE,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAA;YACtC,IAAI,GAAG,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAA;;gBACzB,IAAI,CAAC,MAAM,EAAE,CAAA;QACpB,CAAC,CACF,CAAA;IACH,CAAC;IAES,UAAU;QAClB,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;IAES,QAAQ,CAAC,GAAW;QAC5B,kBAAkB;IACpB,CAAC;IAEO,WAAW;QACjB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;YAC7C,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,SAAS;QACf,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,CAAA;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,IAAI,CAAA;QAC5D,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QACf,OAAO,CAAC,CAAA;IACV,CAAC;IAEO,MAAM;QACZ,IAAI,IAAI,CAAC,iBAAiB;YAAE,OAAM;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAC9B,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG;YAAE,OAAM;QAE3B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE;YACzB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;YACtC,IAAI,CAAC,CAAC;gBAAE,OAAM;YACd,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;YACnB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAA;YACrB,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YACvC,CAAC,CAAC,cAAc,EAAE,CAAA;QACpB,CAAC,CAAA;QACD,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE;YACzB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAM;YACzB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;YACtC,IAAI,CAAC,CAAC;gBAAE,OAAM;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YACxD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,iBAAiB;gBAAE,OAAM;YAC1E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzB,CAAC,CAAA;QACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAM;YACzB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;YACpB,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YAC3C,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,yBAAyB,CAAC,SAAS,EAAE;oBACtD,MAAM,EAAE,IAAI,CAAC,UAAU;oBACvB,IAAI,EAAE,IAAI,CAAC,QAAQ;iBACpB,CAAC,CAAA;YACJ,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACtB,CAAC,CAAA;QAED,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,aAA8B,CAAC,CAAA;QAC3E,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,aAA8B,CAAC,CAAA;QAC3E,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,WAA4B,CAAC,CAAA;QACvE,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,IAAI,CAAC,WAA4B,CAAC,CAAA;QAC3E,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;IAC/B,CAAC;IAEO,MAAM;QACZ,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAA;YAC9B,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,aAA8B,CAAC,CAAA;QAC3G,IAAI,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,aAA8B,CAAC,CAAA;QAC3G,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,WAA4B,CAAC,CAAA;YAC/E,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,IAAI,CAAC,WAA4B,CAAC,CAAA;QACrF,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QACzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAA;IAChC,CAAC;IAEO,OAAO,CACb,CAAe,EACf,MAAyB,EACzB,GAAiC;QAEjC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAA;QAC9B,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,MAAM,IAAI,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAA;QAC3C,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;QAChC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAA;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE;YACvC,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC;SACzD,CAAC,CAAA;QACF,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QACtB,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAA;IACjC,CAAC;CACF;AAED,OAAO,EACL,4BAA4B,GAE7B,MAAM,4BAA4B,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@babylonjsmarket/arcade",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Reusable arcade-style components (mesh, camera, lights, input, physics, scoring, animation) for the @babylonjsmarket/ecs framework",
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Flipper.viz.tsx — collider-vs-visible-geometry overlay.
|
|
3
3
|
*
|
|
4
|
-
* For every flipper we create a unit-cube wireframe child mesh once
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* For every flipper we create a unit-cube wireframe child mesh once (via the
|
|
5
|
+
* adapter's `createDebugBox`, parented to the flipper mesh), then each frame we
|
|
6
|
+
* read the flipper's CURRENT `colliderInflate` values and scale + position the
|
|
7
|
+
* wire to match the inflated bounds. No mesh recreation; tuning sliders update
|
|
8
|
+
* the wire live as they drag.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Renderer-agnostic: everything goes through `this.world.renderer`
|
|
11
|
+
* (createDebugBox / setMeshScale / setMeshPosition / disposeMesh) — no engine
|
|
12
|
+
* import, no adapter cast.
|
|
12
13
|
*/
|
|
13
14
|
import { Component, System } from '@babylonjsmarket/ecs'
|
|
14
15
|
import type { EventBus, Entity } from '@babylonjsmarket/ecs'
|
|
15
16
|
import type { MeshHandle } from '@babylonjsmarket/ecs/renderer-types'
|
|
16
|
-
import { MeshBuilder, StandardMaterial, Color3, type Mesh, type Scene } from '@babylonjs/core'
|
|
17
17
|
import { FlipperComponent, computeTaperedBounds, inflateBounds } from './Flipper'
|
|
18
18
|
import { MeshPrimitiveComponent } from '../MeshPrimitive/MeshPrimitive'
|
|
19
19
|
|
|
@@ -34,9 +34,9 @@ export class FlipperColliderDebuggerComponent extends Component {
|
|
|
34
34
|
constructor(data: FlipperColliderDebuggerInput = {}) {
|
|
35
35
|
super()
|
|
36
36
|
this.visible = data.visible ?? false
|
|
37
|
-
// This debugger is NOT a vizStore panel (it draws a
|
|
38
|
-
//
|
|
39
|
-
//
|
|
37
|
+
// This debugger is NOT a vizStore panel (it draws a wireframe overlay), so
|
|
38
|
+
// the central viz keyboard handler doesn't manage it — it owns its own
|
|
39
|
+
// toggle key. Default Digit5.
|
|
40
40
|
this.activationKey = data.activationKey ?? 'Digit5'
|
|
41
41
|
this.color = data.color ?? [1, 0.2, 0.9]
|
|
42
42
|
}
|
|
@@ -50,24 +50,17 @@ export class FlipperColliderDebuggerComponent extends Component {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
// Minimum surface the FlipperColliderDebugger needs to grab the Babylon Mesh
|
|
54
|
-
// object from the adapter so it can parent a wireframe child to it.
|
|
55
|
-
type BabylonAdapterLike = {
|
|
56
|
-
getMeshObject: (handle: MeshHandle) => Mesh | undefined
|
|
57
|
-
}
|
|
58
|
-
|
|
59
53
|
interface Overlay {
|
|
60
54
|
entityId: string
|
|
61
55
|
flipper: FlipperComponent
|
|
62
|
-
|
|
63
|
-
wire:
|
|
56
|
+
/** Handle of the wireframe box, parented to the flipper mesh by the adapter. */
|
|
57
|
+
wire: MeshHandle
|
|
64
58
|
}
|
|
65
59
|
|
|
66
60
|
export class FlipperColliderDebuggerSystem extends System {
|
|
67
61
|
protected query = { required: [FlipperColliderDebuggerComponent] }
|
|
68
62
|
private component: FlipperColliderDebuggerComponent | null = null
|
|
69
63
|
private overlays = new Map<string, Overlay>()
|
|
70
|
-
private wireMaterial: StandardMaterial | null = null
|
|
71
64
|
private keydownHandler: ((e: KeyboardEvent) => void) | null = null
|
|
72
65
|
|
|
73
66
|
constructor(eventBus: EventBus) {
|
|
@@ -93,8 +86,6 @@ export class FlipperColliderDebuggerSystem extends System {
|
|
|
93
86
|
|
|
94
87
|
protected onShutdown(): void {
|
|
95
88
|
this.clearOverlays()
|
|
96
|
-
this.wireMaterial?.dispose()
|
|
97
|
-
this.wireMaterial = null
|
|
98
89
|
if (this.keydownHandler) {
|
|
99
90
|
window.removeEventListener('keydown', this.keydownHandler)
|
|
100
91
|
this.keydownHandler = null
|
|
@@ -129,12 +120,13 @@ export class FlipperColliderDebuggerSystem extends System {
|
|
|
129
120
|
|
|
130
121
|
/**
|
|
131
122
|
* Resize + reposition the wire each frame from the flipper's CURRENT
|
|
132
|
-
* `colliderInflate` values. No mesh recreation —
|
|
133
|
-
*
|
|
123
|
+
* `colliderInflate` values. No mesh recreation — a scale + position update is
|
|
124
|
+
* cheap. The box is parented to the flipper mesh, so these are LOCAL.
|
|
134
125
|
*/
|
|
135
126
|
private layoutOverlay(entityId: string, flipper: FlipperComponent): void {
|
|
136
127
|
const o = this.overlays.get(entityId)
|
|
137
|
-
|
|
128
|
+
const renderer = this.world?.renderer
|
|
129
|
+
if (!o || !renderer) return
|
|
138
130
|
const dir = flipper.direction === 'left' ? 1 : -1
|
|
139
131
|
const base = computeTaperedBounds(dir, flipper.length)
|
|
140
132
|
const inflated = inflateBounds(base, flipper.colliderInflate)
|
|
@@ -144,8 +136,8 @@ export class FlipperColliderDebuggerSystem extends System {
|
|
|
144
136
|
const cx = (inflated.max[0] + inflated.min[0]) / 2
|
|
145
137
|
const cy = (inflated.max[1] + inflated.min[1]) / 2
|
|
146
138
|
const cz = (inflated.max[2] + inflated.min[2]) / 2
|
|
147
|
-
o.wire
|
|
148
|
-
o.wire
|
|
139
|
+
renderer.setMeshScale(o.wire, sx, sy, sz)
|
|
140
|
+
renderer.setMeshPosition(o.wire, cx, cy, cz)
|
|
149
141
|
}
|
|
150
142
|
|
|
151
143
|
private buildOverlays(): void {
|
|
@@ -160,43 +152,30 @@ export class FlipperColliderDebuggerSystem extends System {
|
|
|
160
152
|
|
|
161
153
|
private createOverlay(entityId: string, flipper: FlipperComponent): void {
|
|
162
154
|
if (this.overlays.has(entityId)) return
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
const renderer = this.world?.renderer
|
|
156
|
+
if (!renderer) return
|
|
157
|
+
const entity = this.world?.getEntity(entityId)
|
|
165
158
|
const mp = entity?.get(MeshPrimitiveComponent)
|
|
166
159
|
if (!mp?.handle) return
|
|
167
160
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// Unit cube — `layoutOverlay` will scale + position it each frame from
|
|
173
|
-
// the current colliderInflate values. Recreating the geometry per slider
|
|
174
|
-
// tick would be wasteful; scaling is a single transform update.
|
|
175
|
-
const wire = MeshBuilder.CreateBox(
|
|
161
|
+
// Unit cube parented to the flipper mesh — `layoutOverlay` scales +
|
|
162
|
+
// positions it each frame from the current colliderInflate values.
|
|
163
|
+
// Recreating the geometry per slider tick would be wasteful.
|
|
164
|
+
const wire = renderer.createDebugBox(
|
|
176
165
|
`flipper-collider-wire-${entityId}`,
|
|
177
|
-
|
|
178
|
-
|
|
166
|
+
mp.handle,
|
|
167
|
+
this.component?.color ?? [1, 0.2, 0.9],
|
|
179
168
|
)
|
|
180
|
-
wire
|
|
181
|
-
wire.isPickable = false
|
|
182
|
-
wire.material = this.ensureMaterial(parent.getScene())
|
|
169
|
+
if (!wire) return
|
|
183
170
|
|
|
184
|
-
this.overlays.set(entityId, { entityId, flipper,
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private ensureMaterial(scene: Scene): StandardMaterial {
|
|
188
|
-
if (this.wireMaterial) return this.wireMaterial
|
|
189
|
-
const color = this.component?.color ?? [1, 0.2, 0.9]
|
|
190
|
-
const mat = new StandardMaterial('flipper-collider-wire', scene)
|
|
191
|
-
mat.wireframe = true
|
|
192
|
-
mat.emissiveColor = new Color3(color[0], color[1], color[2])
|
|
193
|
-
mat.disableLighting = true
|
|
194
|
-
this.wireMaterial = mat
|
|
195
|
-
return mat
|
|
171
|
+
this.overlays.set(entityId, { entityId, flipper, wire })
|
|
196
172
|
}
|
|
197
173
|
|
|
198
174
|
private clearOverlays(): void {
|
|
199
|
-
|
|
175
|
+
const renderer = this.world?.renderer
|
|
176
|
+
if (renderer) {
|
|
177
|
+
for (const o of this.overlays.values()) renderer.disposeMesh(o.wire)
|
|
178
|
+
}
|
|
200
179
|
this.overlays.clear()
|
|
201
180
|
}
|
|
202
181
|
}
|
|
@@ -10,15 +10,13 @@ const SET_DRAW_MODE = 'pinballBuilder.setDrawMode';
|
|
|
10
10
|
const DRAW_PATH = 'pinballBuilder.drawPath';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Renderer
|
|
13
|
+
* Renderer that hands back a real jsdom canvas via `getRenderingCanvas()` and a
|
|
14
14
|
* pickAtScreenPoint that maps screen X→world (x,z). The system reads the canvas
|
|
15
|
-
*
|
|
15
|
+
* through the adapter (`renderer.getRenderingCanvas()`) — no engine coupling.
|
|
16
16
|
*/
|
|
17
17
|
function makeRenderer(canvas: HTMLCanvasElement, pick: (x: number, y: number) => PickResult | null) {
|
|
18
|
-
const r = new MockRendererAdapter()
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
r.scene = { getEngine: () => ({ getRenderingCanvas: () => canvas }) };
|
|
18
|
+
const r = new MockRendererAdapter();
|
|
19
|
+
r.getRenderingCanvas = vi.fn(() => canvas) as never;
|
|
22
20
|
r.pickAtScreenPoint = vi.fn((x: number, y: number) => pick(x, y)) as never;
|
|
23
21
|
return r;
|
|
24
22
|
}
|
|
@@ -22,15 +22,6 @@ import { PinballBuilderInputComponent } from './PinballBuilderInput.core'
|
|
|
22
22
|
|
|
23
23
|
type PickedPoint = { x: number; z: number }
|
|
24
24
|
|
|
25
|
-
// One remaining renderer coupling: the rendering canvas. Fully abstracting
|
|
26
|
-
// it would require a `renderer.getRenderingCanvas()` method on the adapter
|
|
27
|
-
// interface, which we haven't added yet. Everything else (picks, camera
|
|
28
|
-
// controls, etc.) goes through the RendererAdapter API.
|
|
29
|
-
type BabylonSceneLike = {
|
|
30
|
-
getEngine: () => { getRenderingCanvas: () => HTMLCanvasElement | null }
|
|
31
|
-
}
|
|
32
|
-
type BabylonAdapterLike = { scene?: BabylonSceneLike | null }
|
|
33
|
-
|
|
34
25
|
export class PinballBuilderInputSystem extends System {
|
|
35
26
|
protected query = { required: [PinballBuilderInputComponent] }
|
|
36
27
|
private canvas: HTMLCanvasElement | null = null
|
|
@@ -78,8 +69,7 @@ export class PinballBuilderInputSystem extends System {
|
|
|
78
69
|
|
|
79
70
|
private getCanvas(): HTMLCanvasElement | null {
|
|
80
71
|
if (this.canvas) return this.canvas
|
|
81
|
-
const
|
|
82
|
-
const c = adapter?.scene?.getEngine().getRenderingCanvas() ?? null
|
|
72
|
+
const c = this.world?.renderer?.getRenderingCanvas() ?? null
|
|
83
73
|
this.canvas = c
|
|
84
74
|
return c
|
|
85
75
|
}
|