Эх сурвалжийг харах

[ts] Fixed Canvas backend, updated README.md for Canvas backend

badlogic 9 жил өмнө
parent
commit
5ad388fe0c

+ 10 - 7
spine-ts/README.md

@@ -5,6 +5,7 @@ up into multiple modules:
 
 1. **Core**: `core/`, the core classes to load and process Spine models
 1. **WebGL**: `webgl/`, a self-contained WebGL backend, build on the core classes
+1. **Canvas**: `canvas/`, a self-contained Canvas backend, build on the core classes
 1. **Widget**: `widget/`, a self-contained widget to easily display Spine animations on your website, build on core classes & WebGL backend.
 
 While the source code for the core library and backends is written in TypeScript, all code is compiled to easily consumable JavaScript.
@@ -18,7 +19,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
 
 spine-ts works with data exported from the latest Spine version.
 
-spine-ts supports all Spine features.
+spine-ts WebGL & Widget backends supports all Spine features. The spine-ts Canvas backend does not support color tinting, mesh attachments or shearing. Mesh attachments are supported by setting `spine.canvas.SkeletonRenderer.useTriangleRendering` to true. Note that this method is slow and may lead to artifacts on some browsers.
 
 spine-ts does not yet support loading the binary format.
 
@@ -26,6 +27,7 @@ spine-ts does not yet support loading the binary format.
 1. Download the Spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip).
 2. To use only the core library without rendering support, include the `build/spine-core.js` file in your project.
 3. To use the WebGL backend, include the `spine-webgl.js` file in your project.
+3. To use the Canvas backend, include the `spine-canvas.js` file in your project.
 4. To use the Widget, include `spine-widget.js` file in your project.
 
 All `*.js` files are self-contained and include both the core and respective backend classes.
@@ -41,7 +43,7 @@ cd spine-ts
 python -m SimpleHTTPServer
 ````
 
-Then open `http://localhost:8000/webgl/example` or `http://localhost:8000/widget/example` in your browser.
+Then open `http://localhost:8000/webgl/example`, `http://localhost:8000/canvas/example` or `http://localhost:8000/widget/example` in your browser.
 
 ## Development Setup
 The spine-ts runtime and the various backends are implemented in TypeScript for greater maintainability and better tooling support. To
