diff --git a/CHANGELOG.md b/CHANGELOG.md index 07db48da8..aa183651a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -207,6 +207,9 @@ * `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument. * Removed `PlayerEditor`. * `VertexEffect` has been removed. + * Removed `RegionAttachment.rendererObject`. + * Renamed `TextureRegion.renderObject` to `TextureRegion.texture`. + ### WebGL backend * `PolygonBatcher` can now disable culling automatically if the static variable `PolygonBatcher.disableCulling` is set to true. diff --git a/spine-ts/index.html b/spine-ts/index.html index bb13ebed6..181095cc3 100644 --- a/spine-ts/index.html +++ b/spine-ts/index.html @@ -32,6 +32,7 @@
  • Example
  • Barebones
  • Mix & match
  • +
  • Custom attachment
  • Drag & drop
  • Dress-up
  • Bone dragging
  • diff --git a/spine-ts/package.json b/spine-ts/package.json index 23e2a3e68..1d505b1b9 100644 --- a/spine-ts/package.json +++ b/spine-ts/package.json @@ -60,6 +60,9 @@ "esbuild": "^0.16.4", "live-server": "^1.2.2", "rimraf": "^3.0.2", - "typescript": "^4.9.4" + "typescript": "^4.9.4", + "@types/three": "^0.146.0", + "three": "^0.146.0", + "phaser": "^3.60.0" } } diff --git a/spine-ts/spine-canvas/example/index.html b/spine-ts/spine-canvas/example/index.html index eac1ddce3..af596e37a 100644 --- a/spine-ts/spine-canvas/example/index.html +++ b/spine-ts/spine-canvas/example/index.html @@ -21,6 +21,7 @@ canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); skeletonRenderer = new spine.SkeletonRenderer(context); + // skeletonRenderer.triangleRendering = true; // Load the assets. assetManager = new spine.AssetManager("https://esotericsoftware.com/files/examples/4.0/spineboy/export/"); diff --git a/spine-ts/spine-canvas/src/SkeletonRenderer.ts b/spine-ts/spine-canvas/src/SkeletonRenderer.ts index 55b73bbbd..01bc2efca 100644 --- a/spine-ts/spine-canvas/src/SkeletonRenderer.ts +++ b/spine-ts/spine-canvas/src/SkeletonRenderer.ts @@ -27,7 +27,7 @@ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import { Utils, Color, Skeleton, RegionAttachment, TextureAtlasRegion, BlendMode, MeshAttachment, Slot } from "@esotericsoftware/spine-core"; +import { Utils, Color, Skeleton, RegionAttachment, BlendMode, MeshAttachment, Slot, TextureRegion, TextureAtlasRegion } from "@esotericsoftware/spine-core"; import { CanvasTexture } from "./CanvasTexture"; const worldVertices = Utils.newFloatArray(8); @@ -68,8 +68,9 @@ export class SkeletonRenderer { let attachment = slot.getAttachment(); if (!(attachment instanceof RegionAttachment)) continue; attachment.computeWorldVertices(slot, worldVertices, 0, 2); - let region: TextureAtlasRegion = attachment.region; - let image: HTMLImageElement = (region.page.texture).getImage() as HTMLImageElement; + let region: TextureRegion = attachment.region; + + let image: HTMLImageElement = (region.texture).getImage() as HTMLImageElement; let slotColor = slot.color; let regionColor = attachment.color; @@ -98,7 +99,7 @@ export class SkeletonRenderer { ctx.translate(-w / 2, -h / 2); ctx.globalAlpha = color.a; - ctx.drawImage(image, region.x, region.y, w, h, 0, 0, w, h); + ctx.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h); if (this.debugRendering) ctx.strokeRect(0, 0, w, h); ctx.restore(); } @@ -123,15 +124,13 @@ export class SkeletonRenderer { if (attachment instanceof RegionAttachment) { let regionAttachment = attachment; vertices = this.computeRegionVertices(slot, regionAttachment, false); - triangles = SkeletonRenderer.QUAD_TRIANGLES; - region = regionAttachment.region; - texture = (region.page.texture).getImage() as HTMLImageElement; + triangles = SkeletonRenderer.QUAD_TRIANGLES; + texture = (regionAttachment.region!.texture).getImage() as HTMLImageElement; } else if (attachment instanceof MeshAttachment) { let mesh = attachment; vertices = this.computeMeshVertices(slot, mesh, false); - triangles = mesh.triangles; - let region = (mesh.region!.renderObject); - texture = region.page.texture!.getImage() as HTMLImageElement; + triangles = mesh.triangles; + texture = (mesh.region!.texture).getImage() as HTMLImageElement; } else continue; diff --git a/spine-ts/spine-core/src/AtlasAttachmentLoader.ts b/spine-ts/spine-core/src/AtlasAttachmentLoader.ts index a5a044108..c8af304ed 100644 --- a/spine-ts/spine-core/src/AtlasAttachmentLoader.ts +++ b/spine-ts/spine-core/src/AtlasAttachmentLoader.ts @@ -55,8 +55,7 @@ export class AtlasAttachmentLoader implements AttachmentLoader { let path = sequence.getPath(basePath, i); let region = this.atlas.findRegion(path); if (region == null) throw new Error("Region not found in atlas: " + path + " (sequence: " + name + ")"); - regions[i] = region; - regions[i].renderObject = regions[i]; + regions[i] = region; } } @@ -66,8 +65,7 @@ export class AtlasAttachmentLoader implements AttachmentLoader { this.loadSequence(name, path, sequence); } else { let region = this.atlas.findRegion(path); - if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); - region.renderObject = region; + if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); attachment.region = region; } return attachment; @@ -79,8 +77,7 @@ export class AtlasAttachmentLoader implements AttachmentLoader { this.loadSequence(name, path, sequence); } else { let region = this.atlas.findRegion(path); - if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); - region.renderObject = region; + if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); attachment.region = region; } return attachment; diff --git a/spine-ts/spine-core/src/Texture.ts b/spine-ts/spine-core/src/Texture.ts index 877b5a6ed..a9947ed9f 100644 --- a/spine-ts/spine-core/src/Texture.ts +++ b/spine-ts/spine-core/src/Texture.ts @@ -60,7 +60,7 @@ export enum TextureWrap { } export class TextureRegion { - renderObject: any; + texture: any; u = 0; v = 0; u2 = 0; v2 = 0; width = 0; height = 0; diff --git a/spine-ts/spine-core/src/TextureAtlas.ts b/spine-ts/spine-core/src/TextureAtlas.ts index 4bcf50c8b..fd8475c27 100644 --- a/spine-ts/spine-core/src/TextureAtlas.ts +++ b/spine-ts/spine-core/src/TextureAtlas.ts @@ -236,6 +236,7 @@ export class TextureAtlasPage { width: number = 0; height: number = 0; pma: boolean = false; + regions = new Array(); constructor (name: string) { this.name = name; @@ -245,6 +246,8 @@ export class TextureAtlasPage { this.texture = texture; texture.setFilters(this.minFilter, this.magFilter); texture.setWraps(this.uWrap, this.vWrap); + for (let region of this.regions) + region.texture = texture; } } @@ -266,5 +269,6 @@ export class TextureAtlasRegion extends TextureRegion { super(); this.page = page; this.name = name; + page.regions.push(this); } } diff --git a/spine-ts/spine-core/src/attachments/RegionAttachment.ts b/spine-ts/spine-core/src/attachments/RegionAttachment.ts index 6c46306a2..b6c05a0ab 100644 --- a/spine-ts/spine-core/src/attachments/RegionAttachment.ts +++ b/spine-ts/spine-core/src/attachments/RegionAttachment.ts @@ -65,8 +65,7 @@ export class RegionAttachment extends Attachment implements HasTextureRegion { /** The name of the texture region for this attachment. */ path: string; - - private rendererObject: any = null; + region: TextureRegion | null = null; sequence: Sequence | null = null; @@ -195,8 +194,7 @@ export class RegionAttachment extends Attachment implements HasTextureRegion { copy (): Attachment { let copy = new RegionAttachment(this.name, this.path); - copy.region = this.region; - copy.rendererObject = this.rendererObject; + copy.region = this.region; copy.x = this.x; copy.y = this.y; copy.scaleX = this.scaleX; diff --git a/spine-ts/spine-phaser/example/nyan.png b/spine-ts/spine-phaser/example/nyan.png deleted file mode 100644 index 506cafe21..000000000 Binary files a/spine-ts/spine-phaser/example/nyan.png and /dev/null differ diff --git a/spine-ts/spine-phaser/example/assets/phaser.png b/spine-ts/spine-phaser/example/phaser.png similarity index 100% rename from spine-ts/spine-phaser/example/assets/phaser.png rename to spine-ts/spine-phaser/example/phaser.png diff --git a/spine-ts/spine-phaser/package.json b/spine-ts/spine-phaser/package.json index 91916e2aa..31efd4758 100644 --- a/spine-ts/spine-phaser/package.json +++ b/spine-ts/spine-phaser/package.json @@ -30,9 +30,8 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "^4.2.11", - "@esotericsoftware/spine-webgl": "^4.2.11", - "@esotericsoftware/spine-canvas": "^4.2.11", - "phaser": "^3.55.2" + "@esotericsoftware/spine-core": "^4.1.27", + "@esotericsoftware/spine-webgl": "^4.1.27", + "@esotericsoftware/spine-canvas": "^4.1.27" } } \ No newline at end of file diff --git a/spine-ts/spine-phaser/src/SpinePlugin.ts b/spine-ts/spine-phaser/src/SpinePlugin.ts index b9952745b..26f64bbfc 100644 --- a/spine-ts/spine-phaser/src/SpinePlugin.ts +++ b/spine-ts/spine-phaser/src/SpinePlugin.ts @@ -130,11 +130,11 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin { this.game.scale.on(Phaser.Scale.Events.RESIZE, this.onResize, this); } else { if (!this.canvasRenderer) { - this.canvasRenderer = new SkeletonRenderer(this.scene.sys.context); + this.canvasRenderer = new SkeletonRenderer(this.scene!.sys.context); } } - var eventEmitter = this.systems.events; + var eventEmitter = this.systems!.events; eventEmitter.once('shutdown', this.shutdown, this); eventEmitter.once('destroy', this.destroy, this); this.game.events.once('destroy', this.gameDestroy, this); @@ -156,7 +156,7 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin { } shutdown () { - this.systems.events.off("shutdown", this.shutdown, this); + this.systems!.events.off("shutdown", this.shutdown, this); if (this.isWebGL) { this.game.scale.off(Phaser.Scale.Events.RESIZE, this.onResize, this); } diff --git a/spine-ts/spine-threejs/package.json b/spine-ts/spine-threejs/package.json index 378124518..1b7f3c7f9 100644 --- a/spine-ts/spine-threejs/package.json +++ b/spine-ts/spine-threejs/package.json @@ -30,8 +30,6 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@types/three": "^0.146.0", - "three": "^0.146.0", - "@esotericsoftware/spine-core": "^4.2.11" + "@esotericsoftware/spine-core": "^4.1.27" } } \ No newline at end of file diff --git a/spine-ts/spine-threejs/src/SkeletonMesh.ts b/spine-ts/spine-threejs/src/SkeletonMesh.ts index 07c48e119..b3cc553f0 100644 --- a/spine-ts/spine-threejs/src/SkeletonMesh.ts +++ b/spine-ts/spine-threejs/src/SkeletonMesh.ts @@ -181,7 +181,7 @@ export class SkeletonMesh extends THREE.Object3D { region.computeWorldVertices(slot, vertices, 0, vertexSize); triangles = SkeletonMesh.QUAD_TRIANGLES; uvs = region.uvs; - texture = (region.region!.renderObject).page.texture; + texture = region.region!.texture; } else if (attachment instanceof MeshAttachment) { let mesh = attachment; attachmentColor = mesh.color; @@ -193,7 +193,7 @@ export class SkeletonMesh extends THREE.Object3D { mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, vertexSize); triangles = mesh.triangles; uvs = mesh.uvs; - texture = (mesh.region!.renderObject).page.texture; + texture = mesh.region!.texture; } else if (attachment instanceof ClippingAttachment) { let clip = (attachment); clipper.clipStart(slot, clip); diff --git a/spine-ts/spine-webgl/example/custom-attachment.html b/spine-ts/spine-webgl/example/custom-attachment.html new file mode 100644 index 000000000..728912674 --- /dev/null +++ b/spine-ts/spine-webgl/example/custom-attachment.html @@ -0,0 +1,97 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spine-ts/spine-webgl/example/head.png b/spine-ts/spine-webgl/example/head.png new file mode 100644 index 000000000..0ecab2159 Binary files /dev/null and b/spine-ts/spine-webgl/example/head.png differ diff --git a/spine-ts/spine-webgl/src/SkeletonRenderer.ts b/spine-ts/spine-webgl/src/SkeletonRenderer.ts index eeb0ea02c..1e4bfae85 100644 --- a/spine-ts/spine-webgl/src/SkeletonRenderer.ts +++ b/spine-ts/spine-webgl/src/SkeletonRenderer.ts @@ -113,7 +113,7 @@ export class SkeletonRenderer { region.computeWorldVertices(slot, renderable.vertices, 0, clippedVertexSize); triangles = SkeletonRenderer.QUAD_TRIANGLES; uvs = region.uvs; - texture = (region.region!.renderObject).page.texture; + texture = region.region!.texture; attachmentColor = region.color; } else if (attachment instanceof MeshAttachment) { let mesh = attachment; @@ -125,7 +125,7 @@ export class SkeletonRenderer { } mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize); triangles = mesh.triangles; - texture = (mesh.region!.renderObject).page.texture; + texture = mesh.region!.texture; uvs = mesh.uvs; attachmentColor = mesh.color; } else if (attachment instanceof ClippingAttachment) {