Skip to content

Commit d2e0b5c

Browse files
committed
version 1.3.0
1 parent a3a732a commit d2e0b5c

24 files changed

+1608
-1432
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 1.3.0 - 2023-08-28å
4+
5+
- add support for Mesh Attachement
6+
- added more examples under the test folder and separated them into individual files
7+
- add a fullscreen option to examples (pressing the "F" key toggles fullscreen mode)
8+
39
## 1.2.1 - 2023-08-23
410

511
- code refactoring and optimization to prepare for future feature additions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ a [Spine](http://en.esotericsoftware.com/spine-in-depth) 4.1 plugin implementati
1414
Installation
1515
-------------------------------------------------------------------------------
1616
this plugin is already bundled with the required Spine runtime, so there is no need to install it separately.
17-
>Note: this plugin requires melonJS version 15.9 or higher.
17+
>Note: this plugin requires melonJS version 15.9.2 or higher.
1818
1919
To install the plugin using npm :
2020

dist/@melonjs/spine-plugin.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4073,12 +4073,14 @@ declare class SkeletonRenderer {
40734073
skeletonRenderer: any;
40744074
runtime: any;
40754075
tintColor: Color$1;
4076-
vertexSize: number;
4076+
tempColor: Color$1;
40774077
debugRendering: boolean;
40784078
clipper: SkeletonClipping;
40794079
clippingVertices: any[];
40804080
clippingMask: Polygon;
40814081
draw(renderer: any, skeleton: any): void;
4082+
drawTriangle(renderer: any, img: any, x0: any, y0: any, u0: any, v0: any, x1: any, y1: any, u1: any, v1: any, x2: any, y2: any, u2: any, v2: any): void;
4083+
computeMeshVertices(slot: any, mesh: any, pma: boolean | undefined, vertexSize: any): void;
40824084
}
40834085
import { Vector2d } from 'melonjs';
40844086
/******************************************************************************

dist/@melonjs/spine-plugin.js

Lines changed: 131 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* melonJS Spine plugin - v1.2.1
2+
* melonJS Spine plugin - v1.3.0
33
* http://www.melonjs.org
44
* @melonjs/spine-plugin is licensed under the MIT License.
55
* http://www.opensource.org/licenses/mit-license
@@ -14929,17 +14929,19 @@ class AssetManager {
1492914929
}
1493014930
}
1493114931

14932-
const worldVertices = new Float32Array(8);
14932+
const vertexSize = 2 + 2 + 4;
1493314933
const blendModeLUT = ["normal", "additive", "multiply", "screen"];
14934-
1493514934
const regionDebugColor = "green";
14935+
const meshDebugColor = "yellow";
1493614936
const clipDebugColor = "blue";
1493714937

14938+
let worldVertices = new Float32Array(vertexSize * 1024);
14939+
1493814940
class SkeletonRenderer {
1493914941
skeletonRenderer;
1494014942
runtime;
1494114943
tintColor = new Color$1();
14942-
vertexSize = 2 + 2 + 4;
14944+
tempColor = new Color$1();
1494314945
debugRendering = false;
1494414946
clipper = new SkeletonClipping();
1494514947
clippingVertices = [];
@@ -14958,11 +14960,12 @@ class SkeletonRenderer {
1495814960
let debugRendering = this.debugRendering;
1495914961

1496014962
for (var i = 0, n = drawOrder.length; i < n; i++) {
14961-
let clippedVertexSize = clipper.isClipping() ? 2 : this.vertexSize;
14963+
let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
1496214964
let slot = drawOrder[i];
1496314965
let bone = slot.bone;
1496414966
let image;
1496514967
let region;
14968+
let triangles;
1496614969

1496714970
if (!bone.active) {
1496814971
clipper.clipEndWithSlot(slot);
@@ -14977,14 +14980,10 @@ class SkeletonRenderer {
1497714980
region = attachment.region;
1497814981
image = region.texture.getImage();
1497914982
} else if (attachment instanceof MeshAttachment) {
14980-
/*
14981-
// commenting for now as totally untested
14982-
let mesh = attachment;
14983-
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, worldVertices, 0, 2);
14984-
region = mesh.region;
14985-
image = mesh.region.texture.getImage();
14986-
*/
14987-
console.warn("spine-plugin: MeshAttachment is not supported yet");
14983+
this.computeMeshVertices(slot, attachment, false, clippedVertexSize);
14984+
triangles = attachment.triangles;
14985+
region = attachment.region;
14986+
image = region.texture.getImage();
1498814987
} else if (attachment instanceof ClippingAttachment) {
1498914988
let clip = attachment;
1499014989
let vertices = this.clippingVertices;
@@ -15008,43 +15007,55 @@ class SkeletonRenderer {
1500815007
let blendMode = slot.data.blendMode;
1500915008
let color = this.tintColor;
1501015009

15010+
renderer.save();
15011+
1501115012
color.setFloat(skeletonColor.r * slotColor.r * regionColor.r,
1501215013
skeletonColor.g * slotColor.g * regionColor.g,
1501315014
skeletonColor.b * slotColor.b * regionColor.b,
1501415015
skeletonColor.a * slotColor.a * regionColor.a);
1501515016

15016-
renderer.save();
15017-
renderer.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
15018-
renderer.translate(attachment.offset[0], attachment.offset[1]);
15019-
renderer.rotate(Math$1.degToRad(attachment.rotation));
15020-
15021-
let atlasScale = attachment.width / region.originalWidth;
15022-
renderer.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY);
15023-
15024-
let w = region.width, h = region.height;
15025-
let hW = w / 2, hH = h / 2;
15026-
renderer.translate(hW, hH);
15027-
if (region.degrees === 90) {
15028-
let t = w;
15029-
w = h;
15030-
h = t;
15031-
renderer.rotate(-Math$1.ETA);
15032-
}
15033-
renderer.scale(1, -1);
15034-
renderer.translate(-hW, -hH);
15017+
renderer.setGlobalAlpha(color.a);
1503515018
renderer.setTint(color);
1503615019
renderer.setBlendMode(blendModeLUT[blendMode]);
15037-
renderer.setGlobalAlpha(color.a);
1503815020

15039-
if (clipper.isClipping()) {
15040-
renderer.setMask(clippingMask);
15041-
}
15021+
if (typeof triangles !== "undefined") {
15022+
let vertices = worldVertices;
15023+
for (var j = 0; j < triangles.length; j += 3) {
15024+
let t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 2] * 8;
15025+
let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
15026+
let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
15027+
let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
1504215028

15043-
renderer.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h);
15029+
this.drawTriangle(renderer, image, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
15030+
}
15031+
} else {
15032+
let atlasScale = attachment.width / region.originalWidth;
15033+
let w = region.width, h = region.height;
15034+
let hW = w / 2, hH = h / 2;
1504415035

15045-
if (debugRendering === true) {
15046-
renderer.setColor(regionDebugColor);
15047-
renderer.strokeRect(0, 0, w, h);
15036+
renderer.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
15037+
renderer.translate(attachment.offset[0], attachment.offset[1]);
15038+
renderer.rotate(Math$1.degToRad(attachment.rotation));
15039+
renderer.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY);
15040+
renderer.translate(hW, hH);
15041+
if (region.degrees === 90) {
15042+
let t = w;
15043+
w = h;
15044+
h = t;
15045+
renderer.rotate(-Math$1.ETA);
15046+
}
15047+
renderer.scale(1, -1);
15048+
renderer.translate(-hW, -hH);
15049+
15050+
if (clipper.isClipping()) {
15051+
renderer.setMask(clippingMask);
15052+
}
15053+
renderer.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h);
15054+
15055+
if (debugRendering === true) {
15056+
renderer.setColor(regionDebugColor);
15057+
renderer.strokeRect(0, 0, w, h);
15058+
}
1504815059
}
1504915060

1505015061
renderer.restore();
@@ -15054,6 +15065,86 @@ class SkeletonRenderer {
1505415065
}
1505515066
clipper.clipEnd();
1505615067
}
15068+
15069+
drawTriangle(renderer, img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
15070+
u0 *= img.width;
15071+
v0 *= img.height;
15072+
u1 *= img.width;
15073+
v1 *= img.height;
15074+
u2 *= img.width;
15075+
v2 *= img.height;
15076+
15077+
renderer.save();
15078+
renderer.beginPath();
15079+
renderer.moveTo(x0, y0);
15080+
renderer.lineTo(x1, y1);
15081+
renderer.lineTo(x2, y2);
15082+
renderer.closePath();
15083+
renderer.setMask();
15084+
15085+
x1 -= x0;
15086+
y1 -= y0;
15087+
x2 -= x0;
15088+
y2 -= y0;
15089+
15090+
u1 -= u0;
15091+
v1 -= v0;
15092+
u2 -= u0;
15093+
v2 -= v0;
15094+
15095+
var det = 1 / (u1 * v2 - u2 * v1),
15096+
15097+
// linear transformation
15098+
a = (v2 * x1 - v1 * x2) * det,
15099+
b = (v2 * y1 - v1 * y2) * det,
15100+
c = (u1 * x2 - u2 * x1) * det,
15101+
d = (u1 * y2 - u2 * y1) * det,
15102+
15103+
// translation
15104+
e = x0 - a * u0 - c * v0,
15105+
f = y0 - b * u0 - d * v0;
15106+
15107+
renderer.transform(a, b, c, d, e, f);
15108+
renderer.drawImage(img, 0, 0);
15109+
renderer.clearMask();
15110+
renderer.restore();
15111+
15112+
if (this.debugRendering === true) {
15113+
renderer.setColor(meshDebugColor);
15114+
renderer.stroke();
15115+
}
15116+
15117+
}
15118+
15119+
computeMeshVertices(slot, mesh, pma = false, vertexSize) {
15120+
let skeletonColor = slot.bone.skeleton.color;
15121+
let slotColor = slot.color;
15122+
let regionColor = mesh.color;
15123+
let alpha = skeletonColor.a * slotColor.a * regionColor.a;
15124+
let multiplier = pma ? alpha : 1;
15125+
15126+
this.tempColor.setFloat(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
15127+
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
15128+
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
15129+
alpha);
15130+
15131+
if (worldVertices.length < mesh.worldVerticesLength) worldVertices = new Float32Array(mesh.worldVerticesLength);
15132+
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, worldVertices, 0, vertexSize);
15133+
15134+
let uvs = mesh.uvs;
15135+
let color = this.tempColor.toArray();
15136+
let vertices = worldVertices;
15137+
let vertexCount = mesh.worldVerticesLength / 2;
15138+
for (let i = 0, u = 0, v = 2; i < vertexCount; i++) {
15139+
vertices[v++] = color[0];
15140+
vertices[v++] = color[1];
15141+
vertices[v++] = color[2];
15142+
vertices[v++] = color[3];
15143+
vertices[v++] = uvs[u++];
15144+
vertices[v++] = uvs[u++];
15145+
v += 2;
15146+
}
15147+
}
1505715148
}
1505815149

1505915150
let assetManager = new AssetManager();

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@melonjs/spine-plugin",
3-
"version": "1.2.1",
3+
"version": "1.3.0",
44
"description": "melonJS Spine plugin",
55
"homepage": "https://github.com/melonjs/spine-plugin#readme",
66
"type": "module",
@@ -46,25 +46,25 @@
4646
"CHANGELOG.md"
4747
],
4848
"peerDependencies": {
49-
"melonjs": "^15.9.0"
49+
"melonjs": "^15.9.2"
5050
},
5151
"dependencies": {
5252
"@esotericsoftware/spine-canvas": "^4.2.18",
5353
"@esotericsoftware/spine-core": "^4.2.18",
5454
"@esotericsoftware/spine-webgl": "^4.2.18"
5555
},
5656
"devDependencies": {
57-
"@babel/eslint-parser": "^7.22.0",
57+
"@babel/eslint-parser": "^7.22.11",
5858
"@babel/plugin-syntax-import-assertions": "^7.22.5",
5959
"@rollup/plugin-commonjs": "^25.0.4",
6060
"@rollup/plugin-node-resolve": "^15.2.1",
6161
"@rollup/plugin-replace": "^5.0.2",
62-
"del-cli": "^5.0.0",
63-
"eslint": "^8.47.0",
62+
"del-cli": "^5.0.1",
63+
"eslint": "^8.48.0",
6464
"eslint-plugin-jsdoc": "^46.5.0",
6565
"rollup": "^3.28.1",
6666
"rollup-plugin-bundle-size": "^1.0.3",
67-
"typescript": "^5.1.6"
67+
"typescript": "^5.2.2"
6868
},
6969
"scripts": {
7070
"build": "npm run clean && npm run lint && rollup -c --silent && npm run types",

0 commit comments

Comments
 (0)