@@ -52,11 +54,12 @@ setup a development environment, follow these steps.
 3. Install [Visual Studio Code](https://code.visualstudio.com/)
 4. On the command line, change into the `spine-ts` directory
 5. Start the TypeScript compiler in watcher mode for the backend you want to work on:
-  1. **Core**: `tsc -w -p tsconfig.core.json`, builds `core/src`, outputs `build/spine-core.js|d.ts|js.map`
-  2. **WebGL**: `tsc -w -p tsconfig.webgl.json`, builds `core/src` and `webgl/src`, outputs `build/spine-webgl.js|d.ts|js.map`
-  3. **Widget**: `tsc -w -p tsconfig.widget.json`, builds `core/src` and `widget/src`, outputs `build/spine-widget.js|d.ts|js.map`
+  * **Core**: `tsc -w -p tsconfig.core.json`, builds `core/src`, outputs `build/spine-core.js|d.ts|js.map`
+  * **WebGL**: `tsc -w -p tsconfig.webgl.json`, builds `core/src` and `webgl/src`, outputs `build/spine-webgl.js|d.ts|js.map`
+  * **WebGL**: `tsc -w -p tsconfig.canvas.json`, builds `core/src` and `canvas/src`, outputs `build/spine-canvas.js|d.ts|js.map`
+  * **Widget**: `tsc -w -p tsconfig.widget.json`, builds `core/src` and `widget/src`, outputs `build/spine-widget.js|d.ts|js.map`
 6. Open the `spine-ts` folder in Visual Studio Code. VS Code will use the `tsconfig.json` file all source files from core and all 
-backends for your development pleasure. The actual JavaScript output is still created by the command line TypeScript compiler process from the previous step.  
+backends for your development pleasure. The actual JavaScript output is still created by the command line TypeScript compiler process from the previous step.
 
 Each backend contains an `example/` folder with an `index.html` file that demonstrates the respective backend. For development, we
 suggest to run a HTTP server in the root of `spine-ts`, e.g.
@@ -66,4 +69,4 @@ cd spine-ts
 python -m SimpleHTTPServer
 ```
 
-Then navigate to `http://localhost:8000/webgl/example` or `http://localhost:8000/widget/example`
+Then navigate to `http://localhost:8000/webgl/example`, `http://localhost:8000/canvas/example` or `http://localhost:8000/widget/example`

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 82 - 654
spine-ts/build/spine-all.d.ts


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 345 - 248
spine-ts/build/spine-all.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-all.js.map


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 82 - 654
spine-ts/build/spine-core.d.ts


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 345 - 248
spine-ts/build/spine-core.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-core.js.map


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 715
spine-ts/build/spine-widget.d.ts


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 20 - 469
spine-ts/build/spine-widget.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 7 - 5
spine-ts/canvas/example/assets/test.json

@@ -1,15 +1,17 @@
 {
-"skeleton": { "hash": "lDI/ipVg9yXAdln1ZwTDAuXPGng", "spine": "3.4.02", "width": 650.27, "height": 650.27, "images": "./images/" },
+"skeleton": { "hash": "IupPHodxMJRnAG/MhbCuGMvI6B0", "spine": "3.4.02", "width": 62.32, "height": 62.32, "images": "./images/" },
 "bones": [
-	{ "name": "root" }
+	{ "name": "root" },
+	{ "name": "bone", "parent": "root", "y": 142.84 }
 ],
 "slots": [
-	{ "name": "badlogic", "bone": "root", "attachment": "badlogic" }
+	{ "name": "badlogic2", "bone": "bone", "attachment": "badlogic" },
+	{ "name": "badlogic", "bone": "root" }
 ],
 "skins": {
 	"default": {
-		"badlogic": {
-			"badlogic": { "rotation": 43.36, "width": 460, "height": 460 }
+		"badlogic2": {
+			"badlogic": { "x": 30.33, "y": -69.62, "scaleX": 0.1, "scaleY": 0.1, "rotation": 61.65, "width": 460, "height": 460 }
 		}
 	}
 },

+ 6 - 1
spine-ts/canvas/example/index.html

@@ -23,6 +23,10 @@ function init () {
 	context = canvas.getContext("2d");
 
 	skeletonRenderer = new spine.canvas.SkeletonRenderer(context);
+	// enable debug rendering
+	skeletonRenderer.useDebugRendering = true;
+	// enable the triangle renderer, supports meshes, but may produce artifacts in some browsers
+	skeletonRenderer.useTriangleRendering = true;
 
 	assetManager = new spine.AssetManager(function(image) {
 		return new spine.canvas.CanvasTexture(image);
@@ -43,7 +47,7 @@ function init () {
 
 function load () {
 	if (assetManager.isLoadingComplete()) {
-		var data = loadSkeleton("raptor", 0.3, "walk", 320, 20, "default");
+		var data = loadSkeleton("spineboy", 0.7, "walk", 320, 460, "default");
 		skeleton = data.skeleton;
 		state = data.state;		
 		requestAnimationFrame(render);
@@ -73,6 +77,7 @@ function loadSkeleton (name, scale, initialAnimation, positionX, positionY, skin
 	var skeleton = new spine.Skeleton(skeletonData);
 	skeleton.x = positionX;
 	skeleton.y = positionY;
+	skeleton.flipY = true;
 	skeleton.setSkinByName(skin);
 
 	// Create an AnimationState, and set the initial animation in looping mode.

+ 77 - 21
spine-ts/canvas/src/SkeletonRenderer.ts

@@ -34,14 +34,66 @@ module spine.canvas {
 		static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
 		
 		private _ctx: CanvasRenderingContext2D;
+
+		public useTriangleRendering = false;
+		public useDebugRendering = false;
 		
 		constructor (context: CanvasRenderingContext2D) {
 			this._ctx = context;
 		}
 
-		draw (skeleton: Skeleton) {			
-			let blendMode: BlendMode = null;
+		draw (skeleton: Skeleton) {
+			if (this.useTriangleRendering) this.drawTriangles(skeleton);
+			else this.drawImages(skeleton);
+		}
+
+		private drawImages (skeleton: Skeleton) {
 			let ctx = this._ctx;
+			let drawOrder = skeleton.drawOrder;
+
+			if (this.useDebugRendering) ctx.strokeStyle = "green";			
+
+			for (let i = 0, n = drawOrder.length; i < n; i++) {				
+				let slot = drawOrder[i];
+				let attachment = slot.getAttachment();
+				let region: TextureAtlasRegion = null;
+				let image: HTMLImageElement = null;
+				let vertices: ArrayLike<number> = null;	
+				if (attachment instanceof RegionAttachment) {
+					let regionAttachment = <RegionAttachment>attachment;
+					vertices = regionAttachment.updateWorldVertices(slot, false);
+					region = <TextureAtlasRegion>regionAttachment.region;										
+					image = (<CanvasTexture>(region).texture).getImage();
+
+				} else continue;							
+
+				let att = <RegionAttachment>attachment;
+				let bone = slot.bone;
+				let x = vertices[0];
+				let y = vertices[1];
+				let rotation = (bone.getWorldRotationX() - att.rotation) * Math.PI / 180;
+				let xx = vertices[24] - vertices[0];
+				let xy = vertices[25] - vertices[1];
+				let yx = vertices[8] - vertices[0];
+				let yy = vertices[9] - vertices[1];
+				let w = Math.sqrt(xx * xx + xy * xy), h = -Math.sqrt(yx * yx + yy * yy);				
+				ctx.translate(x, y);
+				ctx.rotate(rotation);				
+				if (region.rotate) {
+					ctx.rotate(Math.PI / 2);
+					ctx.drawImage(image, region.x, region.y, region.height, region.width, 0, 0, h, -w);
+					ctx.rotate(-Math.PI / 2);					
+				} else {
+					ctx.drawImage(image, region.x, region.y, region.width, region.height, 0, 0, w, h);
+				}
+				if (this.useDebugRendering) ctx.strokeRect(0, 0, w, h);
+				ctx.rotate(-rotation);
+				ctx.translate(-x, -y);				
+			}			
+		}
+
+		private drawTriangles (skeleton: Skeleton) {			
+			let blendMode: BlendMode = null;			
 
 			let vertices: ArrayLike<number> = null;
 			let triangles: Array<number>  = null;
@@ -64,7 +116,7 @@ module spine.canvas {
 					vertices = mesh.updateWorldVertices(slot, false);
 					triangles = mesh.triangles;
 					texture = (<TextureAtlasRegion>mesh.region.renderObject).texture.getImage();
-				} else continue;
+				} else continue;				
 
 				if (texture != null) {
 					let slotBlendMode = slot.data.blendMode;
@@ -72,30 +124,34 @@ module spine.canvas {
 						blendMode = slotBlendMode;						
 					}
 
-					this.drawTriangles(texture, vertices, triangles);
-
-					// ctx.drawImage(texture, 0, 0);				
-				}
-			}			
-		}
+					let ctx = this._ctx;		
 
-		drawTriangles(texture: HTMLImageElement, vertices: ArrayLike<number>, triangles: ArrayLike<number>) {
-			let ctx = this._ctx;		
+					for (var j = 0; j < triangles.length; j+=3) {
+						let t1 = triangles[j] * 8, t2 = triangles[j+1] * 8, t3 = triangles[j+2] * 8;
 
-			for (var i = 0; i < triangles.length; i+=3) {
-				let t1 = triangles[i] * 8, t2 = triangles[i+1] * 8, t3 = triangles[i+2] * 8;
+						let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
+						let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
+						let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];				
 
-				let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
-				let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
-				let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];				
+						this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
 
-				this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
-			}
-		}
+						if (this.useDebugRendering) {
+							ctx.strokeStyle = "green";
+							ctx.beginPath();
+							ctx.moveTo(x0, y0);
+							ctx.lineTo(x1, y1);
+							ctx.lineTo(x2, y2);
+							ctx.lineTo(x0, y0);				
+							ctx.stroke();
+						}
+					}												
+				}				
+			}			
+		}		
 
 		// Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
 		// Apache 2 licensed
-		drawTriangle(img: HTMLImageElement, x0: number, y0: number, u0: number, v0: number,
+		private drawTriangle(img: HTMLImageElement, x0: number, y0: number, u0: number, v0: number,
 						x1: number, y1: number, u1: number, v1: number,
 						x2: number, y2: number, u2: number, v2: number) {
 			let ctx = this._ctx;
@@ -139,7 +195,7 @@ module spine.canvas {
 			ctx.transform(a, b, c, d, e, f);
 			ctx.clip();
 			ctx.drawImage(img, 0, 0);
-			ctx.restore();
+			ctx.restore();			
 		}
 	}
 }

+ 2 - 4
spine-ts/widget/src/Widget.ts

@@ -114,14 +114,12 @@ module spine {
 					else throw new Error("Failed to load assets: " + JSON.stringify(assetManager.errors));
 				}
 
-				let atlas = new spine.TextureAtlas(this._assetManager.get(this._config.atlas) as string, (path: string, minFilter: TextureFilter, magFilter: TextureFilter, uWrap: TextureWrap, vWrap: TextureWrap) => {
+				let atlas = new spine.TextureAtlas(this._assetManager.get(this._config.atlas) as string, (path: string) => {
 					let texture = assetManager.get(imagesPath + path) as spine.webgl.GLTexture;
-					texture.setFilters(minFilter, magFilter);
-					texture.setWraps(uWrap, vWrap);
 					return texture;
 				});
 				
-				let atlasLoader = new spine.webgl.TextureAtlasAttachmentLoader(atlas);				
+				let atlasLoader = new spine.TextureAtlasAttachmentLoader(atlas);				
 				var skeletonJson = new spine.SkeletonJson(atlasLoader);
 				
 				// Set the scale to apply during parsing, parse the file, and create a new skeleton.

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно