[ts][threejs] Implemented clipping.

This commit is contained in:
badlogic 2017-04-13 10:45:25 +02:00
parent d4266cf89a
commit bd16d0fde8
13 changed files with 304 additions and 399 deletions

View File

@ -121,6 +121,7 @@
* Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`.
* Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface.
* Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface.
* Added `SkeletonClipper` and `ConvexDecomposer`, used to implement software clipping of attachments.
### WebGL backend
* Fixed renderer to work with 3.6 changes.
@ -136,6 +137,7 @@
### Three.js backend
* Fixed renderer to work with 3.6 changes. Two color tinting is not supported.
* Added clipping support
### Widget backend
* Fixed renderer to work for 3.6 changes. Supports two color tinting & clipping (see webgl backend changes for details).

View File

@ -1197,7 +1197,7 @@ declare module spine.threejs {
private indicesLength;
constructor(mesh: THREE.Mesh, maxVertices?: number);
begin(): void;
batch(vertices: ArrayLike<number>, indices: ArrayLike<number>, z?: number): void;
batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
end(): void;
}
}
@ -1207,6 +1207,7 @@ declare module spine.threejs {
state: AnimationState;
zOffset: number;
private batcher;
private clipper;
static QUAD_TRIANGLES: number[];
static VERTEX_SIZE: number;
private vertices;
@ -1214,8 +1215,6 @@ declare module spine.threejs {
constructor(skeletonData: SkeletonData);
update(deltaTime: number): void;
private updateGeometry();
private computeRegionVertices(slot, region, pma);
private computeMeshVertices(slot, mesh, pma);
}
}
declare module spine.threejs {

View File

@ -6509,13 +6509,13 @@ var spine;
this.verticesLength = 0;
this.indicesLength = 0;
};
MeshBatcher.prototype.batch = function (vertices, indices, z) {
MeshBatcher.prototype.batch = function (vertices, verticesLength, indices, indicesLength, z) {
if (z === void 0) { z = 0; }
var indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
var vertexBuffer = this.vertices;
var i = this.verticesLength;
var j = 0;
for (; j < vertices.length;) {
for (; j < verticesLength;) {
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = z;
@ -6528,9 +6528,9 @@ var spine;
}
this.verticesLength = i;
var indicesArray = this.indices;
for (i = this.indicesLength, j = 0; j < indices.length; i++, j++)
for (i = this.indicesLength, j = 0; j < indicesLength; i++, j++)
indicesArray[i] = indices[j] + indexStart;
this.indicesLength += indices.length;
this.indicesLength += indicesLength;
};
MeshBatcher.prototype.end = function () {
this.vertexBuffer.needsUpdate = true;
@ -6558,6 +6558,7 @@ var spine;
function SkeletonMesh(skeletonData) {
_super.call(this);
this.zOffset = 0.1;
this.clipper = new spine.SkeletonClipping();
this.vertices = spine.Utils.newFloatArray(1024);
this.tempColor = new spine.Color();
this.skeleton = new spine.Skeleton(skeletonData);
@ -6583,29 +6584,50 @@ var spine;
var verticesLength = 0;
var indicesLength = 0;
var blendMode = null;
var vertices = null;
var clipper = this.clipper;
var vertices = this.vertices;
var triangles = null;
var uvs = null;
var drawOrder = this.skeleton.drawOrder;
var batcher = this.batcher;
batcher.begin();
var z = 0;
var zOffset = this.zOffset;
for (var i = 0, n = drawOrder.length; i < n; i++) {
var vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
var slot = drawOrder[i];
var attachment = slot.getAttachment();
var attachmentColor = null;
var texture = null;
var numFloats = 0;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = this.computeRegionVertices(slot, region, false);
attachmentColor = region.color;
vertices = this.vertices;
numFloats = vertexSize * 4;
region.computeWorldVertices(slot.bone, vertices, 0, vertexSize);
triangles = SkeletonMesh.QUAD_TRIANGLES;
uvs = region.uvs;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = this.computeMeshVertices(slot, mesh, false);
attachmentColor = mesh.color;
vertices = this.vertices;
numFloats = (mesh.worldVerticesLength >> 1) * vertexSize;
if (numFloats > vertices.length) {
vertices = this.vertices = spine.Utils.newFloatArray(numFloats);
}
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, vertexSize);
triangles = mesh.triangles;
uvs = mesh.uvs;
texture = mesh.region.renderObject.texture;
}
else if (attachment instanceof spine.ClippingAttachment) {
var clip = (attachment);
clipper.clipStart(slot, clip);
continue;
}
else
continue;
if (texture != null) {
@ -6614,77 +6636,35 @@ var spine;
mat.map = texture.texture;
mat.needsUpdate = true;
}
this.batcher.batch(vertices, triangles, z);
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);
if (clipper.isClipping()) {
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
var clippedVertices = clipper.clippedVertices;
var clippedTriangles = clipper.clippedTriangles;
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
}
else {
var verts = vertices;
for (var v = 2, u = 0, n_2 = numFloats; v < n_2; v += vertexSize, u += 2) {
verts[v] = color.r;
verts[v + 1] = color.g;
verts[v + 2] = color.b;
verts[v + 3] = color.a;
verts[v + 4] = uvs[u];
verts[v + 5] = uvs[u + 1];
}
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
}
z += zOffset;
}
}
batcher.end();
};
SkeletonMesh.prototype.computeRegionVertices = function (slot, region, pma) {
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
var regionColor = region.color;
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonMesh.VERTEX_SIZE);
var vertices = this.vertices;
var uvs = region.uvs;
vertices[spine.RegionAttachment.C1R] = color.r;
vertices[spine.RegionAttachment.C1G] = color.g;
vertices[spine.RegionAttachment.C1B] = color.b;
vertices[spine.RegionAttachment.C1A] = color.a;
vertices[spine.RegionAttachment.U1] = uvs[0];
vertices[spine.RegionAttachment.V1] = uvs[1];
vertices[spine.RegionAttachment.C2R] = color.r;
vertices[spine.RegionAttachment.C2G] = color.g;
vertices[spine.RegionAttachment.C2B] = color.b;
vertices[spine.RegionAttachment.C2A] = color.a;
vertices[spine.RegionAttachment.U2] = uvs[2];
vertices[spine.RegionAttachment.V2] = uvs[3];
vertices[spine.RegionAttachment.C3R] = color.r;
vertices[spine.RegionAttachment.C3G] = color.g;
vertices[spine.RegionAttachment.C3B] = color.b;
vertices[spine.RegionAttachment.C3A] = color.a;
vertices[spine.RegionAttachment.U3] = uvs[4];
vertices[spine.RegionAttachment.V3] = uvs[5];
vertices[spine.RegionAttachment.C4R] = color.r;
vertices[spine.RegionAttachment.C4G] = color.g;
vertices[spine.RegionAttachment.C4B] = color.b;
vertices[spine.RegionAttachment.C4A] = color.a;
vertices[spine.RegionAttachment.U4] = uvs[6];
vertices[spine.RegionAttachment.V4] = uvs[7];
return vertices;
};
SkeletonMesh.prototype.computeMeshVertices = function (slot, mesh, pma) {
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
var regionColor = mesh.color;
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
var numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
}
var vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonMesh.VERTEX_SIZE);
var uvs = mesh.uvs;
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
return vertices;
};
SkeletonMesh.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
SkeletonMesh.VERTEX_SIZE = 2 + 2 + 4;
return SkeletonMesh;
@ -8787,7 +8767,7 @@ var spine;
var nn = clip.worldVerticesLength;
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
for (var i_5 = 0, n_2 = world.length; i_5 < n_2; i_5 += 2) {
for (var i_5 = 0, n_3 = world.length; i_5 < n_3; i_5 += 2) {
var x = world[i_5];
var y = world[i_5 + 1];
var x2 = world[(i_5 + 2) % world.length];
@ -8915,7 +8895,7 @@ var spine;
else {
var verts = renderable.vertices;
if (!twoColorTint) {
for (var v = 2, u = 0, n_3 = renderable.numFloats; v < n_3; v += vertexSize, u += 2) {
for (var v = 2, u = 0, n_4 = renderable.numFloats; v < n_4; v += vertexSize, u += 2) {
verts[v] = finalColor.r;
verts[v + 1] = finalColor.g;
verts[v + 2] = finalColor.b;
@ -8925,7 +8905,7 @@ var spine;
}
}
else {
for (var v = 2, u = 0, n_4 = renderable.numFloats; v < n_4; v += vertexSize, u += 2) {
for (var v = 2, u = 0, n_5 = renderable.numFloats; v < n_5; v += vertexSize, u += 2) {
verts[v] = finalColor.r;
verts[v + 1] = finalColor.g;
verts[v + 2] = finalColor.b;

File diff suppressed because one or more lines are too long

View File

@ -1166,7 +1166,7 @@ declare module spine.threejs {
private indicesLength;
constructor(mesh: THREE.Mesh, maxVertices?: number);
begin(): void;
batch(vertices: ArrayLike<number>, indices: ArrayLike<number>, z?: number): void;
batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
end(): void;
}
}
@ -1176,6 +1176,7 @@ declare module spine.threejs {
state: AnimationState;
zOffset: number;
private batcher;
private clipper;
static QUAD_TRIANGLES: number[];
static VERTEX_SIZE: number;
private vertices;
@ -1183,8 +1184,6 @@ declare module spine.threejs {
constructor(skeletonData: SkeletonData);
update(deltaTime: number): void;
private updateGeometry();
private computeRegionVertices(slot, region, pma);
private computeMeshVertices(slot, mesh, pma);
}
}
declare module spine.threejs {

View File

@ -6255,13 +6255,13 @@ var spine;
this.verticesLength = 0;
this.indicesLength = 0;
};
MeshBatcher.prototype.batch = function (vertices, indices, z) {
MeshBatcher.prototype.batch = function (vertices, verticesLength, indices, indicesLength, z) {
if (z === void 0) { z = 0; }
var indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
var vertexBuffer = this.vertices;
var i = this.verticesLength;
var j = 0;
for (; j < vertices.length;) {
for (; j < verticesLength;) {
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = z;
@ -6274,9 +6274,9 @@ var spine;
}
this.verticesLength = i;
var indicesArray = this.indices;
for (i = this.indicesLength, j = 0; j < indices.length; i++, j++)
for (i = this.indicesLength, j = 0; j < indicesLength; i++, j++)
indicesArray[i] = indices[j] + indexStart;
this.indicesLength += indices.length;
this.indicesLength += indicesLength;
};
MeshBatcher.prototype.end = function () {
this.vertexBuffer.needsUpdate = true;
@ -6304,6 +6304,7 @@ var spine;
function SkeletonMesh(skeletonData) {
_super.call(this);
this.zOffset = 0.1;
this.clipper = new spine.SkeletonClipping();
this.vertices = spine.Utils.newFloatArray(1024);
this.tempColor = new spine.Color();
this.skeleton = new spine.Skeleton(skeletonData);
@ -6329,29 +6330,50 @@ var spine;
var verticesLength = 0;
var indicesLength = 0;
var blendMode = null;
var vertices = null;
var clipper = this.clipper;
var vertices = this.vertices;
var triangles = null;
var uvs = null;
var drawOrder = this.skeleton.drawOrder;
var batcher = this.batcher;
batcher.begin();
var z = 0;
var zOffset = this.zOffset;
for (var i = 0, n = drawOrder.length; i < n; i++) {
var vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
var slot = drawOrder[i];
var attachment = slot.getAttachment();
var attachmentColor = null;
var texture = null;
var numFloats = 0;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = this.computeRegionVertices(slot, region, false);
attachmentColor = region.color;
vertices = this.vertices;
numFloats = vertexSize * 4;
region.computeWorldVertices(slot.bone, vertices, 0, vertexSize);
triangles = SkeletonMesh.QUAD_TRIANGLES;
uvs = region.uvs;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = this.computeMeshVertices(slot, mesh, false);
attachmentColor = mesh.color;
vertices = this.vertices;
numFloats = (mesh.worldVerticesLength >> 1) * vertexSize;
if (numFloats > vertices.length) {
vertices = this.vertices = spine.Utils.newFloatArray(numFloats);
}
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, vertexSize);
triangles = mesh.triangles;
uvs = mesh.uvs;
texture = mesh.region.renderObject.texture;
}
else if (attachment instanceof spine.ClippingAttachment) {
var clip = (attachment);
clipper.clipStart(slot, clip);
continue;
}
else
continue;
if (texture != null) {
@ -6360,77 +6382,35 @@ var spine;
mat.map = texture.texture;
mat.needsUpdate = true;
}
this.batcher.batch(vertices, triangles, z);
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);
if (clipper.isClipping()) {
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
var clippedVertices = clipper.clippedVertices;
var clippedTriangles = clipper.clippedTriangles;
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
}
else {
var verts = vertices;
for (var v = 2, u = 0, n_2 = numFloats; v < n_2; v += vertexSize, u += 2) {
verts[v] = color.r;
verts[v + 1] = color.g;
verts[v + 2] = color.b;
verts[v + 3] = color.a;
verts[v + 4] = uvs[u];
verts[v + 5] = uvs[u + 1];
}
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
}
z += zOffset;
}
}
batcher.end();
};
SkeletonMesh.prototype.computeRegionVertices = function (slot, region, pma) {
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
var regionColor = region.color;
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonMesh.VERTEX_SIZE);
var vertices = this.vertices;
var uvs = region.uvs;
vertices[spine.RegionAttachment.C1R] = color.r;
vertices[spine.RegionAttachment.C1G] = color.g;
vertices[spine.RegionAttachment.C1B] = color.b;
vertices[spine.RegionAttachment.C1A] = color.a;
vertices[spine.RegionAttachment.U1] = uvs[0];
vertices[spine.RegionAttachment.V1] = uvs[1];
vertices[spine.RegionAttachment.C2R] = color.r;
vertices[spine.RegionAttachment.C2G] = color.g;
vertices[spine.RegionAttachment.C2B] = color.b;
vertices[spine.RegionAttachment.C2A] = color.a;
vertices[spine.RegionAttachment.U2] = uvs[2];
vertices[spine.RegionAttachment.V2] = uvs[3];
vertices[spine.RegionAttachment.C3R] = color.r;
vertices[spine.RegionAttachment.C3G] = color.g;
vertices[spine.RegionAttachment.C3B] = color.b;
vertices[spine.RegionAttachment.C3A] = color.a;
vertices[spine.RegionAttachment.U3] = uvs[4];
vertices[spine.RegionAttachment.V3] = uvs[5];
vertices[spine.RegionAttachment.C4R] = color.r;
vertices[spine.RegionAttachment.C4G] = color.g;
vertices[spine.RegionAttachment.C4B] = color.b;
vertices[spine.RegionAttachment.C4A] = color.a;
vertices[spine.RegionAttachment.U4] = uvs[6];
vertices[spine.RegionAttachment.V4] = uvs[7];
return vertices;
};
SkeletonMesh.prototype.computeMeshVertices = function (slot, mesh, pma) {
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
var regionColor = mesh.color;
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
var numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
}
var vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonMesh.VERTEX_SIZE);
var uvs = mesh.uvs;
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
return vertices;
};
SkeletonMesh.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
SkeletonMesh.VERTEX_SIZE = 2 + 2 + 4;
return SkeletonMesh;

File diff suppressed because one or more lines are too long

View File

@ -1,279 +1,251 @@
raptor.png
size: 1024,1024
size: 2048,2048
format: RGBA8888
filter: Linear,Linear
repeat: none
back_arm
rotate: true
xy: 140, 191
size: 46, 29
orig: 46, 29
rotate: false
xy: 1888, 1638
size: 91, 57
orig: 91, 57
offset: 0, 0
index: -1
back_bracer
rotate: true
xy: 167, 317
size: 39, 28
orig: 39, 28
rotate: false
xy: 1888, 1581
size: 77, 55
orig: 77, 55
offset: 0, 0
index: -1
back_hand
rotate: false
xy: 167, 358
size: 36, 34
orig: 36, 34
xy: 1954, 1764
size: 72, 68
orig: 72, 68
offset: 0, 0
index: -1
back_knee
rotate: false
xy: 299, 478
size: 49, 67
orig: 49, 67
xy: 275, 438
size: 97, 134
orig: 97, 134
offset: 0, 0
index: -1
back_thigh
rotate: true
xy: 167, 437
size: 39, 24
orig: 39, 24
offset: 0, 0
index: -1
eyes_closed
rotate: true
xy: 2, 2
size: 47, 45
orig: 47, 45
rotate: false
xy: 1778, 1518
size: 78, 47
orig: 78, 47
offset: 0, 0
index: -1
eyes_open
rotate: true
xy: 49, 2
size: 47, 45
orig: 47, 45
offset: 0, 0
index: -1
eyes_surprised
rotate: true
xy: 96, 2
size: 47, 45
orig: 47, 45
rotate: false
xy: 275, 347
size: 93, 89
orig: 93, 89
offset: 0, 0
index: -1
front_arm
rotate: false
xy: 419, 544
size: 48, 30
orig: 48, 30
xy: 830, 1089
size: 96, 60
orig: 96, 60
offset: 0, 0
index: -1
front_bracer
rotate: false
xy: 880, 695
size: 41, 29
orig: 41, 29
xy: 1888, 1697
size: 81, 58
orig: 81, 58
offset: 0, 0
index: -1
front_hand
rotate: true
xy: 167, 394
size: 41, 38
orig: 41, 38
rotate: false
xy: 1870, 1757
size: 82, 75
orig: 82, 75
offset: 0, 0
index: -1
front_open_hand
rotate: false
xy: 880, 726
size: 43, 44
orig: 43, 44
xy: 192, 15
size: 86, 87
orig: 86, 87
offset: 0, 0
index: -1
front_thigh
rotate: false
xy: 360, 545
size: 57, 29
orig: 57, 29
xy: 714, 1091
size: 114, 58
orig: 114, 58
offset: 0, 0
index: -1
gun
rotate: false
xy: 785, 774
size: 107, 103
orig: 107, 103
xy: 1563, 1543
size: 213, 206
orig: 213, 206
offset: 0, 0
index: -1
gun_nohand
rotate: false
xy: 614, 703
size: 105, 102
orig: 105, 102
xy: 1223, 1403
size: 210, 203
orig: 210, 203
offset: 0, 0
index: -1
head
rotate: false
xy: 2, 137
size: 136, 149
orig: 136, 149
xy: 2, 274
size: 271, 298
orig: 271, 298
offset: 0, 0
index: -1
lower_leg
rotate: true
xy: 780, 699
size: 73, 98
orig: 73, 98
offset: 0, 0
index: -1
mouth_grind
rotate: false
xy: 469, 544
size: 47, 30
orig: 47, 30
offset: 0, 0
index: -1
mouth_oooo
rotate: true
xy: 894, 772
size: 105, 30
orig: 105, 30
xy: 551, 893
size: 146, 195
orig: 146, 195
offset: 0, 0
index: -1
mouth_smile
rotate: true
xy: 140, 239
size: 47, 30
orig: 47, 30
rotate: false
xy: 928, 1090
size: 93, 59
orig: 93, 59
offset: 0, 0
index: -1
neck
rotate: true
xy: 538, 577
size: 18, 21
orig: 18, 21
rotate: false
xy: 330, 908
size: 36, 41
orig: 36, 41
offset: 0, 0
index: -1
raptor_arm_back
rotate: false
xy: 940, 936
size: 82, 86
orig: 82, 86
xy: 386, 916
size: 163, 172
orig: 163, 172
offset: 0, 0
index: -1
raptor_body
rotate: false
xy: 2, 737
size: 610, 285
orig: 610, 285
xy: 2, 1467
size: 1219, 570
orig: 1219, 570
offset: 0, 0
index: -1
raptor_front_arm
rotate: true
xy: 195, 464
size: 81, 102
orig: 81, 102
rotate: false
xy: 1870, 1834
size: 162, 203
orig: 162, 203
offset: 0, 0
index: -1
raptor_front_leg
rotate: false
xy: 2, 478
size: 191, 257
orig: 191, 257
xy: 2, 951
size: 382, 514
orig: 382, 514
offset: 0, 0
index: -1
raptor_hindleg_back
rotate: false
xy: 614, 807
size: 169, 215
orig: 169, 215
xy: 1223, 1608
size: 338, 429
orig: 338, 429
offset: 0, 0
index: -1
raptor_horn
rotate: false
xy: 360, 655
size: 182, 80
orig: 182, 80
xy: 714, 1306
size: 363, 159
orig: 363, 159
offset: 0, 0
index: -1
raptor_horn_back
rotate: false
xy: 360, 576
size: 176, 77
orig: 176, 77
xy: 714, 1151
size: 351, 153
orig: 351, 153
offset: 0, 0
index: -1
raptor_jaw
rotate: false
xy: 785, 879
size: 153, 143
orig: 153, 143
xy: 1563, 1751
size: 305, 286
orig: 305, 286
offset: 0, 0
index: -1
raptor_saddle_noshadow
rotate: false
xy: 2, 288
size: 163, 188
orig: 163, 188
xy: 2, 574
size: 326, 375
orig: 326, 375
offset: 0, 0
index: -1
raptor_saddle_strap_front
rotate: false
xy: 721, 710
size: 57, 95
orig: 57, 95
xy: 1435, 1417
size: 114, 189
orig: 114, 189
offset: 0, 0
index: -1
raptor_saddle_strap_rear
rotate: true
xy: 940, 880
size: 54, 74
orig: 54, 74
rotate: false
xy: 1079, 1317
size: 108, 148
orig: 108, 148
offset: 0, 0
index: -1
raptor_saddle_w_shadow
rotate: false
xy: 195, 547
size: 163, 188
orig: 163, 188
xy: 386, 1090
size: 326, 375
orig: 326, 375
offset: 0, 0
index: -1
raptor_tongue
rotate: true
xy: 544, 649
size: 86, 64
orig: 86, 64
rotate: false
xy: 1551, 1413
size: 171, 128
orig: 171, 128
offset: 0, 0
index: -1
stirrup_back
rotate: true
xy: 140, 145
size: 44, 35
orig: 44, 35
rotate: false
xy: 275, 276
size: 87, 69
orig: 87, 69
offset: 0, 0
index: -1
stirrup_front
rotate: false
xy: 538, 597
size: 45, 50
orig: 45, 50
xy: 2, 2
size: 89, 100
orig: 89, 100
offset: 0, 0
index: -1
stirrup_strap
rotate: false
xy: 350, 497
size: 49, 46
orig: 49, 46
xy: 93, 11
size: 97, 91
orig: 97, 91
offset: 0, 0
index: -1
torso
rotate: true
xy: 610, 647
size: 54, 91
orig: 54, 91
rotate: false
xy: 1778, 1567
size: 108, 182
orig: 108, 182
offset: 0, 0
index: -1
visor
rotate: false
xy: 2, 51
size: 131, 84
orig: 131, 84
xy: 2, 104
size: 261, 168
orig: 261, 168
offset: 0, 0
index: -1

View File

@ -1,5 +1,5 @@
{
"skeleton": { "hash": "WOArBZLexLEX/Tow3AuM8ddszEE", "spine": "3.6.14-beta", "width": 1223.73, "height": 1055.62, "images": "./images/" },
"skeleton": { "hash": "T+jP778edtEIrEMb7QvVNAgiHUo", "spine": "3.6.14-beta", "width": 1223.73, "height": 1056.91, "images": "./images/" },
"bones": [
{ "name": "root" },
{ "name": "hip", "parent": "root", "rotation": 3.16, "x": -136.79, "y": 415.48, "color": "fbff00ff" },
@ -199,6 +199,7 @@
{ "name": "tongue3", "parent": "tongue2", "length": 43.65, "rotation": 12.86, "x": 44.27, "y": -0.21, "color": "fff200ff" }
],
"slots": [
{ "name": "clip", "bone": "root", "attachment": "clip" },
{ "name": "back_hand", "bone": "back_hand", "attachment": "back_hand" },
{ "name": "back_arm", "bone": "back_arm", "attachment": "back_arm" },
{ "name": "back_bracer", "bone": "back_bracer", "attachment": "back_bracer" },
@ -310,6 +311,15 @@
"back_thigh": {
"back_thigh": { "x": 37.85, "y": -4.37, "rotation": 19.25, "width": 78, "height": 47 }
},
"clip": {
"clip": {
"type": "clipping",
"end": "clip",
"vertexCount": 25,
"vertices": [ -31.42, 352.85, -182.02, 382.27, -214.91, 562.3, -8.92, 647.12, 183.22, 555.37, 254.19, 375.35, 261.12, 153.78, 3.2, 13.57, -270.3, -36.63, -408.78, 48.19, -349.93, 280.14, -228.76, 133.01, -59.12, 94.93, 107.06, 160.71, 202.26, 349.38, 122.64, 487.86, -41.81, 557.1, -142.21, 489.6, -57.39, 422.09, 49.94, 432.47, 133.02, 370.16, 94.94, 271.49, 43.01, 186.67, -138.74, 174.55, -230.49, 273.22 ],
"color": "ce3a3aff"
}
},
"eyes_open": {
"eyes_open": { "x": 93.24, "y": -25.45, "rotation": -70.58, "width": 93, "height": 89 }
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -63,12 +63,12 @@ module spine.threejs {
this.indicesLength = 0;
}
batch (vertices: ArrayLike<number>, indices: ArrayLike<number>, z: number = 0) {
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;
let i = this.verticesLength;
let j = 0;
for (;j < vertices.length;) {
for (;j < verticesLength;) {
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = vertices[j++];
vertexBuffer[i++] = z;
@ -82,9 +82,9 @@ module spine.threejs {
this.verticesLength = i;
let indicesArray = this.indices;
for (i = this.indicesLength, j = 0; j < indices.length; i++, j++)
for (i = this.indicesLength, j = 0; j < indicesLength; i++, j++)
indicesArray[i] = indices[j] + indexStart;
this.indicesLength += indices.length;
this.indicesLength += indicesLength;
}
end () {

View File

@ -36,6 +36,7 @@ module spine.threejs {
zOffset: number = 0.1;
private batcher: MeshBatcher;
private clipper: SkeletonClipping = new SkeletonClipping();
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
static VERTEX_SIZE = 2 + 2 + 4;
@ -75,29 +76,48 @@ module spine.threejs {
var indicesLength = 0;
let blendMode: BlendMode = null;
let clipper = this.clipper;
let vertices: ArrayLike<number> = null;
let vertices: ArrayLike<number> = this.vertices;
let triangles: Array<number> = null;
let uvs: ArrayLike<number> = null;
let drawOrder = this.skeleton.drawOrder;
let batcher = this.batcher;
batcher.begin();
let z = 0;
let zOffset = this.zOffset;
for (let i = 0, n = drawOrder.length; i < n; i++) {
let vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
let slot = drawOrder[i];
let attachment = slot.getAttachment();
let attachmentColor: Color = null;
let texture: ThreeJsTexture = null;
let numFloats = 0;
if (attachment instanceof RegionAttachment) {
let region = <RegionAttachment>attachment;
vertices = this.computeRegionVertices(slot, region, false);
attachmentColor = region.color;
vertices = this.vertices;
numFloats = vertexSize * 4;
region.computeWorldVertices(slot.bone, vertices, 0, vertexSize);
triangles = SkeletonMesh.QUAD_TRIANGLES;
uvs = region.uvs;
texture = <ThreeJsTexture>(<TextureAtlasRegion>region.region.renderObject).texture;
} else if (attachment instanceof MeshAttachment) {
let mesh = <MeshAttachment>attachment;
vertices = this.computeMeshVertices(slot, mesh, false);
attachmentColor = mesh.color;
vertices = this.vertices;
numFloats = (mesh.worldVerticesLength >> 1) * vertexSize;
if (numFloats > vertices.length) {
vertices = this.vertices = spine.Utils.newFloatArray(numFloats);
}
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, vertexSize);
triangles = mesh.triangles;
uvs = mesh.uvs;
texture = <ThreeJsTexture>(<TextureAtlasRegion>mesh.region.renderObject).texture;
} else if (attachment instanceof ClippingAttachment) {
let clip = <ClippingAttachment>(attachment);
clipper.clipStart(slot, clip);
continue;
} else continue;
if (texture != null) {
@ -106,6 +126,16 @@ module spine.threejs {
mat.map = texture.texture;
mat.needsUpdate = true;
}
let skeleton = slot.bone.skeleton;
let skeletonColor = skeleton.color;
let slotColor = slot.color;
let alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
let color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * attachmentColor.r,
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) {
@ -113,95 +143,28 @@ module spine.threejs {
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
//}
this.batcher.batch(vertices, triangles, z);
if (clipper.isClipping()) {
clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
let clippedVertices = clipper.clippedVertices;
let clippedTriangles = clipper.clippedTriangles;
batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
} else {
let verts = vertices;
for (let v = 2, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {
verts[v] = color.r;
verts[v + 1] = color.g;
verts[v + 2] = color.b;
verts[v + 3] = color.a;
verts[v + 4] = uvs[u];
verts[v + 5] = uvs[u + 1];
}
batcher.batch(vertices, numFloats, triangles, triangles.length, z);
}
z += zOffset;
}
}
batcher.end();
}
private computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean) {
let skeleton = slot.bone.skeleton;
let skeletonColor = skeleton.color;
let slotColor = slot.color;
let regionColor = region.color;
let alpha = skeletonColor.a * slotColor.a * regionColor.a;
let multiplier = pma ? alpha : 1;
let color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonMesh.VERTEX_SIZE);
let vertices = this.vertices;
let uvs = region.uvs;
vertices[RegionAttachment.C1R] = color.r;
vertices[RegionAttachment.C1G] = color.g;
vertices[RegionAttachment.C1B] = color.b;
vertices[RegionAttachment.C1A] = color.a;
vertices[RegionAttachment.U1] = uvs[0];
vertices[RegionAttachment.V1] = uvs[1];
vertices[RegionAttachment.C2R] = color.r;
vertices[RegionAttachment.C2G] = color.g;
vertices[RegionAttachment.C2B] = color.b;
vertices[RegionAttachment.C2A] = color.a;
vertices[RegionAttachment.U2] = uvs[2];
vertices[RegionAttachment.V2] = uvs[3];
vertices[RegionAttachment.C3R] = color.r;
vertices[RegionAttachment.C3G] = color.g;
vertices[RegionAttachment.C3B] = color.b;
vertices[RegionAttachment.C3A] = color.a;
vertices[RegionAttachment.U3] = uvs[4];
vertices[RegionAttachment.V3] = uvs[5];
vertices[RegionAttachment.C4R] = color.r;
vertices[RegionAttachment.C4G] = color.g;
vertices[RegionAttachment.C4B] = color.b;
vertices[RegionAttachment.C4A] = color.a;
vertices[RegionAttachment.U4] = uvs[6];
vertices[RegionAttachment.V4] = uvs[7];
return vertices;
}
private computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean) {
let skeleton = slot.bone.skeleton;
let skeletonColor = skeleton.color;
let slotColor = slot.color;
let regionColor = mesh.color;
let alpha = skeletonColor.a * slotColor.a * regionColor.a;
let multiplier = pma ? alpha : 1;
let color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
alpha);
let numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = Utils.newFloatArray(mesh.worldVerticesLength);
}
let vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonMesh.VERTEX_SIZE);
let uvs = mesh.uvs;
for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
return vertices;
}
}
}

View File

@ -12,8 +12,8 @@
</body>
<script>
var FILE = "coin";
var ANIMATION = "rotate";
var FILE = "raptor";
var ANIMATION = "walk";
var NUM_SKELETONS = 1;
var SCALE = 0.5;
@ -69,7 +69,7 @@ function load() {
stateData.defaultMix = mixDuration;
state.multipleMixing = false;
state.setAnimation(0, "walk", true);
state.setAnimation(0, ANIMATION, true);
skeleton.x = 0;
skeleton.y = 0;
skeleton.updateWorldTransform();