@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 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` / `GLTFLoader`.
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` | `1000` |
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`, `GLTFLoader`
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: 1000 }),
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
- - 3D Component fields use **direct URL strings** for `resource`
98
- (unlike 2D which uses engine resource names).
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: 1000,
136
+ height: 1334,
127
137
  }),
128
138
  ],
129
139
  });
@@ -11,6 +11,9 @@
11
11
  "Renderer3DSystem",
12
12
  "Renderer3D",
13
13
  "Renderer3DManager",
14
- "ThreeContext"
14
+ "ThreeContext",
15
+ "tagObject3D",
16
+ "requireNamedResource",
17
+ "textureFromNamedImage"
15
18
  ]
16
19
  }
@@ -2,7 +2,25 @@
2
2
 
3
3
  var engine = require('@combos-fun/engine');
4
4
  var three = require('three');
5
- var GLTFLoader_js = require('three/addons/loaders/GLTFLoader.js');
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
- async loadGLB(id, url) {
46
- return new Promise((resolve, reject) => {
47
- this.gltfLoader.load(url, (gltf) => {
48
- const model = gltf.scene;
49
- this.scene.add(model);
50
- this.models.set(id, model);
51
- if (gltf.animations && gltf.animations.length > 0) {
52
- const mixer = new three.AnimationMixer(model);
53
- this.mixers.set(id, mixer);
54
- model.userData.animations = gltf.animations;
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 || 1000;
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.39",
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"),r=require("three/addons/loaders/GLTFLoader.js");class s{constructor(e){this.mixers=new Map,this.models=new Map;const{canvas:s,container:n,width:o,height:i,antialias:a=!0,backgroundColor:c=0,backgroundAlpha:h=1}=e;this.scene=new t.Scene,this.camera=new t.PerspectiveCamera(75,o/i,.1,1e3),this.camera.position.z=5;const d={antialias:a};s&&(d.canvas=s),h<1&&(d.alpha=!0),this.renderer=new t.WebGLRenderer(d),this.renderer.setSize(o,i),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setClearColor(c,h),!s&&n&&n.appendChild(this.renderer.domElement);const m=new t.AmbientLight(16777215,.6);this.scene.add(m);const l=new t.DirectionalLight(16777215,.8);l.position.set(5,10,7.5),this.scene.add(l),this.clock=new t.Clock,this.gltfLoader=new r.GLTFLoader}update(){const e=this.clock.getDelta();for(const t of this.mixers.values())t.update(e);this.renderer.render(this.scene,this.camera)}async loadGLB(e,r){return new Promise((s,n)=>{this.gltfLoader.load(r,r=>{const n=r.scene;if(this.scene.add(n),this.models.set(e,n),r.animations&&r.animations.length>0){const s=new t.AnimationMixer(n);this.mixers.set(e,s),n.userData.animations=r.animations}s(n)},void 0,e=>{n(e)})})}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,this.gltfLoader=null}}class n{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 o extends e.System{constructor(){super(...arguments),this.name="Renderer3DSystem"}static{this.systemName="Renderer3DSystem"}init(e){const t=e||{},r=t.width||750,o=t.height||1e3;this.threeContext=new s({canvas:t.canvas,container:t.container,width:r,height:o,antialias:t.antialias,backgroundColor:t.backgroundColor,backgroundAlpha:t.backgroundAlpha}),this.game.canvas=this.threeContext.renderer.domElement,this.rendererManager=new n({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(o,{packageName:"@combos-fun/plugin-renderer-3d",packageVersion:"0.0.39"});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}}exports.Renderer3D=i,exports.Renderer3DManager=n,exports.Renderer3DSystem=o,exports.ThreeContext=s;
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
- loadGLB(id: number, url: string): Promise<Group>;
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
- export { Renderer3D, Renderer3DManager, Renderer3DSystem, ThreeContext };
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
- import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
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
- async loadGLB(id, url) {
44
- return new Promise((resolve, reject) => {
45
- this.gltfLoader.load(url, (gltf) => {
46
- const model = gltf.scene;
47
- this.scene.add(model);
48
- this.models.set(id, model);
49
- if (gltf.animations && gltf.animations.length > 0) {
50
- const mixer = new AnimationMixer(model);
51
- this.mixers.set(id, mixer);
52
- model.userData.animations = gltf.animations;
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 || 1000;
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.39",
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
- export { Renderer3D, Renderer3DManager, Renderer3DSystem, ThreeContext };
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@combos-fun/plugin-renderer-3d",
3
- "version": "0.0.39",
3
+ "version": "0.0.40",
4
4
  "main": "index.js",
5
5
  "module": "dist/plugin-renderer-3d.esm.js",
6
6
  "bundle": "CombosFun.plugin.renderer.3d",