@combos-fun/plugin-renderer-3d-sprite-animation 0.0.39 → 0.0.41

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-sprite-animation` — Agent notes
2
2
 
3
- Spritesheet animation projected onto a `PlaneGeometry` in 3D space. Animates UV offsets each frame to flip through frames from a Texture Packer JSON sheet.
3
+ Spritesheet animation projected onto a `PlaneGeometry` in 3D space. Animates UV offsets each frame. `resource` is an engine **name** (`RESOURCE_TYPE.SPRITE_ANIMATION` with both `src.image` and `src.json`), never a URL.
4
4
 
5
5
  ## When to read
6
6
 
@@ -18,25 +18,38 @@ import { SpriteAnimation3D, SpriteAnimation3DSystem, type SpriteAnimation3DParam
18
18
 
19
19
  | Field | Type | Default |
20
20
  |-------|------|---------|
21
- | `resource` | `string` | `''` (Texture Packer JSON URL — direct) |
21
+ | `resource` | `string` | `''` (engine resource name, `RESOURCE_TYPE.SPRITE_ANIMATION`) |
22
22
  | `autoPlay` | `boolean` | `true` |
23
23
  | `speed` | `number` | `100` (ms per frame) |
24
24
  | `positionX` / `Y` / `Z` | `number` | `0` |
25
25
  | `rotationX` / `Y` / `Z` | `number` | `0` |
26
26
  | `scaleX` / `Y` | `number` | `1` (no `scaleZ` — plane is 2D) |
27
27
 
28
- The system fetches the JSON URL directly (not an engine `resource` name). It reads top-level `frames` (array or name-map) and `meta.image` / `meta.size`. Image URL is resolved relative to the JSON path.
28
+ The system reads `data.json` (`frames` array or name-map, plus `meta.size` when present) and `data.image`. It does **not** overwrite the 2D Pixi `SPRITE_ANIMATION` instance.
29
29
 
30
30
  ## Required setup
31
31
 
32
- `Renderer3DSystem` then `SpriteAnimation3DSystem`. The JSON must reference a co-located image file.
32
+ `Renderer3DSystem` then `SpriteAnimation3DSystem`. Register both image and json slots:
33
+
34
+ ```ts
35
+ resource.addResource([{
36
+ name: 'explosion',
37
+ type: RESOURCE_TYPE.SPRITE_ANIMATION,
38
+ src: {
39
+ image: { type: 'png', url: 'https://cdn.example/explosion.png' },
40
+ json: { type: 'json', url: 'https://cdn.example/explosion.json' },
41
+ },
42
+ preload: true,
43
+ }]);
44
+ ```
33
45
 
34
46
  ## Common pitfalls
35
47
 
36
48
  | Symptom | Fix |
37
49
  |---------|-----|
38
- | Animation never starts | `autoPlay` defaults to `true`; if you set `false`, drive `play()` from a Component lifecycle hook |
39
- | Black plane / load error | JSON must have top-level `frames` plus `meta.image` and `meta.size` |
50
+ | `Unknown resource` / missing json | Register `RESOURCE_TYPE.SPRITE_ANIMATION` with both `image` and `json` slots; do not pass a JSON URL to `resource` |
51
+ | Animation never starts | `autoPlay` defaults to `true` |
52
+ | Black plane / load error | JSON must have top-level `frames`; `meta.size` is optional (falls back to image size) |
40
53
  | Frames in wrong order | Hash `frames` keys are `Object.keys().sort()`; prefer array `frames` for playback order |
41
54
  | Stuck on first frame | Single-frame sheet; verify the JSON contains multiple frame entries |
42
55
 
@@ -45,7 +58,7 @@ The system fetches the JSON URL directly (not an engine `resource` name). It rea
45
58
  ```ts
46
59
  const fx = new GameObject('explosion');
47
60
  fx.addComponent(new SpriteAnimation3D({
48
- resource: '/assets/explosion.json',
61
+ resource: 'explosion',
49
62
  autoPlay: true,
50
63
  speed: 80,
51
64
  positionZ: -1,
@@ -32,7 +32,7 @@ tslib.__decorate([
32
32
  type: 'string',
33
33
  group: 'SpriteAnimation3D',
34
34
  label: 'resource',
35
- description: 'Resource id from the asset registry.',
35
+ description: 'Engine resource name registered with RESOURCE_TYPE.SPRITE_ANIMATION.',
36
36
  editor: 'text',
37
37
  })
38
38
  ], SpriteAnimation3D.prototype, "resource", void 0);
@@ -141,7 +141,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
141
141
  super(...arguments);
142
142
  this.name = 'SpriteAnimation3DSystem';
143
143
  this.entries = new Map();
144
- this.textureLoader = new three.TextureLoader();
145
144
  }
146
145
  static { this.systemName = 'SpriteAnimation3DSystem'; }
147
146
  init() {
@@ -186,22 +185,25 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
186
185
  return;
187
186
  const asyncId = this.increaseAsyncId(gameObject.id);
188
187
  try {
189
- const response = await fetch(component.resource);
190
- const json = await response.json();
188
+ const res = await pluginRenderer3d.requireNamedResource(component.resource);
191
189
  if (!this.validateAsyncId(gameObject.id, asyncId))
192
190
  return;
193
- const meta = json.meta;
194
- const framesData = json.frames;
195
- const imageUrl = this.resolveImageUrl(component.resource, meta.image);
196
- const texture = await this.loadTexture(imageUrl);
191
+ const json = res.data?.json;
192
+ if (!json) {
193
+ throw new Error(`Resource "${res.name}" has no json data; use RESOURCE_TYPE.SPRITE_ANIMATION with src.image and src.json`);
194
+ }
195
+ const texture = pluginRenderer3d.textureFromResourceImage(res);
197
196
  if (!this.validateAsyncId(gameObject.id, asyncId)) {
198
197
  texture.dispose();
199
198
  return;
200
199
  }
201
- const frames = this.parseFrames(framesData);
202
- const sheetWidth = meta.size.w;
203
- const sheetHeight = meta.size.h;
200
+ const frames = this.parseFrames(json.frames);
201
+ const sheetWidth = json.meta?.size?.w || texture.image?.width || 1;
202
+ const sheetHeight = json.meta?.size?.h || texture.image?.height || 1;
204
203
  const firstFrame = frames[0];
204
+ if (!firstFrame) {
205
+ throw new Error(`Resource "${res.name}" spritesheet has no frames`);
206
+ }
205
207
  const aspectRatio = firstFrame.w / firstFrame.h;
206
208
  const geometry = new three.PlaneGeometry(aspectRatio, 1);
207
209
  const material = new three.MeshBasicMaterial({
@@ -210,6 +212,7 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
210
212
  side: three.DoubleSide,
211
213
  });
212
214
  const mesh = new three.Mesh(geometry, material);
215
+ pluginRenderer3d.tagObject3D(mesh, gameObject.id);
213
216
  const entry = {
214
217
  mesh,
215
218
  texture,
@@ -229,6 +232,7 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
229
232
  }
230
233
  catch (e) {
231
234
  console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);
235
+ throw e;
232
236
  }
233
237
  }
