@melonjs/spine-plugin 1.5.0 → 2.0.1
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/CHANGELOG.md +51 -0
- package/LICENSE +1 -1
- package/README.md +73 -25
- package/build/AssetManager.d.ts +74 -0
- package/build/AssetManager.d.ts.map +1 -0
- package/build/SkeletonRenderer.d.ts +75 -0
- package/build/SkeletonRenderer.d.ts.map +1 -0
- package/build/Spine.d.ts +320 -0
- package/build/Spine.d.ts.map +1 -0
- package/build/SpineBatcher.d.ts +35 -0
- package/build/SpineBatcher.d.ts.map +1 -0
- package/build/SpinePlugin.d.ts +12 -0
- package/build/SpinePlugin.d.ts.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +16174 -0
- package/build/index.js.map +7 -0
- package/package.json +72 -77
- package/dist/@melonjs/spine-plugin.d.ts +0 -4410
- package/dist/@melonjs/spine-plugin.js +0 -15798
- package/src/AssetManager.js +0 -129
- package/src/SkeletonRenderer.js +0 -220
- package/src/SpinePlugin.js +0 -24
- package/src/index.js +0 -459
package/src/AssetManager.js
DELETED
|
@@ -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
|
-
}
|
package/src/SkeletonRenderer.js
DELETED
|
@@ -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
|
-
}
|
package/src/SpinePlugin.js
DELETED
|
@@ -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
|
-
}
|