@melonjs/spine-plugin 1.1.0 → 1.2.0

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  a [Spine](http://en.esotericsoftware.com/spine-in-depth) 4.1 plugin implementation for [melonJS 2](www.melonjs.org)
4
4
 
5
- ![melonjs-spine-gif](https://github.com/melonjs/spine-plugin/assets/4033090/e4f1db3e-e2c7-4d18-9d80-b42fc9897c59)
5
+ ![melonjs-spine-gif](https://github.com/melonjs/spine-plugin/assets/4033090/dc259c8e-def6-419e-83a9-cda374715686)
6
6
 
7
7
  >Note: although functional, this plugin is still a work in progress. Feedback and especially contributions are welcome!
8
8
 
@@ -17,6 +17,7 @@ this plugin is already bundled with the required Spine runtime, so there is no n
17
17
  >Note: this plugin requires melonJS version 15.9 or higher.
18
18
 
19
19
  To install the plugin using npm :
20
+
20
21
  `$ [sudo] npm install @melonjs/spine-plugin`
21
22
 
22
23
  Then import and use the plugin in your project. For example:
@@ -4075,7 +4075,11 @@ declare class SkeletonRenderer {
4075
4075
  runtime: any;
4076
4076
  tempColor: Color;
4077
4077
  tintColor: Color$1;
4078
+ vertexSize: number;
4078
4079
  debugRendering: boolean;
4080
+ clipper: SkeletonClipping;
4081
+ clippingVertices: any[];
4082
+ clippingMask: Polygon;
4079
4083
  draw(renderer: any, skeleton: any): void;
4080
4084
  }
4081
4085
  import { Vector2d } from 'melonjs';
@@ -4129,4 +4133,5 @@ declare class Vertices {
4129
4133
  vertices: any;
4130
4134
  }
4131
4135
  import { Color as Color$1 } from 'melonjs';
4136
+ import { Polygon } from 'melonjs';
4132
4137
  export { Spine as default };
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * melonJS Spine plugin - v1.1.0
2
+ * melonJS Spine plugin - v1.2.0
3
3
  * http://www.melonjs.org
4
4
  * @melonjs/spine-plugin is licensed under the MIT License.
5
5
  * http://www.opensource.org/licenses/mit-license
6
6
  * @copyright (C) 2011 - 2023 AltByte Pte Ltd
7
7
  */
8
- import { event, video, Color as Color$1, Math as Math$1, Renderable as Renderable$1, Vector2d } from 'melonjs';
8
+ import { event, video, Color as Color$1, Polygon, Math as Math$1, Renderable as Renderable$1, Vector2d } from 'melonjs';
9
9
 
10
10
  /******************************************************************************
11
11
  * Spine Runtimes License Agreement
@@ -14938,7 +14938,11 @@ class SkeletonRenderer {
14938
14938
  runtime;
14939
14939
  tempColor = new Color();
14940
14940
  tintColor = new Color$1();
14941
+ vertexSize = 2 + 2 + 4;
14941
14942
  debugRendering = false;
14943
+ clipper = new SkeletonClipping();
14944
+ clippingVertices = [];
14945
+ clippingMask = new Polygon(0, 0);
14942
14946
 
14943
14947
  constructor(runtime) {
14944
14948
  this.runtime = runtime;
@@ -14947,19 +14951,20 @@ class SkeletonRenderer {
14947
14951
  }
14948
14952
 
14949
14953
  draw(renderer, skeleton) {
14950
- // based on https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/spine-ts/spine-canvas/src/SkeletonRenderer.ts
14954
+ let clipper = this.clipper;
14951
14955
  let drawOrder = skeleton.drawOrder;
14952
14956
  let skeletonColor = skeleton.color;
14953
14957
 
14954
- if (this.debugRendering === true) {
14955
- renderer.setColor("green");
14956
- }
14957
-
14958
14958
  for (var i = 0, n = drawOrder.length; i < n; i++) {
14959
+ let clippedVertexSize = clipper.isClipping() ? 2 : this.vertexSize;
14959
14960
  let slot = drawOrder[i];
14960
14961
  let bone = slot.bone;
14961
14962
 
14962
- if (!bone.active) continue;
14963
+ if (!bone.active) {
14964
+ clipper.clipEndWithSlot(slot);
14965
+ renderer.clearMask();
14966
+ continue;
14967
+ }
14963
14968
 
14964
14969
  let attachment = slot.getAttachment();
14965
14970
 
@@ -14976,7 +14981,7 @@ class SkeletonRenderer {
14976
14981
  skeletonColor.b * slotColor.b * regionColor.b,
14977
14982
  skeletonColor.a * slotColor.a * regionColor.a);
14978
14983
 
14979
- attachment.computeWorldVertices(slot, worldVertices, 0, 2);
14984
+ attachment.computeWorldVertices(slot, worldVertices, 0, clippedVertexSize);
14980
14985
 
14981
14986
  renderer.save();
14982
14987
  renderer.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
@@ -15000,13 +15005,41 @@ class SkeletonRenderer {
15000
15005
  renderer.setTint(color);
15001
15006
  renderer.setBlendMode(blendModeLUT[blendMode]);
15002
15007
  renderer.setGlobalAlpha(color.a);
15008
+
15009
+ if (clipper.isClipping()) {
15010
+ renderer.setMask(this.clippingMask);
15011
+ }
15012
+
15003
15013
  renderer.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h);
15014
+
15004
15015
  if (this.debugRendering === true) {
15016
+ renderer.setColor("green");
15005
15017
  renderer.strokeRect(0, 0, w, h);
15006
15018
  }
15019
+
15007
15020
  renderer.restore();
15021
+ } else if (attachment instanceof MeshAttachment) {
15022
+ // do nothing for now;
15023
+ } else if (attachment instanceof ClippingAttachment) {
15024
+ let clip = attachment;
15025
+ let vertices = this.clippingVertices;
15026
+ clipper.clipStart(slot, clip);
15027
+ clip.computeWorldVertices(slot, 0, clip.worldVerticesLength, vertices, 0, 2);
15028
+ this.clippingMask.setVertices(vertices, clip.worldVerticesLength);
15029
+ if (this.debugRendering === true) {
15030
+ renderer.setColor("blue");
15031
+ renderer.stroke(this.clippingMask);
15032
+ }
15033
+ continue;
15034
+ } else {
15035
+ clipper.clipEndWithSlot(slot);
15036
+ renderer.clearMask();
15037
+ continue;
15008
15038
  }
15039
+ clipper.clipEndWithSlot(slot);
15040
+ renderer.clearMask();
15009
15041
  }
15042
+ clipper.clipEnd();
15010
15043
  }
15011
15044
  }
15012
15045
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melonjs/spine-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "melonJS Spine plugin",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -56,7 +56,7 @@
56
56
  "@rollup/plugin-replace": "^5.0.2",
57
57
  "del-cli": "^5.0.0",
58
58
  "eslint": "^8.47.0",
59
- "eslint-plugin-jsdoc": "^46.4.6",
59
+ "eslint-plugin-jsdoc": "^46.5.0",
60
60
  "rollup": "^3.28.0",
61
61
  "rollup-plugin-bundle-size": "^1.0.3",
62
62
  "typescript": "^5.1.6"
@@ -1,5 +1,5 @@
1
- import { Color as MColor, Math as MMath } from "melonjs";
2
- import { RegionAttachment, Color } from "@esotericsoftware/spine-core";
1
+ import { Color as MColor, Math as MMath, Polygon } from "melonjs";
2
+ import { SkeletonClipping, ClippingAttachment, MeshAttachment, RegionAttachment, Color } from "@esotericsoftware/spine-core";
3
3
 
4
4
  const worldVertices = new Float32Array(8);
5
5
  const blendModeLUT = ["normal", "additive", "multiply", "screen"];
@@ -10,7 +10,11 @@ export default class SkeletonRenderer {
10
10
  runtime;
11
11
  tempColor = new Color();
12
12
  tintColor = new MColor();
13
+ vertexSize = 2 + 2 + 4;
13
14
  debugRendering = false;
15
+ clipper = new SkeletonClipping();
16
+ clippingVertices = [];
17
+ clippingMask = new Polygon(0, 0);
14
18
 
15
19
  constructor(runtime) {
16
20
  this.runtime = runtime;
@@ -19,19 +23,20 @@ export default class SkeletonRenderer {
19
23
  }
20
24
 
21
25
  draw(renderer, skeleton) {
22
- // based on https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/spine-ts/spine-canvas/src/SkeletonRenderer.ts
26
+ let clipper = this.clipper;
23
27
  let drawOrder = skeleton.drawOrder;
24
28
  let skeletonColor = skeleton.color;
25
29
 
26
- if (this.debugRendering === true) {
27
- renderer.setColor("green");
28
- }
29
-
30
30
  for (var i = 0, n = drawOrder.length; i < n; i++) {
31
+ let clippedVertexSize = clipper.isClipping() ? 2 : this.vertexSize;
31
32
  let slot = drawOrder[i];
32
33
  let bone = slot.bone;
33
34
 
34
- if (!bone.active) continue;
35
+ if (!bone.active) {
36
+ clipper.clipEndWithSlot(slot);
37
+ renderer.clearMask();
38
+ continue;
39
+ }
35
40
 
36
41
  let attachment = slot.getAttachment();
37
42
 
@@ -48,7 +53,7 @@ export default class SkeletonRenderer {
48
53
  skeletonColor.b * slotColor.b * regionColor.b,
49
54
  skeletonColor.a * slotColor.a * regionColor.a);
50
55
 
51
- attachment.computeWorldVertices(slot, worldVertices, 0, 2);
56
+ attachment.computeWorldVertices(slot, worldVertices, 0, clippedVertexSize);
52
57
 
53
58
  renderer.save();
54
59
  renderer.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
@@ -72,12 +77,40 @@ export default class SkeletonRenderer {
72
77
  renderer.setTint(color);
73
78
  renderer.setBlendMode(blendModeLUT[blendMode]);
74
79
  renderer.setGlobalAlpha(color.a);
80
+
81
+ if (clipper.isClipping()) {
82
+ renderer.setMask(this.clippingMask);
83
+ }
84
+
75
85
  renderer.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h);
86
+
76
87
  if (this.debugRendering === true) {
88
+ renderer.setColor("green");
77
89
  renderer.strokeRect(0, 0, w, h);
78
90
  }
91
+
79
92
  renderer.restore();
93
+ } else if (attachment instanceof MeshAttachment) {
94
+ // do nothing for now;
95
+ } else if (attachment instanceof ClippingAttachment) {
96
+ let clip = attachment;
97
+ let vertices = this.clippingVertices;
98
+ clipper.clipStart(slot, clip);
99
+ clip.computeWorldVertices(slot, 0, clip.worldVerticesLength, vertices, 0, 2);
100
+ this.clippingMask.setVertices(vertices, clip.worldVerticesLength);
101
+ if (this.debugRendering === true) {
102
+ renderer.setColor("blue");
103
+ renderer.stroke(this.clippingMask);
104
+ }
105
+ continue;
106
+ } else {
107
+ clipper.clipEndWithSlot(slot);
108
+ renderer.clearMask();
109
+ continue;
80
110
  }
111
+ clipper.clipEndWithSlot(slot);
112
+ renderer.clearMask();
81
113
  }
114
+ clipper.clipEnd();
82
115
  }
83
116
  }