234
238
  handleChange(changed) {
@@ -265,7 +269,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
265
269
  h: f.frame.h,
266
270
  }));
267
271
  }
268
- // Object-based format: { "frameName": { frame: { x, y, w, h } } }
269
272
  return Object.keys(framesData)
270
273
  .sort()
271
274
  .map((key) => ({
@@ -275,15 +278,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends pluginRender
275
278
  h: framesData[key].frame.h,
276
279
  }));
277
280
  }
278
- resolveImageUrl(jsonUrl, imageName) {
279
- const base = jsonUrl.substring(0, jsonUrl.lastIndexOf('/') + 1);
280
- return base + imageName;
281
- }
282
- loadTexture(url) {
283
- return new Promise((resolve, reject) => {
284
- this.textureLoader.load(url, resolve, undefined, reject);
285
- });
286
- }
287
281
  onDestroy() {
288
282
  for (const [id] of this.entries) {
289
283
  this.handleRemove(id);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-renderer-3d-sprite-animation.cjs.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface SpriteAnimation3DParams {\n resource?: string;\n autoPlay?: boolean;\n speed?: number;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n scaleX?: number;\n scaleY?: number;\n}\n\nexport default class SpriteAnimation3D extends Component<SpriteAnimation3DParams> {\n static componentName: string = 'SpriteAnimation3D';\n\n @Field({\n\n type: 'string',\n\n group: 'SpriteAnimation3D',\n\n label: 'resource',\n\n description: 'Resource id from the asset registry.',\n\n editor: 'text',\n\n })\n\n resource: string = '';\n @Field({\n type: 'boolean',\n group: 'SpriteAnimation3D',\n label: 'autoPlay',\n description: 'Start playing automatically when loaded.',\n editor: 'toggle',\n })\n autoPlay: boolean = true;\n @Field({\n type: 'number',\n step: 10,\n group: 'SpriteAnimation3D',\n label: 'speed',\n description: 'Playback speed.',\n editor: 'number-stepper',\n })\n speed: number = 100;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleX',\n description: 'Scale on X.',\n editor: 'number-stepper',\n })\n scaleX: number = 1;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleY',\n description: 'Scale on Y.',\n editor: 'number-stepper',\n })\n scaleY: number = 1;\n\n init(obj?: SpriteAnimation3DParams) {\n if (obj) Object.assign(this, obj);\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem } from '@combos-fun/plugin-renderer-3d';\nimport {\n TextureLoader,\n PlaneGeometry,\n MeshBasicMaterial,\n Mesh,\n DoubleSide,\n} from 'three';\nimport type { Texture } from 'three';\nimport SpriteAnimation3D from './component';\n\ninterface FrameData {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface SpriteAnimation3DEntry {\n mesh: Mesh;\n texture: Texture;\n frames: FrameData[];\n sheetWidth: number;\n sheetHeight: number;\n currentFrame: number;\n elapsed: number;\n playing: boolean;\n}\n\n@decorators.componentObserver({\n SpriteAnimation3D: [\n 'resource', 'speed',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n 'scaleX', 'scaleY',\n ],\n})\nexport default class SpriteAnimation3DSystem extends Renderer3D {\n static systemName = 'SpriteAnimation3DSystem';\n name: string = 'SpriteAnimation3DSystem';\n\n private entries: Map<number, SpriteAnimation3DEntry> = new Map();\n private textureLoader = new TextureLoader();\n\n init() {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'SpriteAnimation3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as SpriteAnimation3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(SpriteAnimation3D) as SpriteAnimation3D;\n if (!component) return;\n\n const entry = this.entries.get(gameObject.id);\n if (!entry) return;\n\n entry.mesh.position.set(component.positionX, component.positionY, component.positionZ);\n entry.mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n entry.mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n if (!entry.playing || entry.frames.length === 0) return;\n\n const delta = this.threeContext.clock.getDelta() * 1000;\n entry.elapsed += delta;\n\n if (entry.elapsed >= component.speed) {\n entry.elapsed -= component.speed;\n entry.currentFrame = (entry.currentFrame + 1) % entry.frames.length;\n this.applyFrame(entry);\n }\n }\n\n private async handleAdd(gameObject: GameObject, component: SpriteAnimation3D) {\n if (!component.resource) return;\n\n const asyncId = this.increaseAsyncId(gameObject.id);\n\n try {\n const response = await fetch(component.resource);\n const json = await response.json();\n if (!this.validateAsyncId(gameObject.id, asyncId)) return;\n\n const meta = json.meta;\n const framesData = json.frames;\n const imageUrl = this.resolveImageUrl(component.resource, meta.image);\n\n const texture = await this.loadTexture(imageUrl);\n if (!this.validateAsyncId(gameObject.id, asyncId)) {\n texture.dispose();\n return;\n }\n\n const frames = this.parseFrames(framesData);\n const sheetWidth = meta.size.w;\n const sheetHeight = meta.size.h;\n\n const firstFrame = frames[0];\n const aspectRatio = firstFrame.w / firstFrame.h;\n const geometry = new PlaneGeometry(aspectRatio, 1);\n const material = new MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n\n const entry: SpriteAnimation3DEntry = {\n mesh,\n texture,\n frames,\n sheetWidth,\n sheetHeight,\n currentFrame: 0,\n elapsed: 0,\n playing: component.autoPlay,\n };\n\n this.applyFrame(entry);\n\n mesh.position.set(component.positionX, component.positionY, component.positionZ);\n mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n this.threeContext.scene.add(mesh);\n this.entries.set(gameObject.id, entry);\n } catch (e) {\n console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);\n }\n }\n\n private handleChange(changed: ComponentChanged) {\n const component = changed.component as SpriteAnimation3D;\n const changedProp = changed.prop?.prop?.[0];\n\n if (changedProp === 'resource') {\n this.handleRemove(changed.gameObject.id);\n this.handleAdd(changed.gameObject, component);\n }\n }\n\n private handleRemove(id: number) {\n this.increaseAsyncId(id);\n const entry = this.entries.get(id);\n if (!entry) return;\n\n this.threeContext.scene.remove(entry.mesh);\n entry.mesh.geometry.dispose();\n (entry.mesh.material as MeshBasicMaterial).dispose();\n entry.texture.dispose();\n this.entries.delete(id);\n }\n\n private applyFrame(entry: SpriteAnimation3DEntry) {\n const frame = entry.frames[entry.currentFrame];\n const tex = entry.texture;\n\n tex.offset.set(frame.x / entry.sheetWidth, 1 - (frame.y + frame.h) / entry.sheetHeight);\n tex.repeat.set(frame.w / entry.sheetWidth, frame.h / entry.sheetHeight);\n }\n\n private parseFrames(framesData: any): FrameData[] {\n if (Array.isArray(framesData)) {\n return framesData.map((f: any) => ({\n x: f.frame.x,\n y: f.frame.y,\n w: f.frame.w,\n h: f.frame.h,\n }));\n }\n // Object-based format: { \"frameName\": { frame: { x, y, w, h } } }\n return Object.keys(framesData)\n .sort()\n .map((key) => ({\n x: framesData[key].frame.x,\n y: framesData[key].frame.y,\n w: framesData[key].frame.w,\n h: framesData[key].frame.h,\n }));\n }\n\n private resolveImageUrl(jsonUrl: string, imageName: string): string {\n const base = jsonUrl.substring(0, jsonUrl.lastIndexOf('/') + 1);\n return base + imageName;\n }\n\n private loadTexture(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n this.textureLoader.load(url, resolve, undefined, reject);\n });\n }\n\n onDestroy() {\n for (const [id] of this.entries) {\n this.handleRemove(id);\n }\n this.entries.clear();\n }\n}\n"],"names":["Component","__decorate","Field","Renderer3D","TextureLoader","Renderer3DSystem","OBSERVER_TYPE","PlaneGeometry","MeshBasicMaterial","DoubleSide","Mesh","decorators"],"mappings":"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"}
1
+ {"version":3,"file":"plugin-renderer-3d-sprite-animation.cjs.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface SpriteAnimation3DParams {\n resource?: string;\n autoPlay?: boolean;\n speed?: number;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n scaleX?: number;\n scaleY?: number;\n}\n\nexport default class SpriteAnimation3D extends Component<SpriteAnimation3DParams> {\n static componentName: string = 'SpriteAnimation3D';\n\n @Field({\n\n type: 'string',\n\n group: 'SpriteAnimation3D',\n\n label: 'resource',\n\n description: 'Engine resource name registered with RESOURCE_TYPE.SPRITE_ANIMATION.',\n\n editor: 'text',\n\n })\n\n resource: string = '';\n @Field({\n type: 'boolean',\n group: 'SpriteAnimation3D',\n label: 'autoPlay',\n description: 'Start playing automatically when loaded.',\n editor: 'toggle',\n })\n autoPlay: boolean = true;\n @Field({\n type: 'number',\n step: 10,\n group: 'SpriteAnimation3D',\n label: 'speed',\n description: 'Playback speed.',\n editor: 'number-stepper',\n })\n speed: number = 100;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleX',\n description: 'Scale on X.',\n editor: 'number-stepper',\n })\n scaleX: number = 1;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleY',\n description: 'Scale on Y.',\n editor: 'number-stepper',\n })\n scaleY: number = 1;\n\n init(obj?: SpriteAnimation3DParams) {\n if (obj) Object.assign(this, obj);\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport {\n Renderer3D,\n Renderer3DSystem,\n requireNamedResource,\n tagObject3D,\n textureFromResourceImage,\n} from '@combos-fun/plugin-renderer-3d';\nimport {\n PlaneGeometry,\n MeshBasicMaterial,\n Mesh,\n DoubleSide,\n} from 'three';\nimport type { Texture } from 'three';\nimport SpriteAnimation3D from './component';\n\ninterface FrameData {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface SpriteAnimation3DEntry {\n mesh: Mesh;\n texture: Texture;\n frames: FrameData[];\n sheetWidth: number;\n sheetHeight: number;\n currentFrame: number;\n elapsed: number;\n playing: boolean;\n}\n\n@decorators.componentObserver({\n SpriteAnimation3D: [\n 'resource', 'speed',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n 'scaleX', 'scaleY',\n ],\n})\nexport default class SpriteAnimation3DSystem extends Renderer3D {\n static systemName = 'SpriteAnimation3DSystem';\n name: string = 'SpriteAnimation3DSystem';\n\n private entries: Map<number, SpriteAnimation3DEntry> = new Map();\n\n init() {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'SpriteAnimation3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as SpriteAnimation3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(SpriteAnimation3D) as SpriteAnimation3D;\n if (!component) return;\n\n const entry = this.entries.get(gameObject.id);\n if (!entry) return;\n\n entry.mesh.position.set(component.positionX, component.positionY, component.positionZ);\n entry.mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n entry.mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n if (!entry.playing || entry.frames.length === 0) return;\n\n const delta = this.threeContext.clock.getDelta() * 1000;\n entry.elapsed += delta;\n\n if (entry.elapsed >= component.speed) {\n entry.elapsed -= component.speed;\n entry.currentFrame = (entry.currentFrame + 1) % entry.frames.length;\n this.applyFrame(entry);\n }\n }\n\n private async handleAdd(gameObject: GameObject, component: SpriteAnimation3D) {\n if (!component.resource) return;\n\n const asyncId = this.increaseAsyncId(gameObject.id);\n\n try {\n const res = await requireNamedResource(component.resource);\n if (!this.validateAsyncId(gameObject.id, asyncId)) return;\n\n const json = res.data?.json;\n if (!json) {\n throw new Error(\n `Resource \"${res.name}\" has no json data; use RESOURCE_TYPE.SPRITE_ANIMATION with src.image and src.json`,\n );\n }\n\n const texture = textureFromResourceImage(res);\n if (!this.validateAsyncId(gameObject.id, asyncId)) {\n texture.dispose();\n return;\n }\n\n const frames = this.parseFrames(json.frames);\n const sheetWidth = json.meta?.size?.w || texture.image?.width || 1;\n const sheetHeight = json.meta?.size?.h || texture.image?.height || 1;\n\n const firstFrame = frames[0];\n if (!firstFrame) {\n throw new Error(`Resource \"${res.name}\" spritesheet has no frames`);\n }\n const aspectRatio = firstFrame.w / firstFrame.h;\n const geometry = new PlaneGeometry(aspectRatio, 1);\n const material = new MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n tagObject3D(mesh, gameObject.id);\n\n const entry: SpriteAnimation3DEntry = {\n mesh,\n texture,\n frames,\n sheetWidth,\n sheetHeight,\n currentFrame: 0,\n elapsed: 0,\n playing: component.autoPlay,\n };\n\n this.applyFrame(entry);\n\n mesh.position.set(component.positionX, component.positionY, component.positionZ);\n mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n this.threeContext.scene.add(mesh);\n this.entries.set(gameObject.id, entry);\n } catch (e) {\n console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);\n throw e;\n }\n }\n\n private handleChange(changed: ComponentChanged) {\n const component = changed.component as SpriteAnimation3D;\n const changedProp = changed.prop?.prop?.[0];\n\n if (changedProp === 'resource') {\n this.handleRemove(changed.gameObject.id);\n this.handleAdd(changed.gameObject, component);\n }\n }\n\n private handleRemove(id: number) {\n this.increaseAsyncId(id);\n const entry = this.entries.get(id);\n if (!entry) return;\n\n this.threeContext.scene.remove(entry.mesh);\n entry.mesh.geometry.dispose();\n (entry.mesh.material as MeshBasicMaterial).dispose();\n entry.texture.dispose();\n this.entries.delete(id);\n }\n\n private applyFrame(entry: SpriteAnimation3DEntry) {\n const frame = entry.frames[entry.currentFrame];\n const tex = entry.texture;\n\n tex.offset.set(frame.x / entry.sheetWidth, 1 - (frame.y + frame.h) / entry.sheetHeight);\n tex.repeat.set(frame.w / entry.sheetWidth, frame.h / entry.sheetHeight);\n }\n\n private parseFrames(framesData: any): FrameData[] {\n if (Array.isArray(framesData)) {\n return framesData.map((f: any) => ({\n x: f.frame.x,\n y: f.frame.y,\n w: f.frame.w,\n h: f.frame.h,\n }));\n }\n return Object.keys(framesData)\n .sort()\n .map((key) => ({\n x: framesData[key].frame.x,\n y: framesData[key].frame.y,\n w: framesData[key].frame.w,\n h: framesData[key].frame.h,\n }));\n }\n\n onDestroy() {\n for (const [id] of this.entries) {\n this.handleRemove(id);\n }\n this.entries.clear();\n }\n}\n"],"names":["Component","__decorate","Field","Renderer3D","Renderer3DSystem","OBSERVER_TYPE","requireNamedResource","textureFromResourceImage","PlaneGeometry","MeshBasicMaterial","DoubleSide","Mesh","tagObject3D","decorators"],"mappings":"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"}
@@ -1 +1 @@
1
- "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),i=require("@combos-fun/inspector-decorator"),o=require("@combos-fun/plugin-renderer-3d"),r=require("three");class s extends t.Component{constructor(){super(...arguments),this.resource="",this.autoPlay=!0,this.speed=100,this.positionX=0,this.positionY=0,this.positionZ=0,this.rotationX=0,this.rotationY=0,this.rotationZ=0,this.scaleX=1,this.scaleY=1}static{this.componentName="SpriteAnimation3D"}init(e){e&&Object.assign(this,e)}}e.__decorate([i.Field({type:"string",group:"SpriteAnimation3D",label:"resource",description:"Resource id from the asset registry.",editor:"text"})],s.prototype,"resource",void 0),e.__decorate([i.Field({type:"boolean",group:"SpriteAnimation3D",label:"autoPlay",description:"Start playing automatically when loaded.",editor:"toggle"})],s.prototype,"autoPlay",void 0),e.__decorate([i.Field({type:"number",step:10,group:"SpriteAnimation3D",label:"speed",description:"Playback speed.",editor:"number-stepper"})],s.prototype,"speed",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionX",description:"Local X position.",editor:"number-stepper"})],s.prototype,"positionX",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionY",description:"Local Y position.",editor:"number-stepper"})],s.prototype,"positionY",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionZ",description:"Local Z position.",editor:"number-stepper"})],s.prototype,"positionZ",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationX",description:"Rotation around X in radians.",editor:"number-stepper"})],s.prototype,"rotationX",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationY",description:"Rotation around Y in radians.",editor:"number-stepper"})],s.prototype,"rotationY",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationZ",description:"Rotation around Z in radians.",editor:"number-stepper"})],s.prototype,"rotationZ",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"scaleX",description:"Scale on X.",editor:"number-stepper"})],s.prototype,"scaleX",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"scaleY",description:"Scale on Y.",editor:"number-stepper"})],s.prototype,"scaleY",void 0);let n=class extends o.Renderer3D{constructor(){super(...arguments),this.name="SpriteAnimation3DSystem",this.entries=new Map,this.textureLoader=new r.TextureLoader}static{this.systemName="SpriteAnimation3DSystem"}init(){this.game.getSystem(o.Renderer3DSystem).rendererManager.register(this)}componentChanged(e){"SpriteAnimation3D"===e.componentName&&(e.type===t.OBSERVER_TYPE.ADD?this.handleAdd(e.gameObject,e.component):e.type===t.OBSERVER_TYPE.REMOVE?this.handleRemove(e.gameObject.id):this.handleChange(e))}rendererUpdate(e){const t=e.getComponent(s);if(!t)return;const i=this.entries.get(e.id);if(!i)return;if(i.mesh.position.set(t.positionX,t.positionY,t.positionZ),i.mesh.rotation.set(t.rotationX,t.rotationY,t.rotationZ),i.mesh.scale.set(t.scaleX,t.scaleY,1),!i.playing||0===i.frames.length)return;const o=1e3*this.threeContext.clock.getDelta();i.elapsed+=o,i.elapsed>=t.speed&&(i.elapsed-=t.speed,i.currentFrame=(i.currentFrame+1)%i.frames.length,this.applyFrame(i))}async handleAdd(e,t){if(!t.resource)return;const i=this.increaseAsyncId(e.id);try{const o=await fetch(t.resource),s=await o.json();if(!this.validateAsyncId(e.id,i))return;const n=s.meta,a=s.frames,p=this.resolveImageUrl(t.resource,n.image),d=await this.loadTexture(p);if(!this.validateAsyncId(e.id,i))return void d.dispose();const c=this.parseFrames(a),m=n.size.w,l=n.size.h,h=c[0],u=h.w/h.h,y=new r.PlaneGeometry(u,1),g=new r.MeshBasicMaterial({map:d,transparent:!0,side:r.DoubleSide}),b=new r.Mesh(y,g),S={mesh:b,texture:d,frames:c,sheetWidth:m,sheetHeight:l,currentFrame:0,elapsed:0,playing:t.autoPlay};this.applyFrame(S),b.position.set(t.positionX,t.positionY,t.positionZ),b.rotation.set(t.rotationX,t.rotationY,t.rotationZ),b.scale.set(t.scaleX,t.scaleY,1),this.threeContext.scene.add(b),this.entries.set(e.id,S)}catch(e){console.error("SpriteAnimation3DSystem: failed to load spritesheet",e)}}handleChange(e){const t=e.component,i=e.prop?.prop?.[0];"resource"===i&&(this.handleRemove(e.gameObject.id),this.handleAdd(e.gameObject,t))}handleRemove(e){this.increaseAsyncId(e);const t=this.entries.get(e);t&&(this.threeContext.scene.remove(t.mesh),t.mesh.geometry.dispose(),t.mesh.material.dispose(),t.texture.dispose(),this.entries.delete(e))}applyFrame(e){const t=e.frames[e.currentFrame],i=e.texture;i.offset.set(t.x/e.sheetWidth,1-(t.y+t.h)/e.sheetHeight),i.repeat.set(t.w/e.sheetWidth,t.h/e.sheetHeight)}parseFrames(e){return Array.isArray(e)?e.map(e=>({x:e.frame.x,y:e.frame.y,w:e.frame.w,h:e.frame.h})):Object.keys(e).sort().map(t=>({x:e[t].frame.x,y:e[t].frame.y,w:e[t].frame.w,h:e[t].frame.h}))}resolveImageUrl(e,t){return e.substring(0,e.lastIndexOf("/")+1)+t}loadTexture(e){return new Promise((t,i)=>{this.textureLoader.load(e,t,void 0,i)})}onDestroy(){for(const[e]of this.entries)this.handleRemove(e);this.entries.clear()}};n=e.__decorate([t.decorators.componentObserver({SpriteAnimation3D:["resource","speed","positionX","positionY","positionZ","rotationX","rotationY","rotationZ","scaleX","scaleY"]})],n);var a=n;exports.SpriteAnimation3D=s,exports.SpriteAnimation3DSystem=a;
1
+ "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),i=require("@combos-fun/inspector-decorator"),o=require("@combos-fun/plugin-renderer-3d"),r=require("three");class s extends t.Component{constructor(){super(...arguments),this.resource="",this.autoPlay=!0,this.speed=100,this.positionX=0,this.positionY=0,this.positionZ=0,this.rotationX=0,this.rotationY=0,this.rotationZ=0,this.scaleX=1,this.scaleY=1}static{this.componentName="SpriteAnimation3D"}init(e){e&&Object.assign(this,e)}}e.__decorate([i.Field({type:"string",group:"SpriteAnimation3D",label:"resource",description:"Engine resource name registered with RESOURCE_TYPE.SPRITE_ANIMATION.",editor:"text"})],s.prototype,"resource",void 0),e.__decorate([i.Field({type:"boolean",group:"SpriteAnimation3D",label:"autoPlay",description:"Start playing automatically when loaded.",editor:"toggle"})],s.prototype,"autoPlay",void 0),e.__decorate([i.Field({type:"number",step:10,group:"SpriteAnimation3D",label:"speed",description:"Playback speed.",editor:"number-stepper"})],s.prototype,"speed",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionX",description:"Local X position.",editor:"number-stepper"})],s.prototype,"positionX",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionY",description:"Local Y position.",editor:"number-stepper"})],s.prototype,"positionY",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"positionZ",description:"Local Z position.",editor:"number-stepper"})],s.prototype,"positionZ",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationX",description:"Rotation around X in radians.",editor:"number-stepper"})],s.prototype,"rotationX",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationY",description:"Rotation around Y in radians.",editor:"number-stepper"})],s.prototype,"rotationY",void 0),e.__decorate([i.Field({type:"number",step:.01,group:"SpriteAnimation3D",label:"rotationZ",description:"Rotation around Z in radians.",editor:"number-stepper"})],s.prototype,"rotationZ",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"scaleX",description:"Scale on X.",editor:"number-stepper"})],s.prototype,"scaleX",void 0),e.__decorate([i.Field({type:"number",step:.1,group:"SpriteAnimation3D",label:"scaleY",description:"Scale on Y.",editor:"number-stepper"})],s.prototype,"scaleY",void 0);let n=class extends o.Renderer3D{constructor(){super(...arguments),this.name="SpriteAnimation3DSystem",this.entries=new Map}static{this.systemName="SpriteAnimation3DSystem"}init(){this.game.getSystem(o.Renderer3DSystem).rendererManager.register(this)}componentChanged(e){"SpriteAnimation3D"===e.componentName&&(e.type===t.OBSERVER_TYPE.ADD?this.handleAdd(e.gameObject,e.component):e.type===t.OBSERVER_TYPE.REMOVE?this.handleRemove(e.gameObject.id):this.handleChange(e))}rendererUpdate(e){const t=e.getComponent(s);if(!t)return;const i=this.entries.get(e.id);if(!i)return;if(i.mesh.position.set(t.positionX,t.positionY,t.positionZ),i.mesh.rotation.set(t.rotationX,t.rotationY,t.rotationZ),i.mesh.scale.set(t.scaleX,t.scaleY,1),!i.playing||0===i.frames.length)return;const o=1e3*this.threeContext.clock.getDelta();i.elapsed+=o,i.elapsed>=t.speed&&(i.elapsed-=t.speed,i.currentFrame=(i.currentFrame+1)%i.frames.length,this.applyFrame(i))}async handleAdd(e,t){if(!t.resource)return;const i=this.increaseAsyncId(e.id);try{const s=await o.requireNamedResource(t.resource);if(!this.validateAsyncId(e.id,i))return;const n=s.data?.json;if(!n)throw new Error(`Resource "${s.name}" has no json data; use RESOURCE_TYPE.SPRITE_ANIMATION with src.image and src.json`);const a=o.textureFromResourceImage(s);if(!this.validateAsyncId(e.id,i))return void a.dispose();const p=this.parseFrames(n.frames),d=n.meta?.size?.w||a.image?.width||1,c=n.meta?.size?.h||a.image?.height||1,m=p[0];if(!m)throw new Error(`Resource "${s.name}" spritesheet has no frames`);const h=m.w/m.h,l=new r.PlaneGeometry(h,1),u=new r.MeshBasicMaterial({map:a,transparent:!0,side:r.DoubleSide}),y=new r.Mesh(l,u);o.tagObject3D(y,e.id);const g={mesh:y,texture:a,frames:p,sheetWidth:d,sheetHeight:c,currentFrame:0,elapsed:0,playing:t.autoPlay};this.applyFrame(g),y.position.set(t.positionX,t.positionY,t.positionZ),y.rotation.set(t.rotationX,t.rotationY,t.rotationZ),y.scale.set(t.scaleX,t.scaleY,1),this.threeContext.scene.add(y),this.entries.set(e.id,g)}catch(e){throw console.error("SpriteAnimation3DSystem: failed to load spritesheet",e),e}}handleChange(e){const t=e.component,i=e.prop?.prop?.[0];"resource"===i&&(this.handleRemove(e.gameObject.id),this.handleAdd(e.gameObject,t))}handleRemove(e){this.increaseAsyncId(e);const t=this.entries.get(e);t&&(this.threeContext.scene.remove(t.mesh),t.mesh.geometry.dispose(),t.mesh.material.dispose(),t.texture.dispose(),this.entries.delete(e))}applyFrame(e){const t=e.frames[e.currentFrame],i=e.texture;i.offset.set(t.x/e.sheetWidth,1-(t.y+t.h)/e.sheetHeight),i.repeat.set(t.w/e.sheetWidth,t.h/e.sheetHeight)}parseFrames(e){return Array.isArray(e)?e.map(e=>({x:e.frame.x,y:e.frame.y,w:e.frame.w,h:e.frame.h})):Object.keys(e).sort().map(t=>({x:e[t].frame.x,y:e[t].frame.y,w:e[t].frame.w,h:e[t].frame.h}))}onDestroy(){for(const[e]of this.entries)this.handleRemove(e);this.entries.clear()}};n=e.__decorate([t.decorators.componentObserver({SpriteAnimation3D:["resource","speed","positionX","positionY","positionZ","rotationX","rotationY","rotationZ","scaleX","scaleY"]})],n);var a=n;exports.SpriteAnimation3D=s,exports.SpriteAnimation3DSystem=a;
@@ -34,7 +34,6 @@ declare class SpriteAnimation3DSystem extends Renderer3D {
34
34
  static systemName: string;
35
35
  name: string;
36
36
  private entries;
37
- private textureLoader;
38
37
  init(): void;
39
38
  componentChanged(changed: ComponentChanged): void;
40
39
  rendererUpdate(gameObject: GameObject): void;
@@ -43,8 +42,6 @@ declare class SpriteAnimation3DSystem extends Renderer3D {
43
42
  private handleRemove;
44
43
  private applyFrame;
45
44
  private parseFrames;
46
- private resolveImageUrl;
47
- private loadTexture;
48
45
  onDestroy(): void;
49
46
  }
50
47
 
@@ -1,8 +1,8 @@
1
1
  import { __decorate } from 'tslib';
2
2
  import { Component, OBSERVER_TYPE, decorators } from '@combos-fun/engine';
3
3
  import { Field } from '@combos-fun/inspector-decorator';
4
- import { Renderer3D, Renderer3DSystem } from '@combos-fun/plugin-renderer-3d';
5
- import { TextureLoader, PlaneGeometry, MeshBasicMaterial, DoubleSide, Mesh } from 'three';
4
+ import { Renderer3D, Renderer3DSystem, requireNamedResource, textureFromResourceImage, tagObject3D } from '@combos-fun/plugin-renderer-3d';
5
+ import { PlaneGeometry, MeshBasicMaterial, DoubleSide, Mesh } from 'three';
6
6
 
7
7
  class SpriteAnimation3D extends Component {
8
8
  constructor() {
@@ -30,7 +30,7 @@ __decorate([
30
30
  type: 'string',
31
31
  group: 'SpriteAnimation3D',
32
32
  label: 'resource',
33
- description: 'Resource id from the asset registry.',
33
+ description: 'Engine resource name registered with RESOURCE_TYPE.SPRITE_ANIMATION.',
34
34
  editor: 'text',
35
35
  })
36
36
  ], SpriteAnimation3D.prototype, "resource", void 0);
@@ -139,7 +139,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
139
139
  super(...arguments);
140
140
  this.name = 'SpriteAnimation3DSystem';
141
141
  this.entries = new Map();
142
- this.textureLoader = new TextureLoader();
143
142
  }
