mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
Merge branch '3.6' into 3.7-beta
This commit is contained in:
commit
c24990a1c4
@ -257,6 +257,7 @@
|
||||
* Fixed renderer to work with 3.6 changes. Two color tinting is not supported.
|
||||
* Added clipping support
|
||||
* Added `VertexEffect` interface, instances of which can be set on `SkeletonMesh`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`.
|
||||
* Added support for multi-page atlases
|
||||
|
||||
### Widget backend
|
||||
* Fixed WebGL context loss (see WebGL backend changes). Enabled automatically.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<groupId>com.esotericsoftware.spine</groupId>
|
||||
<artifactId>spine-libgdx</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.7.0.1-SNAPSHOT</version>
|
||||
<version>3.6.51.2-SNAPSHOT</version>
|
||||
|
||||
<name>spine-libgdx</name>
|
||||
<description>Spine Runtime for libGDX</description>
|
||||
|
||||
@ -20,11 +20,11 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
||||
|
||||
spine-ts works with data exported from Spine 3.6.xx.
|
||||
|
||||
spine-ts WebGL & Widget backends supports all Spine features.
|
||||
spine-ts WebGL & Widget backends supports all Spine features.
|
||||
|
||||
spine-ts Canvas does not support color tinting, mesh attachments and clipping. Only the alpha channel from tint colors is applied. Experimental support for mesh attachments can be enabled by setting `spine.canvas.SkeletonRenderer.useTriangleRendering` to true. Note that this method is slow and may lead to artifacts on some browsers.
|
||||
spine-ts Canvas does not support color tinting, mesh attachments and clipping. Only the alpha channel from tint colors is applied. Experimental support for mesh attachments can be enabled by setting `spine.canvas.SkeletonRenderer.useTriangleRendering` to true. Note that this method is slow and may lead to artifacts on some browsers.
|
||||
|
||||
spine-ts THREE.JS does not support color tinting, blend modes and clipping. The THREE.JS backend provides `SkeletonMesh.zOffset` to avoid z-fighting. Adjust to your near/far plane settings.
|
||||
spine-ts THREE.JS does not support two color tinting & blend modes. The THREE.JS backend provides `SkeletonMesh.zOffset` to avoid z-fighting. Adjust to your near/far plane settings.
|
||||
|
||||
spine-ts does not yet support loading the binary format.
|
||||
|
||||
@ -115,7 +115,7 @@ You can disable two-color tinting like this:
|
||||
// If you use SceneRenderer, disable two-color tinting via the last constructor argument
|
||||
var sceneRenderer = new spine.SceneRenderer(canvas, gl, false);
|
||||
|
||||
// If you use SkeletonRenderer and PolygonBatcher directly,
|
||||
// If you use SkeletonRenderer and PolygonBatcher directly,
|
||||
// disable two-color tinting in the respective constructor
|
||||
// and use the shader returned by Shader.newColoredTextured()
|
||||
// instead of Shader.newTwoColoredTextured()
|
||||
|
||||
17
spine-ts/build/spine-all.d.ts
vendored
17
spine-ts/build/spine-all.d.ts
vendored
@ -1703,22 +1703,26 @@ declare module spine.threejs {
|
||||
}
|
||||
}
|
||||
declare module spine.threejs {
|
||||
class MeshBatcher {
|
||||
mesh: THREE.Mesh;
|
||||
class MeshBatcher extends THREE.Mesh {
|
||||
private static VERTEX_SIZE;
|
||||
private vertexBuffer;
|
||||
private vertices;
|
||||
private verticesLength;
|
||||
private indices;
|
||||
private indicesLength;
|
||||
constructor(mesh: THREE.Mesh, maxVertices?: number);
|
||||
constructor(maxVertices?: number);
|
||||
clear(): void;
|
||||
begin(): void;
|
||||
canBatch(verticesLength: number, indicesLength: number): boolean;
|
||||
batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
|
||||
end(): void;
|
||||
}
|
||||
}
|
||||
declare module spine.threejs {
|
||||
class SkeletonMesh extends THREE.Mesh {
|
||||
class SkeletonMeshMaterial extends THREE.ShaderMaterial {
|
||||
constructor();
|
||||
}
|
||||
class SkeletonMesh extends THREE.Object3D {
|
||||
tempPos: Vector2;
|
||||
tempUv: Vector2;
|
||||
tempLight: Color;
|
||||
@ -1727,7 +1731,8 @@ declare module spine.threejs {
|
||||
state: AnimationState;
|
||||
zOffset: number;
|
||||
vertexEffect: VertexEffect;
|
||||
private batcher;
|
||||
private batches;
|
||||
private nextBatchIndex;
|
||||
private clipper;
|
||||
static QUAD_TRIANGLES: number[];
|
||||
static VERTEX_SIZE: number;
|
||||
@ -1735,6 +1740,8 @@ declare module spine.threejs {
|
||||
private tempColor;
|
||||
constructor(skeletonData: SkeletonData);
|
||||
update(deltaTime: number): void;
|
||||
private clearBatches();
|
||||
private nextBatch();
|
||||
private updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
@ -9563,18 +9563,19 @@ var spine;
|
||||
(function (spine) {
|
||||
var threejs;
|
||||
(function (threejs) {
|
||||
var MeshBatcher = (function () {
|
||||
function MeshBatcher(mesh, maxVertices) {
|
||||
var MeshBatcher = (function (_super) {
|
||||
__extends(MeshBatcher, _super);
|
||||
function MeshBatcher(maxVertices) {
|
||||
if (maxVertices === void 0) { maxVertices = 10920; }
|
||||
this.verticesLength = 0;
|
||||
this.indicesLength = 0;
|
||||
var _this = _super.call(this) || this;
|
||||
_this.verticesLength = 0;
|
||||
_this.indicesLength = 0;
|
||||
if (maxVertices > 10920)
|
||||
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
||||
var vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||
var indices = this.indices = new Uint16Array(maxVertices * 3);
|
||||
this.mesh = mesh;
|
||||
var vertices = _this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||
var indices = _this.indices = new Uint16Array(maxVertices * 3);
|
||||
var geo = new THREE.BufferGeometry();
|
||||
var vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||
var vertexBuffer = _this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||
vertexBuffer.dynamic = true;
|
||||
geo.addAttribute("position", new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0, false));
|
||||
geo.addAttribute("color", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 3, false));
|
||||
@ -9583,12 +9584,27 @@ var spine;
|
||||
geo.getIndex().dynamic = true;
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
mesh.geometry = geo;
|
||||
_this.geometry = geo;
|
||||
_this.material = new threejs.SkeletonMeshMaterial();
|
||||
return _this;
|
||||
}
|
||||
MeshBatcher.prototype.clear = function () {
|
||||
var geo = this.geometry;
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
this.material.uniforms.map.value = null;
|
||||
};
|
||||
MeshBatcher.prototype.begin = function () {
|
||||
this.verticesLength = 0;
|
||||
this.indicesLength = 0;
|
||||
};
|
||||
MeshBatcher.prototype.canBatch = function (verticesLength, indicesLength) {
|
||||
if (this.indicesLength + indicesLength >= this.indices.byteLength / 2)
|
||||
return false;
|
||||
if (this.verticesLength + verticesLength >= this.vertices.byteLength / 2)
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
MeshBatcher.prototype.batch = function (vertices, verticesLength, indices, indicesLength, z) {
|
||||
if (z === void 0) { z = 0; }
|
||||
var indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
|
||||
@ -9616,7 +9632,7 @@ var spine;
|
||||
this.vertexBuffer.needsUpdate = true;
|
||||
this.vertexBuffer.updateRange.offset = 0;
|
||||
this.vertexBuffer.updateRange.count = this.verticesLength;
|
||||
var geo = this.mesh.geometry;
|
||||
var geo = this.geometry;
|
||||
geo.getIndex().needsUpdate = true;
|
||||
geo.getIndex().updateRange.offset = 0;
|
||||
geo.getIndex().updateRange.count = this.indicesLength;
|
||||
@ -9624,7 +9640,7 @@ var spine;
|
||||
geo.drawRange.count = this.indicesLength;
|
||||
};
|
||||
return MeshBatcher;
|
||||
}());
|
||||
}(THREE.Mesh));
|
||||
MeshBatcher.VERTEX_SIZE = 9;
|
||||
threejs.MeshBatcher = MeshBatcher;
|
||||
})(threejs = spine.threejs || (spine.threejs = {}));
|
||||
@ -9633,6 +9649,29 @@ var spine;
|
||||
(function (spine) {
|
||||
var threejs;
|
||||
(function (threejs) {
|
||||
var SkeletonMeshMaterial = (function (_super) {
|
||||
__extends(SkeletonMeshMaterial, _super);
|
||||
function SkeletonMeshMaterial() {
|
||||
var _this = this;
|
||||
var vertexShader = "\n\t\t\t\tattribute vec4 color;\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec4 vColor;\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tvColor = color;\n\t\t\t\t\tgl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);\n\t\t\t\t}\n\t\t\t";
|
||||
var fragmentShader = "\n\t\t\t\tuniform sampler2D map;\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec4 vColor;\n\t\t\t\tvoid main(void) {\n\t\t\t\t\tgl_FragColor = texture2D(map, vUv)*vColor;\n\t\t\t\t}\n\t\t\t";
|
||||
var parameters = {
|
||||
uniforms: {
|
||||
map: { type: "t", value: null }
|
||||
},
|
||||
vertexShader: vertexShader,
|
||||
fragmentShader: fragmentShader,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
alphaTest: 0.5
|
||||
};
|
||||
_this = _super.call(this, parameters) || this;
|
||||
return _this;
|
||||
}
|
||||
;
|
||||
return SkeletonMeshMaterial;
|
||||
}(THREE.ShaderMaterial));
|
||||
threejs.SkeletonMeshMaterial = SkeletonMeshMaterial;
|
||||
var SkeletonMesh = (function (_super) {
|
||||
__extends(SkeletonMesh, _super);
|
||||
function SkeletonMesh(skeletonData) {
|
||||
@ -9642,17 +9681,14 @@ var spine;
|
||||
_this.tempLight = new spine.Color();
|
||||
_this.tempDark = new spine.Color();
|
||||
_this.zOffset = 0.1;
|
||||
_this.batches = new Array();
|
||||
_this.nextBatchIndex = 0;
|
||||
_this.clipper = new spine.SkeletonClipping();
|
||||
_this.vertices = spine.Utils.newFloatArray(1024);
|
||||
_this.tempColor = new spine.Color();
|
||||
_this.skeleton = new spine.Skeleton(skeletonData);
|
||||
var animData = new spine.AnimationStateData(skeletonData);
|
||||
_this.state = new spine.AnimationState(animData);
|
||||
var material = _this.material = new THREE.MeshBasicMaterial();
|
||||
material.side = THREE.DoubleSide;
|
||||
material.transparent = true;
|
||||
material.alphaTest = 0.5;
|
||||
_this.batcher = new threejs.MeshBatcher(_this);
|
||||
return _this;
|
||||
}
|
||||
SkeletonMesh.prototype.update = function (deltaTime) {
|
||||
@ -9663,12 +9699,29 @@ var spine;
|
||||
skeleton.updateWorldTransform();
|
||||
this.updateGeometry();
|
||||
};
|
||||
SkeletonMesh.prototype.clearBatches = function () {
|
||||
for (var i = 0; i < this.batches.length; i++) {
|
||||
this.batches[i].clear();
|
||||
this.batches[i].visible = false;
|
||||
}
|
||||
this.nextBatchIndex = 0;
|
||||
};
|
||||
SkeletonMesh.prototype.nextBatch = function () {
|
||||
if (this.batches.length == this.nextBatchIndex) {
|
||||
var batch_1 = new threejs.MeshBatcher();
|
||||
this.add(batch_1);
|
||||
this.batches.push(batch_1);
|
||||
}
|
||||
var batch = this.batches[this.nextBatchIndex++];
|
||||
batch.visible = true;
|
||||
return batch;
|
||||
};
|
||||
SkeletonMesh.prototype.updateGeometry = function () {
|
||||
this.clearBatches();
|
||||
var tempPos = this.tempPos;
|
||||
var tempUv = this.tempUv;
|
||||
var tempLight = this.tempLight;
|
||||
var tempDark = this.tempDark;
|
||||
var geometry = this.geometry;
|
||||
var numVertices = 0;
|
||||
var verticesLength = 0;
|
||||
var indicesLength = 0;
|
||||
@ -9678,8 +9731,8 @@ var spine;
|
||||
var triangles = null;
|
||||
var uvs = null;
|
||||
var drawOrder = this.skeleton.drawOrder;
|
||||
var batcher = this.batcher;
|
||||
batcher.begin();
|
||||
var batch = this.nextBatch();
|
||||
batch.begin();
|
||||
var z = 0;
|
||||
var zOffset = this.zOffset;
|
||||
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
||||
@ -9720,17 +9773,16 @@ var spine;
|
||||
else
|
||||
continue;
|
||||
if (texture != null) {
|
||||
if (!this.material.map) {
|
||||
var mat = this.material;
|
||||
mat.map = texture.texture;
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
var skeleton = slot.bone.skeleton;
|
||||
var skeletonColor = skeleton.color;
|
||||
var slotColor = slot.color;
|
||||
var alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
|
||||
var color = this.tempColor;
|
||||
color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, alpha);
|
||||
var finalVertices = void 0;
|
||||
var finalVerticesLength = void 0;
|
||||
var finalIndices = void 0;
|
||||
var finalIndicesLength = void 0;
|
||||
if (clipper.isClipping()) {
|
||||
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
|
||||
var clippedVertices = clipper.clippedVertices;
|
||||
@ -9756,7 +9808,10 @@ var spine;
|
||||
verts[v + 7] = tempUv.y;
|
||||
}
|
||||
}
|
||||
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
|
||||
finalVertices = clippedVertices;
|
||||
finalVerticesLength = clippedVertices.length;
|
||||
finalIndices = clippedTriangles;
|
||||
finalIndicesLength = clippedTriangles.length;
|
||||
}
|
||||
else {
|
||||
var verts = vertices;
|
||||
@ -9790,15 +9845,40 @@ var spine;
|
||||
verts[v + 5] = uvs[u + 1];
|
||||
}
|
||||
}
|
||||
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
|
||||
finalVertices = vertices;
|
||||
finalVerticesLength = numFloats;
|
||||
finalIndices = triangles;
|
||||
finalIndicesLength = triangles.length;
|
||||
}
|
||||
if (finalVerticesLength == 0 || finalIndicesLength == 0)
|
||||
continue;
|
||||
if (!batch.canBatch(finalVerticesLength, finalIndicesLength)) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
}
|
||||
var batchMaterial = batch.material;
|
||||
if (batchMaterial.uniforms.map.value == null) {
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
if (batchMaterial.uniforms.map.value != texture.texture) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
batchMaterial = batch.material;
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
batchMaterial.needsUpdate = true;
|
||||
batch.batch(finalVertices, finalVerticesLength, finalIndices, finalIndicesLength, z);
|
||||
z += zOffset;
|
||||
}
|
||||
clipper.clipEndWithSlot(slot);
|
||||
}
|
||||
batcher.end();
|
||||
clipper.clipEnd();
|
||||
batch.end();
|
||||
};
|
||||
return SkeletonMesh;
|
||||
}(THREE.Mesh));
|
||||
}(THREE.Object3D));
|
||||
SkeletonMesh.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
||||
SkeletonMesh.VERTEX_SIZE = 2 + 2 + 4;
|
||||
threejs.SkeletonMesh = SkeletonMesh;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
|
||||
File diff suppressed because one or more lines are too long
17
spine-ts/build/spine-threejs.d.ts
vendored
17
spine-ts/build/spine-threejs.d.ts
vendored
@ -1237,22 +1237,26 @@ declare module spine.threejs {
|
||||
}
|
||||
}
|
||||
declare module spine.threejs {
|
||||
class MeshBatcher {
|
||||
mesh: THREE.Mesh;
|
||||
class MeshBatcher extends THREE.Mesh {
|
||||
private static VERTEX_SIZE;
|
||||
private vertexBuffer;
|
||||
private vertices;
|
||||
private verticesLength;
|
||||
private indices;
|
||||
private indicesLength;
|
||||
constructor(mesh: THREE.Mesh, maxVertices?: number);
|
||||
constructor(maxVertices?: number);
|
||||
clear(): void;
|
||||
begin(): void;
|
||||
canBatch(verticesLength: number, indicesLength: number): boolean;
|
||||
batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
|
||||
end(): void;
|
||||
}
|
||||
}
|
||||
declare module spine.threejs {
|
||||
class SkeletonMesh extends THREE.Mesh {
|
||||
class SkeletonMeshMaterial extends THREE.ShaderMaterial {
|
||||
constructor();
|
||||
}
|
||||
class SkeletonMesh extends THREE.Object3D {
|
||||
tempPos: Vector2;
|
||||
tempUv: Vector2;
|
||||
tempLight: Color;
|
||||
@ -1261,7 +1265,8 @@ declare module spine.threejs {
|
||||
state: AnimationState;
|
||||
zOffset: number;
|
||||
vertexEffect: VertexEffect;
|
||||
private batcher;
|
||||
private batches;
|
||||
private nextBatchIndex;
|
||||
private clipper;
|
||||
static QUAD_TRIANGLES: number[];
|
||||
static VERTEX_SIZE: number;
|
||||
@ -1269,6 +1274,8 @@ declare module spine.threejs {
|
||||
private tempColor;
|
||||
constructor(skeletonData: SkeletonData);
|
||||
update(deltaTime: number): void;
|
||||
private clearBatches();
|
||||
private nextBatch();
|
||||
private updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
@ -6734,18 +6734,19 @@ var spine;
|
||||
(function (spine) {
|
||||
var threejs;
|
||||
(function (threejs) {
|
||||
var MeshBatcher = (function () {
|
||||
function MeshBatcher(mesh, maxVertices) {
|
||||
var MeshBatcher = (function (_super) {
|
||||
__extends(MeshBatcher, _super);
|
||||
function MeshBatcher(maxVertices) {
|
||||
if (maxVertices === void 0) { maxVertices = 10920; }
|
||||
this.verticesLength = 0;
|
||||
this.indicesLength = 0;
|
||||
var _this = _super.call(this) || this;
|
||||
_this.verticesLength = 0;
|
||||
_this.indicesLength = 0;
|
||||
if (maxVertices > 10920)
|
||||
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
||||
var vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||
var indices = this.indices = new Uint16Array(maxVertices * 3);
|
||||
this.mesh = mesh;
|
||||
var vertices = _this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||
var indices = _this.indices = new Uint16Array(maxVertices * 3);
|
||||
var geo = new THREE.BufferGeometry();
|
||||
var vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||
var vertexBuffer = _this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||
vertexBuffer.dynamic = true;
|
||||
geo.addAttribute("position", new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0, false));
|
||||
geo.addAttribute("color", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 3, false));
|
||||
@ -6754,12 +6755,27 @@ var spine;
|
||||
geo.getIndex().dynamic = true;
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
mesh.geometry = geo;
|
||||
_this.geometry = geo;
|
||||
_this.material = new threejs.SkeletonMeshMaterial();
|
||||
return _this;
|
||||
}
|
||||
MeshBatcher.prototype.clear = function () {
|
||||
var geo = this.geometry;
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
this.material.uniforms.map.value = null;
|
||||
};
|
||||
MeshBatcher.prototype.begin = function () {
|
||||
this.verticesLength = 0;
|
||||
this.indicesLength = 0;
|
||||
};
|
||||
MeshBatcher.prototype.canBatch = function (verticesLength, indicesLength) {
|
||||
if (this.indicesLength + indicesLength >= this.indices.byteLength / 2)
|
||||
return false;
|
||||
if (this.verticesLength + verticesLength >= this.vertices.byteLength / 2)
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
MeshBatcher.prototype.batch = function (vertices, verticesLength, indices, indicesLength, z) {
|
||||
if (z === void 0) { z = 0; }
|
||||
var indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
|
||||
@ -6787,7 +6803,7 @@ var spine;
|
||||
this.vertexBuffer.needsUpdate = true;
|
||||
this.vertexBuffer.updateRange.offset = 0;
|
||||
this.vertexBuffer.updateRange.count = this.verticesLength;
|
||||
var geo = this.mesh.geometry;
|
||||
var geo = this.geometry;
|
||||
geo.getIndex().needsUpdate = true;
|
||||
geo.getIndex().updateRange.offset = 0;
|
||||
geo.getIndex().updateRange.count = this.indicesLength;
|
||||
@ -6795,7 +6811,7 @@ var spine;
|
||||
geo.drawRange.count = this.indicesLength;
|
||||
};
|
||||
return MeshBatcher;
|
||||
}());
|
||||
}(THREE.Mesh));
|
||||
MeshBatcher.VERTEX_SIZE = 9;
|
||||
threejs.MeshBatcher = MeshBatcher;
|
||||
})(threejs = spine.threejs || (spine.threejs = {}));
|
||||
@ -6804,6 +6820,29 @@ var spine;
|
||||
(function (spine) {
|
||||
var threejs;
|
||||
(function (threejs) {
|
||||
var SkeletonMeshMaterial = (function (_super) {
|
||||
__extends(SkeletonMeshMaterial, _super);
|
||||
function SkeletonMeshMaterial() {
|
||||
var _this = this;
|
||||
var vertexShader = "\n\t\t\t\tattribute vec4 color;\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec4 vColor;\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tvColor = color;\n\t\t\t\t\tgl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);\n\t\t\t\t}\n\t\t\t";
|
||||
var fragmentShader = "\n\t\t\t\tuniform sampler2D map;\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec4 vColor;\n\t\t\t\tvoid main(void) {\n\t\t\t\t\tgl_FragColor = texture2D(map, vUv)*vColor;\n\t\t\t\t}\n\t\t\t";
|
||||
var parameters = {
|
||||
uniforms: {
|
||||
map: { type: "t", value: null }
|
||||
},
|
||||
vertexShader: vertexShader,
|
||||
fragmentShader: fragmentShader,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
alphaTest: 0.5
|
||||
};
|
||||
_this = _super.call(this, parameters) || this;
|
||||
return _this;
|
||||
}
|
||||
;
|
||||
return SkeletonMeshMaterial;
|
||||
}(THREE.ShaderMaterial));
|
||||
threejs.SkeletonMeshMaterial = SkeletonMeshMaterial;
|
||||
var SkeletonMesh = (function (_super) {
|
||||
__extends(SkeletonMesh, _super);
|
||||
function SkeletonMesh(skeletonData) {
|
||||
@ -6813,17 +6852,14 @@ var spine;
|
||||
_this.tempLight = new spine.Color();
|
||||
_this.tempDark = new spine.Color();
|
||||
_this.zOffset = 0.1;
|
||||
_this.batches = new Array();
|
||||
_this.nextBatchIndex = 0;
|
||||
_this.clipper = new spine.SkeletonClipping();
|
||||
_this.vertices = spine.Utils.newFloatArray(1024);
|
||||
_this.tempColor = new spine.Color();
|
||||
_this.skeleton = new spine.Skeleton(skeletonData);
|
||||
var animData = new spine.AnimationStateData(skeletonData);
|
||||
_this.state = new spine.AnimationState(animData);
|
||||
var material = _this.material = new THREE.MeshBasicMaterial();
|
||||
material.side = THREE.DoubleSide;
|
||||
material.transparent = true;
|
||||
material.alphaTest = 0.5;
|
||||
_this.batcher = new threejs.MeshBatcher(_this);
|
||||
return _this;
|
||||
}
|
||||
SkeletonMesh.prototype.update = function (deltaTime) {
|
||||
@ -6834,12 +6870,29 @@ var spine;
|
||||
skeleton.updateWorldTransform();
|
||||
this.updateGeometry();
|
||||
};
|
||||
SkeletonMesh.prototype.clearBatches = function () {
|
||||
for (var i = 0; i < this.batches.length; i++) {
|
||||
this.batches[i].clear();
|
||||
this.batches[i].visible = false;
|
||||
}
|
||||
this.nextBatchIndex = 0;
|
||||
};
|
||||
SkeletonMesh.prototype.nextBatch = function () {
|
||||
if (this.batches.length == this.nextBatchIndex) {
|
||||
var batch_1 = new threejs.MeshBatcher();
|
||||
this.add(batch_1);
|
||||
this.batches.push(batch_1);
|
||||
}
|
||||
var batch = this.batches[this.nextBatchIndex++];
|
||||
batch.visible = true;
|
||||
return batch;
|
||||
};
|
||||
SkeletonMesh.prototype.updateGeometry = function () {
|
||||
this.clearBatches();
|
||||
var tempPos = this.tempPos;
|
||||
var tempUv = this.tempUv;
|
||||
var tempLight = this.tempLight;
|
||||
var tempDark = this.tempDark;
|
||||
var geometry = this.geometry;
|
||||
var numVertices = 0;
|
||||
var verticesLength = 0;
|
||||
var indicesLength = 0;
|
||||
@ -6849,8 +6902,8 @@ var spine;
|
||||
var triangles = null;
|
||||
var uvs = null;
|
||||
var drawOrder = this.skeleton.drawOrder;
|
||||
var batcher = this.batcher;
|
||||
batcher.begin();
|
||||
var batch = this.nextBatch();
|
||||
batch.begin();
|
||||
var z = 0;
|
||||
var zOffset = this.zOffset;
|
||||
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
||||
@ -6891,17 +6944,16 @@ var spine;
|
||||
else
|
||||
continue;
|
||||
if (texture != null) {
|
||||
if (!this.material.map) {
|
||||
var mat = this.material;
|
||||
mat.map = texture.texture;
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
var skeleton = slot.bone.skeleton;
|
||||
var skeletonColor = skeleton.color;
|
||||
var slotColor = slot.color;
|
||||
var alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
|
||||
var color = this.tempColor;
|
||||
color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, alpha);
|
||||
var finalVertices = void 0;
|
||||
var finalVerticesLength = void 0;
|
||||
var finalIndices = void 0;
|
||||
var finalIndicesLength = void 0;
|
||||
if (clipper.isClipping()) {
|
||||
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
|
||||
var clippedVertices = clipper.clippedVertices;
|
||||
@ -6927,7 +6979,10 @@ var spine;
|
||||
verts[v + 7] = tempUv.y;
|
||||
}
|
||||
}
|
||||
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
|
||||
finalVertices = clippedVertices;
|
||||
finalVerticesLength = clippedVertices.length;
|
||||
finalIndices = clippedTriangles;
|
||||
finalIndicesLength = clippedTriangles.length;
|
||||
}
|
||||
else {
|
||||
var verts = vertices;
|
||||
@ -6961,15 +7016,40 @@ var spine;
|
||||
verts[v + 5] = uvs[u + 1];
|
||||
}
|
||||
}
|
||||
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
|
||||
finalVertices = vertices;
|
||||
finalVerticesLength = numFloats;
|
||||
finalIndices = triangles;
|
||||
finalIndicesLength = triangles.length;
|
||||
}
|
||||
if (finalVerticesLength == 0 || finalIndicesLength == 0)
|
||||
continue;
|
||||
if (!batch.canBatch(finalVerticesLength, finalIndicesLength)) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
}
|
||||
var batchMaterial = batch.material;
|
||||
if (batchMaterial.uniforms.map.value == null) {
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
if (batchMaterial.uniforms.map.value != texture.texture) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
batchMaterial = batch.material;
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
batchMaterial.needsUpdate = true;
|
||||
batch.batch(finalVertices, finalVerticesLength, finalIndices, finalIndicesLength, z);
|
||||
z += zOffset;
|
||||
}
|
||||
clipper.clipEndWithSlot(slot);
|
||||
}
|
||||
batcher.end();
|
||||
clipper.clipEnd();
|
||||
batch.end();
|
||||
};
|
||||
return SkeletonMesh;
|
||||
}(THREE.Mesh));
|
||||
}(THREE.Object3D));
|
||||
SkeletonMesh.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
||||
SkeletonMesh.VERTEX_SIZE = 2 + 2 + 4;
|
||||
threejs.SkeletonMesh = SkeletonMesh;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -2131,6 +2131,7 @@ var spine;
|
||||
path = this.pathPrefix + path;
|
||||
this.toLoad++;
|
||||
AssetManager.downloadText(path, function (atlasData) {
|
||||
var pagesLoaded = { count: 0 };
|
||||
var atlasPages = new Array();
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2151,11 +2152,10 @@ var spine;
|
||||
return;
|
||||
}
|
||||
var _loop_1 = function (atlasPage) {
|
||||
var pagesLoaded = 0;
|
||||
var pageLoadError = false;
|
||||
_this.loadTexture(atlasPage, function (imagePath, image) {
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
||||
@ -2186,8 +2186,8 @@ var spine;
|
||||
}
|
||||
}, function (imagePath, errorMessage) {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
pagesLoaded.count++;
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
||||
if (error)
|
||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -147,6 +147,7 @@ module spine {
|
||||
this.toLoad++;
|
||||
|
||||
AssetManager.downloadText(path, (atlasData: string): void => {
|
||||
var pagesLoaded: any = { count: 0 };
|
||||
var atlasPages = new Array<string>();
|
||||
try {
|
||||
let atlas = new spine.TextureAtlas(atlasData, (path: string) => {
|
||||
@ -166,12 +167,11 @@ module spine {
|
||||
}
|
||||
|
||||
for (let atlasPage of atlasPages) {
|
||||
let pagesLoaded = 0;
|
||||
let pageLoadError = false;
|
||||
this.loadTexture(atlasPage, (imagePath: string, image: HTMLImageElement) => {
|
||||
pagesLoaded++;
|
||||
pagesLoaded.count++;
|
||||
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
if (!pageLoadError) {
|
||||
try {
|
||||
let atlas = new spine.TextureAtlas(atlasData, (path: string) => {
|
||||
@ -197,9 +197,9 @@ module spine {
|
||||
}
|
||||
}, (imagePath: string, errorMessage: string) => {
|
||||
pageLoadError = true;
|
||||
pagesLoaded++;
|
||||
pagesLoaded.count++;
|
||||
|
||||
if (pagesLoaded == atlasPages.length) {
|
||||
if (pagesLoaded.count == atlasPages.length) {
|
||||
this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`;
|
||||
if (error) error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`);
|
||||
this.toLoad--;
|
||||
|
||||
@ -19,6 +19,11 @@ var assetManager;
|
||||
var canvas;
|
||||
var lastFrameTime = Date.now() / 1000;
|
||||
|
||||
var baseUrl = "assets/";
|
||||
var skeletonFile = "raptor-pro.json";
|
||||
var atlasFile = skeletonFile.replace("-pro", "").replace("-ess", "").replace(".json", ".atlas");
|
||||
var animation = "walk";
|
||||
|
||||
function init () {
|
||||
// create the THREE.JS camera, scene and renderer (WebGL)
|
||||
var width = window.innerWidth, height = window.innerHeight;
|
||||
@ -32,10 +37,9 @@ function init () {
|
||||
canvas = renderer.domElement;
|
||||
|
||||
// load the assets required to display the Raptor model
|
||||
assetManager = new spine.threejs.AssetManager();
|
||||
assetManager.loadText("assets/raptor-pro.json");
|
||||
assetManager.loadText("assets/raptor.atlas");
|
||||
assetManager.loadTexture("assets/raptor.png");
|
||||
assetManager = new spine.threejs.AssetManager(baseUrl);
|
||||
assetManager.loadText(skeletonFile);
|
||||
assetManager.loadTextureAtlas(atlasFile);
|
||||
|
||||
requestAnimationFrame(load);
|
||||
}
|
||||
@ -50,39 +54,27 @@ function load (name, scale) {
|
||||
|
||||
// Load the texture atlas using name.atlas and name.png from the AssetManager.
|
||||
// The function passed to TextureAtlas is used to resolve relative paths.
|
||||
atlas = new spine.TextureAtlas(assetManager.get("assets/raptor.atlas"), function(path) {
|
||||
return assetManager.get("assets/" + path);
|
||||
});
|
||||
var skeletonData = loadSkeleton("raptor-pro", 0.4);
|
||||
atlas = assetManager.get(atlasFile);
|
||||
|
||||
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
|
||||
atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
||||
|
||||
// Create a SkeletonJson instance for parsing the .json file.
|
||||
var skeletonJson = new spine.SkeletonJson(atlasLoader);
|
||||
|
||||
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
|
||||
skeletonJson.scale = 0.4;
|
||||
var skeletonData = skeletonJson.readSkeletonData(assetManager.get(skeletonFile));
|
||||
|
||||
// Create a SkeletonMesh from the data and attach it to the scene
|
||||
skeletonMesh = new spine.threejs.SkeletonMesh(skeletonData);
|
||||
skeletonMesh.state.setAnimation(0, "walk", true);
|
||||
skeletonMesh.state.setAnimation(0, animation, true);
|
||||
mesh.add(skeletonMesh);
|
||||
|
||||
requestAnimationFrame(render);
|
||||
} else requestAnimationFrame(load);
|
||||
}
|
||||
|
||||
function loadSkeleton (name, scale) {
|
||||
// Load the texture atlas using name.atlas and name.png from the AssetManager.
|
||||
// The function passed to TextureAtlas is used to resolve relative paths.
|
||||
atlas = new spine.TextureAtlas(assetManager.get("assets/" + name.replace("-pro", "") + ".atlas"), function(path) {
|
||||
return assetManager.get("assets/" + path);
|
||||
});
|
||||
|
||||
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
|
||||
atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
||||
|
||||
// Create a SkeletonJson instance for parsing the .json file.
|
||||
var skeletonJson = new spine.SkeletonJson(atlasLoader);
|
||||
|
||||
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
|
||||
skeletonJson.scale = scale;
|
||||
var skeletonData = skeletonJson.readSkeletonData(assetManager.get("assets/" + name + ".json"));
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
var lastTime = Date.now();
|
||||
function render() {
|
||||
// calculate delta time for animation purposes
|
||||
|
||||
@ -29,9 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
module spine.threejs {
|
||||
export class MeshBatcher {
|
||||
mesh: THREE.Mesh;
|
||||
|
||||
export class MeshBatcher extends THREE.Mesh {
|
||||
private static VERTEX_SIZE = 9;
|
||||
private vertexBuffer: THREE.InterleavedBuffer;
|
||||
private vertices: Float32Array;
|
||||
@ -39,12 +37,11 @@ module spine.threejs {
|
||||
private indices: Uint16Array;
|
||||
private indicesLength = 0;
|
||||
|
||||
constructor (mesh: THREE.Mesh, maxVertices: number = 10920) {
|
||||
constructor (maxVertices: number = 10920) {
|
||||
super();
|
||||
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
||||
|
||||
let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||
let indices = this.indices = new Uint16Array(maxVertices * 3);
|
||||
this.mesh = mesh;
|
||||
let geo = new THREE.BufferGeometry();
|
||||
let vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||
vertexBuffer.dynamic = true;
|
||||
@ -55,7 +52,15 @@ module spine.threejs {
|
||||
geo.getIndex().dynamic = true;
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
mesh.geometry = geo;
|
||||
this.geometry = geo;
|
||||
this.material = new SkeletonMeshMaterial();
|
||||
}
|
||||
|
||||
clear () {
|
||||
let geo = (<THREE.BufferGeometry>this.geometry);
|
||||
geo.drawRange.start = 0;
|
||||
geo.drawRange.count = 0;
|
||||
(<SkeletonMeshMaterial>this.material).uniforms.map.value = null;
|
||||
}
|
||||
|
||||
begin () {
|
||||
@ -63,6 +68,12 @@ module spine.threejs {
|
||||
this.indicesLength = 0;
|
||||
}
|
||||
|
||||
canBatch(verticesLength: number, indicesLength: number) {
|
||||
if (this.indicesLength + indicesLength >= this.indices.byteLength / 2) return false;
|
||||
if (this.verticesLength + verticesLength >= this.vertices.byteLength / 2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
batch (vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z: number = 0) {
|
||||
let indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
|
||||
let vertexBuffer = this.vertices;
|
||||
@ -91,7 +102,7 @@ module spine.threejs {
|
||||
this.vertexBuffer.needsUpdate = true;
|
||||
this.vertexBuffer.updateRange.offset = 0;
|
||||
this.vertexBuffer.updateRange.count = this.verticesLength;
|
||||
let geo = (<THREE.BufferGeometry>this.mesh.geometry);
|
||||
let geo = (<THREE.BufferGeometry>this.geometry);
|
||||
geo.getIndex().needsUpdate = true;
|
||||
geo.getIndex().updateRange.offset = 0;
|
||||
geo.getIndex().updateRange.count = this.indicesLength;
|
||||
|
||||
@ -29,7 +29,42 @@
|
||||
*****************************************************************************/
|
||||
|
||||
module spine.threejs {
|
||||
export class SkeletonMesh extends THREE.Mesh {
|
||||
export class SkeletonMeshMaterial extends THREE.ShaderMaterial {
|
||||
constructor () {
|
||||
let vertexShader = `
|
||||
attribute vec4 color;
|
||||
varying vec2 vUv;
|
||||
varying vec4 vColor;
|
||||
void main() {
|
||||
vUv = uv;
|
||||
vColor = color;
|
||||
gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
|
||||
}
|
||||
`;
|
||||
let fragmentShader = `
|
||||
uniform sampler2D map;
|
||||
varying vec2 vUv;
|
||||
varying vec4 vColor;
|
||||
void main(void) {
|
||||
gl_FragColor = texture2D(map, vUv)*vColor;
|
||||
}
|
||||
`;
|
||||
|
||||
let parameters: THREE.ShaderMaterialParameters = {
|
||||
uniforms: {
|
||||
map: { type: "t", value: null }
|
||||
},
|
||||
vertexShader: vertexShader,
|
||||
fragmentShader: fragmentShader,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
alphaTest: 0.5
|
||||
};
|
||||
super(parameters);
|
||||
};
|
||||
}
|
||||
|
||||
export class SkeletonMesh extends THREE.Object3D {
|
||||
tempPos: Vector2 = new Vector2();
|
||||
tempUv: Vector2 = new Vector2();
|
||||
tempLight = new Color();
|
||||
@ -39,7 +74,8 @@ module spine.threejs {
|
||||
zOffset: number = 0.1;
|
||||
vertexEffect: VertexEffect;
|
||||
|
||||
private batcher: MeshBatcher;
|
||||
private batches = new Array<MeshBatcher>();
|
||||
private nextBatchIndex = 0;
|
||||
private clipper: SkeletonClipping = new SkeletonClipping();
|
||||
|
||||
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
||||
@ -54,12 +90,6 @@ module spine.threejs {
|
||||
this.skeleton = new Skeleton(skeletonData);
|
||||
let animData = new AnimationStateData(skeletonData);
|
||||
this.state = new AnimationState(animData);
|
||||
|
||||
let material = this.material = new THREE.MeshBasicMaterial();
|
||||
material.side = THREE.DoubleSide;
|
||||
material.transparent = true;
|
||||
material.alphaTest = 0.5;
|
||||
this.batcher = new MeshBatcher(this);
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
@ -73,13 +103,33 @@ module spine.threejs {
|
||||
this.updateGeometry();
|
||||
}
|
||||
|
||||
private clearBatches () {
|
||||
for (var i = 0; i < this.batches.length; i++) {
|
||||
this.batches[i].clear();
|
||||
this.batches[i].visible = false;
|
||||
}
|
||||
this.nextBatchIndex = 0;
|
||||
}
|
||||
|
||||
private nextBatch () {
|
||||
if (this.batches.length == this.nextBatchIndex) {
|
||||
let batch = new MeshBatcher();
|
||||
this.add(batch);
|
||||
this.batches.push(batch);
|
||||
}
|
||||
let batch = this.batches[this.nextBatchIndex++];
|
||||
batch.visible = true;
|
||||
return batch;
|
||||
}
|
||||
|
||||
private updateGeometry() {
|
||||
this.clearBatches();
|
||||
|
||||
let tempPos = this.tempPos;
|
||||
let tempUv = this.tempUv;
|
||||
let tempLight = this.tempLight;
|
||||
let tempDark = this.tempDark;
|
||||
|
||||
let geometry = <THREE.BufferGeometry>this.geometry;
|
||||
var numVertices = 0;
|
||||
var verticesLength = 0;
|
||||
var indicesLength = 0;
|
||||
@ -91,8 +141,8 @@ module spine.threejs {
|
||||
let triangles: Array<number> = null;
|
||||
let uvs: ArrayLike<number> = null;
|
||||
let drawOrder = this.skeleton.drawOrder;
|
||||
let batcher = this.batcher;
|
||||
batcher.begin();
|
||||
let batch = this.nextBatch();
|
||||
batch.begin();
|
||||
let z = 0;
|
||||
let zOffset = this.zOffset;
|
||||
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
||||
@ -130,12 +180,6 @@ module spine.threejs {
|
||||
} else continue;
|
||||
|
||||
if (texture != null) {
|
||||
if (!(<THREE.MeshBasicMaterial>this.material).map) {
|
||||
let mat = <THREE.MeshBasicMaterial>this.material;
|
||||
mat.map = texture.texture;
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
|
||||
let skeleton = slot.bone.skeleton;
|
||||
let skeletonColor = skeleton.color;
|
||||
let slotColor = slot.color;
|
||||
@ -145,12 +189,11 @@ module spine.threejs {
|
||||
skeletonColor.g * slotColor.g * attachmentColor.g,
|
||||
skeletonColor.b * slotColor.b * attachmentColor.b,
|
||||
alpha);
|
||||
// FIXME per slot blending would require multiple material support
|
||||
//let slotBlendMode = slot.data.blendMode;
|
||||
//if (slotBlendMode != blendMode) {
|
||||
// blendMode = slotBlendMode;
|
||||
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
|
||||
//}
|
||||
|
||||
let finalVertices: ArrayLike<number>;
|
||||
let finalVerticesLength: number;
|
||||
let finalIndices: ArrayLike<number>;
|
||||
let finalIndicesLength: number;
|
||||
|
||||
if (clipper.isClipping()) {
|
||||
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
|
||||
@ -177,7 +220,10 @@ module spine.threejs {
|
||||
verts[v + 7] = tempUv.y;
|
||||
}
|
||||
}
|
||||
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
|
||||
finalVertices = clippedVertices;
|
||||
finalVerticesLength = clippedVertices.length;
|
||||
finalIndices = clippedTriangles;
|
||||
finalIndicesLength = clippedTriangles.length;
|
||||
} else {
|
||||
let verts = vertices;
|
||||
if (this.vertexEffect != null) {
|
||||
@ -209,13 +255,50 @@ module spine.threejs {
|
||||
verts[v + 5] = uvs[u + 1];
|
||||
}
|
||||
}
|
||||
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
|
||||
finalVertices = vertices;
|
||||
finalVerticesLength = numFloats;
|
||||
finalIndices = triangles;
|
||||
finalIndicesLength = triangles.length;
|
||||
}
|
||||
|
||||
if (finalVerticesLength == 0 || finalIndicesLength == 0)
|
||||
continue;
|
||||
|
||||
// Start new batch if this one can't hold vertices/indices
|
||||
if (!batch.canBatch(finalVerticesLength, finalIndicesLength)) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
}
|
||||
|
||||
// FIXME per slot blending would require multiple material support
|
||||
//let slotBlendMode = slot.data.blendMode;
|
||||
//if (slotBlendMode != blendMode) {
|
||||
// blendMode = slotBlendMode;
|
||||
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
|
||||
//}
|
||||
|
||||
let batchMaterial = <SkeletonMeshMaterial>batch.material;
|
||||
if (batchMaterial.uniforms.map.value == null) {
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
if (batchMaterial.uniforms.map.value != texture.texture) {
|
||||
batch.end();
|
||||
batch = this.nextBatch();
|
||||
batch.begin();
|
||||
batchMaterial = <SkeletonMeshMaterial>batch.material;
|
||||
batchMaterial.uniforms.map.value = texture.texture;
|
||||
}
|
||||
batchMaterial.needsUpdate = true;
|
||||
|
||||
batch.batch(finalVertices, finalVerticesLength, finalIndices, finalIndicesLength, z);
|
||||
z += zOffset;
|
||||
}
|
||||
}
|
||||
|
||||
batcher.end();
|
||||
clipper.clipEndWithSlot(slot);
|
||||
}
|
||||
clipper.clipEnd();
|
||||
batch.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user