Quellcode durchsuchen

Merge branch '4.1' into 4.2-beta

# Conflicts:
#	spine-ts/package-lock.json
#	spine-ts/package.json
#	spine-ts/publish.sh
#	spine-ts/spine-canvas/package.json
#	spine-ts/spine-core/package.json
#	spine-ts/spine-phaser/package.json
#	spine-ts/spine-player/package.json
#	spine-ts/spine-threejs/package.json
#	spine-ts/spine-webgl/package.json
Mario Zechner vor 2 Jahren
Ursprung
Commit
db6f624bc6

+ 3 - 0
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.

+ 1 - 0
spine-ts/index.html

@@ -32,6 +32,7 @@
 			<li><a href="/spine-webgl/example">Example</a></li>
 			<li><a href="/spine-webgl/example/barebones.html">Barebones</a></li>
 			<li><a href="/spine-webgl/example/mix-and-match.html">Mix &amp; match</a></li>
+			<li><a href="/spine-webgl/example/custom-attachment.html">Custom attachment</a></li>
 			<li><a href="/spine-webgl/example/drag-and-drop.html">Drag &amp; drop</a></li>
 			<li><a href="/spine-webgl/example/dress-up.html">Dress-up</a></li>
 			<li><a href="/spine-webgl/example/bone-dragging.html">Bone dragging</a></li>

+ 4 - 1
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"
   }
 }

+ 1 - 0
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/");

+ 9 - 10
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 = <TextureAtlasRegion>attachment.region;
-			let image: HTMLImageElement = (<CanvasTexture>region.page.texture).getImage() as HTMLImageElement;
+			let region: TextureRegion = <TextureRegion>attachment.region;
+
+			let image: HTMLImageElement = (<CanvasTexture>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 = <RegionAttachment>attachment;
 				vertices = this.computeRegionVertices(slot, regionAttachment, false);
-				triangles = SkeletonRenderer.QUAD_TRIANGLES;
-				region = <TextureAtlasRegion>regionAttachment.region;
-				texture = (<CanvasTexture>region.page.texture).getImage() as HTMLImageElement;
+				triangles = SkeletonRenderer.QUAD_TRIANGLES;				
+				texture = (<CanvasTexture>regionAttachment.region!.texture).getImage() as HTMLImageElement;
 			} else if (attachment instanceof MeshAttachment) {
 				let mesh = <MeshAttachment>attachment;
 				vertices = this.computeMeshVertices(slot, mesh, false);
-				triangles = mesh.triangles;
-				let region = (<TextureAtlasRegion>mesh.region!.renderObject);
-				texture = region.page.texture!.getImage() as HTMLImageElement;
+				triangles = mesh.triangles;				
+				texture = (<CanvasTexture>mesh.region!.texture).getImage() as HTMLImageElement;
 			} else
 				continue;
 

+ 3 - 6
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;

+ 1 - 1
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;

+ 4 - 0
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<TextureAtlasRegion>();
 
 	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);
 	}
 }

+ 2 - 4
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;

BIN
spine-ts/spine-phaser/example/nyan.png


+ 0 - 0
spine-ts/spine-phaser/example/assets/phaser.png → spine-ts/spine-phaser/example/phaser.png


+ 3 - 4
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"    
   }
 }

+ 3 - 3
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);
 		}

+ 1 - 3
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"
   }
 }