144
143
  static { this.systemName = 'SpriteAnimation3DSystem'; }
145
144
  init() {
@@ -184,22 +183,25 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
184
183
  return;
185
184
  const asyncId = this.increaseAsyncId(gameObject.id);
186
185
  try {
187
- const response = await fetch(component.resource);
188
- const json = await response.json();
186
+ const res = await requireNamedResource(component.resource);
189
187
  if (!this.validateAsyncId(gameObject.id, asyncId))
190
188
  return;
191
- const meta = json.meta;
192
- const framesData = json.frames;
193
- const imageUrl = this.resolveImageUrl(component.resource, meta.image);
194
- const texture = await this.loadTexture(imageUrl);
189
+ const json = res.data?.json;
190
+ if (!json) {
191
+ throw new Error(`Resource "${res.name}" has no json data; use RESOURCE_TYPE.SPRITE_ANIMATION with src.image and src.json`);
192
+ }
193
+ const texture = textureFromResourceImage(res);
195
194
  if (!this.validateAsyncId(gameObject.id, asyncId)) {
196
195
  texture.dispose();
197
196
  return;
198
197
  }
199
- const frames = this.parseFrames(framesData);
200
- const sheetWidth = meta.size.w;
201
- const sheetHeight = meta.size.h;
198
+ const frames = this.parseFrames(json.frames);
199
+ const sheetWidth = json.meta?.size?.w || texture.image?.width || 1;
200
+ const sheetHeight = json.meta?.size?.h || texture.image?.height || 1;
202
201
  const firstFrame = frames[0];
202
+ if (!firstFrame) {
203
+ throw new Error(`Resource "${res.name}" spritesheet has no frames`);
204
+ }
203
205
  const aspectRatio = firstFrame.w / firstFrame.h;
204
206
  const geometry = new PlaneGeometry(aspectRatio, 1);
205
207
  const material = new MeshBasicMaterial({
@@ -208,6 +210,7 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
208
210
  side: DoubleSide,
209
211
  });
210
212
  const mesh = new Mesh(geometry, material);
213
+ tagObject3D(mesh, gameObject.id);
211
214
  const entry = {
212
215
  mesh,
213
216
  texture,
@@ -227,6 +230,7 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
227
230
  }
228
231
  catch (e) {
229
232
  console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);
233
+ throw e;
230
234
  }
231
235
  }
