@melonjs/spine-plugin 1.5.0 → 2.0.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.
@@ -1,129 +0,0 @@
1
- import { utils, loader } from "melonjs";
2
- import * as spineWebGL from "@esotericsoftware/spine-webgl";
3
- import * as spineCanvas from "@esotericsoftware/spine-canvas";
4
-
5
- /**
6
- * @classdesc
7
- * An Asset Manager class to load spine assets
8
- */
9
- export default class AssetManager {
10
- asset_manager;
11
- pathPrefix;
12
-
13
- /**
14
- * @param {CanvasRenderer|WebGLRenderer} renderer - a melonJS renderer instance
15
- * @param {string} [pathPrefix=""] - a default path prefix for assets location
16
- */
17
- constructor(renderer, pathPrefix = "") {
18
- this.pathPrefix = pathPrefix;
19
- if (renderer.WebGLVersion >= 1) {
20
- this.asset_manager = new spineWebGL.AssetManager(renderer.getContext(), this.pathPrefix);
21
- } else {
22
- // canvas renderer
23
- this.asset_manager = new spineCanvas.AssetManager(this.pathPrefix);
24
- }
25
-
26
- // set the spine custom parser
27
- loader.setParser("spine", (data, onload, onerror) => {
28
- // decompose data.src for the spine loader
29
- const ext = utils.file.getExtension(data.src);
30
- const basename = utils.file.getBasename(data.src);
31
- const path = utils.file.getPath(data.src);
32
- const filename = basename + "." + ext;
33
-
34
- this.setPrefix(path);
35
-
36
- // load asset
37
- switch (ext) {
38
- case "atlas":
39
- this.loadTextureAtlas(filename, onload, onerror);
40
- break;
41
- case "json":
42
- this.loadText(filename, onload, onerror);
43
- break;
44
- case "skel":
45
- this.loadBinary(filename, onload, onerror);
46
- break;
47
- default:
48
- throw "Spine plugin: unknown extension when preloading spine assets";
49
- }
50
-
51
- return 1;
52
- });
53
-
54
- }
55
-
56
- /**
57
- * set a default path prefix for assets location
58
- * @see loadAsset
59
- * @param {string} pathPrefix
60
- */
61
- setPrefix(pathPrefix) {
62
- this.asset_manager.pathPrefix = this.pathPrefix = pathPrefix;
63
- }
64
-
65
- /**
66
- * define all spine assets to be loaded
67
- * @see setPrefix
68
- * @see loadAll
69
- * @param {string} atlas
70
- * @param {string} skel
71
- * @example
72
- * // "manually" load spine assets
73
- * Spine.assetManager.setPrefix("data/spine/");
74
- * Spine.assetManager.loadAsset("alien.atlas", "alien-ess.json");
75
- * await Spine.assetManager.loadAll();
76
- */
77
- loadAsset(atlas, skel) {
78
- if (atlas) {
79
- this.loadTextureAtlas(atlas);
80
- }
81
-
82
- if (skel.endsWith(".skel")) {
83
- this.loadBinary(skel);
84
- } else {
85
- this.loadText(skel);
86
- }
87
- }
88
-
89
- /**
90
- * load the given texture atlas
91
- * @param {string} atlas
92
- */
93
- loadTextureAtlas(atlas, onload, onerror) {
94
- return this.asset_manager.loadTextureAtlas(atlas, onload, onerror);
95
- }
96
-
97
-
98
- /**
99
- * load the given skeleton .skel file
100
- * @param {string} skel
101
- */
102
- loadBinary(skel, onload, onerror) {
103
- return this.asset_manager.loadBinary(skel, onload, onerror);
104
- }
105
-
106
- /**
107
- * load the given skeleton binary file
108
- * @param {string} skel
109
- */
110
- loadText(skel, onload, onerror) {
111
- return this.asset_manager.loadText(skel, onload, onerror);
112
- }
113
-
114
- /**
115
- * load all defined spine assets
116
- * @see loadAsset
117
- */
118
- loadAll() {
119
- return this.asset_manager.loadAll();
120
- }
121
-
122
- /**
123
- * get the loaded skeleton data
124
- * @param {string} path
125
- */
126
- require(path) {
127
- return this.asset_manager.require(path);
128
- }
129
- }
@@ -1,220 +0,0 @@
1
- import { Color as MColor, Math as MMath, Polygon } from "melonjs";
2
- import { SkeletonClipping, ClippingAttachment, MeshAttachment, RegionAttachment } from "@esotericsoftware/spine-core";
3
-
4
- const vertexSize = 2 + 2 + 4;
5
- const blendModeLUT = ["normal", "additive", "multiply", "screen"];
6
- const regionDebugColor = "green";
7
- const meshDebugColor = "yellow";
8
- const clipDebugColor = "blue";
9
-
10
- let worldVertices = new Float32Array(vertexSize * 1024);
11
-
12
- export default class SkeletonRenderer {
13
- skeletonRenderer;
14
- runtime;
15
- tintColor = new MColor();
16
- tempColor = new MColor();
17
- debugRendering = false;
18
- clipper = new SkeletonClipping();
19
- clippingVertices = [];
20
- clippingMask = new Polygon(0, 0);
21
-
22
- constructor(runtime) {
23
- this.runtime = runtime;
24
- this.skeletonRenderer = new runtime.SkeletonRenderer();
25
- }
26
-
27
- draw(renderer, skeleton) {
28
- let clipper = this.clipper;
29
- let drawOrder = skeleton.drawOrder;
30
- let skeletonColor = skeleton.color;
31
- let clippingMask = this.clippingMask;
32
- let debugRendering = this.debugRendering;
33
-
34
- for (var i = 0, n = drawOrder.length; i < n; i++) {
35
- let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
36
- let slot = drawOrder[i];
37
- let bone = slot.bone;
38
- let image;
39
- let region;
40
- let triangles;
41
-
42
- if (!bone.active) {
43
- clipper.clipEndWithSlot(slot);
44
- renderer.clearMask();
45
- continue;
46
- }
47
-
48
- let attachment = slot.getAttachment();
49
-
50
- if (attachment instanceof RegionAttachment) {
51
- attachment.computeWorldVertices(slot, worldVertices, 0, clippedVertexSize);
52
- region = attachment.region;
53
- image = region.texture.getImage();
54
- } else if (attachment instanceof MeshAttachment) {
55
- this.computeMeshVertices(slot, attachment, false, clippedVertexSize);
56
- triangles = attachment.triangles;
57
- region = attachment.region;
58
- image = region.texture.getImage();
59
- } else if (attachment instanceof ClippingAttachment) {
60
- let clip = attachment;
61
- let vertices = this.clippingVertices;
62
- clipper.clipStart(slot, clip);
63
- clip.computeWorldVertices(slot, 0, clip.worldVerticesLength, vertices, 0, 2);
64
- clippingMask.setVertices(vertices, clip.worldVerticesLength);
65
- if (debugRendering === true) {
66
- renderer.setColor(clipDebugColor);
67
- renderer.stroke(clippingMask);
68
- }
69
- continue;
70
- } else {
71
- clipper.clipEndWithSlot(slot);
72
- renderer.clearMask();
73
- continue;
74
- }
75
-
76
- if (typeof image !== "undefined") {
77
- let slotColor = slot.color;
78
- let regionColor = attachment.color;
79
- let blendMode = slot.data.blendMode;
80
- let color = this.tintColor;
81
-
82
- renderer.save();
83
-
84
- color.setFloat(skeletonColor.r * slotColor.r * regionColor.r,
85
- skeletonColor.g * slotColor.g * regionColor.g,
86
- skeletonColor.b * slotColor.b * regionColor.b,
87
- skeletonColor.a * slotColor.a * regionColor.a);
88
-
89
- renderer.setGlobalAlpha(color.a);
90
- renderer.setTint(color);
91
- renderer.setBlendMode(blendModeLUT[blendMode]);
92
-
93
- if (typeof triangles !== "undefined") {
94
- let vertices = worldVertices;
95
- for (var j = 0; j < triangles.length; j += 3) {
96
- let t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 2] * 8;
97
- let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
98
- let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
99
- let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
100
-
101
- this.drawTriangle(renderer, image, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
102
- }
103
- } else {
104
- let atlasScale = attachment.width / region.originalWidth;
105
- let w = region.width, h = region.height;
106
- let hW = w / 2, hH = h / 2;
107
-
108
- renderer.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
109
- renderer.translate(attachment.offset[0], attachment.offset[1]);
110
- renderer.rotate(MMath.degToRad(attachment.rotation));
111
- renderer.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY);
112
- renderer.translate(hW, hH);
113
- if (region.degrees === 90) {
114
- let t = w;
115
- w = h;
116
- h = t;
117
- renderer.rotate(-MMath.ETA);
118
- }
119
- renderer.scale(1, -1);
120
- renderer.translate(-hW, -hH);
121
-
122
- if (clipper.isClipping()) {
123
- renderer.setMask(clippingMask);
124
- }
125
- renderer.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h);
126
-
127
- if (debugRendering === true) {
128
- renderer.setColor(regionDebugColor);
129
- renderer.strokeRect(0, 0, w, h);
130
- }
131
- }
132
-
133
- renderer.restore();
134
- }
135
- clipper.clipEndWithSlot(slot);
136
- renderer.clearMask();
137
- }
138
- clipper.clipEnd();
139
- }
140
-
141
- drawTriangle(renderer, img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
142
- u0 *= img.width;
143
- v0 *= img.height;
144
- u1 *= img.width;
145
- v1 *= img.height;
146
- u2 *= img.width;
147
- v2 *= img.height;
148
-
149
- renderer.save();
150
- renderer.beginPath();
151
- renderer.moveTo(x0, y0);
152
- renderer.lineTo(x1, y1);
153
- renderer.lineTo(x2, y2);
154
- renderer.closePath();
155
- renderer.setMask();
156
-
157
- x1 -= x0;
158
- y1 -= y0;
159
- x2 -= x0;
160
- y2 -= y0;
161
-
162
- u1 -= u0;
163
- v1 -= v0;
164
- u2 -= u0;
165
- v2 -= v0;
166
-
167
- var det = 1 / (u1 * v2 - u2 * v1),
168
-
169
- // linear transformation
170
- a = (v2 * x1 - v1 * x2) * det,
171
- b = (v2 * y1 - v1 * y2) * det,
172
- c = (u1 * x2 - u2 * x1) * det,
173
- d = (u1 * y2 - u2 * y1) * det,
174
-
175
- // translation
176
- e = x0 - a * u0 - c * v0,
177
- f = y0 - b * u0 - d * v0;
178
-
179
- renderer.transform(a, b, c, d, e, f);
180
- renderer.drawImage(img, 0, 0);
181
- renderer.clearMask();
182
- renderer.restore();
183
-
184
- if (this.debugRendering === true) {
185
- renderer.setColor(meshDebugColor);
186
- renderer.stroke();
187
- }
188
-
189
- }
190
-
191
- computeMeshVertices(slot, mesh, pma = false, vertexSize) {
192
- let skeletonColor = slot.bone.skeleton.color;
193
- let slotColor = slot.color;
194
- let regionColor = mesh.color;
195
- let alpha = skeletonColor.a * slotColor.a * regionColor.a;
196
- let multiplier = pma ? alpha : 1;
197
-
198
- this.tempColor.setFloat(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
199
- skeletonColor.g * slotColor.g * regionColor.g * multiplier,
200
- skeletonColor.b * slotColor.b * regionColor.b * multiplier,
201
- alpha);
202
-
203
- if (worldVertices.length < mesh.worldVerticesLength) worldVertices = new Float32Array(mesh.worldVerticesLength);
204
- mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, worldVertices, 0, vertexSize);
205
-
206
- let uvs = mesh.uvs;
207
- let color = this.tempColor.toArray();
208
- let vertices = worldVertices;
209
- let vertexCount = mesh.worldVerticesLength / 2;
210
- for (let i = 0, u = 0, v = 2; i < vertexCount; i++) {
211
- vertices[v++] = color[0];
212
- vertices[v++] = color[1];
213
- vertices[v++] = color[2];
214
- vertices[v++] = color[3];
215
- vertices[v++] = uvs[u++];
216
- vertices[v++] = uvs[u++];
217
- v += 2;
218
- }
219
- }
220
- }
@@ -1,24 +0,0 @@
1
- import { plugin } from "melonjs";
2
- import { name, version, dependencies, homepage, peerDependencies } from "../package.json";
3
- import AssetManager from "./AssetManager";
4
-
5
- /**
6
- * @classdesc
7
- * a Spine 4.x plugin implementation for melonJS
8
- * @augments plugin.BasePlugin
9
- */
10
- export class SpinePlugin extends plugin.BasePlugin {
11
- constructor() {
12
- // call the super constructor
13
- super();
14
-
15
- // minimum melonJS version expected to run this plugin
16
- this.version = peerDependencies["melonjs"];
17
-
18
- // hello world
19
- console.log(`${name} ${version} - spine runtime ${dependencies["@esotericsoftware/spine-core"]} | ${homepage}`);
20
-
21
- // instantiate the asset manager
22
- this.assetManager = new AssetManager(this.app.renderer);
23
- }
24
- }