@combos-fun/plugin-renderer-3d 0.0.39 → 0.0.40
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/agent-skill.md +23 -13
- package/combos-plugin.json +4 -1
- package/dist/plugin-renderer-3d.cjs.js +64 -21
- package/dist/plugin-renderer-3d.cjs.js.map +1 -1
- package/dist/plugin-renderer-3d.cjs.prod.js +1 -1
- package/dist/plugin-renderer-3d.d.ts +13 -6
- package/dist/plugin-renderer-3d.esm.js +61 -24
- package/dist/plugin-renderer-3d.esm.js.map +1 -1
- package/package.json +1 -1
package/agent-skill.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@combos-fun/plugin-renderer-3d` — Agent notes
|
|
2
2
|
|
|
3
|
-
3D rendering foundation for Combos Fun. Wraps Three.js (`three` ^0.172) and exposes `Renderer3DSystem`, the `Renderer3D` base class, and a `ThreeContext` that owns the Three.js scene / camera / lights / WebGL renderer / `Clock
|
|
3
|
+
3D rendering foundation for Combos Fun. Wraps Three.js (`three` ^0.172) and exposes `Renderer3DSystem`, the `Renderer3D` base class, and a `ThreeContext` that owns the Three.js scene / camera / lights / WebGL renderer / `Clock`.
|
|
4
4
|
|
|
5
5
|
## When to read
|
|
6
6
|
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
Renderer3D,
|
|
15
15
|
Renderer3DManager,
|
|
16
16
|
ThreeContext,
|
|
17
|
+
tagObject3D,
|
|
18
|
+
requireNamedResource,
|
|
19
|
+
textureFromNamedImage,
|
|
17
20
|
} from '@combos-fun/plugin-renderer-3d';
|
|
18
21
|
```
|
|
19
22
|
|
|
@@ -26,7 +29,7 @@ import {
|
|
|
26
29
|
| `canvas` | `HTMLCanvasElement?` | — |
|
|
27
30
|
| `container` | `HTMLElement?` | — |
|
|
28
31
|
| `width` | `number` | `750` |
|
|
29
|
-
| `height` | `number` | `
|
|
32
|
+
| `height` | `number` | `1334` |
|
|
30
33
|
| `antialias` | `boolean` | `true` |
|
|
31
34
|
| `backgroundColor` | `number` | `0x000000` |
|
|
32
35
|
| `backgroundAlpha` | `number` | `1` |
|
|
@@ -40,7 +43,7 @@ Either `canvas` or `container` must be provided.
|
|
|
40
43
|
- `PerspectiveCamera` (FOV 75, z=5)
|
|
41
44
|
- `AmbientLight` (`0xffffff`, intensity `0.6`)
|
|
42
45
|
- `DirectionalLight` (`0xffffff`, intensity `0.8`, position `(5, 10, 7.5)`)
|
|
43
|
-
- `WebGLRenderer`, `Clock
|
|
46
|
+
- `WebGLRenderer`, `Clock`
|
|
44
47
|
|
|
45
48
|
There are **no separate camera or light plugins** — these come for free.
|
|
46
49
|
|
|
@@ -57,6 +60,7 @@ class MyRenderer3D extends Renderer3D {
|
|
|
57
60
|
componentChanged(changed) {
|
|
58
61
|
const scene = this.threeContext.scene;
|
|
59
62
|
/* create / update / dispose THREE.Object3D under scene */
|
|
63
|
+
tagObject3D(object3d, changed.gameObject.id);
|
|
60
64
|
}
|
|
61
65
|
rendererUpdate(gameObject) {
|
|
62
66
|
/* per-frame sync */
|
|
@@ -64,6 +68,14 @@ class MyRenderer3D extends Renderer3D {
|
|
|
64
68
|
}
|
|
65
69
|
```
|
|
66
70
|
|
|
71
|
+
Always call `tagObject3D(object, gameObject.id)` so `plugin-renderer-3d-event` can raycast the mesh.
|
|
72
|
+
|
|
73
|
+
### Named resources (same as 2D)
|
|
74
|
+
|
|
75
|
+
3D `Img3D` / `Model3D` / `TilingSprite3D` / `SpriteAnimation3D` take an engine **resource name**. Register with `resource.addResource` (`RESOURCE_TYPE.IMAGE` / `MODEL` / `SPRITE_ANIMATION`). Put CDN URLs in `src`, not on the component. A missing name throws; there is no `http` / `./` / `/` fallback.
|
|
76
|
+
|
|
77
|
+
Use `requireNamedResource(name)` and `textureFromNamedImage(name)` from this package. 3D image systems read `data.image` (and `data.json` for spritesheets) so they do not overwrite 2D Pixi `registerInstance(IMAGE)`.
|
|
78
|
+
|
|
67
79
|
### Async loading pattern
|
|
68
80
|
|
|
69
81
|
For 3D plugins that load assets (`Img3D`, `Model3D`, etc.) use the inherited helpers to drop stale work when a component is removed mid-load:
|
|
@@ -79,14 +91,15 @@ This prevents memory leaks and double-add bugs when the same `GameObject` is re-
|
|
|
79
91
|
|
|
80
92
|
## Required setup
|
|
81
93
|
|
|
82
|
-
`Renderer3DSystem` **must** be the first system added before any 3D sub-system that calls `getSystem(Renderer3DSystem)` in `init`.
|
|
94
|
+
`Renderer3DSystem` **must** be the first system added before any 3D sub-system that calls `getSystem(Renderer3DSystem)` in `init`. For taps, also register `Event3DSystem` from `@combos-fun/plugin-renderer-3d-event`.
|
|
83
95
|
|
|
84
96
|
```ts
|
|
85
97
|
new Game({
|
|
86
98
|
systems: [
|
|
87
|
-
new Renderer3DSystem({ canvas, width: 750, height:
|
|
99
|
+
new Renderer3DSystem({ canvas, width: 750, height: 1334 }),
|
|
88
100
|
new Graphics3DSystem(),
|
|
89
101
|
new Img3DSystem(),
|
|
102
|
+
new Event3DSystem(),
|
|
90
103
|
// ...other 3D sub-systems, physics, audio
|
|
91
104
|
],
|
|
92
105
|
});
|
|
@@ -94,12 +107,8 @@ new Game({
|
|
|
94
107
|
|
|
95
108
|
## Runtime behaviour
|
|
96
109
|
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
- `ThreeContext` owns the render loop. `Renderer3D` subclasses register
|
|
100
|
-
with `rendererManager` and are driven each frame.
|
|
101
|
-
- Three.js `Object3D`s should always be attached to `this.threeContext.scene`,
|
|
102
|
-
not directly to the renderer.
|
|
110
|
+
- `ThreeContext` owns the render loop. `Renderer3D` subclasses register with `rendererManager` and are driven each frame.
|
|
111
|
+
- Three.js `Object3D`s should always be attached to `this.threeContext.scene`, not directly to the renderer.
|
|
103
112
|
|
|
104
113
|
## Common pitfalls
|
|
105
114
|
|
|
@@ -110,7 +119,8 @@ new Game({
|
|
|
110
119
|
| Object loaded but not visible | Object likely loaded at origin — adjust `position*` fields, or check camera distance (default `z=5`) |
|
|
111
120
|
| `getSystem` undefined | Use class reference `game.getSystem(Renderer3DSystem)` |
|
|
112
121
|
| Memory leak after fast remove | Use `increaseAsyncId` / `validateAsyncId` to drop stale async work |
|
|
113
|
-
| CORS errors loading 3D assets | Host on same origin or CORS-enabled CDN |
|
|
122
|
+
| CORS errors loading 3D assets | Host on same origin or CORS-enabled CDN; URLs live in `addResource` `src` |
|
|
123
|
+
| `tap` never fires | Use `Event3D` + `Event3DSystem`, not 2D `Event` |
|
|
114
124
|
|
|
115
125
|
## Minimal example
|
|
116
126
|
|
|
@@ -123,7 +133,7 @@ new Game({
|
|
|
123
133
|
new Renderer3DSystem({
|
|
124
134
|
canvas: document.querySelector('#canvas')!,
|
|
125
135
|
width: 750,
|
|
126
|
-
height:
|
|
136
|
+
height: 1334,
|
|
127
137
|
}),
|
|
128
138
|
],
|
|
129
139
|
});
|
package/combos-plugin.json
CHANGED
|
@@ -2,7 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
var engine = require('@combos-fun/engine');
|
|
4
4
|
var three = require('three');
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
const COMBOS_GAME_OBJECT_ID = 'combosGameObjectId';
|
|
7
|
+
/** Stamp a Three.js object (and its children) so Event3D raycasts can resolve the GameObject. */
|
|
8
|
+
function tagObject3D(object, gameObjectId) {
|
|
9
|
+
object.traverse((child) => {
|
|
10
|
+
child.userData[COMBOS_GAME_OBJECT_ID] = gameObjectId;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function gameObjectIdFromObject3D(object) {
|
|
14
|
+
let current = object;
|
|
15
|
+
while (current) {
|
|
16
|
+
const id = current.userData?.[COMBOS_GAME_OBJECT_ID];
|
|
17
|
+
if (typeof id === 'number') {
|
|
18
|
+
return id;
|
|
19
|
+
}
|
|
20
|
+
current = current.parent;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
6
24
|
|
|
7
25
|
class ThreeContext {
|
|
8
26
|
constructor(params) {
|
|
@@ -33,7 +51,6 @@ class ThreeContext {
|
|
|
33
51
|
directionalLight.position.set(5, 10, 7.5);
|
|
34
52
|
this.scene.add(directionalLight);
|
|
35
53
|
this.clock = new three.Clock();
|
|
36
|
-
this.gltfLoader = new GLTFLoader_js.GLTFLoader();
|
|
37
54
|
}
|
|
38
55
|
update() {
|
|
39
56
|
const delta = this.clock.getDelta();
|
|
@@ -42,22 +59,16 @@ class ThreeContext {
|
|
|
42
59
|
}
|
|
43
60
|
this.renderer.render(this.scene, this.camera);
|
|
44
61
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
resolve(model);
|
|
57
|
-
}, undefined, (error) => {
|
|
58
|
-
reject(error);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
62
|
+
attachParsedModel(id, model, animations) {
|
|
63
|
+
tagObject3D(model, id);
|
|
64
|
+
this.scene.add(model);
|
|
65
|
+
this.models.set(id, model);
|
|
66
|
+
if (animations && animations.length > 0) {
|
|
67
|
+
const mixer = new three.AnimationMixer(model);
|
|
68
|
+
this.mixers.set(id, mixer);
|
|
69
|
+
model.userData.animations = animations;
|
|
70
|
+
}
|
|
71
|
+
return model;
|
|
61
72
|
}
|
|
62
73
|
playAnimation(id, animationIndex, speed) {
|
|
63
74
|
const mixer = this.mixers.get(id);
|
|
@@ -116,7 +127,6 @@ class ThreeContext {
|
|
|
116
127
|
this.camera = null;
|
|
117
128
|
this.renderer = null;
|
|
118
129
|
this.clock = null;
|
|
119
|
-
this.gltfLoader = null;
|
|
120
130
|
}
|
|
121
131
|
}
|
|
122
132
|
|
|
@@ -194,7 +204,7 @@ class Renderer3DSystem extends engine.System {
|
|
|
194
204
|
init(params) {
|
|
195
205
|
const opts = params || {};
|
|
196
206
|
const width = opts.width || 750;
|
|
197
|
-
const height = opts.height ||
|
|
207
|
+
const height = opts.height || 1334;
|
|
198
208
|
this.threeContext = new ThreeContext({
|
|
199
209
|
canvas: opts.canvas,
|
|
200
210
|
container: opts.container,
|
|
@@ -230,7 +240,7 @@ class Renderer3DSystem extends engine.System {
|
|
|
230
240
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
231
241
|
Object.assign(Renderer3DSystem, {
|
|
232
242
|
packageName: "@combos-fun/plugin-renderer-3d",
|
|
233
|
-
packageVersion: "0.0.
|
|
243
|
+
packageVersion: "0.0.40",
|
|
234
244
|
});
|
|
235
245
|
|
|
236
246
|
class Renderer3D extends engine.System {
|
|
@@ -257,8 +267,41 @@ class Renderer3D extends engine.System {
|
|
|
257
267
|
}
|
|
258
268
|
}
|
|
259
269
|
|
|
270
|
+
async function requireNamedResource(name) {
|
|
271
|
+
const trimmed = String(name ?? '').trim();
|
|
272
|
+
if (!trimmed) {
|
|
273
|
+
throw new Error('resource name is required; register it with resource.addResource');
|
|
274
|
+
}
|
|
275
|
+
const res = await engine.resource.getResource(trimmed);
|
|
276
|
+
if (!res || !res.name) {
|
|
277
|
+
throw new Error(`Unknown resource "${trimmed}"; register it with resource.addResource first`);
|
|
278
|
+
}
|
|
279
|
+
return res;
|
|
280
|
+
}
|
|
281
|
+
function textureFromResourceImage(res) {
|
|
282
|
+
const image = res.data?.image;
|
|
283
|
+
if (!image) {
|
|
284
|
+
throw new Error(`Resource "${res.name}" has no image data; use RESOURCE_TYPE.IMAGE with src.image.url`);
|
|
285
|
+
}
|
|
286
|
+
const texture = new three.Texture(image);
|
|
287
|
+
texture.colorSpace = three.SRGBColorSpace;
|
|
288
|
+
texture.needsUpdate = true;
|
|
289
|
+
return texture;
|
|
290
|
+
}
|
|
291
|
+
async function textureFromNamedImage(name) {
|
|
292
|
+
// Always build a Three.Texture from data.image so 2D Pixi
|
|
293
|
+
// registerInstance(IMAGE) is never overwritten or reused.
|
|
294
|
+
return textureFromResourceImage(await requireNamedResource(name));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
exports.COMBOS_GAME_OBJECT_ID = COMBOS_GAME_OBJECT_ID;
|
|
260
298
|
exports.Renderer3D = Renderer3D;
|
|
261
299
|
exports.Renderer3DManager = Renderer3DManager;
|
|
262
300
|
exports.Renderer3DSystem = Renderer3DSystem;
|
|
263
301
|
exports.ThreeContext = ThreeContext;
|
|
302
|
+
exports.gameObjectIdFromObject3D = gameObjectIdFromObject3D;
|
|
303
|
+
exports.requireNamedResource = requireNamedResource;
|
|
304
|
+
exports.tagObject3D = tagObject3D;
|
|
305
|
+
exports.textureFromNamedImage = textureFromNamedImage;
|
|
306
|
+
exports.textureFromResourceImage = textureFromResourceImage;
|
|
264
307
|
//# sourceMappingURL=plugin-renderer-3d.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-3d.cjs.js","sources":["../lib/ThreeContext.ts","../lib/Renderer3DManager.ts","../lib/system.ts","../lib/__combosPackageMeta.gen.ts","../lib/Renderer3D.ts"],"sourcesContent":["import {\n Scene,\n PerspectiveCamera,\n WebGLRenderer,\n Clock,\n AmbientLight,\n DirectionalLight,\n AnimationMixer,\n AnimationClip,\n Mesh,\n Material,\n Group,\n} from 'three';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n\nexport interface ThreeContextParams {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width: number;\n height: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class ThreeContext {\n scene: Scene;\n camera: PerspectiveCamera;\n renderer: WebGLRenderer;\n clock: Clock;\n gltfLoader: GLTFLoader;\n mixers: Map<number, AnimationMixer> = new Map();\n models: Map<number, Group> = new Map();\n\n constructor(params: ThreeContextParams) {\n const {\n canvas,\n container,\n width,\n height,\n antialias = true,\n backgroundColor = 0x000000,\n backgroundAlpha = 1,\n } = params;\n\n this.scene = new Scene();\n\n this.camera = new PerspectiveCamera(75, width / height, 0.1, 1000);\n this.camera.position.z = 5;\n\n const rendererOpts: any = { antialias };\n if (canvas) {\n rendererOpts.canvas = canvas;\n }\n if (backgroundAlpha < 1) {\n rendererOpts.alpha = true;\n }\n\n this.renderer = new WebGLRenderer(rendererOpts);\n this.renderer.setSize(width, height);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setClearColor(backgroundColor, backgroundAlpha);\n\n // If no canvas was provided but a container was, append the generated canvas\n if (!canvas && container) {\n container.appendChild(this.renderer.domElement);\n }\n\n const ambientLight = new AmbientLight(0xffffff, 0.6);\n this.scene.add(ambientLight);\n const directionalLight = new DirectionalLight(0xffffff, 0.8);\n directionalLight.position.set(5, 10, 7.5);\n this.scene.add(directionalLight);\n\n this.clock = new Clock();\n this.gltfLoader = new GLTFLoader();\n }\n\n update() {\n const delta = this.clock.getDelta();\n for (const mixer of this.mixers.values()) {\n mixer.update(delta);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n async loadGLB(id: number, url: string): Promise<Group> {\n return new Promise((resolve, reject) => {\n this.gltfLoader.load(url, (gltf) => {\n const model = gltf.scene;\n this.scene.add(model);\n this.models.set(id, model);\n\n if (gltf.animations && gltf.animations.length > 0) {\n const mixer = new AnimationMixer(model);\n this.mixers.set(id, mixer);\n model.userData.animations = gltf.animations;\n }\n\n resolve(model);\n }, undefined, (error) => {\n reject(error);\n });\n });\n }\n\n playAnimation(id: number, animationIndex: number, speed: number) {\n const mixer = this.mixers.get(id);\n const model = this.models.get(id);\n if (!mixer || !model) return;\n\n mixer.stopAllAction();\n const animations = model.userData.animations as AnimationClip[];\n if (animations && animations[animationIndex]) {\n const action = mixer.clipAction(animations[animationIndex]);\n action.timeScale = speed;\n action.play();\n }\n }\n\n stopAnimation(id: number) {\n const mixer = this.mixers.get(id);\n if (mixer) mixer.stopAllAction();\n }\n\n removeModel(id: number) {\n const model = this.models.get(id);\n if (model) {\n this.scene.remove(model);\n model.traverse((child) => {\n const mesh = child as Mesh;\n if (mesh.geometry) {\n mesh.geometry.dispose();\n }\n if (mesh.material) {\n const materials = Array.isArray(mesh.material)\n ? mesh.material as Material[]\n : [mesh.material as Material];\n materials.forEach(m => m.dispose());\n }\n });\n this.models.delete(id);\n }\n const mixer = this.mixers.get(id);\n if (mixer) {\n mixer.stopAllAction();\n this.mixers.delete(id);\n }\n }\n\n resize(width: number, height: number) {\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height);\n }\n\n destroy() {\n for (const id of this.models.keys()) {\n this.removeModel(id);\n }\n this.renderer.dispose();\n this.renderer.domElement.remove();\n this.scene = null;\n this.camera = null;\n this.renderer = null;\n this.clock = null;\n this.gltfLoader = null;\n }\n}\n","import { GameObject, Game, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type Renderer3D from './Renderer3D';\nimport type Renderer3DSystem from './system';\n\nexport default class Renderer3DManager {\n game: Game;\n rendererSystem: Renderer3DSystem;\n renderers: Renderer3D[] = [];\n\n constructor({ game, rendererSystem }: { game: Game; rendererSystem: Renderer3DSystem }) {\n this.game = game;\n this.rendererSystem = rendererSystem;\n }\n\n register(...renderers: Renderer3D[]) {\n for (const renderer of renderers) {\n renderer.game = this.game;\n renderer.rendererManager = this;\n renderer.threeContext = this.rendererSystem.threeContext;\n this.renderers.push(renderer);\n }\n }\n\n componentChanged(changes: ComponentChanged[]) {\n for (const changed of changes) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[changed.componentName];\n if (!props) continue;\n\n if (changed.type === OBSERVER_TYPE.ADD || changed.type === OBSERVER_TYPE.REMOVE) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject.name}, ${changed.componentName} error.`,\n changed,\n e,\n );\n }\n continue;\n }\n\n // CHANGE type: check if the changed prop matches\n const index = props.findIndex((prop) => {\n if (typeof prop === 'string' && typeof changed.prop === 'string') {\n return prop === changed.prop;\n }\n // Deep comparison for object-style props\n return JSON.stringify(prop) === JSON.stringify(changed.prop);\n });\n\n if (index > -1) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject?.name}, ${changed.componentName} componentChanged error.`,\n changed,\n e,\n );\n }\n }\n }\n }\n }\n\n update(gameObject: GameObject) {\n for (const component of gameObject.components) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[component.name];\n if (props) {\n try {\n renderer.rendererUpdate(gameObject);\n } catch (e) {\n console.info(\n `gameObject: ${gameObject.name}, ${component.name} update error`,\n e,\n );\n }\n }\n }\n }\n }\n}\n","import { System } from '@combos-fun/engine';\nimport type { UpdateParams } from '@combos-fun/engine';\nimport ThreeContext from './ThreeContext';\nimport type { ThreeContextParams } from './ThreeContext';\nimport Renderer3DManager from './Renderer3DManager';\n\nexport interface Renderer3DSystemParams extends Partial<ThreeContextParams> {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width?: number;\n height?: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class Renderer3DSystem extends System<Renderer3DSystemParams> {\n static systemName = 'Renderer3DSystem';\n name: string = 'Renderer3DSystem';\n threeContext: ThreeContext;\n rendererManager: Renderer3DManager;\n\n init(params?: Renderer3DSystemParams) {\n const opts = params || {};\n const width = opts.width || 750;\n const height = opts.height || 1000;\n\n this.threeContext = new ThreeContext({\n canvas: opts.canvas,\n container: opts.container,\n width,\n height,\n antialias: opts.antialias,\n backgroundColor: opts.backgroundColor,\n backgroundAlpha: opts.backgroundAlpha,\n });\n\n this.game.canvas = this.threeContext.renderer.domElement;\n\n this.rendererManager = new Renderer3DManager({\n game: this.game,\n rendererSystem: this,\n });\n }\n\n update(e?: UpdateParams) {\n for (const gameObject of this.game.gameObjects) {\n this.rendererManager.update(gameObject);\n }\n }\n\n lateUpdate() {\n this.threeContext?.update();\n }\n\n resize(width: number, height: number) {\n this.threeContext?.resize(width, height);\n }\n\n onDestroy(): void {\n this.threeContext?.destroy();\n this.threeContext = null;\n }\n}\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport Renderer3DSystem from './system';\n\nObject.assign(Renderer3DSystem, {\n packageName: \"@combos-fun/plugin-renderer-3d\",\n packageVersion: \"0.0.39\",\n});\n","import { Game, PureObserverInfo, ComponentChanged, System, GameObject, UpdateParams } from '@combos-fun/engine';\nimport type Renderer3DManager from './Renderer3DManager';\nimport type ThreeContext from './ThreeContext';\n\nexport default class Renderer3D<T extends {} = {}> extends System<T> {\n name: string;\n game: Game;\n static observerInfo: PureObserverInfo;\n observerInfo: PureObserverInfo;\n rendererManager: Renderer3DManager;\n threeContext: ThreeContext;\n\n constructor(params?: T) {\n super(params);\n const Ctor = this.constructor as typeof Renderer3D & { observerInfo: PureObserverInfo };\n this.observerInfo = Ctor.observerInfo;\n }\n\n componentChanged(_changed: ComponentChanged) {}\n rendererUpdate(_gameObject: GameObject) {}\n\n override update(e?: UpdateParams): void {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n protected asyncIdMap: Record<number, number> = {};\n\n protected increaseAsyncId(id: number) {\n this.asyncIdMap[id] = (this.asyncIdMap[id] || 0) + 1;\n return this.asyncIdMap[id];\n }\n\n protected validateAsyncId(id: number, asyncId: number) {\n return this.asyncIdMap[id] === asyncId;\n }\n}\n"],"names":["Scene","PerspectiveCamera","WebGLRenderer","AmbientLight","DirectionalLight","Clock","GLTFLoader","AnimationMixer","OBSERVER_TYPE","System"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-3d.cjs.js","sources":["../lib/tagObject3D.ts","../lib/ThreeContext.ts","../lib/Renderer3DManager.ts","../lib/system.ts","../lib/__combosPackageMeta.gen.ts","../lib/Renderer3D.ts","../lib/namedResource.ts"],"sourcesContent":["import type { Object3D } from 'three';\n\nexport const COMBOS_GAME_OBJECT_ID = 'combosGameObjectId';\n\n/** Stamp a Three.js object (and its children) so Event3D raycasts can resolve the GameObject. */\nexport function tagObject3D(object: Object3D, gameObjectId: number): void {\n object.traverse((child) => {\n child.userData[COMBOS_GAME_OBJECT_ID] = gameObjectId;\n });\n}\n\nexport function gameObjectIdFromObject3D(object: Object3D | null | undefined): number | undefined {\n let current = object;\n while (current) {\n const id = current.userData?.[COMBOS_GAME_OBJECT_ID];\n if (typeof id === 'number') {\n return id;\n }\n current = current.parent;\n }\n return undefined;\n}\n","import {\n Scene,\n PerspectiveCamera,\n WebGLRenderer,\n Clock,\n AmbientLight,\n DirectionalLight,\n AnimationMixer,\n AnimationClip,\n Mesh,\n Material,\n Group,\n} from 'three';\nimport { tagObject3D } from './tagObject3D';\n\nexport interface ThreeContextParams {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width: number;\n height: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class ThreeContext {\n scene: Scene;\n camera: PerspectiveCamera;\n renderer: WebGLRenderer;\n clock: Clock;\n mixers: Map<number, AnimationMixer> = new Map();\n models: Map<number, Group> = new Map();\n\n constructor(params: ThreeContextParams) {\n const {\n canvas,\n container,\n width,\n height,\n antialias = true,\n backgroundColor = 0x000000,\n backgroundAlpha = 1,\n } = params;\n\n this.scene = new Scene();\n\n this.camera = new PerspectiveCamera(75, width / height, 0.1, 1000);\n this.camera.position.z = 5;\n\n const rendererOpts: any = { antialias };\n if (canvas) {\n rendererOpts.canvas = canvas;\n }\n if (backgroundAlpha < 1) {\n rendererOpts.alpha = true;\n }\n\n this.renderer = new WebGLRenderer(rendererOpts);\n this.renderer.setSize(width, height);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setClearColor(backgroundColor, backgroundAlpha);\n\n // If no canvas was provided but a container was, append the generated canvas\n if (!canvas && container) {\n container.appendChild(this.renderer.domElement);\n }\n\n const ambientLight = new AmbientLight(0xffffff, 0.6);\n this.scene.add(ambientLight);\n const directionalLight = new DirectionalLight(0xffffff, 0.8);\n directionalLight.position.set(5, 10, 7.5);\n this.scene.add(directionalLight);\n\n this.clock = new Clock();\n }\n\n update() {\n const delta = this.clock.getDelta();\n for (const mixer of this.mixers.values()) {\n mixer.update(delta);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n attachParsedModel(id: number, model: Group, animations?: AnimationClip[]): Group {\n tagObject3D(model, id);\n this.scene.add(model);\n this.models.set(id, model);\n\n if (animations && animations.length > 0) {\n const mixer = new AnimationMixer(model);\n this.mixers.set(id, mixer);\n model.userData.animations = animations;\n }\n\n return model;\n }\n\n playAnimation(id: number, animationIndex: number, speed: number) {\n const mixer = this.mixers.get(id);\n const model = this.models.get(id);\n if (!mixer || !model) return;\n\n mixer.stopAllAction();\n const animations = model.userData.animations as AnimationClip[];\n if (animations && animations[animationIndex]) {\n const action = mixer.clipAction(animations[animationIndex]);\n action.timeScale = speed;\n action.play();\n }\n }\n\n stopAnimation(id: number) {\n const mixer = this.mixers.get(id);\n if (mixer) mixer.stopAllAction();\n }\n\n removeModel(id: number) {\n const model = this.models.get(id);\n if (model) {\n this.scene.remove(model);\n model.traverse((child) => {\n const mesh = child as Mesh;\n if (mesh.geometry) {\n mesh.geometry.dispose();\n }\n if (mesh.material) {\n const materials = Array.isArray(mesh.material)\n ? mesh.material as Material[]\n : [mesh.material as Material];\n materials.forEach(m => m.dispose());\n }\n });\n this.models.delete(id);\n }\n const mixer = this.mixers.get(id);\n if (mixer) {\n mixer.stopAllAction();\n this.mixers.delete(id);\n }\n }\n\n resize(width: number, height: number) {\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height);\n }\n\n destroy() {\n for (const id of this.models.keys()) {\n this.removeModel(id);\n }\n this.renderer.dispose();\n this.renderer.domElement.remove();\n this.scene = null;\n this.camera = null;\n this.renderer = null;\n this.clock = null;\n }\n}\n","import { GameObject, Game, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type Renderer3D from './Renderer3D';\nimport type Renderer3DSystem from './system';\n\nexport default class Renderer3DManager {\n game: Game;\n rendererSystem: Renderer3DSystem;\n renderers: Renderer3D[] = [];\n\n constructor({ game, rendererSystem }: { game: Game; rendererSystem: Renderer3DSystem }) {\n this.game = game;\n this.rendererSystem = rendererSystem;\n }\n\n register(...renderers: Renderer3D[]) {\n for (const renderer of renderers) {\n renderer.game = this.game;\n renderer.rendererManager = this;\n renderer.threeContext = this.rendererSystem.threeContext;\n this.renderers.push(renderer);\n }\n }\n\n componentChanged(changes: ComponentChanged[]) {\n for (const changed of changes) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[changed.componentName];\n if (!props) continue;\n\n if (changed.type === OBSERVER_TYPE.ADD || changed.type === OBSERVER_TYPE.REMOVE) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject.name}, ${changed.componentName} error.`,\n changed,\n e,\n );\n }\n continue;\n }\n\n // CHANGE type: check if the changed prop matches\n const index = props.findIndex((prop) => {\n if (typeof prop === 'string' && typeof changed.prop === 'string') {\n return prop === changed.prop;\n }\n // Deep comparison for object-style props\n return JSON.stringify(prop) === JSON.stringify(changed.prop);\n });\n\n if (index > -1) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject?.name}, ${changed.componentName} componentChanged error.`,\n changed,\n e,\n );\n }\n }\n }\n }\n }\n\n update(gameObject: GameObject) {\n for (const component of gameObject.components) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[component.name];\n if (props) {\n try {\n renderer.rendererUpdate(gameObject);\n } catch (e) {\n console.info(\n `gameObject: ${gameObject.name}, ${component.name} update error`,\n e,\n );\n }\n }\n }\n }\n }\n}\n","import { System } from '@combos-fun/engine';\nimport type { UpdateParams } from '@combos-fun/engine';\nimport ThreeContext from './ThreeContext';\nimport type { ThreeContextParams } from './ThreeContext';\nimport Renderer3DManager from './Renderer3DManager';\n\nexport interface Renderer3DSystemParams extends Partial<ThreeContextParams> {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width?: number;\n height?: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class Renderer3DSystem extends System<Renderer3DSystemParams> {\n static systemName = 'Renderer3DSystem';\n name: string = 'Renderer3DSystem';\n threeContext: ThreeContext;\n rendererManager: Renderer3DManager;\n\n init(params?: Renderer3DSystemParams) {\n const opts = params || {};\n const width = opts.width || 750;\n const height = opts.height || 1334;\n\n this.threeContext = new ThreeContext({\n canvas: opts.canvas,\n container: opts.container,\n width,\n height,\n antialias: opts.antialias,\n backgroundColor: opts.backgroundColor,\n backgroundAlpha: opts.backgroundAlpha,\n });\n\n this.game.canvas = this.threeContext.renderer.domElement;\n\n this.rendererManager = new Renderer3DManager({\n game: this.game,\n rendererSystem: this,\n });\n }\n\n update(e?: UpdateParams) {\n for (const gameObject of this.game.gameObjects) {\n this.rendererManager.update(gameObject);\n }\n }\n\n lateUpdate() {\n this.threeContext?.update();\n }\n\n resize(width: number, height: number) {\n this.threeContext?.resize(width, height);\n }\n\n onDestroy(): void {\n this.threeContext?.destroy();\n this.threeContext = null;\n }\n}\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport Renderer3DSystem from './system';\n\nObject.assign(Renderer3DSystem, {\n packageName: \"@combos-fun/plugin-renderer-3d\",\n packageVersion: \"0.0.40\",\n});\n","import { Game, PureObserverInfo, ComponentChanged, System, GameObject, UpdateParams } from '@combos-fun/engine';\nimport type Renderer3DManager from './Renderer3DManager';\nimport type ThreeContext from './ThreeContext';\n\nexport default class Renderer3D<T extends {} = {}> extends System<T> {\n name: string;\n game: Game;\n static observerInfo: PureObserverInfo;\n observerInfo: PureObserverInfo;\n rendererManager: Renderer3DManager;\n threeContext: ThreeContext;\n\n constructor(params?: T) {\n super(params);\n const Ctor = this.constructor as typeof Renderer3D & { observerInfo: PureObserverInfo };\n this.observerInfo = Ctor.observerInfo;\n }\n\n componentChanged(_changed: ComponentChanged) {}\n rendererUpdate(_gameObject: GameObject) {}\n\n override update(e?: UpdateParams): void {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n protected asyncIdMap: Record<number, number> = {};\n\n protected increaseAsyncId(id: number) {\n this.asyncIdMap[id] = (this.asyncIdMap[id] || 0) + 1;\n return this.asyncIdMap[id];\n }\n\n protected validateAsyncId(id: number, asyncId: number) {\n return this.asyncIdMap[id] === asyncId;\n }\n}\n","import { resource } from '@combos-fun/engine';\nimport type { ResourceStruct } from '@combos-fun/engine';\nimport { SRGBColorSpace, Texture } from 'three';\n\nexport async function requireNamedResource(name: string): Promise<ResourceStruct> {\n const trimmed = String(name ?? '').trim();\n if (!trimmed) {\n throw new Error('resource name is required; register it with resource.addResource');\n }\n const res = await resource.getResource(trimmed);\n if (!res || !res.name) {\n throw new Error(\n `Unknown resource \"${trimmed}\"; register it with resource.addResource first`,\n );\n }\n return res;\n}\n\nexport function textureFromResourceImage(res: ResourceStruct): Texture {\n const image = res.data?.image as HTMLImageElement | undefined;\n if (!image) {\n throw new Error(\n `Resource \"${res.name}\" has no image data; use RESOURCE_TYPE.IMAGE with src.image.url`,\n );\n }\n const texture = new Texture(image);\n texture.colorSpace = SRGBColorSpace;\n texture.needsUpdate = true;\n return texture;\n}\n\nexport async function textureFromNamedImage(name: string): Promise<Texture> {\n // Always build a Three.Texture from data.image so 2D Pixi\n // registerInstance(IMAGE) is never overwritten or reused.\n return textureFromResourceImage(await requireNamedResource(name));\n}\n"],"names":["Scene","PerspectiveCamera","WebGLRenderer","AmbientLight","DirectionalLight","Clock","AnimationMixer","OBSERVER_TYPE","System","resource","Texture","SRGBColorSpace"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("@combos-fun/engine"),t=require("three")
|
|
1
|
+
"use strict";var e=require("@combos-fun/engine"),t=require("three");const r="combosGameObjectId";function s(e,t){e.traverse(e=>{e.userData[r]=t})}class n{constructor(e){this.mixers=new Map,this.models=new Map;const{canvas:r,container:s,width:n,height:o,antialias:a=!0,backgroundColor:i=0,backgroundAlpha:c=1}=e;this.scene=new t.Scene,this.camera=new t.PerspectiveCamera(75,n/o,.1,1e3),this.camera.position.z=5;const h={antialias:a};r&&(h.canvas=r),c<1&&(h.alpha=!0),this.renderer=new t.WebGLRenderer(h),this.renderer.setSize(n,o),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setClearColor(i,c),!r&&s&&s.appendChild(this.renderer.domElement);const d=new t.AmbientLight(16777215,.6);this.scene.add(d);const m=new t.DirectionalLight(16777215,.8);m.position.set(5,10,7.5),this.scene.add(m),this.clock=new t.Clock}update(){const e=this.clock.getDelta();for(const t of this.mixers.values())t.update(e);this.renderer.render(this.scene,this.camera)}attachParsedModel(e,r,n){if(s(r,e),this.scene.add(r),this.models.set(e,r),n&&n.length>0){const s=new t.AnimationMixer(r);this.mixers.set(e,s),r.userData.animations=n}return r}playAnimation(e,t,r){const s=this.mixers.get(e),n=this.models.get(e);if(!s||!n)return;s.stopAllAction();const o=n.userData.animations;if(o&&o[t]){const e=s.clipAction(o[t]);e.timeScale=r,e.play()}}stopAnimation(e){const t=this.mixers.get(e);t&&t.stopAllAction()}removeModel(e){const t=this.models.get(e);t&&(this.scene.remove(t),t.traverse(e=>{const t=e;if(t.geometry&&t.geometry.dispose(),t.material){(Array.isArray(t.material)?t.material:[t.material]).forEach(e=>e.dispose())}}),this.models.delete(e));const r=this.mixers.get(e);r&&(r.stopAllAction(),this.mixers.delete(e))}resize(e,t){this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t)}destroy(){for(const e of this.models.keys())this.removeModel(e);this.renderer.dispose(),this.renderer.domElement.remove(),this.scene=null,this.camera=null,this.renderer=null,this.clock=null}}class o{constructor({game:e,rendererSystem:t}){this.renderers=[],this.game=e,this.rendererSystem=t}register(...e){for(const t of e)t.game=this.game,t.rendererManager=this,t.threeContext=this.rendererSystem.threeContext,this.renderers.push(t)}componentChanged(t){for(const r of t)for(const t of this.renderers){const s=t.observerInfo[r.componentName];if(!s)continue;if(r.type===e.OBSERVER_TYPE.ADD||r.type===e.OBSERVER_TYPE.REMOVE){try{t.componentChanged(r)}catch(e){console.error(`gameObject: ${r.gameObject.name}, ${r.componentName} error.`,r,e)}continue}if(s.findIndex(e=>"string"==typeof e&&"string"==typeof r.prop?e===r.prop:JSON.stringify(e)===JSON.stringify(r.prop))>-1)try{t.componentChanged(r)}catch(e){console.error(`gameObject: ${r.gameObject?.name}, ${r.componentName} componentChanged error.`,r,e)}}}update(e){for(const t of e.components)for(const r of this.renderers){if(r.observerInfo[t.name])try{r.rendererUpdate(e)}catch(r){console.info(`gameObject: ${e.name}, ${t.name} update error`,r)}}}}class a extends e.System{constructor(){super(...arguments),this.name="Renderer3DSystem"}static{this.systemName="Renderer3DSystem"}init(e){const t=e||{},r=t.width||750,s=t.height||1334;this.threeContext=new n({canvas:t.canvas,container:t.container,width:r,height:s,antialias:t.antialias,backgroundColor:t.backgroundColor,backgroundAlpha:t.backgroundAlpha}),this.game.canvas=this.threeContext.renderer.domElement,this.rendererManager=new o({game:this.game,rendererSystem:this})}update(e){for(const e of this.game.gameObjects)this.rendererManager.update(e)}lateUpdate(){this.threeContext?.update()}resize(e,t){this.threeContext?.resize(e,t)}onDestroy(){this.threeContext?.destroy(),this.threeContext=null}}Object.assign(a,{packageName:"@combos-fun/plugin-renderer-3d",packageVersion:"0.0.40"});class i extends e.System{constructor(e){super(e),this.asyncIdMap={};const t=this.constructor;this.observerInfo=t.observerInfo}componentChanged(e){}rendererUpdate(e){}update(e){const t=this.componentObserver.clear();for(const e of t)this.componentChanged(e)}increaseAsyncId(e){return this.asyncIdMap[e]=(this.asyncIdMap[e]||0)+1,this.asyncIdMap[e]}validateAsyncId(e,t){return this.asyncIdMap[e]===t}}async function c(t){const r=String(t??"").trim();if(!r)throw new Error("resource name is required; register it with resource.addResource");const s=await e.resource.getResource(r);if(!s||!s.name)throw new Error(`Unknown resource "${r}"; register it with resource.addResource first`);return s}function h(e){const r=e.data?.image;if(!r)throw new Error(`Resource "${e.name}" has no image data; use RESOURCE_TYPE.IMAGE with src.image.url`);const s=new t.Texture(r);return s.colorSpace=t.SRGBColorSpace,s.needsUpdate=!0,s}exports.COMBOS_GAME_OBJECT_ID=r,exports.Renderer3D=i,exports.Renderer3DManager=o,exports.Renderer3DSystem=a,exports.ThreeContext=n,exports.gameObjectIdFromObject3D=function(e){let t=e;for(;t;){const e=t.userData?.[r];if("number"==typeof e)return e;t=t.parent}},exports.requireNamedResource=c,exports.tagObject3D=s,exports.textureFromNamedImage=async function(e){return h(await c(e))},exports.textureFromResourceImage=h;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { System, Game, PureObserverInfo, ComponentChanged, GameObject, UpdateParams } from '@combos-fun/engine';
|
|
2
|
-
import { Scene, PerspectiveCamera, WebGLRenderer, Clock, AnimationMixer, Group } from 'three';
|
|
3
|
-
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
1
|
+
import { System, Game, PureObserverInfo, ComponentChanged, GameObject, UpdateParams, ResourceStruct } from '@combos-fun/engine';
|
|
2
|
+
import { Scene, PerspectiveCamera, WebGLRenderer, Clock, AnimationMixer, Group, AnimationClip, Object3D, Texture } from 'three';
|
|
4
3
|
|
|
5
4
|
interface ThreeContextParams {
|
|
6
5
|
canvas?: HTMLCanvasElement;
|
|
@@ -16,12 +15,11 @@ declare class ThreeContext {
|
|
|
16
15
|
camera: PerspectiveCamera;
|
|
17
16
|
renderer: WebGLRenderer;
|
|
18
17
|
clock: Clock;
|
|
19
|
-
gltfLoader: GLTFLoader;
|
|
20
18
|
mixers: Map<number, AnimationMixer>;
|
|
21
19
|
models: Map<number, Group>;
|
|
22
20
|
constructor(params: ThreeContextParams);
|
|
23
21
|
update(): void;
|
|
24
|
-
|
|
22
|
+
attachParsedModel(id: number, model: Group, animations?: AnimationClip[]): Group;
|
|
25
23
|
playAnimation(id: number, animationIndex: number, speed: number): void;
|
|
26
24
|
stopAnimation(id: number): void;
|
|
27
25
|
removeModel(id: number): void;
|
|
@@ -79,5 +77,14 @@ declare class Renderer3DSystem extends System<Renderer3DSystemParams> {
|
|
|
79
77
|
onDestroy(): void;
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
declare const COMBOS_GAME_OBJECT_ID = "combosGameObjectId";
|
|
81
|
+
/** Stamp a Three.js object (and its children) so Event3D raycasts can resolve the GameObject. */
|
|
82
|
+
declare function tagObject3D(object: Object3D, gameObjectId: number): void;
|
|
83
|
+
declare function gameObjectIdFromObject3D(object: Object3D | null | undefined): number | undefined;
|
|
84
|
+
|
|
85
|
+
declare function requireNamedResource(name: string): Promise<ResourceStruct>;
|
|
86
|
+
declare function textureFromResourceImage(res: ResourceStruct): Texture;
|
|
87
|
+
declare function textureFromNamedImage(name: string): Promise<Texture>;
|
|
88
|
+
|
|
89
|
+
export { COMBOS_GAME_OBJECT_ID, Renderer3D, Renderer3DManager, Renderer3DSystem, ThreeContext, gameObjectIdFromObject3D, requireNamedResource, tagObject3D, textureFromNamedImage, textureFromResourceImage };
|
|
83
90
|
export type { Renderer3DSystemParams, ThreeContextParams };
|
|
@@ -1,6 +1,24 @@
|
|
|
1
|
-
import { OBSERVER_TYPE, System } from '@combos-fun/engine';
|
|
2
|
-
import { Scene, PerspectiveCamera, WebGLRenderer, AmbientLight, DirectionalLight, Clock, AnimationMixer } from 'three';
|
|
3
|
-
|
|
1
|
+
import { OBSERVER_TYPE, System, resource } from '@combos-fun/engine';
|
|
2
|
+
import { Scene, PerspectiveCamera, WebGLRenderer, AmbientLight, DirectionalLight, Clock, AnimationMixer, Texture, SRGBColorSpace } from 'three';
|
|
3
|
+
|
|
4
|
+
const COMBOS_GAME_OBJECT_ID = 'combosGameObjectId';
|
|
5
|
+
/** Stamp a Three.js object (and its children) so Event3D raycasts can resolve the GameObject. */
|
|
6
|
+
function tagObject3D(object, gameObjectId) {
|
|
7
|
+
object.traverse((child) => {
|
|
8
|
+
child.userData[COMBOS_GAME_OBJECT_ID] = gameObjectId;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function gameObjectIdFromObject3D(object) {
|
|
12
|
+
let current = object;
|
|
13
|
+
while (current) {
|
|
14
|
+
const id = current.userData?.[COMBOS_GAME_OBJECT_ID];
|
|
15
|
+
if (typeof id === 'number') {
|
|
16
|
+
return id;
|
|
17
|
+
}
|
|
18
|
+
current = current.parent;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
4
22
|
|
|
5
23
|
class ThreeContext {
|
|
6
24
|
constructor(params) {
|
|
@@ -31,7 +49,6 @@ class ThreeContext {
|
|
|
31
49
|
directionalLight.position.set(5, 10, 7.5);
|
|
32
50
|
this.scene.add(directionalLight);
|
|
33
51
|
this.clock = new Clock();
|
|
34
|
-
this.gltfLoader = new GLTFLoader();
|
|
35
52
|
}
|
|
36
53
|
update() {
|
|
37
54
|
const delta = this.clock.getDelta();
|
|
@@ -40,22 +57,16 @@ class ThreeContext {
|
|
|
40
57
|
}
|
|
41
58
|
this.renderer.render(this.scene, this.camera);
|
|
42
59
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
resolve(model);
|
|
55
|
-
}, undefined, (error) => {
|
|
56
|
-
reject(error);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
60
|
+
attachParsedModel(id, model, animations) {
|
|
61
|
+
tagObject3D(model, id);
|
|
62
|
+
this.scene.add(model);
|
|
63
|
+
this.models.set(id, model);
|
|
64
|
+
if (animations && animations.length > 0) {
|
|
65
|
+
const mixer = new AnimationMixer(model);
|
|
66
|
+
this.mixers.set(id, mixer);
|
|
67
|
+
model.userData.animations = animations;
|
|
68
|
+
}
|
|
69
|
+
return model;
|
|
59
70
|
}
|
|
60
71
|
playAnimation(id, animationIndex, speed) {
|
|
61
72
|
const mixer = this.mixers.get(id);
|
|
@@ -114,7 +125,6 @@ class ThreeContext {
|
|
|
114
125
|
this.camera = null;
|
|
115
126
|
this.renderer = null;
|
|
116
127
|
this.clock = null;
|
|
117
|
-
this.gltfLoader = null;
|
|
118
128
|
}
|
|
119
129
|
}
|
|
120
130
|
|
|
@@ -192,7 +202,7 @@ class Renderer3DSystem extends System {
|
|
|
192
202
|
init(params) {
|
|
193
203
|
const opts = params || {};
|
|
194
204
|
const width = opts.width || 750;
|
|
195
|
-
const height = opts.height ||
|
|
205
|
+
const height = opts.height || 1334;
|
|
196
206
|
this.threeContext = new ThreeContext({
|
|
197
207
|
canvas: opts.canvas,
|
|
198
208
|
container: opts.container,
|
|
@@ -228,7 +238,7 @@ class Renderer3DSystem extends System {
|
|
|
228
238
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
229
239
|
Object.assign(Renderer3DSystem, {
|
|
230
240
|
packageName: "@combos-fun/plugin-renderer-3d",
|
|
231
|
-
packageVersion: "0.0.
|
|
241
|
+
packageVersion: "0.0.40",
|
|
232
242
|
});
|
|
233
243
|
|
|
234
244
|
class Renderer3D extends System {
|
|
@@ -255,5 +265,32 @@ class Renderer3D extends System {
|
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
267
|
|
|
258
|
-
|
|
268
|
+
async function requireNamedResource(name) {
|
|
269
|
+
const trimmed = String(name ?? '').trim();
|
|
270
|
+
if (!trimmed) {
|
|
271
|
+
throw new Error('resource name is required; register it with resource.addResource');
|
|
272
|
+
}
|
|
273
|
+
const res = await resource.getResource(trimmed);
|
|
274
|
+
if (!res || !res.name) {
|
|
275
|
+
throw new Error(`Unknown resource "${trimmed}"; register it with resource.addResource first`);
|
|
276
|
+
}
|
|
277
|
+
return res;
|
|
278
|
+
}
|
|
279
|
+
function textureFromResourceImage(res) {
|
|
280
|
+
const image = res.data?.image;
|
|
281
|
+
if (!image) {
|
|
282
|
+
throw new Error(`Resource "${res.name}" has no image data; use RESOURCE_TYPE.IMAGE with src.image.url`);
|
|
283
|
+
}
|
|
284
|
+
const texture = new Texture(image);
|
|
285
|
+
texture.colorSpace = SRGBColorSpace;
|
|
286
|
+
texture.needsUpdate = true;
|
|
287
|
+
return texture;
|
|
288
|
+
}
|
|
289
|
+
async function textureFromNamedImage(name) {
|
|
290
|
+
// Always build a Three.Texture from data.image so 2D Pixi
|
|
291
|
+
// registerInstance(IMAGE) is never overwritten or reused.
|
|
292
|
+
return textureFromResourceImage(await requireNamedResource(name));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export { COMBOS_GAME_OBJECT_ID, Renderer3D, Renderer3DManager, Renderer3DSystem, ThreeContext, gameObjectIdFromObject3D, requireNamedResource, tagObject3D, textureFromNamedImage, textureFromResourceImage };
|
|
259
296
|
//# sourceMappingURL=plugin-renderer-3d.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-3d.esm.js","sources":["../lib/ThreeContext.ts","../lib/Renderer3DManager.ts","../lib/system.ts","../lib/__combosPackageMeta.gen.ts","../lib/Renderer3D.ts"],"sourcesContent":["import {\n Scene,\n PerspectiveCamera,\n WebGLRenderer,\n Clock,\n AmbientLight,\n DirectionalLight,\n AnimationMixer,\n AnimationClip,\n Mesh,\n Material,\n Group,\n} from 'three';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n\nexport interface ThreeContextParams {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width: number;\n height: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class ThreeContext {\n scene: Scene;\n camera: PerspectiveCamera;\n renderer: WebGLRenderer;\n clock: Clock;\n gltfLoader: GLTFLoader;\n mixers: Map<number, AnimationMixer> = new Map();\n models: Map<number, Group> = new Map();\n\n constructor(params: ThreeContextParams) {\n const {\n canvas,\n container,\n width,\n height,\n antialias = true,\n backgroundColor = 0x000000,\n backgroundAlpha = 1,\n } = params;\n\n this.scene = new Scene();\n\n this.camera = new PerspectiveCamera(75, width / height, 0.1, 1000);\n this.camera.position.z = 5;\n\n const rendererOpts: any = { antialias };\n if (canvas) {\n rendererOpts.canvas = canvas;\n }\n if (backgroundAlpha < 1) {\n rendererOpts.alpha = true;\n }\n\n this.renderer = new WebGLRenderer(rendererOpts);\n this.renderer.setSize(width, height);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setClearColor(backgroundColor, backgroundAlpha);\n\n // If no canvas was provided but a container was, append the generated canvas\n if (!canvas && container) {\n container.appendChild(this.renderer.domElement);\n }\n\n const ambientLight = new AmbientLight(0xffffff, 0.6);\n this.scene.add(ambientLight);\n const directionalLight = new DirectionalLight(0xffffff, 0.8);\n directionalLight.position.set(5, 10, 7.5);\n this.scene.add(directionalLight);\n\n this.clock = new Clock();\n this.gltfLoader = new GLTFLoader();\n }\n\n update() {\n const delta = this.clock.getDelta();\n for (const mixer of this.mixers.values()) {\n mixer.update(delta);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n async loadGLB(id: number, url: string): Promise<Group> {\n return new Promise((resolve, reject) => {\n this.gltfLoader.load(url, (gltf) => {\n const model = gltf.scene;\n this.scene.add(model);\n this.models.set(id, model);\n\n if (gltf.animations && gltf.animations.length > 0) {\n const mixer = new AnimationMixer(model);\n this.mixers.set(id, mixer);\n model.userData.animations = gltf.animations;\n }\n\n resolve(model);\n }, undefined, (error) => {\n reject(error);\n });\n });\n }\n\n playAnimation(id: number, animationIndex: number, speed: number) {\n const mixer = this.mixers.get(id);\n const model = this.models.get(id);\n if (!mixer || !model) return;\n\n mixer.stopAllAction();\n const animations = model.userData.animations as AnimationClip[];\n if (animations && animations[animationIndex]) {\n const action = mixer.clipAction(animations[animationIndex]);\n action.timeScale = speed;\n action.play();\n }\n }\n\n stopAnimation(id: number) {\n const mixer = this.mixers.get(id);\n if (mixer) mixer.stopAllAction();\n }\n\n removeModel(id: number) {\n const model = this.models.get(id);\n if (model) {\n this.scene.remove(model);\n model.traverse((child) => {\n const mesh = child as Mesh;\n if (mesh.geometry) {\n mesh.geometry.dispose();\n }\n if (mesh.material) {\n const materials = Array.isArray(mesh.material)\n ? mesh.material as Material[]\n : [mesh.material as Material];\n materials.forEach(m => m.dispose());\n }\n });\n this.models.delete(id);\n }\n const mixer = this.mixers.get(id);\n if (mixer) {\n mixer.stopAllAction();\n this.mixers.delete(id);\n }\n }\n\n resize(width: number, height: number) {\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height);\n }\n\n destroy() {\n for (const id of this.models.keys()) {\n this.removeModel(id);\n }\n this.renderer.dispose();\n this.renderer.domElement.remove();\n this.scene = null;\n this.camera = null;\n this.renderer = null;\n this.clock = null;\n this.gltfLoader = null;\n }\n}\n","import { GameObject, Game, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type Renderer3D from './Renderer3D';\nimport type Renderer3DSystem from './system';\n\nexport default class Renderer3DManager {\n game: Game;\n rendererSystem: Renderer3DSystem;\n renderers: Renderer3D[] = [];\n\n constructor({ game, rendererSystem }: { game: Game; rendererSystem: Renderer3DSystem }) {\n this.game = game;\n this.rendererSystem = rendererSystem;\n }\n\n register(...renderers: Renderer3D[]) {\n for (const renderer of renderers) {\n renderer.game = this.game;\n renderer.rendererManager = this;\n renderer.threeContext = this.rendererSystem.threeContext;\n this.renderers.push(renderer);\n }\n }\n\n componentChanged(changes: ComponentChanged[]) {\n for (const changed of changes) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[changed.componentName];\n if (!props) continue;\n\n if (changed.type === OBSERVER_TYPE.ADD || changed.type === OBSERVER_TYPE.REMOVE) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject.name}, ${changed.componentName} error.`,\n changed,\n e,\n );\n }\n continue;\n }\n\n // CHANGE type: check if the changed prop matches\n const index = props.findIndex((prop) => {\n if (typeof prop === 'string' && typeof changed.prop === 'string') {\n return prop === changed.prop;\n }\n // Deep comparison for object-style props\n return JSON.stringify(prop) === JSON.stringify(changed.prop);\n });\n\n if (index > -1) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject?.name}, ${changed.componentName} componentChanged error.`,\n changed,\n e,\n );\n }\n }\n }\n }\n }\n\n update(gameObject: GameObject) {\n for (const component of gameObject.components) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[component.name];\n if (props) {\n try {\n renderer.rendererUpdate(gameObject);\n } catch (e) {\n console.info(\n `gameObject: ${gameObject.name}, ${component.name} update error`,\n e,\n );\n }\n }\n }\n }\n }\n}\n","import { System } from '@combos-fun/engine';\nimport type { UpdateParams } from '@combos-fun/engine';\nimport ThreeContext from './ThreeContext';\nimport type { ThreeContextParams } from './ThreeContext';\nimport Renderer3DManager from './Renderer3DManager';\n\nexport interface Renderer3DSystemParams extends Partial<ThreeContextParams> {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width?: number;\n height?: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class Renderer3DSystem extends System<Renderer3DSystemParams> {\n static systemName = 'Renderer3DSystem';\n name: string = 'Renderer3DSystem';\n threeContext: ThreeContext;\n rendererManager: Renderer3DManager;\n\n init(params?: Renderer3DSystemParams) {\n const opts = params || {};\n const width = opts.width || 750;\n const height = opts.height || 1000;\n\n this.threeContext = new ThreeContext({\n canvas: opts.canvas,\n container: opts.container,\n width,\n height,\n antialias: opts.antialias,\n backgroundColor: opts.backgroundColor,\n backgroundAlpha: opts.backgroundAlpha,\n });\n\n this.game.canvas = this.threeContext.renderer.domElement;\n\n this.rendererManager = new Renderer3DManager({\n game: this.game,\n rendererSystem: this,\n });\n }\n\n update(e?: UpdateParams) {\n for (const gameObject of this.game.gameObjects) {\n this.rendererManager.update(gameObject);\n }\n }\n\n lateUpdate() {\n this.threeContext?.update();\n }\n\n resize(width: number, height: number) {\n this.threeContext?.resize(width, height);\n }\n\n onDestroy(): void {\n this.threeContext?.destroy();\n this.threeContext = null;\n }\n}\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport Renderer3DSystem from './system';\n\nObject.assign(Renderer3DSystem, {\n packageName: \"@combos-fun/plugin-renderer-3d\",\n packageVersion: \"0.0.39\",\n});\n","import { Game, PureObserverInfo, ComponentChanged, System, GameObject, UpdateParams } from '@combos-fun/engine';\nimport type Renderer3DManager from './Renderer3DManager';\nimport type ThreeContext from './ThreeContext';\n\nexport default class Renderer3D<T extends {} = {}> extends System<T> {\n name: string;\n game: Game;\n static observerInfo: PureObserverInfo;\n observerInfo: PureObserverInfo;\n rendererManager: Renderer3DManager;\n threeContext: ThreeContext;\n\n constructor(params?: T) {\n super(params);\n const Ctor = this.constructor as typeof Renderer3D & { observerInfo: PureObserverInfo };\n this.observerInfo = Ctor.observerInfo;\n }\n\n componentChanged(_changed: ComponentChanged) {}\n rendererUpdate(_gameObject: GameObject) {}\n\n override update(e?: UpdateParams): void {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n protected asyncIdMap: Record<number, number> = {};\n\n protected increaseAsyncId(id: number) {\n this.asyncIdMap[id] = (this.asyncIdMap[id] || 0) + 1;\n return this.asyncIdMap[id];\n }\n\n protected validateAsyncId(id: number, asyncId: number) {\n return this.asyncIdMap[id] === asyncId;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-3d.esm.js","sources":["../lib/tagObject3D.ts","../lib/ThreeContext.ts","../lib/Renderer3DManager.ts","../lib/system.ts","../lib/__combosPackageMeta.gen.ts","../lib/Renderer3D.ts","../lib/namedResource.ts"],"sourcesContent":["import type { Object3D } from 'three';\n\nexport const COMBOS_GAME_OBJECT_ID = 'combosGameObjectId';\n\n/** Stamp a Three.js object (and its children) so Event3D raycasts can resolve the GameObject. */\nexport function tagObject3D(object: Object3D, gameObjectId: number): void {\n object.traverse((child) => {\n child.userData[COMBOS_GAME_OBJECT_ID] = gameObjectId;\n });\n}\n\nexport function gameObjectIdFromObject3D(object: Object3D | null | undefined): number | undefined {\n let current = object;\n while (current) {\n const id = current.userData?.[COMBOS_GAME_OBJECT_ID];\n if (typeof id === 'number') {\n return id;\n }\n current = current.parent;\n }\n return undefined;\n}\n","import {\n Scene,\n PerspectiveCamera,\n WebGLRenderer,\n Clock,\n AmbientLight,\n DirectionalLight,\n AnimationMixer,\n AnimationClip,\n Mesh,\n Material,\n Group,\n} from 'three';\nimport { tagObject3D } from './tagObject3D';\n\nexport interface ThreeContextParams {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width: number;\n height: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class ThreeContext {\n scene: Scene;\n camera: PerspectiveCamera;\n renderer: WebGLRenderer;\n clock: Clock;\n mixers: Map<number, AnimationMixer> = new Map();\n models: Map<number, Group> = new Map();\n\n constructor(params: ThreeContextParams) {\n const {\n canvas,\n container,\n width,\n height,\n antialias = true,\n backgroundColor = 0x000000,\n backgroundAlpha = 1,\n } = params;\n\n this.scene = new Scene();\n\n this.camera = new PerspectiveCamera(75, width / height, 0.1, 1000);\n this.camera.position.z = 5;\n\n const rendererOpts: any = { antialias };\n if (canvas) {\n rendererOpts.canvas = canvas;\n }\n if (backgroundAlpha < 1) {\n rendererOpts.alpha = true;\n }\n\n this.renderer = new WebGLRenderer(rendererOpts);\n this.renderer.setSize(width, height);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setClearColor(backgroundColor, backgroundAlpha);\n\n // If no canvas was provided but a container was, append the generated canvas\n if (!canvas && container) {\n container.appendChild(this.renderer.domElement);\n }\n\n const ambientLight = new AmbientLight(0xffffff, 0.6);\n this.scene.add(ambientLight);\n const directionalLight = new DirectionalLight(0xffffff, 0.8);\n directionalLight.position.set(5, 10, 7.5);\n this.scene.add(directionalLight);\n\n this.clock = new Clock();\n }\n\n update() {\n const delta = this.clock.getDelta();\n for (const mixer of this.mixers.values()) {\n mixer.update(delta);\n }\n this.renderer.render(this.scene, this.camera);\n }\n\n attachParsedModel(id: number, model: Group, animations?: AnimationClip[]): Group {\n tagObject3D(model, id);\n this.scene.add(model);\n this.models.set(id, model);\n\n if (animations && animations.length > 0) {\n const mixer = new AnimationMixer(model);\n this.mixers.set(id, mixer);\n model.userData.animations = animations;\n }\n\n return model;\n }\n\n playAnimation(id: number, animationIndex: number, speed: number) {\n const mixer = this.mixers.get(id);\n const model = this.models.get(id);\n if (!mixer || !model) return;\n\n mixer.stopAllAction();\n const animations = model.userData.animations as AnimationClip[];\n if (animations && animations[animationIndex]) {\n const action = mixer.clipAction(animations[animationIndex]);\n action.timeScale = speed;\n action.play();\n }\n }\n\n stopAnimation(id: number) {\n const mixer = this.mixers.get(id);\n if (mixer) mixer.stopAllAction();\n }\n\n removeModel(id: number) {\n const model = this.models.get(id);\n if (model) {\n this.scene.remove(model);\n model.traverse((child) => {\n const mesh = child as Mesh;\n if (mesh.geometry) {\n mesh.geometry.dispose();\n }\n if (mesh.material) {\n const materials = Array.isArray(mesh.material)\n ? mesh.material as Material[]\n : [mesh.material as Material];\n materials.forEach(m => m.dispose());\n }\n });\n this.models.delete(id);\n }\n const mixer = this.mixers.get(id);\n if (mixer) {\n mixer.stopAllAction();\n this.mixers.delete(id);\n }\n }\n\n resize(width: number, height: number) {\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height);\n }\n\n destroy() {\n for (const id of this.models.keys()) {\n this.removeModel(id);\n }\n this.renderer.dispose();\n this.renderer.domElement.remove();\n this.scene = null;\n this.camera = null;\n this.renderer = null;\n this.clock = null;\n }\n}\n","import { GameObject, Game, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type Renderer3D from './Renderer3D';\nimport type Renderer3DSystem from './system';\n\nexport default class Renderer3DManager {\n game: Game;\n rendererSystem: Renderer3DSystem;\n renderers: Renderer3D[] = [];\n\n constructor({ game, rendererSystem }: { game: Game; rendererSystem: Renderer3DSystem }) {\n this.game = game;\n this.rendererSystem = rendererSystem;\n }\n\n register(...renderers: Renderer3D[]) {\n for (const renderer of renderers) {\n renderer.game = this.game;\n renderer.rendererManager = this;\n renderer.threeContext = this.rendererSystem.threeContext;\n this.renderers.push(renderer);\n }\n }\n\n componentChanged(changes: ComponentChanged[]) {\n for (const changed of changes) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[changed.componentName];\n if (!props) continue;\n\n if (changed.type === OBSERVER_TYPE.ADD || changed.type === OBSERVER_TYPE.REMOVE) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject.name}, ${changed.componentName} error.`,\n changed,\n e,\n );\n }\n continue;\n }\n\n // CHANGE type: check if the changed prop matches\n const index = props.findIndex((prop) => {\n if (typeof prop === 'string' && typeof changed.prop === 'string') {\n return prop === changed.prop;\n }\n // Deep comparison for object-style props\n return JSON.stringify(prop) === JSON.stringify(changed.prop);\n });\n\n if (index > -1) {\n try {\n renderer.componentChanged(changed);\n } catch (e) {\n console.error(\n `gameObject: ${changed.gameObject?.name}, ${changed.componentName} componentChanged error.`,\n changed,\n e,\n );\n }\n }\n }\n }\n }\n\n update(gameObject: GameObject) {\n for (const component of gameObject.components) {\n for (const renderer of this.renderers) {\n const props = renderer.observerInfo[component.name];\n if (props) {\n try {\n renderer.rendererUpdate(gameObject);\n } catch (e) {\n console.info(\n `gameObject: ${gameObject.name}, ${component.name} update error`,\n e,\n );\n }\n }\n }\n }\n }\n}\n","import { System } from '@combos-fun/engine';\nimport type { UpdateParams } from '@combos-fun/engine';\nimport ThreeContext from './ThreeContext';\nimport type { ThreeContextParams } from './ThreeContext';\nimport Renderer3DManager from './Renderer3DManager';\n\nexport interface Renderer3DSystemParams extends Partial<ThreeContextParams> {\n canvas?: HTMLCanvasElement;\n container?: HTMLElement;\n width?: number;\n height?: number;\n antialias?: boolean;\n backgroundColor?: number;\n backgroundAlpha?: number;\n}\n\nexport default class Renderer3DSystem extends System<Renderer3DSystemParams> {\n static systemName = 'Renderer3DSystem';\n name: string = 'Renderer3DSystem';\n threeContext: ThreeContext;\n rendererManager: Renderer3DManager;\n\n init(params?: Renderer3DSystemParams) {\n const opts = params || {};\n const width = opts.width || 750;\n const height = opts.height || 1334;\n\n this.threeContext = new ThreeContext({\n canvas: opts.canvas,\n container: opts.container,\n width,\n height,\n antialias: opts.antialias,\n backgroundColor: opts.backgroundColor,\n backgroundAlpha: opts.backgroundAlpha,\n });\n\n this.game.canvas = this.threeContext.renderer.domElement;\n\n this.rendererManager = new Renderer3DManager({\n game: this.game,\n rendererSystem: this,\n });\n }\n\n update(e?: UpdateParams) {\n for (const gameObject of this.game.gameObjects) {\n this.rendererManager.update(gameObject);\n }\n }\n\n lateUpdate() {\n this.threeContext?.update();\n }\n\n resize(width: number, height: number) {\n this.threeContext?.resize(width, height);\n }\n\n onDestroy(): void {\n this.threeContext?.destroy();\n this.threeContext = null;\n }\n}\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport Renderer3DSystem from './system';\n\nObject.assign(Renderer3DSystem, {\n packageName: \"@combos-fun/plugin-renderer-3d\",\n packageVersion: \"0.0.40\",\n});\n","import { Game, PureObserverInfo, ComponentChanged, System, GameObject, UpdateParams } from '@combos-fun/engine';\nimport type Renderer3DManager from './Renderer3DManager';\nimport type ThreeContext from './ThreeContext';\n\nexport default class Renderer3D<T extends {} = {}> extends System<T> {\n name: string;\n game: Game;\n static observerInfo: PureObserverInfo;\n observerInfo: PureObserverInfo;\n rendererManager: Renderer3DManager;\n threeContext: ThreeContext;\n\n constructor(params?: T) {\n super(params);\n const Ctor = this.constructor as typeof Renderer3D & { observerInfo: PureObserverInfo };\n this.observerInfo = Ctor.observerInfo;\n }\n\n componentChanged(_changed: ComponentChanged) {}\n rendererUpdate(_gameObject: GameObject) {}\n\n override update(e?: UpdateParams): void {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n protected asyncIdMap: Record<number, number> = {};\n\n protected increaseAsyncId(id: number) {\n this.asyncIdMap[id] = (this.asyncIdMap[id] || 0) + 1;\n return this.asyncIdMap[id];\n }\n\n protected validateAsyncId(id: number, asyncId: number) {\n return this.asyncIdMap[id] === asyncId;\n }\n}\n","import { resource } from '@combos-fun/engine';\nimport type { ResourceStruct } from '@combos-fun/engine';\nimport { SRGBColorSpace, Texture } from 'three';\n\nexport async function requireNamedResource(name: string): Promise<ResourceStruct> {\n const trimmed = String(name ?? '').trim();\n if (!trimmed) {\n throw new Error('resource name is required; register it with resource.addResource');\n }\n const res = await resource.getResource(trimmed);\n if (!res || !res.name) {\n throw new Error(\n `Unknown resource \"${trimmed}\"; register it with resource.addResource first`,\n );\n }\n return res;\n}\n\nexport function textureFromResourceImage(res: ResourceStruct): Texture {\n const image = res.data?.image as HTMLImageElement | undefined;\n if (!image) {\n throw new Error(\n `Resource \"${res.name}\" has no image data; use RESOURCE_TYPE.IMAGE with src.image.url`,\n );\n }\n const texture = new Texture(image);\n texture.colorSpace = SRGBColorSpace;\n texture.needsUpdate = true;\n return texture;\n}\n\nexport async function textureFromNamedImage(name: string): Promise<Texture> {\n // Always build a Three.Texture from data.image so 2D Pixi\n // registerInstance(IMAGE) is never overwritten or reused.\n return textureFromResourceImage(await requireNamedResource(name));\n}\n"],"names":[],"mappings":"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"}
|