diff --git a/spine-ts/spine-core/src/Skeleton.ts b/spine-ts/spine-core/src/Skeleton.ts index 5182ef29d..1c730cd7f 100644 --- a/spine-ts/spine-core/src/Skeleton.ts +++ b/spine-ts/spine-core/src/Skeleton.ts @@ -652,8 +652,7 @@ export class Skeleton { continue; } if (vertices && triangles) { - if (clipper != null && clipper.isClipping()) { - clipper.clipTriangles(vertices, triangles, triangles.length); + if (clipper != null && clipper.isClipping() && clipper.clipTriangles(vertices, triangles, triangles.length)) { vertices = clipper.clippedVertices; verticesLength = clipper.clippedVertices.length; } diff --git a/spine-ts/spine-core/src/SkeletonClipping.ts b/spine-ts/spine-core/src/SkeletonClipping.ts index e31dbd929..aabb6c95c 100644 --- a/spine-ts/spine-core/src/SkeletonClipping.ts +++ b/spine-ts/spine-core/src/SkeletonClipping.ts @@ -81,59 +81,18 @@ export class SkeletonClipping { return this.clipAttachment != null; } - /** - * @deprecated Use clipTriangles without verticesLength parameter. Mark for removal in 4.3. - */ - clipTriangles (vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number): void; + clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): boolean; + clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, + uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean, stride: number): boolean; + clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, + uvs?: NumberArrayLike, light?: Color, dark?: Color, twoColor?: boolean, stride?: number): boolean { - /** - * @deprecated Use clipTriangles without verticesLength parameter. Mark for removal in 4.3. - */ - clipTriangles (vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void; - - clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): void; - clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void; - clipTriangles ( - vertices: NumberArrayLike, - verticesLengthOrTriangles: number | NumberArrayLike, - trianglesOrTrianglesLength: NumberArrayLike | number, - trianglesLengthOrUvs?: number | NumberArrayLike, - uvsOrLight?: NumberArrayLike | Color, - lightOrDark?: Color, - darkOrTwoColor?: Color | boolean, - twoColorParam?: boolean - ): void { - // Determine which overload is being used - let triangles: NumberArrayLike; - let trianglesLength: number; - let uvs: NumberArrayLike | undefined; - let light: Color | undefined; - let dark: Color | undefined; - let twoColor: boolean | undefined; - - if (typeof verticesLengthOrTriangles === 'number') { - triangles = trianglesOrTrianglesLength as NumberArrayLike; - trianglesLength = trianglesLengthOrUvs as number; - uvs = uvsOrLight as NumberArrayLike; - light = lightOrDark as Color | undefined; - dark = darkOrTwoColor as Color | undefined; - twoColor = twoColorParam; - } else { - triangles = verticesLengthOrTriangles; - trianglesLength = trianglesOrTrianglesLength as number; - uvs = trianglesLengthOrUvs as NumberArrayLike; - light = uvsOrLight as Color | undefined; - dark = lightOrDark as Color | undefined; - twoColor = darkOrTwoColor as boolean; - } - - if (uvs && light && dark && typeof twoColor === 'boolean') - this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor); - else - this.clipTrianglesNoRender(vertices, triangles, trianglesLength); + return (uvs && light && dark && typeof twoColor === 'boolean' && typeof stride === 'number') + ? this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor, stride) + : this.clipTrianglesNoRender(vertices, triangles, trianglesLength); } - private clipTrianglesNoRender (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number) { + private clipTrianglesNoRender (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): boolean { let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; let clippedTriangles = this.clippedTriangles; @@ -143,24 +102,25 @@ export class SkeletonClipping { let index = 0; clippedVertices.length = 0; clippedTriangles.length = 0; + let clipOutputItems = null; for (let i = 0; i < trianglesLength; i += 3) { - let vertexOffset = triangles[i] << 1; - let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let v = triangles[i] << 1; + let x1 = vertices[v], y1 = vertices[v + 1]; - vertexOffset = triangles[i + 1] << 1; - let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + v = triangles[i + 1] << 1; + let x2 = vertices[v], y2 = vertices[v + 1]; - vertexOffset = triangles[i + 2] << 1; - let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + v = triangles[i + 2] << 1; + let x3 = vertices[v], y3 = vertices[v + 1]; for (let p = 0; p < polygonsCount; p++) { let s = clippedVertices.length; if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + clipOutputItems = this.clipOutput; let clipOutputLength = clipOutput.length; if (clipOutputLength == 0) continue; let clipOutputCount = clipOutputLength >> 1; - let clipOutputItems = this.clipOutput; let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * 2); for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; @@ -199,45 +159,46 @@ export class SkeletonClipping { } } } + return clipOutputItems != null; } private clipTrianglesRender (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, - light: Color, dark: Color, twoColor: boolean) { + light: Color, dark: Color, twoColor: boolean, stride: number): boolean { let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; let clippedTriangles = this.clippedTriangles; let polygons = this.clippingPolygons!; let polygonsCount = polygons.length; - let vertexSize = twoColor ? 12 : 8; let index = 0; clippedVertices.length = 0; clippedTriangles.length = 0; + let clipOutputItems = null; for (let i = 0; i < trianglesLength; i += 3) { - let vertexOffset = triangles[i] << 1; - let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; - let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + let t = triangles[i]; + let u1 = uvs[t << 1], v1 = uvs[(t << 1) + 1]; + let x1 = vertices[t * stride], y1 = vertices[t * stride + 1]; - vertexOffset = triangles[i + 1] << 1; - let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; - let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + t = triangles[i + 1]; + let u2 = uvs[t << 1], v2 = uvs[(t << 1) + 1]; + let x2 = vertices[t * stride], y2 = vertices[t * stride + 1]; - vertexOffset = triangles[i + 2] << 1; - let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; - let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + t = triangles[i + 2]; + let u3 = uvs[t << 1], v3 = uvs[(t << 1) + 1]; + let x3 = vertices[t * stride], y3 = vertices[t * stride + 1]; for (let p = 0; p < polygonsCount; p++) { let s = clippedVertices.length; if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + clipOutputItems = this.clipOutput; let clipOutputLength = clipOutput.length; if (clipOutputLength == 0) continue; let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; let d = 1 / (d0 * d2 + d1 * (y1 - y3)); let clipOutputCount = clipOutputLength >> 1; - let clipOutputItems = this.clipOutput; - let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); - for (let ii = 0; ii < clipOutputLength; ii += 2, s += vertexSize) { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * stride); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += stride) { let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; clippedVerticesItems[s] = x; clippedVerticesItems[s + 1] = y; @@ -270,7 +231,7 @@ export class SkeletonClipping { index += clipOutputCount + 1; } else { - let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * stride); clippedVerticesItems[s] = x1; clippedVerticesItems[s + 1] = y1; clippedVerticesItems[s + 2] = light.r; @@ -343,6 +304,7 @@ export class SkeletonClipping { } } } + return clipOutputItems != null; } public clipTrianglesUnpacked (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike) { @@ -356,17 +318,17 @@ export class SkeletonClipping { clippedUVs.length = 0; clippedTriangles.length = 0; for (let i = 0; i < trianglesLength; i += 3) { - let vertexOffset = triangles[i] << 1; - let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; - let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + let v = triangles[i] << 1; + let x1 = vertices[v], y1 = vertices[v + 1]; + let u1 = uvs[v], v1 = uvs[v + 1]; - vertexOffset = triangles[i + 1] << 1; - let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; - let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + v = triangles[i + 1] << 1; + let x2 = vertices[v], y2 = vertices[v + 1]; + let u2 = uvs[v], v2 = uvs[v + 1]; - vertexOffset = triangles[i + 2] << 1; - let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; - let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + v = triangles[i + 2] << 1; + let x3 = vertices[v], y3 = vertices[v + 1]; + let u3 = uvs[v], v3 = uvs[v + 1]; for (let p = 0; p < polygonsCount; p++) { let s = clippedVertices.length; @@ -433,7 +395,7 @@ export class SkeletonClipping { /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ - clip (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array, output: Array) { + private clip (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array, output: Array) { let originalOutput = output; let clipped = false; diff --git a/spine-ts/spine-pixi-v7/src/Spine.ts b/spine-ts/spine-pixi-v7/src/Spine.ts index eb49e192b..25fce8a59 100644 --- a/spine-ts/spine-pixi-v7/src/Spine.ts +++ b/spine-ts/spine-pixi-v7/src/Spine.ts @@ -659,7 +659,7 @@ export class Spine extends Container { } const useDarkColor = slot.darkColor != null; - const vertexSize = Spine.clipper.isClipping() ? 2 : useDarkColor ? Spine.DARK_VERTEX_SIZE : Spine.VERTEX_SIZE; + const vertexSize = useDarkColor ? Spine.DARK_VERTEX_SIZE : Spine.VERTEX_SIZE; if (!slot.bone.active) { Spine.clipper.clipEndWithSlot(slot); this.pixiMaskCleanup(slot); @@ -728,9 +728,7 @@ export class Spine extends Container { let finalIndices: NumberArrayLike; let finalIndicesLength: number; - if (Spine.clipper.isClipping()) { - Spine.clipper.clipTriangles(this.verticesCache, triangles, triangles.length, uvs, this.lightColor, this.darkColor, useDarkColor); - + if (Spine.clipper.isClipping() && Spine.clipper.clipTriangles(this.verticesCache, triangles, triangles.length, uvs, this.lightColor, this.darkColor, useDarkColor, vertexSize)) { finalVertices = Spine.clipper.clippedVertices; finalVerticesLength = finalVertices.length; diff --git a/spine-ts/spine-threejs/src/SkeletonMesh.ts b/spine-ts/spine-threejs/src/SkeletonMesh.ts index 797af709e..c394254a6 100644 --- a/spine-ts/spine-threejs/src/SkeletonMesh.ts +++ b/spine-ts/spine-threejs/src/SkeletonMesh.ts @@ -101,7 +101,7 @@ export class SkeletonMesh extends THREE.Object3D { static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; static VERTEX_SIZE = 2 + 2 + 4; private vertexSize = 2 + 2 + 4; - private twoColorTint; + private twoColorTint: boolean; private vertices = Utils.newFloatArray(1024); private tempColor = new Color(); @@ -231,8 +231,8 @@ export class SkeletonMesh extends THREE.Object3D { batch.begin(); let z = 0; let zOffset = this.zOffset; + let vertexSize = this.vertexSize; for (let i = 0, n = drawOrder.length; i < n; i++) { - let vertexSize = clipper.isClipping() ? 2 : this.vertexSize; let slot = drawOrder[i]; if (!slot.bone.active) { clipper.clipEndWithSlot(slot); @@ -243,36 +243,33 @@ export class SkeletonMesh extends THREE.Object3D { let texture: ThreeJsTexture | null; let numFloats = 0; if (attachment instanceof RegionAttachment) { - let region = attachment; - attachmentColor = region.color; + attachmentColor = attachment.color; vertices = this.vertices; numFloats = vertexSize * 4; - region.computeWorldVertices(slot, vertices, 0, vertexSize); + attachment.computeWorldVertices(slot, vertices, 0, vertexSize); triangles = SkeletonMesh.QUAD_TRIANGLES; - uvs = region.uvs; - texture = region.region!.texture; + uvs = attachment.uvs; + texture = attachment.region!.texture; } else if (attachment instanceof MeshAttachment) { - let mesh = attachment; - attachmentColor = mesh.color; + attachmentColor = attachment.color; vertices = this.vertices; - numFloats = (mesh.worldVerticesLength >> 1) * vertexSize; + numFloats = (attachment.worldVerticesLength >> 1) * vertexSize; if (numFloats > vertices.length) { vertices = this.vertices = Utils.newFloatArray(numFloats); } - mesh.computeWorldVertices( + attachment.computeWorldVertices( slot, 0, - mesh.worldVerticesLength, + attachment.worldVerticesLength, vertices, 0, vertexSize ); - triangles = mesh.triangles; - uvs = mesh.uvs; - texture = mesh.region!.texture; + triangles = attachment.triangles; + uvs = attachment.uvs; + texture = attachment.region!.texture; } else if (attachment instanceof ClippingAttachment) { - let clip = attachment; - clipper.clipStart(slot, clip); + clipper.clipStart(slot, attachment); continue; } else { clipper.clipEndWithSlot(slot); @@ -307,16 +304,7 @@ export class SkeletonMesh extends THREE.Object3D { let finalIndices: NumberArrayLike; let finalIndicesLength: number; - if (clipper.isClipping()) { - clipper.clipTriangles( - vertices, - triangles, - triangles.length, - uvs, - color, - tempLight, - this.twoColorTint, - ); + if (clipper.isClipping() && clipper.clipTriangles( vertices, triangles, triangles.length, uvs, color, tempLight, this.twoColorTint, vertexSize)) { let clippedVertices = clipper.clippedVertices; let clippedTriangles = clipper.clippedTriangles; finalVertices = clippedVertices; diff --git a/spine-ts/spine-webgl/src/SkeletonRenderer.ts b/spine-ts/spine-webgl/src/SkeletonRenderer.ts index ad81b6a3d..36958c54c 100644 --- a/spine-ts/spine-webgl/src/SkeletonRenderer.ts +++ b/spine-ts/spine-webgl/src/SkeletonRenderer.ts @@ -78,7 +78,6 @@ export class SkeletonRenderer { let inRange = false; if (slotRangeStart == -1) inRange = true; for (let i = 0, n = drawOrder.length; i < n; i++) { - let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize; let slot = drawOrder[i]; if (!slot.bone.active) { clipper.clipEndWithSlot(slot); @@ -101,31 +100,29 @@ export class SkeletonRenderer { let attachment = slot.getAttachment(); let texture: GLTexture; if (attachment instanceof RegionAttachment) { - let region = attachment; renderable.vertices = this.vertices; renderable.numVertices = 4; - renderable.numFloats = clippedVertexSize << 2; - region.computeWorldVertices(slot, renderable.vertices, 0, clippedVertexSize); + renderable.numFloats = vertexSize << 2; + attachment.computeWorldVertices(slot, renderable.vertices, 0, vertexSize); triangles = SkeletonRenderer.QUAD_TRIANGLES; - uvs = region.uvs; - texture = region.region!.texture; - attachmentColor = region.color; + uvs = attachment.uvs; + texture = attachment.region!.texture; + attachmentColor = attachment.color; } else if (attachment instanceof MeshAttachment) { - let mesh = attachment; renderable.vertices = this.vertices; - renderable.numVertices = (mesh.worldVerticesLength >> 1); - renderable.numFloats = renderable.numVertices * clippedVertexSize; + renderable.numVertices = (attachment.worldVerticesLength >> 1); + renderable.numFloats = renderable.numVertices * vertexSize; + if (renderable.numFloats > renderable.vertices.length) { renderable.vertices = this.vertices = Utils.newFloatArray(renderable.numFloats); } - mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize); - triangles = mesh.triangles; - texture = mesh.region!.texture; - uvs = mesh.uvs; - attachmentColor = mesh.color; + attachment.computeWorldVertices(slot, 0, attachment.worldVerticesLength, renderable.vertices, 0, vertexSize); + triangles = attachment.triangles; + texture = attachment.region!.texture; + uvs = attachment.uvs; + attachmentColor = attachment.color; } else if (attachment instanceof ClippingAttachment) { - let clip = (attachment); - clipper.clipStart(slot, clip); + clipper.clipStart(slot, attachment); continue; } else { clipper.clipEndWithSlot(slot); @@ -164,8 +161,7 @@ export class SkeletonRenderer { batcher.setBlendMode(blendMode, premultipliedAlpha); } - if (clipper.isClipping()) { - clipper.clipTriangles(renderable.vertices, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint); + if (clipper.isClipping() && clipper.clipTriangles(renderable.vertices, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint, vertexSize)) { let clippedVertices = new Float32Array(clipper.clippedVertices); let clippedTriangles = clipper.clippedTriangles; if (transformer) transformer(clippedVertices, clippedVertices.length, vertexSize);