+ 2 - 2
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 = <ThreeJsTexture>(<TextureAtlasRegion>region.region!.renderObject).page.texture;
+				texture = <ThreeJsTexture>region.region!.texture;
 			} else if (attachment instanceof MeshAttachment) {
 				let mesh = <MeshAttachment>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 = <ThreeJsTexture>(<TextureAtlasRegion>mesh.region!.renderObject).page.texture;
+				texture = <ThreeJsTexture>mesh.region!.texture;
 			} else if (attachment instanceof ClippingAttachment) {
 				let clip = <ClippingAttachment>(attachment);
 				clipper.clipStart(slot, clip);

+ 97 - 0
spine-ts/spine-webgl/example/custom-attachment.html

@@ -0,0 +1,97 @@
+<html>
+<script src="../dist/iife/spine-webgl.js"></script>
+<style>
+	* {
+		margin: 0;
+		padding: 0;
+	}
+</style>
+
+<body>
+	<canvas id="canvas" style="position: absolute; width: 100%; height: 100%;"></canvas>
+	<script>
+		class App {
+			constructor() {
+				this.skeleton = null;
+				this.animationState = null;
+			}
+
+			loadAssets(canvas) {				
+				canvas.assetManager.loadBinary("assets/spineboy-pro.skel");
+				canvas.assetManager.loadTextureAtlas("assets/spineboy-pma.atlas");
+				canvas.assetManager.loadTexture("head.png");
+			}
+
+			initialize(canvas) {
+				let assetManager = canvas.assetManager;
+
+				// Create the texture atlas.
+				let atlas = assetManager.require("assets/spineboy-pma.atlas");
+
+				// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
+				let atlasLoader = new spine.AtlasAttachmentLoader(atlas);
+
+				// Create a SkeletonBinary instance for parsing the .skel file.
+				let skeletonBinary = new spine.SkeletonBinary(atlasLoader);
+
+				// Set the scale to apply during parsing, parse the file, and create a new skeleton.
+				skeletonBinary.scale = 1;
+				let skeletonData = skeletonBinary.readSkeletonData(assetManager.require("assets/spineboy-pro.skel"));
+				this.skeleton = new spine.Skeleton(skeletonData);
+
+				// Create an AnimationState, and set the "run" animation in looping mode.
+				let animationStateData = new spine.AnimationStateData(skeletonData);
+				this.animationState = new spine.AnimationState(animationStateData);
+				this.animationState.setAnimation(0, "run", true);
+
+				// Get the custom head image from the asset manager and create an
+				// attachment from it.				
+				let texture = assetManager.require("head.png");
+				let textureRegion = {
+					texture: texture,
+					u: 0, v: 0, u2: 1, v2: 1,
+					width: texture.getImage().width, height: texture.getImage().height,
+					degrees: 0,
+					offsetX: 0, offsetY: 0,
+					originalWidth: texture.getImage().width, originalHeight: texture.getImage().height
+				};				
+				let headSlot = this.skeleton.findSlot("head");
+				let newHeadAttachment = headSlot.getAttachment().copy();				
+				newHeadAttachment.region = textureRegion;
+				newHeadAttachment.updateRegion();
+				headSlot.setAttachment(newHeadAttachment);			
+			}
+
+			update(canvas, delta) {
+				// Update the animation state using the delta time.
+				this.animationState.update(delta);
+				// Apply the animation state to the skeleton.
+				this.animationState.apply(this.skeleton);
+				// Let the skeleton update the transforms of its bones.
+				this.skeleton.updateWorldTransform();
+			}
+
+			render(canvas) {
+				let renderer = canvas.renderer;
+				// Resize the viewport to the full canvas.
+				renderer.resize(spine.ResizeMode.Expand);
+
+				// Clear the canvas with a light gray color.
+				canvas.clear(0.2, 0.2, 0.2, 1);
+
+				// Begin rendering.
+				renderer.begin();
+				// Draw the skeleton
+				renderer.drawSkeleton(this.skeleton, false);
+				// Complete rendering.
+				renderer.end();
+			}
+		}
+
+		new spine.SpineCanvas(document.getElementById("canvas"), {
+			app: new App()
+		})
+	</script>
+</body>
+
+</html>

BIN
spine-ts/spine-webgl/example/head.png


+ 2 - 2
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 = <GLTexture>(<TextureAtlasRegion>region.region!.renderObject).page.texture;
+				texture = <GLTexture>region.region!.texture;
 				attachmentColor = region.color;
 			} else if (attachment instanceof MeshAttachment) {
 				let mesh = <MeshAttachment>attachment;
@@ -125,7 +125,7 @@ export class SkeletonRenderer {
 				}
 				mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
 				triangles = mesh.triangles;
-				texture = <GLTexture>(<TextureAtlasRegion>mesh.region!.renderObject).page.texture;
+				texture = <GLTexture>mesh.region!.texture;
 				uvs = mesh.uvs;
 				attachmentColor = mesh.color;
 			} else if (attachment instanceof ClippingAttachment) {