232
236
  handleChange(changed) {
@@ -263,7 +267,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
263
267
  h: f.frame.h,
264
268
  }));
265
269
  }
266
- // Object-based format: { "frameName": { frame: { x, y, w, h } } }
267
270
  return Object.keys(framesData)
268
271
  .sort()
269
272
  .map((key) => ({
@@ -273,15 +276,6 @@ let SpriteAnimation3DSystem = class SpriteAnimation3DSystem extends Renderer3D {
273
276
  h: framesData[key].frame.h,
274
277
  }));
275
278
  }
276
- resolveImageUrl(jsonUrl, imageName) {
277
- const base = jsonUrl.substring(0, jsonUrl.lastIndexOf('/') + 1);
278
- return base + imageName;
279
- }
280
- loadTexture(url) {
281
- return new Promise((resolve, reject) => {
282
- this.textureLoader.load(url, resolve, undefined, reject);
283
- });
284
- }
285
279
  onDestroy() {
286
280
  for (const [id] of this.entries) {
287
281
  this.handleRemove(id);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-renderer-3d-sprite-animation.esm.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface SpriteAnimation3DParams {\n resource?: string;\n autoPlay?: boolean;\n speed?: number;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n scaleX?: number;\n scaleY?: number;\n}\n\nexport default class SpriteAnimation3D extends Component<SpriteAnimation3DParams> {\n static componentName: string = 'SpriteAnimation3D';\n\n @Field({\n\n type: 'string',\n\n group: 'SpriteAnimation3D',\n\n label: 'resource',\n\n description: 'Resource id from the asset registry.',\n\n editor: 'text',\n\n })\n\n resource: string = '';\n @Field({\n type: 'boolean',\n group: 'SpriteAnimation3D',\n label: 'autoPlay',\n description: 'Start playing automatically when loaded.',\n editor: 'toggle',\n })\n autoPlay: boolean = true;\n @Field({\n type: 'number',\n step: 10,\n group: 'SpriteAnimation3D',\n label: 'speed',\n description: 'Playback speed.',\n editor: 'number-stepper',\n })\n speed: number = 100;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleX',\n description: 'Scale on X.',\n editor: 'number-stepper',\n })\n scaleX: number = 1;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleY',\n description: 'Scale on Y.',\n editor: 'number-stepper',\n })\n scaleY: number = 1;\n\n init(obj?: SpriteAnimation3DParams) {\n if (obj) Object.assign(this, obj);\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem } from '@combos-fun/plugin-renderer-3d';\nimport {\n TextureLoader,\n PlaneGeometry,\n MeshBasicMaterial,\n Mesh,\n DoubleSide,\n} from 'three';\nimport type { Texture } from 'three';\nimport SpriteAnimation3D from './component';\n\ninterface FrameData {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface SpriteAnimation3DEntry {\n mesh: Mesh;\n texture: Texture;\n frames: FrameData[];\n sheetWidth: number;\n sheetHeight: number;\n currentFrame: number;\n elapsed: number;\n playing: boolean;\n}\n\n@decorators.componentObserver({\n SpriteAnimation3D: [\n 'resource', 'speed',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n 'scaleX', 'scaleY',\n ],\n})\nexport default class SpriteAnimation3DSystem extends Renderer3D {\n static systemName = 'SpriteAnimation3DSystem';\n name: string = 'SpriteAnimation3DSystem';\n\n private entries: Map<number, SpriteAnimation3DEntry> = new Map();\n private textureLoader = new TextureLoader();\n\n init() {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'SpriteAnimation3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as SpriteAnimation3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(SpriteAnimation3D) as SpriteAnimation3D;\n if (!component) return;\n\n const entry = this.entries.get(gameObject.id);\n if (!entry) return;\n\n entry.mesh.position.set(component.positionX, component.positionY, component.positionZ);\n entry.mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n entry.mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n if (!entry.playing || entry.frames.length === 0) return;\n\n const delta = this.threeContext.clock.getDelta() * 1000;\n entry.elapsed += delta;\n\n if (entry.elapsed >= component.speed) {\n entry.elapsed -= component.speed;\n entry.currentFrame = (entry.currentFrame + 1) % entry.frames.length;\n this.applyFrame(entry);\n }\n }\n\n private async handleAdd(gameObject: GameObject, component: SpriteAnimation3D) {\n if (!component.resource) return;\n\n const asyncId = this.increaseAsyncId(gameObject.id);\n\n try {\n const response = await fetch(component.resource);\n const json = await response.json();\n if (!this.validateAsyncId(gameObject.id, asyncId)) return;\n\n const meta = json.meta;\n const framesData = json.frames;\n const imageUrl = this.resolveImageUrl(component.resource, meta.image);\n\n const texture = await this.loadTexture(imageUrl);\n if (!this.validateAsyncId(gameObject.id, asyncId)) {\n texture.dispose();\n return;\n }\n\n const frames = this.parseFrames(framesData);\n const sheetWidth = meta.size.w;\n const sheetHeight = meta.size.h;\n\n const firstFrame = frames[0];\n const aspectRatio = firstFrame.w / firstFrame.h;\n const geometry = new PlaneGeometry(aspectRatio, 1);\n const material = new MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n\n const entry: SpriteAnimation3DEntry = {\n mesh,\n texture,\n frames,\n sheetWidth,\n sheetHeight,\n currentFrame: 0,\n elapsed: 0,\n playing: component.autoPlay,\n };\n\n this.applyFrame(entry);\n\n mesh.position.set(component.positionX, component.positionY, component.positionZ);\n mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n this.threeContext.scene.add(mesh);\n this.entries.set(gameObject.id, entry);\n } catch (e) {\n console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);\n }\n }\n\n private handleChange(changed: ComponentChanged) {\n const component = changed.component as SpriteAnimation3D;\n const changedProp = changed.prop?.prop?.[0];\n\n if (changedProp === 'resource') {\n this.handleRemove(changed.gameObject.id);\n this.handleAdd(changed.gameObject, component);\n }\n }\n\n private handleRemove(id: number) {\n this.increaseAsyncId(id);\n const entry = this.entries.get(id);\n if (!entry) return;\n\n this.threeContext.scene.remove(entry.mesh);\n entry.mesh.geometry.dispose();\n (entry.mesh.material as MeshBasicMaterial).dispose();\n entry.texture.dispose();\n this.entries.delete(id);\n }\n\n private applyFrame(entry: SpriteAnimation3DEntry) {\n const frame = entry.frames[entry.currentFrame];\n const tex = entry.texture;\n\n tex.offset.set(frame.x / entry.sheetWidth, 1 - (frame.y + frame.h) / entry.sheetHeight);\n tex.repeat.set(frame.w / entry.sheetWidth, frame.h / entry.sheetHeight);\n }\n\n private parseFrames(framesData: any): FrameData[] {\n if (Array.isArray(framesData)) {\n return framesData.map((f: any) => ({\n x: f.frame.x,\n y: f.frame.y,\n w: f.frame.w,\n h: f.frame.h,\n }));\n }\n // Object-based format: { \"frameName\": { frame: { x, y, w, h } } }\n return Object.keys(framesData)\n .sort()\n .map((key) => ({\n x: framesData[key].frame.x,\n y: framesData[key].frame.y,\n w: framesData[key].frame.w,\n h: framesData[key].frame.h,\n }));\n }\n\n private resolveImageUrl(jsonUrl: string, imageName: string): string {\n const base = jsonUrl.substring(0, jsonUrl.lastIndexOf('/') + 1);\n return base + imageName;\n }\n\n private loadTexture(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n this.textureLoader.load(url, resolve, undefined, reject);\n });\n }\n\n onDestroy() {\n for (const [id] of this.entries) {\n this.handleRemove(id);\n }\n this.entries.clear();\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-renderer-3d-sprite-animation.esm.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface SpriteAnimation3DParams {\n resource?: string;\n autoPlay?: boolean;\n speed?: number;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n scaleX?: number;\n scaleY?: number;\n}\n\nexport default class SpriteAnimation3D extends Component<SpriteAnimation3DParams> {\n static componentName: string = 'SpriteAnimation3D';\n\n @Field({\n\n type: 'string',\n\n group: 'SpriteAnimation3D',\n\n label: 'resource',\n\n description: 'Engine resource name registered with RESOURCE_TYPE.SPRITE_ANIMATION.',\n\n editor: 'text',\n\n })\n\n resource: string = '';\n @Field({\n type: 'boolean',\n group: 'SpriteAnimation3D',\n label: 'autoPlay',\n description: 'Start playing automatically when loaded.',\n editor: 'toggle',\n })\n autoPlay: boolean = true;\n @Field({\n type: 'number',\n step: 10,\n group: 'SpriteAnimation3D',\n label: 'speed',\n description: 'Playback speed.',\n editor: 'number-stepper',\n })\n speed: number = 100;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'SpriteAnimation3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleX',\n description: 'Scale on X.',\n editor: 'number-stepper',\n })\n scaleX: number = 1;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'SpriteAnimation3D',\n label: 'scaleY',\n description: 'Scale on Y.',\n editor: 'number-stepper',\n })\n scaleY: number = 1;\n\n init(obj?: SpriteAnimation3DParams) {\n if (obj) Object.assign(this, obj);\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport {\n Renderer3D,\n Renderer3DSystem,\n requireNamedResource,\n tagObject3D,\n textureFromResourceImage,\n} from '@combos-fun/plugin-renderer-3d';\nimport {\n PlaneGeometry,\n MeshBasicMaterial,\n Mesh,\n DoubleSide,\n} from 'three';\nimport type { Texture } from 'three';\nimport SpriteAnimation3D from './component';\n\ninterface FrameData {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface SpriteAnimation3DEntry {\n mesh: Mesh;\n texture: Texture;\n frames: FrameData[];\n sheetWidth: number;\n sheetHeight: number;\n currentFrame: number;\n elapsed: number;\n playing: boolean;\n}\n\n@decorators.componentObserver({\n SpriteAnimation3D: [\n 'resource', 'speed',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n 'scaleX', 'scaleY',\n ],\n})\nexport default class SpriteAnimation3DSystem extends Renderer3D {\n static systemName = 'SpriteAnimation3DSystem';\n name: string = 'SpriteAnimation3DSystem';\n\n private entries: Map<number, SpriteAnimation3DEntry> = new Map();\n\n init() {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'SpriteAnimation3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as SpriteAnimation3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(SpriteAnimation3D) as SpriteAnimation3D;\n if (!component) return;\n\n const entry = this.entries.get(gameObject.id);\n if (!entry) return;\n\n entry.mesh.position.set(component.positionX, component.positionY, component.positionZ);\n entry.mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n entry.mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n if (!entry.playing || entry.frames.length === 0) return;\n\n const delta = this.threeContext.clock.getDelta() * 1000;\n entry.elapsed += delta;\n\n if (entry.elapsed >= component.speed) {\n entry.elapsed -= component.speed;\n entry.currentFrame = (entry.currentFrame + 1) % entry.frames.length;\n this.applyFrame(entry);\n }\n }\n\n private async handleAdd(gameObject: GameObject, component: SpriteAnimation3D) {\n if (!component.resource) return;\n\n const asyncId = this.increaseAsyncId(gameObject.id);\n\n try {\n const res = await requireNamedResource(component.resource);\n if (!this.validateAsyncId(gameObject.id, asyncId)) return;\n\n const json = res.data?.json;\n if (!json) {\n throw new Error(\n `Resource \"${res.name}\" has no json data; use RESOURCE_TYPE.SPRITE_ANIMATION with src.image and src.json`,\n );\n }\n\n const texture = textureFromResourceImage(res);\n if (!this.validateAsyncId(gameObject.id, asyncId)) {\n texture.dispose();\n return;\n }\n\n const frames = this.parseFrames(json.frames);\n const sheetWidth = json.meta?.size?.w || texture.image?.width || 1;\n const sheetHeight = json.meta?.size?.h || texture.image?.height || 1;\n\n const firstFrame = frames[0];\n if (!firstFrame) {\n throw new Error(`Resource \"${res.name}\" spritesheet has no frames`);\n }\n const aspectRatio = firstFrame.w / firstFrame.h;\n const geometry = new PlaneGeometry(aspectRatio, 1);\n const material = new MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: DoubleSide,\n });\n const mesh = new Mesh(geometry, material);\n tagObject3D(mesh, gameObject.id);\n\n const entry: SpriteAnimation3DEntry = {\n mesh,\n texture,\n frames,\n sheetWidth,\n sheetHeight,\n currentFrame: 0,\n elapsed: 0,\n playing: component.autoPlay,\n };\n\n this.applyFrame(entry);\n\n mesh.position.set(component.positionX, component.positionY, component.positionZ);\n mesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n mesh.scale.set(component.scaleX, component.scaleY, 1);\n\n this.threeContext.scene.add(mesh);\n this.entries.set(gameObject.id, entry);\n } catch (e) {\n console.error('SpriteAnimation3DSystem: failed to load spritesheet', e);\n throw e;\n }\n }\n\n private handleChange(changed: ComponentChanged) {\n const component = changed.component as SpriteAnimation3D;\n const changedProp = changed.prop?.prop?.[0];\n\n if (changedProp === 'resource') {\n this.handleRemove(changed.gameObject.id);\n this.handleAdd(changed.gameObject, component);\n }\n }\n\n private handleRemove(id: number) {\n this.increaseAsyncId(id);\n const entry = this.entries.get(id);\n if (!entry) return;\n\n this.threeContext.scene.remove(entry.mesh);\n entry.mesh.geometry.dispose();\n (entry.mesh.material as MeshBasicMaterial).dispose();\n entry.texture.dispose();\n this.entries.delete(id);\n }\n\n private applyFrame(entry: SpriteAnimation3DEntry) {\n const frame = entry.frames[entry.currentFrame];\n const tex = entry.texture;\n\n tex.offset.set(frame.x / entry.sheetWidth, 1 - (frame.y + frame.h) / entry.sheetHeight);\n tex.repeat.set(frame.w / entry.sheetWidth, frame.h / entry.sheetHeight);\n }\n\n private parseFrames(framesData: any): FrameData[] {\n if (Array.isArray(framesData)) {\n return framesData.map((f: any) => ({\n x: f.frame.x,\n y: f.frame.y,\n w: f.frame.w,\n h: f.frame.h,\n }));\n }\n return Object.keys(framesData)\n .sort()\n .map((key) => ({\n x: framesData[key].frame.x,\n y: framesData[key].frame.y,\n w: framesData[key].frame.w,\n h: framesData[key].frame.h,\n }));\n }\n\n onDestroy() {\n for (const [id] of this.entries) {\n this.handleRemove(id);\n }\n this.entries.clear();\n }\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-sprite-animation",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "Spritesheet animation projected onto a PlaneGeometry in 3D space",
5
5
  "main": "index.js",
6
6
  "module": "dist/plugin-renderer-3d-sprite-animation.esm.js",
@@ -26,10 +26,10 @@
26
26
  "pluginManifest": "./combos-plugin.json"
27
27
  },
28
28
  "dependencies": {
29
- "@combos-fun/engine": "0.0.39",
30
- "@combos-fun/inspector-decorator": "0.0.39",
31
- "@combos-fun/plugin-renderer-3d": "0.0.39",
32
- "three": "^0.172.0"
29
+ "three": "^0.172.0",
30
+ "@combos-fun/engine": "0.0.41",
31
+ "@combos-fun/plugin-renderer-3d": "0.0.41",
32
+ "@combos-fun/inspector-decorator": "0.0.41"
33
33
  },
34
34
  "keywords": [
35
35
  "combos-fun",