diff --git a/spine-ts/spine-core/src/SkeletonClipping.ts b/spine-ts/spine-core/src/SkeletonClipping.ts index 91b6dde71..271cc6668 100644 --- a/spine-ts/spine-core/src/SkeletonClipping.ts +++ b/spine-ts/spine-core/src/SkeletonClipping.ts @@ -324,7 +324,7 @@ export class SkeletonClipping { return clipOutputItems != null; } - public clipTrianglesUnpacked (vertices: NumberArrayLike, triangles: NumberArrayLike | Uint32Array, trianglesLength: number, uvs: NumberArrayLike) { + public clipTrianglesUnpacked (vertices: NumberArrayLike, triangles: NumberArrayLike | Uint32Array, trianglesLength: number, uvs: NumberArrayLike, stride = 2) { const clipOutput = this.clipOutput; let clippedVertices = this._clippedVerticesTyped, clippedUVs = this._clippedUVsTyped, clippedTriangles = this._clippedTrianglesTyped; // biome-ignore lint/style/noNonNullAssertion: clipStart define it @@ -343,17 +343,23 @@ export class SkeletonClipping { let clipped = false; for (let i = 0; i < trianglesLength; i += 3) { - let v = triangles[i] << 1; + let t = triangles[i]; + let v = t * stride; const x1 = vertices[v], y1 = vertices[v + 1]; - const u1 = uvs[v], v1 = uvs[v + 1]; + let uv = t << 1; + const u1 = uvs[uv], v1 = uvs[uv + 1]; - v = triangles[i + 1] << 1; + t = triangles[i + 1]; + v = t * stride; const x2 = vertices[v], y2 = vertices[v + 1]; - const u2 = uvs[v], v2 = uvs[v + 1]; + uv = t << 1; + const u2 = uvs[uv], v2 = uvs[uv + 1]; - v = triangles[i + 2] << 1; + t = triangles[i + 2]; + v = t * stride; const x3 = vertices[v], y3 = vertices[v + 1]; - const u3 = uvs[v], v3 = uvs[v + 1]; + uv = t << 1; + const u3 = uvs[uv], v3 = uvs[uv + 1]; for (let p = 0; p < polygonsCount; p++) { let s = this.clippedVerticesLength; @@ -367,20 +373,22 @@ export class SkeletonClipping { let clipOutputCount = clipOutputLength >> 1; const clipOutputItems = this.clipOutput; - const newLength = s + clipOutputCount * 2; + const newLength = s + clipOutputCount * stride; if (clippedVertices.length < newLength) { this._clippedVerticesTyped = new Float32Array(newLength * 2); this._clippedVerticesTyped.set(clippedVertices.subarray(0, s)); - this._clippedUVsTyped = new Float32Array(newLength * 2); - this._clippedUVsTyped.set(clippedUVs.subarray(0, s)); + this._clippedUVsTyped = new Float32Array((this.clippedUVsLength + clipOutputCount * 2) * 2); + this._clippedUVsTyped.set(clippedUVs.subarray(0, this.clippedUVsLength)); clippedVertices = this._clippedVerticesTyped; clippedUVs = this._clippedUVsTyped; } const clippedVerticesItems = clippedVertices; const clippedUVsItems = clippedUVs; this.clippedVerticesLength = newLength; - this.clippedUVsLength = newLength; - for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { + + let uvIndex = this.clippedUVsLength; + this.clippedUVsLength = uvIndex + clipOutputCount * 2; + for (let ii = 0; ii < clipOutputLength; ii += 2, s += stride, uvIndex += 2) { const x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; clippedVerticesItems[s] = x; clippedVerticesItems[s + 1] = y; @@ -388,8 +396,8 @@ export class SkeletonClipping { const a = (d0 * c0 + d1 * c1) * d; const b = (d4 * c0 + d2 * c1) * d; const c = 1 - a - b; - clippedUVsItems[s] = u1 * a + u2 * b + u3 * c; - clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c; + clippedUVsItems[uvIndex] = u1 * a + u2 * b + u3 * c; + clippedUVsItems[uvIndex + 1] = v1 * a + v2 * b + v3 * c; } s = this.clippedTrianglesLength; @@ -411,7 +419,7 @@ export class SkeletonClipping { } else { - let newLength = s + 3 * 2; + let newLength = s + 3 * stride; if (clippedVertices.length < newLength) { this._clippedVerticesTyped = new Float32Array(newLength * 2); this._clippedVerticesTyped.set(clippedVertices.subarray(0, s)); @@ -419,25 +427,27 @@ export class SkeletonClipping { } clippedVertices[s] = x1; clippedVertices[s + 1] = y1; - clippedVertices[s + 2] = x2; - clippedVertices[s + 3] = y2; - clippedVertices[s + 4] = x3; - clippedVertices[s + 5] = y3; + clippedVertices[s + stride] = x2; + clippedVertices[s + stride + 1] = y2; + clippedVertices[s + stride * 2] = x3; + clippedVertices[s + stride * 2 + 1] = y3; - if (clippedUVs.length < newLength) { - this._clippedUVsTyped = new Float32Array(newLength * 2); - this._clippedUVsTyped.set(clippedUVs.subarray(0, s)); + let uvLength = this.clippedUVsLength + 3 * 2; + if (clippedUVs.length < uvLength) { + this._clippedUVsTyped = new Float32Array(uvLength * 2); + this._clippedUVsTyped.set(clippedUVs.subarray(0, this.clippedUVsLength)); clippedUVs = this._clippedUVsTyped; } - clippedUVs[s] = u1; - clippedUVs[s + 1] = v1; - clippedUVs[s + 2] = u2; - clippedUVs[s + 3] = v2; - clippedUVs[s + 4] = u3; - clippedUVs[s + 5] = v3; + let uvIndex = this.clippedUVsLength; + clippedUVs[uvIndex] = u1; + clippedUVs[uvIndex + 1] = v1; + clippedUVs[uvIndex + 2] = u2; + clippedUVs[uvIndex + 3] = v2; + clippedUVs[uvIndex + 4] = u3; + clippedUVs[uvIndex + 5] = v3; this.clippedVerticesLength = newLength; - this.clippedUVsLength = newLength; + this.clippedUVsLength = uvLength; s = this.clippedTrianglesLength; newLength = s + 3; diff --git a/spine-ts/spine-core/src/SkeletonRendererCore.ts b/spine-ts/spine-core/src/SkeletonRendererCore.ts index 79c6d3d91..b4fdc426c 100644 --- a/spine-ts/spine-core/src/SkeletonRendererCore.ts +++ b/spine-ts/spine-core/src/SkeletonRendererCore.ts @@ -40,7 +40,7 @@ export class SkeletonRendererCore { private clipping = new SkeletonClipping(); private renderCommands: RenderCommand[] = []; - render (skeleton: Skeleton, pma = false, inColor?: [number, number, number, number]): RenderCommand | undefined { + render (skeleton: Skeleton, pma = false, inColor?: [number, number, number, number], stride = 2): RenderCommand | undefined { this.commandPool.reset(); this.renderCommands.length = 0; @@ -80,7 +80,7 @@ export class SkeletonRendererCore { continue; } - attachment.computeWorldVertices(slot, this.worldVertices, 0, 2); + attachment.computeWorldVertices(slot, this.worldVertices, 0, stride); vertices = this.worldVertices; verticesCount = 4; uvs = attachment.uvs as Float32Array; @@ -99,7 +99,7 @@ export class SkeletonRendererCore { if (this.worldVertices.length < attachment.worldVerticesLength) this.worldVertices = new Float32Array(attachment.worldVerticesLength); - attachment.computeWorldVertices(skeleton, slot, 0, attachment.worldVerticesLength, this.worldVertices, 0, 2); + attachment.computeWorldVertices(skeleton, slot, 0, attachment.worldVerticesLength, this.worldVertices, 0, stride); vertices = this.worldVertices; verticesCount = attachment.worldVerticesLength >> 1; uvs = attachment.uvs as Float32Array; @@ -163,19 +163,19 @@ export class SkeletonRendererCore { } if (clipper.isClipping()) { - clipper.clipTrianglesUnpacked(vertices, indices, indicesCount, uvs); + clipper.clipTrianglesUnpacked(vertices, indices, indicesCount, uvs, stride); vertices = clipper.clippedVerticesTyped; - verticesCount = clipper.clippedVerticesLength >> 1; + verticesCount = clipper.clippedVerticesLength / stride; uvs = clipper.clippedUVsTyped; indices = clipper.clippedTrianglesTyped; indicesCount = clipper.clippedTrianglesLength; } - const cmd = this.commandPool.getCommand(verticesCount, indicesCount); + const cmd = this.commandPool.getCommand(verticesCount, indicesCount, stride); cmd.blendMode = slot.data.blendMode; cmd.texture = texture; - cmd.positions.set(vertices.subarray(0, verticesCount << 1)); + cmd.positions.set(vertices.subarray(0, verticesCount * stride)); cmd.uvs.set(uvs.subarray(0, verticesCount << 1)); for (let j = 0; j < verticesCount; j++) { @@ -194,14 +194,14 @@ export class SkeletonRendererCore { } clipper.clipEnd(); - return this.batchCommands(); + return this.batchCommands(stride); } private batchSubCommands (commands: RenderCommand[], first: number, last: number, - numVertices: number, numIndices: number): RenderCommand { + numVertices: number, numIndices: number, stride: number): RenderCommand { const firstCmd = commands[first]; - const batched = this.commandPool.getCommand(numVertices, numIndices); + const batched = this.commandPool.getCommand(numVertices, numIndices, stride); batched.blendMode = firstCmd.blendMode; batched.texture = firstCmd.texture; @@ -216,7 +216,7 @@ export class SkeletonRendererCore { const cmd = commands[i]; batched.positions.set(cmd.positions, positionsOffset); - positionsOffset += cmd.numVertices << 1; + positionsOffset += cmd.numVertices * stride; batched.uvs.set(cmd.uvs, uvsOffset); uvsOffset += cmd.numVertices << 1; @@ -236,7 +236,7 @@ export class SkeletonRendererCore { return batched; } - private batchCommands (): RenderCommand | undefined { + private batchCommands (stride: number): RenderCommand | undefined { if (this.renderCommands.length === 0) return undefined; let root: RenderCommand | undefined; @@ -267,7 +267,7 @@ export class SkeletonRendererCore { numIndices += cmd.numIndices; } else { const batched = this.batchSubCommands(this.renderCommands, startIndex, i - 1, - numVertices, numIndices); + numVertices, numIndices, stride); if (!last) { root = last = batched; @@ -315,17 +315,17 @@ class CommandPool { private pool: RenderCommand[] = []; private inUse: RenderCommand[] = []; - getCommand (numVertices: number, numIndices: number): RenderCommand { + getCommand (numVertices: number, numIndices: number, stride: number): RenderCommand { let cmd: RenderCommand | undefined; for (const c of this.pool) { - if (c._positions.length >= numVertices << 1 && c._indices.length >= numIndices) { + if (c._positions.length >= numVertices * stride && c._indices.length >= numIndices) { cmd = c; break; } } if (!cmd) { - const _positions = new Float32Array(numVertices << 1); + const _positions = new Float32Array(numVertices * stride); const _uvs = new Float32Array(numVertices << 1); const _colors = new Uint32Array(numVertices); const _darkColors = new Uint32Array(numVertices); @@ -352,8 +352,8 @@ class CommandPool { cmd.numVertices = numVertices; cmd.numIndices = numIndices; - cmd.positions = cmd._positions.subarray(0, numVertices << 1); - cmd.uvs = cmd._uvs.subarray(0, numVertices * 2); + cmd.positions = cmd._positions.subarray(0, numVertices * stride); + cmd.uvs = cmd._uvs.subarray(0, numVertices << 1); cmd.colors = cmd._colors.subarray(0, numVertices); cmd.darkColors = cmd._darkColors.subarray(0, numVertices); cmd.indices = cmd._indices.subarray(0, numIndices);