From a6b762d25ace3a803035b1a34935d5be1199ab32 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 14:58:27 +0800 Subject: [PATCH 01/18] Optimize spine performance & fix memory leaks. --- cocos/spine/assembler/simple.ts | 61 +- cocos/spine/attach-util.ts | 80 +- cocos/spine/lib/spine-core.d.ts | 28 +- cocos/spine/lib/spine-define.ts | 156 ++- cocos/spine/skeleton-system.ts | 5 + cocos/spine/skeleton.ts | 43 +- .../editor-support/spine-wasm/CMakeLists.txt | 12 +- .../spine-wasm/spine-mesh-data.cpp | 4 +- .../spine-wasm/spine-mesh-data.h | 4 +- .../editor-support/spine-wasm/spine-model.cpp | 70 +- .../editor-support/spine-wasm/spine-model.h | 14 +- .../spine-wasm/spine-skeleton-instance.cpp | 219 ++-- .../spine-wasm/spine-skeleton-instance.h | 6 +- .../spine-wasm/spine-skeleton-system.cpp | 59 ++ .../spine-wasm/spine-skeleton-system.h | 15 + .../spine-wasm/spine-type-export.cpp | 948 ++++++++++++------ .../editor-support/spine-wasm/spine-wasm.cpp | 5 +- native/cocos/editor-support/spine/Skin.h | 2 +- 18 files changed, 1174 insertions(+), 557 deletions(-) create mode 100644 native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp create mode 100644 native/cocos/editor-support/spine-wasm/spine-skeleton-system.h diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index f7e853bc516..81b6036bf83 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -36,6 +36,7 @@ import { director } from '../../game'; import spine from '../lib/spine-core.js'; import { Color, Vec3 } from '../../core'; import { MaterialInstance } from '../../render-scene'; +import { SkeletonSystem } from '../skeleton-system'; const _slotColor = new Color(0, 0, 255, 255); const _boneColor = new Color(255, 0, 0, 255); @@ -58,6 +59,8 @@ const _byteStrideTwoColor = getAttributeStride(vfmtPosUvTwoColor4B); const DEBUG_TYPE_REGION = 0; const DEBUG_TYPE_MESH = 1; +const tempVecPos = new Vec3(0, 0, 0); + function _getSlotMaterial (blendMode: number, comp: Skeleton): MaterialInstance { let src: BlendFactor; let dst: BlendFactor; @@ -84,6 +87,7 @@ function _getSlotMaterial (blendMode: number, comp: Skeleton): MaterialInstance } export const simple: IAssembler = { + fillBuffers (render: UIRenderable, batcher: Batcher2D) { }, @@ -151,60 +155,75 @@ function realTimeTraverse (comp: Skeleton): void { const vc = model.vCount as number; const ic = model.iCount as number; const rd = comp.renderData!; - if (rd.vertexCount !== vc || rd.indexCount !== ic) { rd.resize(vc, ic); rd.indices = new Uint16Array(ic); + comp._vLength = vc * Float32Array.BYTES_PER_ELEMENT * floatStride; + comp._vBuffer = new Uint8Array(rd.chunk.vb.buffer, rd.chunk.vb.byteOffset, Float32Array.BYTES_PER_ELEMENT * rd.chunk.vb.length); + comp._iLength = Uint16Array.BYTES_PER_ELEMENT * ic; + comp._iBuffer = new Uint8Array(rd.indices.buffer); } if (vc < 1 || ic < 1) return; - - const vbuf = rd.chunk.vb; - const vUint8Buf = new Uint8Array(vbuf.buffer, vbuf.byteOffset, Float32Array.BYTES_PER_ELEMENT * vbuf.length); - + let vbuf = rd.chunk.vb; const vPtr = model.vPtr; - const vLength = vc * Float32Array.BYTES_PER_ELEMENT * floatStride; // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const vData = spine.wasmUtil.wasm.HEAPU8.subarray(vPtr, vPtr + vLength); - vUint8Buf.set(vData as TypedArray); - + const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; + comp._vBuffer?.set(HEAPU8.subarray(vPtr, vPtr + comp._vLength), 0); const iPtr = model.iPtr; const ibuf = rd.indices!; - const iLength = Uint16Array.BYTES_PER_ELEMENT * ic; - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const iData = spine.wasmUtil.wasm.HEAPU8.subarray(iPtr, iPtr + iLength); - const iUint8Buf = new Uint8Array(ibuf.buffer); - iUint8Buf.set(iData as TypedArray); + comp._iBuffer?.set(HEAPU8.subarray(iPtr, iPtr + comp._iLength), 0); const chunkOffset = rd.chunk.vertexOffset; - for (let i = 0; i < ic; i++) { - ibuf[i] += chunkOffset; + for (let i = 0; i < ic; i++) ibuf[i] += chunkOffset; + + const data = model.getData(); + const count = data.size(); + let indexOffset = 0; + let indexCount = 0; + for (let i = 0; i < count; i += 6) { + indexCount = data.get(i+3); + const material = _getSlotMaterial(data.get(i+4), comp); + const textureID = data.get(i+5); + comp.requestDrawData(material, textureID, indexOffset, indexCount); + indexOffset += indexCount; } + /* const meshes = model.getMeshes(); const count = meshes.size(); let indexOffset = 0; let indexCount = 0; for (let i = 0; i < count; i++) { const mesh = meshes.get(i); - const material = _getSlotMaterial(mesh.blendMode as number, comp); - const textureID = mesh.textureID as number; + const material = _getSlotMaterial(mesh.blendMode, comp); + const textureID = mesh.textureID; indexCount = mesh.iCount; comp.requestDrawData(material, textureID, indexOffset, indexCount); indexOffset += indexCount; } + */ + /* + let indexOffset = 0; + let indexCount = 0; + for (let i = 0; i < 1; i++) { + const material = _getSlotMaterial(0, comp); + const textureID = 0 + indexCount = 1029; + comp.requestDrawData(material, textureID, indexOffset, indexCount); + indexOffset += indexCount; + } + */ // if enableBatch apply worldMatrix if (comp.enableBatch) { const worldMat = comp.node.worldMatrix; let index = 0; - const tempVecPos = new Vec3(0, 0, 0); for (let i = 0; i < vc; i++) { index = i * floatStride; tempVecPos.x = vbuf[index]; tempVecPos.y = vbuf[index + 1]; - tempVecPos.z = 0; tempVecPos.transformMat4(worldMat); vbuf[index] = tempVecPos.x; vbuf[index + 1] = tempVecPos.y; - vbuf[index + 2] = tempVecPos.z; + vbuf[index + 2] = 0 } } diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index ce14f687145..fc70ebabb96 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -36,74 +36,64 @@ const tempMat4 = new Mat4(); */ export class AttachUtil { protected _inited = false; - protected _skeleton: spine.Skeleton | null = null; - protected _skeletonNode: Node|null = null; - protected _skeletonComp: Skeleton|null = null; + protected skeletonBones: spine.Bone[] | null = []; constructor () { this._inited = false; - this._skeleton = null; - this._skeletonNode = null; - this._skeletonComp = null; } init (skeletonComp: Skeleton): void { this._inited = true; - this._skeleton = skeletonComp._skeleton; - this._skeletonNode = skeletonComp.node; - this._skeletonComp = skeletonComp; + this.skeletonBones = skeletonComp._skeleton.bones; } reset (): void { this._inited = false; - this._skeleton = null; - this._skeletonNode = null; - this._skeletonComp = null; + this.skeletonBones = null; } - _syncAttachedNode (): void { - if (!this._inited) return; - - const socketNodes = this._skeletonComp!.socketNodes; - if (socketNodes.size === 0) return; - - let boneInfos; - const isCached = this._skeletonComp!.isAnimationCached(); - if (isCached && this._skeletonComp!._curFrame) { - boneInfos = this._skeletonComp!._curFrame.boneInfos; - } else { - boneInfos = this._skeleton!.bones; + _syncAttachedNode (skeletonComp: Skeleton): void { + if (!this._inited || skeletonComp!.socketNodes.size === 0) { + return; } - - if (!boneInfos || boneInfos.length < 1) return; - - const matrixHandle = (node: Node, bone: any): void => { - const tm = tempMat4; - tm.m00 = bone.a; - tm.m01 = bone.c; - tm.m04 = bone.b; - tm.m05 = bone.d; - tm.m12 = bone.worldX; - tm.m13 = bone.worldY; - node.matrix = tempMat4; - }; - - for (const boneIdx of socketNodes.keys()) { - const boneNode = socketNodes.get(boneIdx); - // Node has been destroy + const isCached = skeletonComp!.isAnimationCached(); + const boneInfos = isCached && skeletonComp!._curFrame ? skeletonComp!._curFrame.boneInfos : this.skeletonBones; + + if (!boneInfos || boneInfos.length < 1) { + return; + } + const socketNodes = skeletonComp!.socketNodes; + const keysToDelete = []; + + for (const [boneIdx, boneNode] of socketNodes) { if (!boneNode || !boneNode.isValid) { - socketNodes.delete(boneIdx); + keysToDelete.push(boneIdx); continue; } + const bone = boneInfos[boneIdx]; - // Bone has been destroy if (!bone) { boneNode.removeFromParent(); boneNode.destroy(); - socketNodes.delete(boneIdx); + keysToDelete.push(boneIdx); continue; } - matrixHandle(boneNode, bone); + + this.matrixHandle(boneNode, bone); + } + for (const boneIdx of keysToDelete) { + socketNodes.delete(boneIdx); } } + + matrixHandle (node: Node, bone: any): void { + const tm = tempMat4; + tm.m00 = bone.a; + tm.m01 = bone.c; + tm.m04 = bone.b; + tm.m05 = bone.d; + tm.m12 = bone.worldX; + tm.m13 = bone.worldY; + node.matrix = tempMat4; + } } diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index 49265a616e7..0efbaa4bf3f 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -24,6 +24,22 @@ /* eslint @typescript-eslint/no-explicit-any: "off" */ declare namespace spine { + + class String { + length: number; + isEmpty: boolean; + strPtr: number; + str: string; + } + + class SPVectorFloat { + size(): number; + resize(newSize: number, defaultValue: number); + set(index: number, value: number); + get(index: number): number; + delete(); + } + class Animation { constructor(name: string, timelines: Array, duration: number); duration: number; @@ -555,7 +571,6 @@ declare namespace spine { transformConstraints: Array; pathConstraints: Array; _updateCache: Updatable[]; - updateCacheReset: Updatable[]; skin: Skin; color: Color; time: number; @@ -1140,6 +1155,7 @@ declare namespace spine { updateOffset(): void; computeWorldVertices(bone: Bone, worldVertices: ArrayLike, offset: number, stride: number): void; copy(): Attachment; + private _uvs: ArrayLike | undefined; } class JitterEffect implements VertexEffect { jitterX: number; @@ -1163,7 +1179,17 @@ declare namespace spine { end(): void; } + class SkeletonSystem { + public static updateAnimation(deltaTime:number): void; + public static updateRenderData(): void; + public static getCount(): number; + } + class SkeletonInstance { + dtRate: number; + isCache: boolean; + isDelete: boolean; + enable: boolean; initSkeleton(data: SkeletonData); getAnimationState(); setAnimation(trackIndex: number, name: string, loop: boolean): spine.TrackEntry | null; diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index f267bf1c1fe..03b7bb3a545 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -26,6 +26,7 @@ import spine from './spine-core.js'; import { js } from '../../core'; +import { array, value } from 'cocos/core/utils/js.js'; function overrideDefineArrayProp (prototype: any, getPropVector: any, name: string): void { Object.defineProperty(prototype, name, { @@ -64,9 +65,9 @@ function overrideDefineArrayArrayProp (prototype: any, getPropVector: any, name: }); } -function overrideDefineArrayPropGetSet (prototype: any, getPropVector: any, setPropVector: any, Type: any, name: string): void { +function overrideDefineArrayFunction (prototype: any, getPropVector: any, name: string): void { Object.defineProperty(prototype, name, { - get (): any[] { + value () { const array: any[] = []; const vectors = getPropVector.call(this); const count = vectors.size(); @@ -77,31 +78,25 @@ function overrideDefineArrayPropGetSet (prototype: any, getPropVector: any, setP // eslint-disable-next-line @typescript-eslint/no-unsafe-return return array; }, - set (value: any[]) { - const vectors = new Type(); - const count = value.length; - // vector.resize(count, 0) default 0, because currently only the number type will use this function. - vectors.resize(count, 0); - for (let i = 0; i < count; i++) { - vectors.set(i, value[i]); - } - setPropVector.call(this, vectors); - }, }); } -function overrideDefineArrayFunction (prototype: any, getPropVector: any, name: string): void { +function overrideDefinePtrStringFunction (prototype: any, getPtr: any, name: string): void { Object.defineProperty(prototype, name, { - value () { - const array: any[] = []; - const vectors = getPropVector.call(this); - const count = vectors.size(); - for (let i = 0; i < count; i++) { - const objPtr = vectors.get(i); - array.push(objPtr); + value (): string { + let str = ''; + const ptr = getPtr.call(this); + const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; + /* + let length = this.length + ptr; + for (let i = ptr; i < length; ++i) { + str += String.fromCharCode(HEAPU8[i]); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return array; + */ + let length = this.length; + const buffer = HEAPU8.subarray(ptr, ptr + length); + str = String.fromCharCode(...buffer); + return str; }, }); } @@ -111,8 +106,12 @@ function overrideClass (wasm): void { spine.wasmUtil.wasm = wasm; spine.wasmUtil.spineWasmInit(); + spine.SPVectorFloat = wasm.SPVectorFloat; + spine.MathUtils = wasm.MathUtils; spine.Color = wasm.Color; + spine.String = wasm.String; + spine.Vector2 = wasm.Vector2; spine.Interpolation = wasm.Interpolation; spine.Triangulator = wasm.Triangulator; spine.ConstraintData = wasm.ConstraintData; @@ -176,6 +175,53 @@ function overrideClass (wasm): void { spine.SwirlEffect = wasm.SwirlEffect; spine.SkeletonInstance = wasm.SkeletonInstance; + spine.SkeletonSystem = wasm.SkeletonSystem; +} + +function overrideProperty_String (): void { + const prototype = spine.String.prototype as any; + const propertyPolyfills = [ + { + proto: prototype, + property: 'length', + getter: prototype.length, + }, + { + proto: prototype, + property: 'isEmpty', + getter: prototype.isEmpty, + }, + { + proto: prototype, + property: 'str', + getter: prototype.str + } + ]; + propertyPolyfills.forEach((prop): void => { + js.get(prop.proto, prop.property, prop.getter); + }); + overrideDefinePtrStringFunction(prototype, prototype.strPtr, 'strPtr'); +} + +function overrideProperty_Vector2 (): void { + const prototype = spine.Vector2.prototype as any; + const propertyPolyfills = [ + { + proto: prototype, + property: 'x', + getter: prototype.getX, + setter: prototype.setX, + }, + { + proto: prototype, + property: 'y', + getter: prototype.getY, + setter: prototype.setY + }, + ]; + propertyPolyfills.forEach((prop): void => { + js.get(prop.proto, prop.property, prop.getter, prop.setter); + }); } function overrideProperty_BoneData (): void { @@ -543,6 +589,18 @@ function overrideProperty_VertexAttachment (): void { }); overrideDefineArrayProp(prototype, prototype.getBones, 'bones'); overrideDefineArrayProp(prototype, prototype.getVertices, 'vertices'); + const originComputeWorldVertices = prototype.computeWorldVertices; + Object.defineProperty(prototype, 'computeWorldVertices', { + value (slot: spine.Slot, start: number, count: number, worldVertices: number[], offset: number, stride: number) { + const vectors = new spine.SPVectorFloat(); + const length = worldVertices.length; + vectors.resize(length, 0); + for (let i = 0; i < length; i++) vectors.set(i, worldVertices[i]); + originComputeWorldVertices.call(this, slot, start, count, vectors, offset, stride); + for (let i = 0; i < length; i++) worldVertices[i] = vectors.get(i); + vectors.delete(); + }, + }); } function overrideProperty_BoundingBoxAttachment (): void { @@ -732,7 +790,33 @@ function overrideProperty_RegionAttachment (): void { }); overrideDefineArrayProp(prototype, prototype.getOffset, 'offset'); - overrideDefineArrayPropGetSet(prototype, prototype.getUVs, prototype.setUVs, spine.wasmUtil.wasm.VectorFloat, 'uvs'); + const getUVs = prototype.getUVs; + const setUVs = prototype.setUVs; + Object.defineProperty(prototype, 'uvs', { + get (): any { + if(this._uvs == undefined) this._uvs = new Array(8); + const vectors = getUVs.call(this); + const count = vectors.size(); + for (let i = 0; i < count; i++) this._uvs[i] = vectors.get(i); + return this._uvs; + }, + set (value: number[]) { + setUVs.call(this, value[0], value[1], value[2], value[3], value[4] == 1); + } + }); + + const originComputeWorldVertices = prototype.computeWorldVertices; + Object.defineProperty(prototype, 'computeWorldVertices', { + value (bone: spine.Bone, worldVertices: number[], offset: number, stride: number) { + const vectors = new spine.SPVectorFloat(); + const length = worldVertices.length; + vectors.resize(length, 0); + for (let i = 0; i < length; i++) vectors.set(i, worldVertices[i]); + originComputeWorldVertices.call(this, bone, vectors, offset, stride); + for (let i = 0; i < length; i++) worldVertices[i] = vectors.get(i); + vectors.delete(); + }, + }); } function overrideProperty_TextureAtlas (): void { @@ -1182,22 +1266,6 @@ function overrideProperty_Bone (): void { js.getset(prop.proto, prop.property, prop.getter, prop.setter); }); overrideDefineArrayProp(prototype, prototype.getChildren, 'children'); - const worldToLocal = prototype.worldToLocal; - Object.defineProperty(prototype, 'worldToLocal', { - value (vec2: spine.Vector2) { - const vectors = worldToLocal.call(this, vec2.x, vec2.y); - vec2.x = vectors.get(0); - vec2.y = vectors.get(1); - }, - }); - const localToWorld = prototype.localToWorld; - Object.defineProperty(prototype, 'localToWorld', { - value (vec2: spine.Vector2) { - const vectors = localToWorld.call(this, vec2.x, vec2.y); - vec2.x = vectors.get(0); - vec2.y = vectors.get(1); - }, - }); } function overrideProperty_Slot (): void { @@ -1260,6 +1328,7 @@ function overrideProperty_Skin (): void { const objPtr = vectors.get(i); attachments.push(objPtr); } + vectors.delete(); }, }); const originFindNamesForSlot = prototype.findNamesForSlot; @@ -1271,6 +1340,7 @@ function overrideProperty_Skin (): void { const objPtr = vectors.get(i); names.push(objPtr); } + vectors.delete(); }, }); } @@ -1693,11 +1763,6 @@ function overrideProperty_Skeleton (): void { property: 'data', getter: prototype.getData, }, - { - proto: prototype, - property: '_updateCache', - getter: prototype.getUpdateCache, - }, { proto: prototype, property: 'skin', @@ -1748,6 +1813,7 @@ function overrideProperty_Skeleton (): void { overrideDefineArrayProp(prototype, prototype.getIkConstraints, 'ikConstraints'); overrideDefineArrayProp(prototype, prototype.getTransformConstraints, 'transformConstraints'); overrideDefineArrayProp(prototype, prototype.getPathConstraints, 'pathConstraints'); + overrideDefineArrayProp(prototype, prototype.getUpdateCache, '_updateCache'); } function overrideProperty_JitterEffect (): void { @@ -1806,6 +1872,8 @@ function overrideProperty_SwirlEffect (): void { export function overrideSpineDefine (wasm): void { overrideClass(wasm); + overrideProperty_String(); + overrideProperty_Vector2(); overrideProperty_BoneData(); overrideProperty_ConstraintData(); overrideProperty_IkConstraintData(); diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index d629b72c66a..e35555a7a64 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -26,6 +26,7 @@ import { director } from '../game/director'; import { System } from '../core'; import { Skeleton } from './skeleton'; import { legacyCC } from '../core/global-exports'; +import spine from './lib/spine-core.js'; export class SkeletonSystem extends System { /** @@ -72,14 +73,18 @@ export class SkeletonSystem extends System { } } + index = 0; postUpdate (dt: number): void { if (!this._skeletons) { return; } + this.index++; + spine.SkeletonSystem.updateAnimation(dt); this._skeletons.forEach((skeleton) => { skeleton.updateAnimation(dt); skeleton.syncAttachedNode(); }); + //this.index % 500 == 0 && console.log('spine update :', this.index , `count:${spine.SkeletonSystem.getCount()}`); } public prepareRenderData (): void { diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 90c375bb127..a81916438d3 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -301,6 +301,13 @@ export class Skeleton extends UIRenderer { private _slotTextures: Map | null = null; + _vLength = 0; + _vBuffer:Uint8Array | null = null; + _iLength = 0; + _iBuffer:Uint8Array | null = null; + _model:any | undefined; + _tempColor:Color = new Color(1, 1, 1, 1); + constructor () { super(); this._useVertexOpacity = true; @@ -310,6 +317,8 @@ export class Skeleton extends UIRenderer { this._endSlotIndex = -1; if (!JSB) { this._instance = new spine.SkeletonInstance(); + this._instance.dtRate = this._timeScale * timeScale; + this._instance.isCache = this.isAnimationCached(); } this.attachUtil = new AttachUtil(); } @@ -499,6 +508,9 @@ export class Skeleton extends UIRenderer { set timeScale (value) { if (value !== this._timeScale) { this._timeScale = value; + if(this._instance) { + this._instance.dtRate = this._timeScale * timeScale; + } } } /** @@ -659,6 +671,7 @@ export class Skeleton extends UIRenderer { */ public onEnable (): void { super.onEnable(); + this._instance.enable = true; this._flushAssembler(); SkeletonSystem.getInstance().add(this); } @@ -668,15 +681,31 @@ export class Skeleton extends UIRenderer { */ public onDisable (): void { super.onDisable(); + this._instance.enable = false; SkeletonSystem.getInstance().remove(this); + } public onDestroy (): void { + this._drawList.destroy(); this.destroyRenderData(); this._cleanMaterialCache(); + this._vBuffer = null; + this._iBuffer = null; + this.attachUtil.reset(); + this.attachUtil = null; + this._textures = null; + this._slotTextures?.clear(); + this._slotTextures = null; + this._cachedSockets.clear(); + this._cachedSockets = null; + this._socketNodes.clear(); + this._socketNodes = null; + SkeletonSystem.getInstance().remove(this); if (!JSB) { spine.wasmUtil.destroySpineInstance(this._instance); } + this._instance = null; super.onDestroy(); } /** @@ -700,6 +729,7 @@ export class Skeleton extends UIRenderer { this._refreshInspector(); return; } + this._instance.dtRate = this._timeScale * timeScale; this._needUpdateSkeltonData = false; const data = this.skeletonData?.getRuntimeData(); if (!data) return; @@ -986,7 +1016,7 @@ export class Skeleton extends UIRenderer { } this._updateCache(dt); } else { - this._instance.updateAnimation(dt); + //this._instance.updateAnimation(dt); } } @@ -997,7 +1027,7 @@ export class Skeleton extends UIRenderer { } const frames = frameCache.frames; const frameTime = SkeletonCache.FrameTime; - // Animation Start, the event different from dragonbones inner event, + // Animation Start, the event different from _customMaterial inner event, // It has no event object. if (this._accTime === 0 && this._playCount === 0) { this._startEntry.animation.name = this._animationName; @@ -1238,7 +1268,7 @@ export class Skeleton extends UIRenderer { */ public syncAttachedNode (): void { // sync attached node matrix - this.attachUtil._syncAttachedNode(); + this.attachUtil._syncAttachedNode(this); } /** @@ -1264,6 +1294,7 @@ export class Skeleton extends UIRenderer { if (this._preCacheMode !== cacheMode) { this._cacheMode = cacheMode; //this.setSkin(this.defaultSkin); + this._instance.isCache = this.isAnimationCached(); this._updateSkeletonData(); this.setSkin(this.defaultSkin); this._updateUseTint(); @@ -1579,6 +1610,12 @@ export class Skeleton extends UIRenderer { const g = this._color.g / 255.0; const b = this._color.b / 255.0; const a = this.node._uiProps.opacity; + + if (this._tempColor.r == r || + this._tempColor.g == g || + this._tempColor.b == b) + return; + this._tempColor.set(r, g, b, this._tempColor.a); this._instance.setColor(r, g, b, a); } diff --git a/native/cocos/editor-support/spine-wasm/CMakeLists.txt b/native/cocos/editor-support/spine-wasm/CMakeLists.txt index 339864386b3..b76f1dcadc1 100644 --- a/native/cocos/editor-support/spine-wasm/CMakeLists.txt +++ b/native/cocos/editor-support/spine-wasm/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_BUILD_TYPE "Release") +set(CMAKE_BUILD_TYPE "Debug") set(APP_NAME "spine" CACHE STRING "Project Name") project(${APP_NAME}_wasm) @@ -9,15 +9,19 @@ project(${APP_NAME}_wasm) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -frtti -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=1") +message("Current directory: ${CMAKE_CURRENT_SOURCE_DIR}") -include_directories(../ ../../) -file(GLOB SPINE_CORE_SRC "../spine/*.cpp") +#include_directories(../ ../../) +include_directories(../ ../../ ../spine-creator-support/) +file(GLOB SPINE_CORE_SRC "../spine/*.cpp" ../spine-creator-support/Vector2.cpp) file(GLOB COCOS_ADAPTER_SRC "./*.cpp") +#file(GLOB SPINE_CORE_SRC ../spine-creator-support/Vector2.cpp) + add_executable(${APP_NAME} ${SPINE_CORE_SRC} ${COCOS_ADAPTER_SRC} ) #add_executable(${APP_NAME} ${COCOS_ADAPTER_SRC}) -set(EMS_LINK_FLAGS "-O3 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ +set(EMS_LINK_FLAGS "-00 -g3 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ -flto --no-entry --bind -s USE_ES6_IMPORT_META=0 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORT_NAME='spineWasm' \ -s ENVIRONMENT=web -s FILESYSTEM=0 -s NO_EXIT_RUNTIME=1 -s LLD_REPORT_UNDEFINED \ -s MIN_SAFARI_VERSION=110000 \ diff --git a/native/cocos/editor-support/spine-wasm/spine-mesh-data.cpp b/native/cocos/editor-support/spine-wasm/spine-mesh-data.cpp index e62687837d4..91cb713f096 100644 --- a/native/cocos/editor-support/spine-wasm/spine-mesh-data.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-mesh-data.cpp @@ -43,11 +43,11 @@ void SpineMeshData::moveIB(uint32_t count) { iPtr += count; } -uint8_t* SpineMeshData::queryVBuffer(uint32_t count) { +uint8_t* SpineMeshData::queryVBuffer() { return vPtr; } -uint16_t* SpineMeshData::queryIBuffer(uint32_t count) { +uint16_t* SpineMeshData::queryIBuffer() { return iPtr; } diff --git a/native/cocos/editor-support/spine-wasm/spine-mesh-data.h b/native/cocos/editor-support/spine-wasm/spine-mesh-data.h index c4b505f6bef..66ad046b02f 100644 --- a/native/cocos/editor-support/spine-wasm/spine-mesh-data.h +++ b/native/cocos/editor-support/spine-wasm/spine-mesh-data.h @@ -9,8 +9,8 @@ class SpineMeshData { static void reset(); static void moveVB(uint32_t count); static void moveIB(uint32_t count); - static uint8_t *queryVBuffer(uint32_t count); - static uint16_t *queryIBuffer(uint32_t count); + static uint8_t *queryVBuffer(); + static uint16_t *queryIBuffer(); static uint8_t *vb(); static uint16_t *ib(); diff --git a/native/cocos/editor-support/spine-wasm/spine-model.cpp b/native/cocos/editor-support/spine-wasm/spine-model.cpp index e817671e055..b8f2671c7f6 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-model.cpp @@ -1,11 +1,14 @@ #include "spine-model.h" SpineModel::SpineModel() { + SpineModel::data = new std::vector(6, 0); } SpineModel::~SpineModel() { + delete SpineModel::data; } +/* void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { bool canMerge = false; auto count = meshArray.size(); @@ -18,31 +21,82 @@ void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { } } if (!canMerge) { - meshArray.push_back(mesh); + auto mergeMesh = SlotMesh(mesh.vBuf, mesh.iBuf, mesh.vCount, mesh.iCount); + mergeMesh.blendMode = mesh.blendMode; + mergeMesh.textureID = mesh.textureID; + meshArray.push_back(mergeMesh); } + auto indexCount = mesh.iCount; uint16_t* iiPtr = mesh.iBuf; - for (int i = 0; i < mesh.iCount; i++) { + for (uint16_t i = 0; i < indexCount; i++) { iiPtr[i] += vCount; + } + + auto vertexCount = mesh.vCount; + float* floatPtr = (float*)mesh.vBuf; + int floatStride = this->byteStride / 4; + for (int i = 0; i < vertexCount; i++) { + floatPtr[floatStride * i + 2] = 0; + } + vCount += vertexCount; + iCount += indexCount; +} +*/ + +void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { + bool canMerge = false; + auto count = data->size(); + if (needMerge && count > 0) { + if (data->at(count - 2) == mesh.blendMode && data->at(count - 1) == mesh.textureID) { + canMerge = true; + data->at(count-4) += mesh.vCount; + data->at(count-3) += mesh.iCount; + } } + if (!canMerge) { + data->resize(count + 6); + data->at(count) = (uint32_t)mesh.vBuf; + data->at(count + 1) = (uint32_t)mesh.iBuf; + data->at(count + 2) = mesh.vCount; + data->at(count + 3) = mesh.iCount; + data->at(count + 4) = mesh.blendMode; + data->at(count + 5) = mesh.textureID; + } + + auto indexCount = mesh.iCount; + uint16_t* iiPtr = mesh.iBuf; + for (uint16_t i = 0; i < indexCount; i++) { + iiPtr[i] += vCount; + } + + auto vertexCount = mesh.vCount; float* floatPtr = (float*)mesh.vBuf; int floatStride = this->byteStride / 4; - for (int i = 0; i < mesh.vCount; i++) { + for (int i = 0; i < vertexCount; i++) { floatPtr[floatStride * i + 2] = 0; } - vCount += mesh.vCount; - iCount += mesh.iCount; + vCount += vertexCount; + iCount += indexCount; } void SpineModel::clearMeshes() { - meshArray.clear(); + //for (auto it = meshArray.begin(); it != meshArray.end(); ++it) { + // delete &(*it); + //} + //meshArray.clear(); + data->resize(0); vCount = 0; iCount = 0; } -std::vector& SpineModel::getMeshes() { - return meshArray; +std::vector* SpineModel::getData() { + return data; } +//std::vector* SpineModel::getMeshes() { +// return &meshArray; +//} + void SpineModel::setBufferPtr(uint8_t* vp, uint16_t* ip) { vPtr = (uint32_t)vp; iPtr = (uint32_t)ip; diff --git a/native/cocos/editor-support/spine-wasm/spine-model.h b/native/cocos/editor-support/spine-wasm/spine-model.h index 227520a41d2..e8af1d1e019 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.h +++ b/native/cocos/editor-support/spine-wasm/spine-model.h @@ -11,6 +11,13 @@ class SlotMesh { SlotMesh(uint8_t* vb, uint16_t* ib, uint32_t vc, uint32_t ic) : vBuf(vb), iBuf(ib), vCount(vc), iCount(ic) {} ~SlotMesh() {} + void set(uint8_t* vb, uint16_t* ib, uint32_t vc, uint32_t ic) + { + this->vBuf = vb; + this->iBuf = ib; + this->vCount = vc; + this->iCount = ic; + } uint8_t* vBuf; uint16_t* iBuf; uint32_t vCount; @@ -26,7 +33,9 @@ class SpineModel { void addSlotMesh(SlotMesh& mesh, bool needMerge = true); void clearMeshes(); void setBufferPtr(uint8_t* vp, uint16_t* ip); - std::vector& getMeshes(); + std::vector* data; + std::vector* getData(); + //std::vector* getMeshes(); public: uint32_t vCount; @@ -34,7 +43,8 @@ class SpineModel { uint32_t vPtr; uint32_t iPtr; uint32_t byteStride; - std::vector meshArray{}; + //std::vector meshArray{}; + }; #endif \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp index 00d0d2af986..b98ea8f0609 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp @@ -5,6 +5,9 @@ #include "spine-mesh-data.h" #include "spine-wasm.h" #include "util-function.h" +#include "spine-skeleton-system.h" + +SlotMesh globalMesh(nullptr, nullptr, 0, 0); extern "C" { extern void spineListenerCallBackFromJS(); @@ -18,9 +21,11 @@ static void animationCallback(AnimationState *state, EventType type, TrackEntry SpineSkeletonInstance::SpineSkeletonInstance() { _model = new SpineModel(); + SpineSkeletonSystem::addSpineInstance(this); } SpineSkeletonInstance::~SpineSkeletonInstance() { + _skeletonData = nullptr; if (_clipper) delete _clipper; if (_animState) delete _animState; if (_animStateData) delete _animStateData; @@ -74,10 +79,27 @@ void SpineSkeletonInstance::setSkin(const std::string &name) { void SpineSkeletonInstance::updateAnimation(float dltTime) { if (!_skeleton) return; + dltTime *= dtRate; _skeleton->update(dltTime); _animState->update(dltTime); _animState->apply(*_skeleton); _skeleton->updateWorldTransform(); + //preUpdateRenderData(); +} + +void SpineSkeletonInstance::preUpdateRenderData() { + if (_userData.debugMode) { + _debugShapes.clear(); + } + //SpineMeshData::reset(); + _model->clearMeshes(); + if (_userData.useTint) { + _model->byteStride = sizeof(V3F_T2F_C4B_C4B); + } else { + _model->byteStride = sizeof(V3F_T2F_C4B); + } + _model->setBufferPtr(SpineMeshData::vb(), SpineMeshData::ib()); + collectMeshData(); } SpineModel *SpineSkeletonInstance::updateRenderData() { @@ -95,124 +117,130 @@ SpineModel *SpineSkeletonInstance::updateRenderData() { collectMeshData(); _model->setBufferPtr(SpineMeshData::vb(), SpineMeshData::ib()); + return _model; } void SpineSkeletonInstance::collectMeshData() { uint32_t byteStrideOneColor = sizeof(V3F_T2F_C4B); uint32_t byteStrideTwoColor = sizeof(V3F_T2F_C4B_C4B); + uint32_t sizeof_float = sizeof(float); + uint32_t strideOneColor = byteStrideOneColor / sizeof_float; + uint32_t strideTwoColor = byteStrideTwoColor / sizeof_float; + uint16_t sizeof_uint16 = sizeof(uint16_t); + + uint32_t byteStrideColor = !_userData.useTint ? byteStrideOneColor : byteStrideTwoColor; + uint32_t strideColor = byteStrideColor / sizeof_float; Color4F color; auto &slotArray = _skeleton->getDrawOrder(); uint32_t slotCount = slotArray.size(); DEBUG_SHAPE_TYPE debugShapeType = DEBUG_SHAPE_TYPE::DEBUG_REGION; - SlotMesh currMesh; + SlotMesh currMesh = globalMesh; if (_effect) { _effect->begin(*_skeleton); } - + const Color& skeletonColor = _skeleton->getColor(); for (uint32_t drawIdx = 0; drawIdx < slotCount; ++drawIdx) { auto slot = slotArray[drawIdx]; - if (slot->getBone().isActive() == false) { + auto& bone = slot->getBone(); + if (bone.isActive() == false) { continue; } if (!slot->getAttachment()) { _clipper->clipEnd(*slot); continue; - } + } color.r = _userData.color.r; color.g = _userData.color.g; color.b = _userData.color.b; color.a = _userData.color.a; - if (slot->getAttachment()->getRTTI().isExactly(spine::RegionAttachment::rtti)) { + spine::Attachment* attachmentSlot = slot->getAttachment(); + const spine::RTTI& attachmentRTTI = attachmentSlot->getRTTI(); + if (attachmentRTTI.isExactly(spine::RegionAttachment::rtti)) { debugShapeType = DEBUG_SHAPE_TYPE::DEBUG_REGION; - auto *attachment = static_cast(slot->getAttachment()); + auto *attachment = static_cast(attachmentSlot); auto *attachmentVertices = reinterpret_cast(attachment->getRendererObject()); - - auto vertCount = attachmentVertices->_triangles->vertCount; - auto indexCount = attachmentVertices->_triangles->indexCount; - auto ibSize = indexCount * sizeof(uint16_t); - + + auto& triangles = attachmentVertices->_triangles; + auto vertCount = triangles->vertCount; + auto indexCount = triangles->indexCount; + auto ibSize = indexCount * sizeof_uint16; + + auto vbSize = vertCount * byteStrideColor; + auto *vertices = SpineMeshData::queryVBuffer(); + auto *indices = SpineMeshData::queryIBuffer(); + if (!_userData.useTint) { - auto vbSize = vertCount * byteStrideOneColor; - auto *vertices = SpineMeshData::queryVBuffer(vbSize); - auto *indices = SpineMeshData::queryIBuffer(indexCount); - memcpy(static_cast(vertices), static_cast(attachmentVertices->_triangles->verts), vbSize); - memcpy(indices, attachmentVertices->_triangles->indices, ibSize); - attachment->computeWorldVertices(slot->getBone(), (float *)vertices, 0, byteStrideOneColor / sizeof(float)); - currMesh = SlotMesh((uint8_t *)vertices, indices, vertCount, indexCount); + memcpy(static_cast(vertices), static_cast(triangles->verts), vbSize); } else { - auto vbSize = vertCount * byteStrideTwoColor; - auto *vertices = SpineMeshData::queryVBuffer(vbSize); - auto *indices = SpineMeshData::queryIBuffer(indexCount); V3F_T2F_C4B_C4B *verts = (V3F_T2F_C4B_C4B *)vertices; for (int ii = 0; ii < vertCount; ii++) { - verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + verts[ii].texCoord = triangles->verts[ii].texCoord; } - memcpy(indices, attachmentVertices->_triangles->indices, ibSize); - attachment->computeWorldVertices(slot->getBone(), (float *)vertices, 0, byteStrideTwoColor / sizeof(float)); - currMesh = SlotMesh((uint8_t *)vertices, indices, vertCount, indexCount); } - color.r *= attachment->getColor().r; - color.g *= attachment->getColor().g; - color.b *= attachment->getColor().b; - color.a *= attachment->getColor().a; + memcpy(indices, triangles->indices, ibSize); + attachment->computeWorldVertices(bone, (float *)vertices, 0, strideColor); + currMesh.set((uint8_t *)vertices, indices, vertCount, indexCount); + const Color& attachmentColor = attachment->getColor(); + color.r *= attachmentColor.r; + color.g *= attachmentColor.g; + color.b *= attachmentColor.b; + color.a *= attachmentColor.a; currMesh.textureID = attachmentVertices->_textureId; - } else if (slot->getAttachment()->getRTTI().isExactly(spine::MeshAttachment::rtti)) { + } else if (attachmentRTTI.isExactly(spine::MeshAttachment::rtti)) { debugShapeType = DEBUG_SHAPE_TYPE::DEBUG_MESH; - auto *attachment = static_cast(slot->getAttachment()); + auto *attachment = static_cast(attachmentSlot); auto *attachmentVertices = static_cast(attachment->getRendererObject()); - auto vertCount = attachmentVertices->_triangles->vertCount; - auto indexCount = attachmentVertices->_triangles->indexCount; - auto ibSize = indexCount * sizeof(uint16_t); + auto& triangles = attachmentVertices->_triangles; + auto vertCount = triangles->vertCount; + auto indexCount = triangles->indexCount; + auto ibSize = indexCount * sizeof_uint16; + + auto vbSize = vertCount * byteStrideColor; + auto *vertices = SpineMeshData::queryVBuffer(); + auto *indices = SpineMeshData::queryIBuffer(); if (!_userData.useTint) { - auto vbSize = vertCount * byteStrideOneColor; - auto *vertices = SpineMeshData::queryVBuffer(vbSize); - auto *indices = SpineMeshData::queryIBuffer(indexCount); - memcpy(static_cast(vertices), static_cast(attachmentVertices->_triangles->verts), vbSize); - memcpy(indices, attachmentVertices->_triangles->indices, ibSize); - attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float *)vertices, 0, byteStrideOneColor / sizeof(float)); - currMesh = SlotMesh((uint8_t *)vertices, indices, vertCount, indexCount); + memcpy(static_cast(vertices), static_cast(triangles->verts), vbSize); } else { - auto vbSize = vertCount * byteStrideTwoColor; - auto *vertices = SpineMeshData::queryVBuffer(vbSize); - auto *indices = SpineMeshData::queryIBuffer(indexCount); V3F_T2F_C4B_C4B *verts = (V3F_T2F_C4B_C4B *)vertices; for (int ii = 0; ii < vertCount; ii++) { - verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + verts[ii].texCoord = triangles->verts[ii].texCoord; } - memcpy(indices, attachmentVertices->_triangles->indices, ibSize); - attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float *)vertices, 0, byteStrideTwoColor / sizeof(float)); - currMesh = SlotMesh((uint8_t *)vertices, indices, vertCount, indexCount); } - color.r *= attachment->getColor().r; - color.g *= attachment->getColor().g; - color.b *= attachment->getColor().b; - color.a *= attachment->getColor().a; + memcpy(indices, triangles->indices, ibSize); + attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float *)vertices, 0, strideColor); + currMesh.set((uint8_t *)vertices, indices, vertCount, indexCount); + const Color& attachmentColor = attachment->getColor(); + color.r *= attachmentColor.r; + color.g *= attachmentColor.g; + color.b *= attachmentColor.b; + color.a *= attachmentColor.a; currMesh.textureID = attachmentVertices->_textureId; - } else if (slot->getAttachment()->getRTTI().isExactly(spine::ClippingAttachment::rtti)) { - auto *clip = static_cast(slot->getAttachment()); + } else if (attachmentRTTI.isExactly(spine::ClippingAttachment::rtti)) { + auto *clip = static_cast(attachmentSlot); _clipper->clipStart(*slot, clip); continue; } else { _clipper->clipEnd(*slot); continue; } - - uint32_t uintA = (uint32_t)(255 * _skeleton->getColor().a * slot->getColor().a * color.a); + const Color& slotColor = slot->getColor(); + uint32_t uintA = (uint32_t)(255 * skeletonColor.a * slotColor.a * color.a); uint32_t multiplier = _userData.premultipliedAlpha ? uintA : 255; - uint32_t uintR = (uint32_t)(_skeleton->getColor().r * slot->getColor().r * color.r * multiplier); - uint32_t uintG = (uint32_t)(_skeleton->getColor().g * slot->getColor().g * color.g * multiplier); - uint32_t uintB = (uint32_t)(_skeleton->getColor().b * slot->getColor().b * color.b * multiplier); + uint32_t uintR = (uint32_t)(skeletonColor.r * slotColor.r * color.r * multiplier); + uint32_t uintG = (uint32_t)(skeletonColor.g * slotColor.g * color.g * multiplier); + uint32_t uintB = (uint32_t)(skeletonColor.b * slotColor.b * color.b * multiplier); uint32_t light = (uintA << 24) + (uintB << 16) + (uintG << 8) + uintR; if (slot->hasDarkColor()) { - uintR = (uint32_t)(_skeleton->getColor().r * slot->getDarkColor().r * color.r * multiplier); - uintG = (uint32_t)(_skeleton->getColor().g * slot->getDarkColor().g * color.g * multiplier); - uintB = (uint32_t)(_skeleton->getColor().b * slot->getDarkColor().b * color.b * multiplier); + const Color& slotDarkColor = slot->getDarkColor(); + uintR = (uint32_t)(skeletonColor.r * slotDarkColor.r * color.r * multiplier); + uintG = (uint32_t)(skeletonColor.g * slotDarkColor.g * color.g * multiplier); + uintB = (uint32_t)(skeletonColor.b * slotDarkColor.b * color.b * multiplier); } else { uintR = 0; uintG = 0; @@ -223,22 +251,24 @@ void SpineSkeletonInstance::collectMeshData() { if (!_userData.useTint) { if (_clipper->isClipping()) { - _clipper->clipTriangles(reinterpret_cast(currMesh.vBuf), currMesh.iBuf, currMesh.iCount, (float *)(&currMesh.vBuf[3 * 4]), byteStrideOneColor / sizeof(float)); - - if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipTriangles(reinterpret_cast(currMesh.vBuf), currMesh.iBuf, currMesh.iCount, (float *)(&currMesh.vBuf[3 * 4]), strideColor); + auto& clippedTriangles = _clipper->getClippedTriangles(); + if (clippedTriangles.size() == 0) { _clipper->clipEnd(*slot); continue; } - auto vertCount = static_cast(_clipper->getClippedVertices().size()) >> 1; - auto indexCount = static_cast(_clipper->getClippedTriangles().size()); - auto vbSize = vertCount * byteStrideOneColor; - uint8_t *vPtr = SpineMeshData::queryVBuffer(vbSize); - uint16_t *iPtr = SpineMeshData::queryIBuffer(indexCount); - currMesh = SlotMesh(vPtr, iPtr, vertCount, indexCount); - memcpy(iPtr, _clipper->getClippedTriangles().buffer(), sizeof(uint16_t) * indexCount); - - float *verts = _clipper->getClippedVertices().buffer(); - float *uvs = _clipper->getClippedUVs().buffer(); + auto& clippedVertices = _clipper->getClippedVertices(); + auto& clippedUVs = _clipper->getClippedUVs(); + const auto vertCount = static_cast(clippedVertices.size()) >> 1; + const auto indexCount = static_cast(clippedTriangles.size()); + const auto vbSize = vertCount * byteStrideColor; + uint8_t *vPtr = SpineMeshData::queryVBuffer(); + uint16_t *iPtr = SpineMeshData::queryIBuffer(); + currMesh.set(vPtr, iPtr, vertCount, indexCount); + memcpy(iPtr, clippedTriangles.buffer(), sizeof_uint16 * indexCount); + float *verts = clippedVertices.buffer(); + float *uvs = clippedUVs.buffer(); + V3F_T2F_C4B *vertices = (V3F_T2F_C4B *)currMesh.vBuf; if (_effect) { for (int v = 0, vn = vertCount, vv = 0; v < vn; ++v, vv += 2) { @@ -261,8 +291,6 @@ void SpineSkeletonInstance::collectMeshData() { } else { auto vertCount = currMesh.vCount; V3F_T2F_C4B *vertex = (V3F_T2F_C4B *)currMesh.vBuf; - uint32_t *uPtr = (uint32_t *)currMesh.vBuf; - auto stride = byteStrideOneColor / sizeof(float); if (_effect) { for (int v = 0; v < vertCount; ++v) { _effect->transform(vertex[v].vertex.x, vertex[v].vertex.y); @@ -276,22 +304,24 @@ void SpineSkeletonInstance::collectMeshData() { } } else { if (_clipper->isClipping()) { - _clipper->clipTriangles(reinterpret_cast(currMesh.vBuf), currMesh.iBuf, currMesh.iCount, (float *)(&currMesh.vBuf[3 * 4]), byteStrideTwoColor / sizeof(float)); - - if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipTriangles(reinterpret_cast(currMesh.vBuf), currMesh.iBuf, currMesh.iCount, (float *)(&currMesh.vBuf[3 * 4]), strideColor); + auto& clippedTriangles = _clipper->getClippedTriangles(); + if (clippedTriangles.size() == 0) { _clipper->clipEnd(*slot); continue; } - auto vertCount = static_cast(_clipper->getClippedVertices().size()) >> 1; - auto indexCount = static_cast(_clipper->getClippedTriangles().size()); - auto vbSize = vertCount * byteStrideTwoColor; - uint8_t *vPtr = SpineMeshData::queryVBuffer(vbSize); - uint16_t *iPtr = SpineMeshData::queryIBuffer(indexCount); - currMesh = SlotMesh(vPtr, iPtr, vertCount, indexCount); - memcpy(iPtr, _clipper->getClippedTriangles().buffer(), sizeof(uint16_t) * indexCount); - - float *verts = _clipper->getClippedVertices().buffer(); - float *uvs = _clipper->getClippedUVs().buffer(); + auto& clippedVertices = _clipper->getClippedVertices(); + auto& clippedUVs = _clipper->getClippedUVs(); + const auto vertCount = static_cast(clippedVertices.size()) >> 1; + const auto indexCount = static_cast(clippedTriangles.size()); + const auto vbSize = vertCount * byteStrideColor; + uint8_t *vPtr = SpineMeshData::queryVBuffer(); + uint16_t *iPtr = SpineMeshData::queryIBuffer(); + currMesh.set(vPtr, iPtr, vertCount, indexCount); + memcpy(iPtr, clippedTriangles.buffer(), sizeof_uint16 * indexCount); + float *verts = clippedVertices.buffer(); + float *uvs = clippedUVs.buffer(); + V3F_T2F_C4B_C4B *vertices = (V3F_T2F_C4B_C4B *)currMesh.vBuf; if (_effect) { for (int v = 0, vn = vertCount, vv = 0; v < vn; ++v, vv += 2) { @@ -315,9 +345,7 @@ void SpineSkeletonInstance::collectMeshData() { } } else { auto vertCount = currMesh.vCount; - V3F_T2F_C4B_C4B *vertex = (V3F_T2F_C4B_C4B *)currMesh.vBuf; - uint32_t *uPtr = (uint32_t *)currMesh.vBuf; - auto stride = byteStrideTwoColor / sizeof(float); + V3F_T2F_C4B_C4B *vertex = (V3F_T2F_C4B_C4B *)currMesh.vBuf; if (_effect) { for (int v = 0; v < vertCount; ++v) { _effect->transform(vertex[v].vertex.x, vertex[v].vertex.y); @@ -333,8 +361,7 @@ void SpineSkeletonInstance::collectMeshData() { } } - auto stride = _userData.useTint ? byteStrideTwoColor : byteStrideOneColor; - SpineMeshData::moveVB(currMesh.vCount * stride); + SpineMeshData::moveVB(currMesh.vCount * byteStrideColor); SpineMeshData::moveIB(currMesh.iCount); // record debug shape info if (_userData.debugMode) { @@ -355,9 +382,9 @@ void SpineSkeletonInstance::collectMeshData() { } } _model->addSlotMesh(currMesh); - _clipper->clipEnd(*slot); } + _clipper->clipEnd(); if (_effect) _effect->end(); } diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h index bf1d08dc88b..5d8c0b2ce32 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h @@ -47,6 +47,7 @@ class SpineSkeletonInstance { TrackEntry *setAnimation(float trackIndex, const std::string &name, bool loop); void setSkin(const std::string &name); void updateAnimation(float dltTime); + void preUpdateRenderData(); SpineModel *updateRenderData(); void setPremultipliedAlpha(bool val); void setUseTint(bool useTint); @@ -62,7 +63,10 @@ class SpineSkeletonInstance { std::vector &getDebugShapes(); void resizeSlotRegion(const std::string &slotName, uint32_t width, uint32_t height, bool createNew = false); void setSlotTexture(const std::string &slotName, uint32_t index); - + bool isCache = false; + bool enable = true; + float dtRate = 1; + bool isDelete = false; private: void collectMeshData(); diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp new file mode 100644 index 00000000000..9e8ce792485 --- /dev/null +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp @@ -0,0 +1,59 @@ +#include "spine-skeleton-system.h" +#include "spine-skeleton-instance.h" +#include "spine-mesh-data.h" + +using namespace spine; + +std::vector SpineSkeletonSystem::vectorSpines; + +void SpineSkeletonSystem::updateAnimation(float deltaTime) { + //SpineMeshData::reset(); + auto count = static_cast(vectorSpines.size()); + for (int i = count - 1; i >= 0; --i) { + SpineSkeletonInstance* spineInstance = vectorSpines[i]; + if(spineInstance->isDelete) { + std::swap(spineInstance, vectorSpines.back()); + vectorSpines.pop_back(); + delete spineInstance; + continue; + } + if(!spineInstance->enable) continue; + if (!spineInstance->isCache) { + spineInstance->updateAnimation(deltaTime); + } + + } +} + +int SpineSkeletonSystem::getCount() { + auto count = vectorSpines.size(); + return count; +} + +void SpineSkeletonSystem::updateRenderData() { + SpineMeshData::reset(); + auto count = vectorSpines.size(); + for (size_t i = 0; i < count; ++i) { + SpineSkeletonInstance* spineInstance = vectorSpines[i]; + if (!spineInstance->isCache) { + spineInstance->preUpdateRenderData(); + } + } +} + +void SpineSkeletonSystem::addSpineInstance(SpineSkeletonInstance* instance) +{ + if(vectorSpines.size() == vectorSpines.capacity()){ + vectorSpines.reserve(vectorSpines.size() + 20); + } + vectorSpines.push_back(instance); +} + +void SpineSkeletonSystem::removeSpineInstance(SpineSkeletonInstance* instance) +{ + auto it = std::find(vectorSpines.begin(), vectorSpines.end(), instance); + if (it != vectorSpines.end()) { + vectorSpines.erase(it); + delete instance; + } +} \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-system.h b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.h new file mode 100644 index 00000000000..6e47b0a5069 --- /dev/null +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.h @@ -0,0 +1,15 @@ +#include +#include "spine-skeleton-instance.h" + +using namespace spine; +class SpineSkeletonSystem +{ +public: + static void updateAnimation(float deltaTime); + static void updateRenderData(); + static int getCount(); + static void addSpineInstance(SpineSkeletonInstance* instance); + static void removeSpineInstance(SpineSkeletonInstance* instance); +private: + static std::vector vectorSpines; +}; \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp index 54d5284e21e..c435a162b54 100644 --- a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp @@ -3,8 +3,10 @@ #include #include #include +#include "spine-skeleton-system.h" #include "spine-skeleton-instance.h" #include "spine-wasm.h" +#include "Vector2.h" using namespace emscripten; using namespace spine; @@ -20,6 +22,7 @@ const spine::String STRING_STD2SP(const std::string &str) { return spString; } +/* template std::vector VECTOR_SP2STD(Vector &container) { int count = container.size(); @@ -38,6 +41,7 @@ std::vector VECTOR_SP2STD_SIZE_T(Vector &container) { } return stdVector; } +*/ const std::vector VECTOR_SP2STD_STRING(Vector &container) { int count = container.size(); @@ -48,6 +52,7 @@ const std::vector VECTOR_SP2STD_STRING(Vector &container) { return stdVector; } +/* template std::vector> VECTOR_2_SP2STD(Vector> &container) { int count = container.size(); @@ -58,6 +63,7 @@ std::vector> VECTOR_2_SP2STD(Vector> &container) { return stdVector; } + template std::vector VECTOR_SP2STD2(Vector container) { int count = container.size(); @@ -67,6 +73,7 @@ std::vector VECTOR_SP2STD2(Vector container) { } return stdVector; } +*/ template Vector VECTOR_STD2SP(std::vector &container) { @@ -98,12 +105,37 @@ void VECTOR_STD_COPY_SP(std::vector &stdVector, Vector &spVector) { } } +using SPVectorFloat = Vector; +using SPVectorVectorFloat = Vector>; +using SPVectorInt = Vector; +using SPVectorVectorInt = Vector>; +using SPVectorBonePtr = Vector; +using SPVectorBoneDataPtr = Vector; +using SPVectorUnsignedShort = Vector; +using SPVectorConstraintDataPtr = Vector; +using SPVectorSlotPtr = Vector; +using SPVectorSkinPtr = Vector; +using SPVectorEventDataPtr = Vector; +using SPVectorAnimationPtr = Vector; +using SPVectorIkConstraintPtr = Vector; +using SPVectorIkConstraintDataPtr = Vector; +using SPVectorTransformConstraintPtr = Vector; +using SPVectorPathConstraintPtr = Vector; +using SPVectorTimelinePtr = Vector; +using SPVectorTrackEntryPtr = Vector; +using SPVectorUpdatablePtr = Vector; + +//using SPVectorEntry = Vector; +//using SPVectorVectorEntry = Vector>; + } // namespace EMSCRIPTEN_BINDINGS(spine) { + register_vector("VectorFloat"); register_vector>("VectorVectorFloat"); register_vector("VectorUnsignedShort"); + register_vector("VectorOfUInt"); register_vector("VectorString"); register_vector("VectorBoneData"); register_vector("VectorBone"); @@ -124,6 +156,210 @@ EMSCRIPTEN_BINDINGS(spine) { register_vector("VectorPathConstraintData"); register_vector("VectorTrackEntry"); + class_("SPVectorFloat") + .constructor<>() + .function("resize", &SPVectorFloat::setSize) + .function("size", &SPVectorFloat::size) + .function("get", &SPVectorFloat::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorFloat &obj, int index, float value) { + obj[index] = value; + })); + + class_("SPVectorVectorFloat") + .constructor<>() + .function("resize", &SPVectorVectorFloat::setSize) + .function("size", &SPVectorVectorFloat::size) + .function("get", &SPVectorVectorFloat::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorVectorFloat &obj, int index, SPVectorFloat &value) { + obj[index] = value; + })); + + class_("SPVectorInt") + .constructor<>() + .function("resize", &SPVectorInt::setSize) + .function("size", &SPVectorInt::size) + .function("get", &SPVectorInt::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorInt &obj, int index, int value) { + obj[index] = value; + })); + + class_("SPVectorVectorInt") + .constructor<>() + .function("resize", &SPVectorVectorInt::setSize) + .function("size", &SPVectorVectorInt::size) + .function("get", &SPVectorVectorInt::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorVectorInt &obj, int index, SPVectorInt &value) { + obj[index] = value; + })); + + class_("SPVectorBonePtr") + .constructor<>() + .function("resize", &SPVectorBonePtr::setSize) + .function("size", &SPVectorBonePtr::size) + .function("get", &SPVectorBonePtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorBonePtr &obj, int index, Bone *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorBoneDataPtr") + .constructor<>() + .function("resize", &SPVectorBoneDataPtr::setSize) + .function("size", &SPVectorBoneDataPtr::size) + .function("get", &SPVectorBoneDataPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorBoneDataPtr &obj, int index, BoneData *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorConstraintDataPtr") + .constructor<>() + .function("resize", &SPVectorConstraintDataPtr::setSize) + .function("size", &SPVectorConstraintDataPtr::size) + .function("get", &SPVectorConstraintDataPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorConstraintDataPtr &obj, int index, ConstraintData *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorSlotPtr") + .constructor<>() + .function("resize", &SPVectorSlotPtr::setSize) + .function("size", &SPVectorSlotPtr::size) + .function("get", &SPVectorSlotPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorSlotPtr &obj, int index, Slot *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorSkinPtr") + .constructor<>() + .function("resize", &SPVectorSkinPtr::setSize) + .function("size", &SPVectorSkinPtr::size) + .function("get", &SPVectorSkinPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorSkinPtr &obj, int index, Skin *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorEventDataPtr") + .constructor<>() + .function("resize", &SPVectorEventDataPtr::setSize) + .function("size", &SPVectorEventDataPtr::size) + .function("get", &SPVectorEventDataPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorEventDataPtr &obj, int index, EventData *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorAnimationPtr") + .constructor<>() + .function("resize", &SPVectorAnimationPtr::setSize) + .function("size", &SPVectorAnimationPtr::size) + .function("get", &SPVectorAnimationPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorAnimationPtr &obj, int index, Animation *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorIkConstraintPtr") + .constructor<>() + .function("resize", &SPVectorIkConstraintPtr::setSize) + .function("size", &SPVectorIkConstraintPtr::size) + .function("get", &SPVectorIkConstraintPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorIkConstraintPtr &obj, int index, IkConstraint *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorIkConstraintDataPtr") + .constructor<>() + .function("resize", &SPVectorIkConstraintDataPtr::setSize) + .function("size", &SPVectorIkConstraintDataPtr::size) + .function("get", &SPVectorIkConstraintDataPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorIkConstraintDataPtr &obj, int index, IkConstraintData *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorTransformConstraintPtr") + .constructor<>() + .function("resize", &SPVectorTransformConstraintPtr::setSize) + .function("size", &SPVectorTransformConstraintPtr::size) + .function("get", &SPVectorTransformConstraintPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorTransformConstraintPtr &obj, int index, TransformConstraint *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorPathConstraintPtr") + .constructor<>() + .function("resize", &SPVectorPathConstraintPtr::setSize) + .function("size", &SPVectorPathConstraintPtr::size) + .function("get", &SPVectorPathConstraintPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorPathConstraintPtr &obj, int index, PathConstraint *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorTimelinePtr") + .constructor<>() + .function("resize", &SPVectorTimelinePtr::setSize) + .function("size", &SPVectorTimelinePtr::size) + .function("get", &SPVectorTimelinePtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorTimelinePtr &obj, int index, Timeline *value) { + obj[index] = value; + }), allow_raw_pointer()); + + class_("SPVectorTrackEntryPtr") + .constructor<>() + .function("resize", &SPVectorTrackEntryPtr::setSize) + .function("size", &SPVectorTrackEntryPtr::size) + .function("get", &SPVectorTrackEntryPtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorTrackEntryPtr &obj, int index, TrackEntry *value) { + obj[index] = value; + }), allow_raw_pointer()); + + + class_("Vector2") + .constructor<>() + .constructor() + .function("setX", &Vector2::setX) + .function("getX", &Vector2::getX) + .function("setY", &Vector2::setY) + .function("getY", &Vector2::getY) + .function("set", &Vector2::set) + .function("length", &Vector2::length) + .function("normalize", &Vector2::normalize); +/* + class_("SPVectorEntry") + .function("size", &SPVectorEntry::size) + .function("get", &SPVectorEntry::operator[], allow_raw_pointers()); + + class_("SPVectorVectorEntry") + .function("size", &SPVectorVectorEntry::size) + .function("get", &SPVectorVectorEntry::operator[], allow_raw_pointers()); + + + class_("AttachmentMap") + .function("get", &Skin::AttachmentMap::get, allow_raw_pointers()); + + + class_("Entries") + .function("hasNext", &Skin::AttachmentMap::Entries::hasNext) + .function("next", &Skin::AttachmentMap::Entries::next); + + value_object("Entry") + //.constructor<>() + //.constructor() + .field("_slotIndex",&Skin::AttachmentMap::Entry::_slotIndex) + .field("_name",&Skin::AttachmentMap::Entry::_name); + ///.field("_attachment", &Skin::AttachmentMap::Entry::_attachment, allow_raw_pointer()); + */ + class_("String") + .function("length", &String::length) + .function("isEmpty", &String::isEmpty) + .function("append", select_overload(&String::append)) + .function("equals", select_overload(&String::operator=)) + .function("buffer", &String::buffer, allow_raw_pointer()) + //.function("estr", optional_override([](String &obj) { + // auto str = emscripten::val(obj.buffer()); + // return str; }), allow_raw_pointers()) + .function("strPtr", optional_override([](String &obj) { + return reinterpret_cast(obj.buffer());}), allow_raw_pointers()) + .function("str", optional_override([](String &obj) { + std::string stdStr(obj.buffer(), obj.length()); + return stdStr; }), allow_raw_pointers()); + enum_("TimelineType") .value("rotate", TimelineType_Rotate) .value("translate", TimelineType_Translate) @@ -211,7 +447,7 @@ EMSCRIPTEN_BINDINGS(spine) { .value("Clipping", AttachmentType_Clipping); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// class_("MathUtils") .class_property("PI", &MathUtil::Pi) @@ -266,7 +502,7 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("IkConstraintData") .constructor() - .function("getBones", optional_override([](IkConstraintData &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getBones", &IkConstraintData::getBones, allow_raw_pointer()) .function("getTarget", &IkConstraintData::getTarget, allow_raw_pointer()) .function("setTarget", &IkConstraintData::setTarget, allow_raw_pointer()) .function("getBendDirection", &IkConstraintData::getBendDirection) @@ -284,7 +520,7 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("PathConstraintData") .constructor() - .function("getBones", optional_override([](PathConstraintData &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getBones", &PathConstraintData::getBones, allow_raw_pointer()) .function("getTarget", &PathConstraintData::getTarget, allow_raw_pointer()) .function("setTarget", &PathConstraintData::setTarget, allow_raw_pointer()) .function("getPositionMode", &PathConstraintData::getPositionMode) @@ -309,23 +545,31 @@ EMSCRIPTEN_BINDINGS(spine) { .function("aabbContainsPoint", &SkeletonBounds::aabbcontainsPoint) .function("aabbIntersectsSegment", &SkeletonBounds::aabbintersectsSegment) .function("aabbIntersectsSkeleton", &SkeletonBounds::aabbIntersectsSkeleton) - .function("containsPoint", optional_override([](SkeletonBounds &obj, float x, float y) { return obj.containsPoint(x, y); }), allow_raw_pointers()) - .function("containsPointPolygon", optional_override([](SkeletonBounds &obj, Polygon *polygon, float x, float y) { return obj.containsPoint(polygon, x, y); }), allow_raw_pointers()) - .function("intersectsSegment", optional_override([](SkeletonBounds &obj, float x1, float y1, float x2, float y2) { return obj.intersectsSegment(x1, y1, x2, y2); }), allow_raw_pointers()) - .function("intersectsSegmentPolygon", optional_override([](SkeletonBounds &obj, Polygon *polygon, float x1, float y1, float x2, float y2) { return obj.intersectsSegment(polygon, x1, y1, x2, y2); }), allow_raw_pointers()) + .function("containsPoint", optional_override([](SkeletonBounds &obj, float x, float y) { + return obj.containsPoint(x, y); }),allow_raw_pointers()) + .function("containsPointPolygon", optional_override([](SkeletonBounds &obj,Polygon* polygon, float x, float y) { + return obj.containsPoint(polygon, x, y); }),allow_raw_pointers()) + .function("intersectsSegment", optional_override([](SkeletonBounds &obj, float x1, float y1, float x2, float y2){ + return obj.intersectsSegment(x1, y1, x2, y2); }),allow_raw_pointers()) + .function("intersectsSegmentPolygon", optional_override([](SkeletonBounds &obj,Polygon* polygon, + float x1, float y1, float x2, float y2){ + return obj.intersectsSegment(polygon, x1, y1, x2, y2); }),allow_raw_pointers()) .function("getPolygon", &SkeletonBounds::getPolygon, allow_raw_pointers()) .function("getWidth", &SkeletonBounds::getWidth) .function("getHeight", &SkeletonBounds::getHeight); class_("Event") .constructor() - .function("getData", optional_override([](Event &obj) { return const_cast(&obj.getData()); }), allow_raw_pointers()) + .function("getData", optional_override([](Event &obj) { + return const_cast(&obj.getData()); }), allow_raw_pointers()) .function("getIntValue", &Event::getIntValue) .function("setIntValue", &Event::setIntValue) .function("getFloatValue", &Event::getFloatValue) .function("setFloatValue", &Event::setFloatValue) - .function("getStringValue", optional_override([](Event &obj) { return STRING_SP2STD(obj.getStringValue()); })) - .function("setStringValue", optional_override([](Event &obj, const std::string &name) { return obj.setStringValue(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("getStringValue", optional_override([](Event &obj) { + return STRING_SP2STD(obj.getStringValue()); })) + .function("setStringValue", optional_override([](Event &obj, const std::string &name) { + return obj.setStringValue(STRING_STD2SP(name)); }), allow_raw_pointers()) .function("getTime", &Event::getTime) .function("getVolume", &Event::getVolume) .function("setVolume", &Event::setVolume) @@ -334,42 +578,47 @@ EMSCRIPTEN_BINDINGS(spine) { class_("EventData") .constructor() - .function("getName", optional_override([](EventData &obj) { return STRING_SP2STD(obj.getName()); })) + .function("getName", optional_override([](EventData &obj) { + return STRING_SP2STD(obj.getName()); })) .function("getIntValue", &EventData::getIntValue) .function("setIntValue", &EventData::setIntValue) .function("getFloatValue", &EventData::getFloatValue) .function("setFloatValue", &EventData::setFloatValue) - .function("getStringValue", optional_override([](EventData &obj) { return STRING_SP2STD(obj.getStringValue()); })) - .function("setStringValue", optional_override([](EventData &obj, const std::string &name) { return obj.setStringValue(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("getAudioPath", optional_override([](EventData &obj) { return STRING_SP2STD(obj.getAudioPath()); })) - .function("setAudioPath", optional_override([](EventData &obj, const std::string &name) { return obj.setAudioPath(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("getStringValue", optional_override([](EventData &obj) { + return STRING_SP2STD(obj.getStringValue()); })) + .function("setStringValue", optional_override([](EventData &obj, const std::string &name) { + return obj.setStringValue(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("getAudioPath", optional_override([](EventData &obj) { + return STRING_SP2STD(obj.getAudioPath()); })) + .function("setAudioPath", optional_override([](EventData &obj, const std::string &name) { + return obj.setAudioPath(STRING_STD2SP(name)); }), allow_raw_pointers()) .function("getVolume", &EventData::getVolume) .function("setVolume", &EventData::setVolume) .function("getBalance", &EventData::getBalance) .function("setBalance", &EventData::setBalance); class_("Attachment") - .function("getName", optional_override([](Attachment &obj) { return STRING_SP2STD(obj.getName()); })); + //.function("getName", optional_override([](Attachment &obj) { + // return emscripten::val(obj.getName().buffer()); })); + .function("getName", &Attachment::getName, allow_raw_pointers()); // pure_virtual and raw pointer class_>("VertexAttachment") .function("getId", &VertexAttachment::getId) - .function("getBones", optional_override([](VertexAttachment &obj) { return VECTOR_SP2STD_SIZE_T(obj.getBones()); }), allow_raw_pointers()) - .function("getVertices", optional_override([](VertexAttachment &obj) { return VECTOR_SP2STD(obj.getVertices()); }), allow_raw_pointers()) + .function("getBones", &VertexAttachment::getBones, allow_raw_pointer()) + .function("getVertices", &VertexAttachment::getVertices, allow_raw_pointer()) .function("getWorldVerticesLength", &VertexAttachment::getWorldVerticesLength) .function("setWorldVerticesLength", &VertexAttachment::setWorldVerticesLength) .function("getDeformAttachment", &VertexAttachment::getDeformAttachment, allow_raw_pointer()) .function("setDeformAttachment", &VertexAttachment::setDeformAttachment, allow_raw_pointer()) - .function("computeWorldVertices", optional_override([](VertexAttachment &obj, Slot &slot, size_t start, size_t count, std::vector worldVertices, size_t offset, size_t stride) { - auto spWorldVertices = VECTOR_STD2SP(worldVertices); - obj.computeWorldVertices(slot, start, count, spWorldVertices, offset, stride); - VECTOR_STD_COPY_SP(worldVertices, spWorldVertices); - })) + .function("computeWorldVertices", select_overload&, size_t, size_t)> + (&VertexAttachment::computeWorldVertices), allow_raw_pointer()) .function("copyTo", &VertexAttachment::copyTo, allow_raw_pointers()); class_>("BoundingBoxAttachment") .constructor() - .function("getName", optional_override([](BoundingBoxAttachment &obj) { return STRING_SP2STD(obj.getName()); })) + .function("getName", optional_override([](BoundingBoxAttachment &obj) { + return STRING_SP2STD(obj.getName()); })) .function("copy", &BoundingBoxAttachment::copy, allow_raw_pointers()); class_>("ClippingAttachment") @@ -380,21 +629,23 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("MeshAttachment") .constructor() - .function("getPath", optional_override([](MeshAttachment &obj) { return STRING_SP2STD(obj.getPath()); })) + .function("getPath", optional_override([](MeshAttachment &obj) { + return STRING_SP2STD(obj.getPath()); })) .function("setPath", optional_override([](MeshAttachment &obj, const std::string &path) { const String &pathSP = STRING_STD2SP(path); obj.setPath(pathSP); })) - .function("getRegionUVs", optional_override([](MeshAttachment &obj) { return VECTOR_SP2STD(obj.getRegionUVs()); })) - .function("getUVs", optional_override([](MeshAttachment &obj) { return VECTOR_SP2STD(obj.getUVs()); }), allow_raw_pointers()) - .function("getTriangles", optional_override([](MeshAttachment &obj) { return VECTOR_SP2STD(obj.getTriangles()); }), allow_raw_pointers()) - .function("getColor", optional_override([](MeshAttachment &obj) { return &obj.getColor(); }), allow_raw_pointers()) + .function("getRegionUVs", &MeshAttachment::getRegionUVs, allow_raw_pointer()) + .function("getUVs", &MeshAttachment::getUVs, allow_raw_pointer()) + .function("getTriangles", &MeshAttachment::getTriangles, allow_raw_pointer()) + .function("getColor", optional_override([](MeshAttachment &obj) { + return &obj.getColor(); }), allow_raw_pointers()) .function("getWidth", &MeshAttachment::getWidth) .function("setWidth", &MeshAttachment::setWidth) .function("getHeight", &MeshAttachment::getHeight) .function("setHeight", &MeshAttachment::setHeight) .function("getHullLength", &MeshAttachment::getHullLength) .function("setHullLength", &MeshAttachment::setHullLength) - .function("getEdges", optional_override([](MeshAttachment &obj) { return VECTOR_SP2STD(obj.getEdges()); })) + .function("getEdges", &MeshAttachment::getEdges, allow_raw_pointer()) .function("updateUVs", &MeshAttachment::updateUVs) .function("getParentMesh", &MeshAttachment::getParentMesh, allow_raw_pointers()) .function("setParentMesh", &MeshAttachment::setParentMesh, allow_raw_pointers()) @@ -403,7 +654,7 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("PathAttachment") .constructor() - .function("getLengths", optional_override([](PathAttachment &obj) { return VECTOR_SP2STD(obj.getLengths()); })) + .function("getLengths", &PathAttachment::getLengths, allow_raw_pointer()) .function("getClosed", &PathAttachment::isClosed) .function("setClosed", &PathAttachment::setClosed) .function("getConstantSpeed", &PathAttachment::isConstantSpeed) @@ -418,7 +669,8 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setY", &PointAttachment::setY) .function("getRotation", &PointAttachment::getRotation) .function("setRotation", &PointAttachment::setRotation) - .function("computeWorldPosition", optional_override([](PointAttachment &obj, Bone &bone, float ox, float oy) { obj.computeWorldPosition(bone, ox, oy); })) + .function("computeWorldPosition", optional_override([](PointAttachment &obj, Bone &bone, float ox, float oy) { + obj.computeWorldPosition(bone, ox, oy);})) .function("computeWorldRotation", &PointAttachment::computeWorldRotation) .function("copy", &PointAttachment::copy, allow_raw_pointers()); @@ -438,33 +690,20 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setWidth", &RegionAttachment::setWidth) .function("getHeight", &RegionAttachment::getHeight) .function("setHeight", &RegionAttachment::setHeight) - .function("getColor", optional_override([](RegionAttachment &obj) { return &obj.getColor(); }), allow_raw_pointers()) - .function("getPath", optional_override([](RegionAttachment &obj) { return STRING_SP2STD(obj.getPath()); })) + .function("getColor", optional_override([](RegionAttachment &obj) { + return &obj.getColor(); }), allow_raw_pointers()) + .function("getPath", optional_override([](RegionAttachment &obj) { + return STRING_SP2STD(obj.getPath()); })) .function("setPath", optional_override([](RegionAttachment &obj, const std::string &path) { const String &pathSP = STRING_STD2SP(path); obj.setPath(pathSP); })) .function("getRendererObject", &RegionAttachment::getRendererObject, allow_raw_pointers()) - .function("getOffset", optional_override([](RegionAttachment &obj) { return VECTOR_SP2STD(obj.getOffset()); }), allow_raw_pointers()) - .function("setUVs", optional_override([](RegionAttachment &obj, std::vector &data) { - auto uvs = obj.getUVs(); - int count = data.size(); - float u = count > 1 ? data[0] : uvs[0]; - float v = count > 2 ? data[1] : uvs[1]; - float u2 = count > 3 ? data[2] : uvs[2]; - float v2 = count > 4 ? data[3] : uvs[3]; - bool rotate = count > 5 ? (data[4] != 0) : false; - obj.setUVs(u, v, u2, v2, rotate); - }), - allow_raw_pointers()) - .function("getUVs", optional_override([](RegionAttachment &obj) { return VECTOR_SP2STD(obj.getUVs()); }), allow_raw_pointers()) + .function("getOffset", &RegionAttachment::getOffset, allow_raw_pointer()) + .function("setUVs", &RegionAttachment::setUVs) + .function("getUVs", &RegionAttachment::getUVs, allow_raw_pointer()) .function("updateOffset", &RegionAttachment::updateOffset) - .function("computeWorldVertices", optional_override([]( - RegionAttachment &obj, Bone &bone, std::vector worldVertices, - size_t offset, size_t stride) { - auto spWorldVertices = VECTOR_STD2SP(worldVertices); - obj.computeWorldVertices(bone, spWorldVertices, offset, stride); - VECTOR_STD_COPY_SP(worldVertices, spWorldVertices); - })) + .function("computeWorldVertices", select_overload&, size_t, size_t)> + (&RegionAttachment::computeWorldVertices), allow_raw_pointer()) .function("copy", &RegionAttachment::copy, allow_raw_pointer()); class_("AttachmentLoader") @@ -487,7 +726,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_("TextureAtlasPage") .constructor() - .function("getName", optional_override([](AtlasPage &obj) { return STRING_SP2STD((const String)obj.name); })) + .function("getName", optional_override([](AtlasPage &obj) { + return STRING_SP2STD((const String)obj.name); })) .property("minFilter", &AtlasPage::minFilter) .property("magFilter", &AtlasPage::magFilter) .property("uWrap", &AtlasPage::uWrap) @@ -498,17 +738,19 @@ EMSCRIPTEN_BINDINGS(spine) { class_("TextureAtlasRegion") //.property("page", &AtlasRegion::page) - .function("getName", optional_override([](AtlasRegion &obj) { return STRING_SP2STD((const String)obj.name); })) + .function("getName", optional_override([](AtlasRegion &obj) { + return STRING_SP2STD((const String)obj.name); })) .property("x", &AtlasRegion::x) .property("y", &AtlasRegion::y) .property("index", &AtlasRegion::index) .property("rotate", &AtlasRegion::rotate) .property("degrees", &AtlasRegion::degrees); - //.property("texture", &AtlasRegion::height) + //.property("texture", &AtlasRegion::height) class_("TextureAtlas") .constructor() - .function("findRegion", optional_override([](Atlas &obj, const std::string &name) { return obj.findRegion(STRING_STD2SP(name)); }), allow_raw_pointers()); + .function("findRegion", optional_override([](Atlas &obj, const std::string &name) { + return obj.findRegion(STRING_STD2SP(name)); }), allow_raw_pointers()); class_>("Pow") .constructor() @@ -518,21 +760,17 @@ EMSCRIPTEN_BINDINGS(spine) { .constructor() .function("apply", &PowInterpolation::apply); - // class_("Vector2") - // .constructor() - // .function("set", static_cast(&Vector2::set)) - // .function("length", &Vector2::length) - // .function("normalize", static_cast(&Vector2::normalize)) - // .property("x", &Vector2::x) - // .property("y", &Vector2::y); - class_("SlotData") .constructor() .function("getIndex", &SlotData::getIndex) - .function("getName", optional_override([](SlotData &obj) { return STRING_SP2STD(obj.getName()); })) - .function("getBoneData", optional_override([](SlotData &obj) { return &obj.getBoneData(); }), allow_raw_pointers()) - .function("getColor", optional_override([](SlotData &obj) { return &obj.getColor(); }), allow_raw_pointers()) - .function("getDarkColor", optional_override([](SlotData &obj) { return &obj.getDarkColor(); }), allow_raw_pointers()) + .function("getName", optional_override([](SlotData &obj) { + return STRING_SP2STD(obj.getName()); })) + .function("getBoneData", optional_override([](SlotData &obj) { + return &obj.getBoneData(); }), allow_raw_pointers()) + .function("getColor", optional_override([](SlotData &obj) { + return &obj.getColor();}), allow_raw_pointers()) + .function("getDarkColor", optional_override([](SlotData &obj) { + return &obj.getDarkColor();}), allow_raw_pointers()) .function("getBlendMode", &SlotData::getBlendMode) .function("setBlendMode", &SlotData::setBlendMode); @@ -542,8 +780,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("IkConstraint") .constructor() - .function("getData", optional_override([](IkConstraint &obj) { return &obj.getData(); }), allow_raw_pointers()) - .function("getBones", optional_override([](IkConstraint &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getData", &IkConstraint::getData, allow_raw_pointers()) + .function("getBones", &IkConstraint::getBones, allow_raw_pointer()) .function("getTarget", &IkConstraint::getTarget, allow_raw_pointer()) .function("setTarget", &IkConstraint::setTarget, allow_raw_pointer()) .function("getBendDirection", &IkConstraint::getBendDirection) @@ -562,20 +800,20 @@ EMSCRIPTEN_BINDINGS(spine) { .function("apply", static_cast(&IkConstraint::apply)) .function("update", &IkConstraint::update) .class_function("apply1", optional_override([]( - IkConstraint &obj, Bone &bone, float targetX, float targetY, - bool compress, bool stretch, bool uniform, float alpha) { - obj.apply(bone, targetX, targetY, compress, stretch, uniform, alpha); - })) + IkConstraint &obj, Bone &bone, float targetX, float targetY, + bool compress, bool stretch, bool uniform, float alpha){ + obj.apply(bone, targetX, targetY, compress, stretch, uniform, alpha); + })) .class_function("apply2", optional_override([]( - IkConstraint &obj, Bone &parent, Bone &child, float targetX, float targetY, - int bendDir, bool stretch, float softness, float alpha) { - obj.apply(parent, child, targetX, targetY, bendDir, stretch, softness, alpha); - })); + IkConstraint &obj, Bone &parent, Bone &child, float targetX, float targetY, + int bendDir, bool stretch, float softness, float alpha){ + obj.apply(parent, child, targetX, targetY, bendDir, stretch, softness, alpha); + })); class_>("PathConstraint") .constructor() - .function("getData", optional_override([](PathConstraint &obj) { return &obj.getData(); }), allow_raw_pointers()) - .function("getBones", optional_override([](PathConstraint &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getData", &PathConstraint::getData, allow_raw_pointers()) + .function("getBones", &PathConstraint::getBones, allow_raw_pointer()) .function("getTarget", &PathConstraint::getTarget, allow_raw_pointer()) .function("setTarget", &PathConstraint::setTarget, allow_raw_pointer()) .function("getPosition", &PathConstraint::getPosition) @@ -594,7 +832,7 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("TransformConstraintData") .constructor() - .function("getBones", optional_override([](TransformConstraintData &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getBones", &TransformConstraintData::getBones, allow_raw_pointer()) .function("getTarget", &TransformConstraintData::getTarget, allow_raw_pointers()) .function("getRotateMix", &TransformConstraintData::getRotateMix) .function("getTranslateMix", &TransformConstraintData::getTranslateMix) @@ -611,8 +849,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("TransformConstraint") .constructor() - .function("getData", optional_override([](TransformConstraint &obj) { return &obj.getData(); }), allow_raw_pointers()) - .function("getBones", optional_override([](TransformConstraint &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) + .function("getData", &TransformConstraint::getData, allow_raw_pointers()) + .function("getBones", &TransformConstraint::getBones, allow_raw_pointer()) .function("getTarget", &TransformConstraint::getTarget, allow_raw_pointers()) .function("getRotateMix", &TransformConstraint::getRotateMix) .function("setRotateMix", &TransformConstraint::setRotateMix) @@ -630,10 +868,13 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("Bone") .constructor() - .function("getData", optional_override([](Bone &obj) { return &obj.getData(); }), allow_raw_pointers()) - .function("getSkeleton", optional_override([](Bone &obj) { return &obj.getSkeleton(); }), allow_raw_pointers()) - .function("getParent", optional_override([](Bone &obj) { return obj.getParent(); }), allow_raw_pointers()) - .function("getChildren", optional_override([](Bone &obj) { return VECTOR_SP2STD(obj.getChildren()); }), allow_raw_pointers()) + .function("getData", optional_override([](Bone &obj) { + return &obj.getData(); }), allow_raw_pointers()) + .function("getSkeleton", optional_override([](Bone &obj) { + return &obj.getSkeleton(); }), allow_raw_pointers()) + .function("getParent", optional_override([](Bone &obj) { + return obj.getParent(); }), allow_raw_pointers()) + .function("getChildren", &Bone::getChildren, allow_raw_pointer()) .function("getX", &Bone::getX) .function("setX", &Bone::setX) .function("getY", &Bone::getY) @@ -686,19 +927,23 @@ EMSCRIPTEN_BINDINGS(spine) { .function("getWorldRotationX", &Bone::getWorldRotationX) .function("getWorldRotationY", &Bone::getWorldRotationY) .function("getWorldScaleX", &Bone::getWorldScaleX) - .function("getWorldScaleY", &Bone::getWorldScaleY) - .function("worldToLocal", optional_override([](Bone &obj, float a, float b) { - std::vector vec2(2); - obj.worldToLocal(a, b, vec2[0], vec2[1]); - return vec2; - }), - allow_raw_pointers()) - .function("localToWorld", optional_override([](Bone &obj, float a, float b) { - std::vector vec2(2); - obj.localToWorld(a, b, vec2[0], vec2[1]); - return vec2; - }), - allow_raw_pointers()) + .function("getWorldScaleY", &Bone::getWorldScaleY) + .function("worldToLocal", optional_override([](Bone &obj, Vector2 &vec2) { + float outLocalX, outLocalY; + obj.worldToLocal(vec2.x, vec2.y, outLocalX, outLocalY); + vec2.x = outLocalX; + vec2.y = outLocalY; + }), + allow_raw_pointers() + ) + .function("localToWorld", optional_override([](Bone &obj, Vector2 &vec2) { + float outWorldX, outWorldY; + obj.localToWorld(vec2.x, vec2.y, outWorldX, outWorldY); + vec2.x = outWorldX; + vec2.y = outWorldY; + }), + allow_raw_pointers() + ) .function("worldToLocalRotation", &Bone::worldToLocalRotation) .function("localToWorldRotation", &Bone::localToWorldRotation) .function("rotateWorld", &Bone::rotateWorld); @@ -731,12 +976,17 @@ EMSCRIPTEN_BINDINGS(spine) { class_("Slot") .constructor() - .function("getData", optional_override([](Slot &obj) { return &obj.getData(); }), allow_raw_pointers()) - .function("getBone", optional_override([](Slot &obj) { return &obj.getBone(); }), allow_raw_pointers()) - .function("getColor", optional_override([](Slot &obj) { return &obj.getColor(); }), allow_raw_pointers()) - .function("getDarkColor", optional_override([](Slot &obj) { return &obj.getDarkColor(); }), allow_raw_pointers()) - .function("getDeform", optional_override([](Slot &obj) { return VECTOR_SP2STD(obj.getDeform()); }), allow_raw_pointers()) - .function("getSkeleton", optional_override([](Slot &obj) { return &obj.getSkeleton(); }), allow_raw_pointers()) + .function("getData", optional_override([](Slot &obj) { + return &obj.getData(); }), allow_raw_pointers()) + .function("getBone", optional_override([](Slot &obj) { + return &obj.getBone(); }), allow_raw_pointers()) + .function("getColor", optional_override([](Slot &obj) { + return &obj.getColor(); }), allow_raw_pointers()) + .function("getDarkColor", optional_override([](Slot &obj) { + return &obj.getDarkColor(); }), allow_raw_pointers()) + .function("getDeform", &Slot::getDeform, allow_raw_pointers()) + .function("getSkeleton", optional_override([](Slot &obj) { + return &obj.getSkeleton(); }), allow_raw_pointers()) .function("getAttachment", &Slot::getAttachment, allow_raw_pointers()) .function("setAttachment", &Slot::setAttachment, allow_raw_pointers()) .function("setAttachmentTime", &Slot::setAttachmentTime) @@ -745,51 +995,50 @@ EMSCRIPTEN_BINDINGS(spine) { class_("Skin") .constructor() - .function("getName", optional_override([](Skin &obj) { return STRING_SP2STD(obj.getName()); })) - .function("getBones", optional_override([](Skin &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) - .function("getConstraints", optional_override([](Skin &obj) { return VECTOR_SP2STD(obj.getConstraints()); }), allow_raw_pointers()) - .function("setAttachment", optional_override([](Skin &obj, size_t index, const std::string &name, Attachment *attachment) { - return obj.setAttachment(index, STRING_STD2SP(name), attachment); - }), - allow_raw_pointers()) + .function("getName", optional_override([](Skin &obj) { + return STRING_SP2STD(obj.getName()); })) + .function("getBones", &Skin::getBones, allow_raw_pointer()) + .function("getConstraints", &Skin::getConstraints, allow_raw_pointer()) + .function("setAttachment", optional_override([](Skin &obj, size_t index, + const std::string &name, Attachment *attachment) { + return obj.setAttachment(index, STRING_STD2SP(name), attachment); + }), allow_raw_pointers()) .function("addSkin", select_overload(&Skin::addSkin), allow_raw_pointers()) .function("copySkin", select_overload(&Skin::copySkin), allow_raw_pointers()) .function("findNamesForSlot", optional_override([](Skin &obj, size_t slotIndex) { - std::vector vetNames; - std::vector entriesVector; - auto entries = obj.getAttachments(); - while (entries.hasNext()) { - Skin::AttachmentMap::Entry &entry = entries.next(); - if (entry._slotIndex == slotIndex) vetNames.push_back(STRING_SP2STD(entry._name)); - } - return vetNames; - }), - allow_raw_pointers()) - .function("getAttachment", optional_override([](Skin &obj, size_t slotIndex, const std::string &name) { - return obj.getAttachment(slotIndex, STRING_STD2SP(name)); - }), - allow_raw_pointers()) + std::vector vetNames; + std::vector entriesVector; + auto entries = obj.getAttachments(); + while (entries.hasNext()) { + Skin::AttachmentMap::Entry &entry = entries.next(); + if (entry._slotIndex == slotIndex) vetNames.push_back(STRING_SP2STD(entry._name)); + } + return vetNames; + }), allow_raw_pointers()) + .function("getAttachment", optional_override([](Skin &obj, size_t slotIndex, + const std::string &name) { + return obj.getAttachment(slotIndex, STRING_STD2SP(name)); + }), allow_raw_pointers()) .function("getAttachments", optional_override([](Skin &obj) { - std::vector entriesVector; - auto entries = obj.getAttachments(); - while (entries.hasNext()) { - entriesVector.push_back(&entries.next()); - } - return entriesVector; - }), - allow_raw_pointers()) + std::vector entriesVector; + auto entries = obj.getAttachments(); + while (entries.hasNext()) { + entriesVector.push_back(&entries.next()); + } + return entriesVector; + }),allow_raw_pointers()) .function("removeAttachment", optional_override([](Skin &obj, size_t index, - const std::string &name) { obj.removeAttachment(index, STRING_STD2SP(name)); })) + const std::string &name) { + obj.removeAttachment(index, STRING_STD2SP(name)); })) .function("getAttachmentsForSlot", optional_override([](Skin &obj, size_t index) { - std::vector entriesVector; - auto entries = obj.getAttachments(); - while (entries.hasNext()) { - Skin::AttachmentMap::Entry &entry = entries.next(); - if (entry._slotIndex == index) entriesVector.push_back(&entry); - } - return entriesVector; - }), - allow_raw_pointers()); + std::vector entriesVector; + auto entries = obj.getAttachments(); + while (entries.hasNext()) { + Skin::AttachmentMap::Entry &entry = entries.next(); + if (entry._slotIndex == index) entriesVector.push_back(&entry); + } + return entriesVector; + }),allow_raw_pointers()); class_("SkinEntry") .constructor() @@ -809,18 +1058,19 @@ EMSCRIPTEN_BINDINGS(spine) { class_("SkeletonData") .constructor<>() - .function("getName", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getName()); })) + .function("getName", optional_override([](SkeletonData &obj) { + return STRING_SP2STD(obj.getName()); })) .function("setName", &SkeletonData::setName) - .function("getBones", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) - .function("getSlots", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getSlots()); }), allow_raw_pointers()) - .function("getSkins", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getSkins()); }), allow_raw_pointers()) + .function("getBones", &SkeletonData::getBones, allow_raw_pointer()) + .function("getSlots", &SkeletonData::getSlots, allow_raw_pointer()) + .function("getSkins", &SkeletonData::getSkins, allow_raw_pointer()) .function("getDefaultSkin", &SkeletonData::getDefaultSkin, allow_raw_pointers()) .function("setDefaultSkin", &SkeletonData::setDefaultSkin, allow_raw_pointers()) - .function("getEvents", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getEvents()); }), allow_raw_pointers()) - .function("getAnimations", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getAnimations()); }), allow_raw_pointers()) - .function("getIkConstraints", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getIkConstraints()); }), allow_raw_pointers()) - .function("getTransformConstraints", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getTransformConstraints()); }), allow_raw_pointers()) - .function("getPathConstraints", optional_override([](SkeletonData &obj) { return VECTOR_SP2STD(obj.getPathConstraints()); }), allow_raw_pointers()) + .function("getEvents", &SkeletonData::getEvents, allow_raw_pointer()) + .function("getAnimations", &SkeletonData::getAnimations, allow_raw_pointer()) + .function("getIkConstraints", &SkeletonData::getIkConstraints, allow_raw_pointer()) + .function("getTransformConstraints", &SkeletonData::getTransformConstraints, allow_raw_pointer()) + .function("getPathConstraints", &SkeletonData::getPathConstraints, allow_raw_pointer()) .function("getX", &SkeletonData::getX) .function("setX", &SkeletonData::setX) .function("getY", &SkeletonData::getY) @@ -829,56 +1079,73 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setWidth", &SkeletonData::setWidth) .function("getHeight", &SkeletonData::getHeight) .function("setHeight", &SkeletonData::setHeight) - .function("getVersion", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getVersion()); })) + .function("getVersion", optional_override([](SkeletonData &obj) { + return STRING_SP2STD(obj.getVersion()); })) .function("setVersion", &SkeletonData::setVersion) - .function("getHash", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getHash()); })) + .function("getHash", optional_override([](SkeletonData &obj) { + return STRING_SP2STD(obj.getHash()); })) .function("setHash", &SkeletonData::setHash) .function("getFps", &SkeletonData::getFps) .function("setFps", &SkeletonData::setFps) - .function("getImagesPath", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getImagesPath()); })) + .function("getImagesPath", optional_override([](SkeletonData &obj) { + return STRING_SP2STD(obj.getImagesPath()); })) .function("setImagesPath", &SkeletonData::setImagesPath) - .function("getAudioPath", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getAudioPath()); })) + .function("getAudioPath", optional_override([](SkeletonData &obj) { + return STRING_SP2STD(obj.getAudioPath()); })) .function("setAudioPath", &SkeletonData::setAudioPath) - .function("findBone", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findBone(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findBoneIndex", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findBoneIndex(STRING_STD2SP(name)); })) - .function("findSlot", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findSlot(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findSlotIndex", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findSlotIndex(STRING_STD2SP(name)); })) - .function("findSkin", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findSkin(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findEvent", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findEvent(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findAnimation", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findAnimation(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findIkConstraint", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findIkConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findTransformConstraint", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findTransformConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findPathConstraint", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findPathConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findPathConstraintIndex", optional_override([](SkeletonData &obj, const std::string &name) { return obj.findPathConstraintIndex(STRING_STD2SP(name)); })); + .function("findBone", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findBone(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findBoneIndex", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findBoneIndex(STRING_STD2SP(name)); })) + .function("findSlot", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findSlot(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findSlotIndex", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findSlotIndex(STRING_STD2SP(name)); })) + .function("findSkin", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findSkin(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findEvent", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findEvent(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findAnimation", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findAnimation(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findIkConstraint", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findIkConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findTransformConstraint", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findTransformConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findPathConstraint", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findPathConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) + .function("findPathConstraintIndex", optional_override([](SkeletonData &obj, const std::string &name) { + return obj.findPathConstraintIndex(STRING_STD2SP(name)); })); class_("Animation") .constructor &, float>() .function("apply", optional_override([](Animation &obj, Skeleton &skeleton, - float lastTime, float time, bool loop, std::vector &stdPEvents, float alpha, - MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, loop, &pEvents, alpha, blend, direction); - })) + float lastTime, float time, bool loop, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, loop, &pEvents, alpha, blend, direction); + })) .function("getName", optional_override([](Animation &obj) { return STRING_SP2STD(obj.getName()); })) - .function("getTimelines", optional_override([](Animation &obj) { return VECTOR_SP2STD(obj.getTimelines()); }), allow_raw_pointers()) + .function("getTimelines", &Animation::getTimelines, allow_raw_pointer()) .function("hasTimeline", &Animation::hasTimeline) .function("getDuration", &Animation::getDuration) .function("setDuration", &Animation::setDuration); class_("Timeline") - .function("apply", optional_override([](Timeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - pure_virtual()) + .function("apply", optional_override([](Timeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), pure_virtual()) .function("getPropertyId", &Timeline::getPropertyId, pure_virtual()); class_>("CurveTimeline") - .function("apply", optional_override([](CurveTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - pure_virtual()) + .function("apply", optional_override([](CurveTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), pure_virtual()) .function("getPropertyId", &CurveTimeline::getPropertyId, pure_virtual()) .function("getFrameCount", &CurveTimeline::getFrameCount) .function("setLinear", &CurveTimeline::setLinear) @@ -892,57 +1159,62 @@ EMSCRIPTEN_BINDINGS(spine) { .class_property("ENTRIES", &TranslateTimeline::ENTRIES) .function("getPropertyId", &TranslateTimeline::getPropertyId) .function("setFrame", &TranslateTimeline::setFrame) - .function("apply", optional_override([](TranslateTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](TranslateTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("ScaleTimeline") .constructor() .function("getPropertyId", &ScaleTimeline::getPropertyId) - .function("apply", optional_override([](ScaleTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](ScaleTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("ShearTimeline") .constructor() .function("getPropertyId", &ShearTimeline::getPropertyId) - .function("apply", optional_override([](ShearTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](ShearTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("RotateTimeline") .constructor() //.class_property("ENTRIES", &RotateTimeline::ENTRIES) not bind .function("getBoneIndex", &RotateTimeline::getBoneIndex) .function("setBoneIndex", &RotateTimeline::setBoneIndex) - .function("getFrames", optional_override([](RotateTimeline &obj) { return VECTOR_SP2STD(obj.getFrames()); }), allow_raw_pointers()) + .function("getFrames", &RotateTimeline::getFrames, allow_raw_pointer()) .function("getPropertyId", &RotateTimeline::getPropertyId) .function("setFrame", &RotateTimeline::setFrame) - .function("apply", optional_override([](RotateTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](RotateTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("ColorTimeline") .constructor() - .class_property("ENTRIES", &ColorTimeline::ENTRIES) + .class_property("ENTRIES", &ColorTimeline::ENTRIES) .function("getSlotIndex", &ColorTimeline::getSlotIndex) .function("setSlotIndex", &ColorTimeline::setSlotIndex) - .function("getFrames", optional_override([](ColorTimeline &obj) { return VECTOR_SP2STD(obj.getFrames()); }), allow_raw_pointers()) + .function("getFrames", &ColorTimeline::getFrames, allow_raw_pointer()) .function("getPropertyId", &ColorTimeline::getPropertyId) .function("setFrame", &ColorTimeline::setFrame) - .function("apply", optional_override([](ColorTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](ColorTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("TwoColorTimeline") .constructor() @@ -951,32 +1223,33 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setSlotIndex", &TwoColorTimeline::setSlotIndex) .function("getPropertyId", &TwoColorTimeline::getPropertyId) .function("setFrame", &TwoColorTimeline::setFrame) - .function("apply", optional_override([](TwoColorTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](TwoColorTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("AttachmentTimeline") .constructor() .function("getSlotIndex", &AttachmentTimeline::getSlotIndex) .function("setSlotIndex", &AttachmentTimeline::setSlotIndex) - .function("getFrames", optional_override([](AttachmentTimeline &obj) { return VECTOR_SP2STD((Vector &)obj.getFrames()); }), allow_raw_pointers()) - .function("getAttachmentNames", optional_override([](AttachmentTimeline &obj) { + .function("getFrames", &AttachmentTimeline::getFrames, allow_raw_pointer()) + .function("getAttachmentNames",optional_override([](AttachmentTimeline &obj) { Vector attachmentNames = obj.getAttachmentNames(); return VECTOR_SP2STD_STRING(attachmentNames); }), allow_raw_pointers()) .function("getPropertyId", &AttachmentTimeline::getPropertyId) .function("getFrameCount", &AttachmentTimeline::getFrameCount) - .function("setFrame", optional_override([](AttachmentTimeline &obj, int frameIndex, float time, const std::string &attachmentName) { - const String attachmentNameSP = STRING_STD2SP(attachmentName); - obj.setFrame(frameIndex, time, attachmentNameSP); - }), - allow_raw_pointers()) - .function("apply", optional_override([](AttachmentTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("setFrame", optional_override([](AttachmentTimeline &obj, int frameIndex, float time, const std::string &attachmentName){ + const String attachmentNameSP = STRING_STD2SP(attachmentName); + obj.setFrame(frameIndex, time, attachmentNameSP); + }), allow_raw_pointers()) + .function("apply", optional_override([](AttachmentTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("DeformTimeline") .constructor() @@ -984,95 +1257,94 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setSlotIndex", &DeformTimeline::setSlotIndex) .function("getAttachment", &DeformTimeline::getAttachment, allow_raw_pointers()) .function("setAttachment", &DeformTimeline::setAttachment, allow_raw_pointers()) - .function("getFrames", optional_override([](DeformTimeline &obj) { return VECTOR_SP2STD((Vector &)obj.getFrames()); })) - .function("getFrameVertices", optional_override([](DeformTimeline &obj) { - return VECTOR_2_SP2STD(obj.getVertices()); - }), - allow_raw_pointers()) + .function("getFrames", &DeformTimeline::getFrames, allow_raw_pointer()) + .function("getFrameVertices", &DeformTimeline::getVertices, allow_raw_pointer()) .function("getPropertyId", &DeformTimeline::getPropertyId) - .function("setFrame", optional_override([](DeformTimeline &obj, int frameIndex, float time, std::vector &vertices) { - Vector sp_vertices = VECTOR_STD2SP(vertices); - obj.setFrame(frameIndex, time, sp_vertices); - }), - allow_raw_pointers()) - .function("apply", optional_override([](DeformTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("setFrame", optional_override([](DeformTimeline &obj, int frameIndex, float time, std::vector &vertices){ + Vector sp_vertices = VECTOR_STD2SP(vertices); + obj.setFrame(frameIndex, time, sp_vertices); + }), allow_raw_pointers()) + .function("apply", optional_override([](DeformTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("EventTimeline") .constructor() - .function("getFrames", optional_override([](EventTimeline &obj) { return VECTOR_SP2STD2(obj.getFrames()); })) - .function("getEvents", optional_override([](EventTimeline &obj) { return VECTOR_SP2STD(obj.getEvents()); }), allow_raw_pointers()) + .function("getFrames", &EventTimeline::getFrames, allow_raw_pointer()) + .function("getEvents", &EventTimeline::getEvents, allow_raw_pointer()) .function("getPropertyId", &EventTimeline::getPropertyId) .function("getFrameCount", &EventTimeline::getFrameCount) .function("setFrame", &EventTimeline::setFrame, allow_raw_pointers()) - .function("apply", optional_override([](EventTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](EventTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("DrawOrderTimeline") .constructor() - .function("getFrames", optional_override([](DrawOrderTimeline &obj) { return VECTOR_SP2STD(obj.getFrames()); })) + .function("getFrames", &DrawOrderTimeline::getFrames, allow_raw_pointer()) .function("getPropertyId", &DrawOrderTimeline::getPropertyId) .function("getFrameCount", &DrawOrderTimeline::getFrameCount) - .function("getDrawOrders", optional_override([](DrawOrderTimeline &obj) { - auto drawOrders = obj.getDrawOrders(); - return VECTOR_2_SP2STD(drawOrders); - }), - allow_raw_pointers()) + .function("getDrawOrders", &DrawOrderTimeline::getDrawOrders, allow_raw_pointer()) .function("setFrame", &DrawOrderTimeline::setFrame, allow_raw_pointers()) - .function("apply", optional_override([](DrawOrderTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](DrawOrderTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("IkConstraintTimeline") .constructor() .class_property("ENTRIES", &IkConstraintTimeline::ENTRIES) .function("getPropertyId", &IkConstraintTimeline::getPropertyId) .function("setFrame", &IkConstraintTimeline::setFrame) - .function("apply", optional_override([](IkConstraintTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](IkConstraintTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("TransformConstraintTimeline") .constructor() .class_property("ENTRIES", &TransformConstraintTimeline::ENTRIES) .function("getPropertyId", &TransformConstraintTimeline::getPropertyId) .function("setFrame", &TransformConstraintTimeline::setFrame) - .function("apply", optional_override([](TransformConstraintTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](TransformConstraintTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("PathConstraintPositionTimeline") .constructor() .class_property("ENTRIES", &TransformConstraintTimeline::ENTRIES) .function("getPropertyId", &PathConstraintPositionTimeline::getPropertyId) .function("setFrame", &PathConstraintPositionTimeline::setFrame) - .function("apply", optional_override([](PathConstraintPositionTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](PathConstraintPositionTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_>("PathConstraintMixTimeline") .constructor() .class_property("ENTRIES", &PathConstraintMixTimeline::ENTRIES) .function("getPropertyId", &PathConstraintMixTimeline::getPropertyId) - .function("apply", optional_override([](PathConstraintMixTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, MixBlend blend, MixDirection direction) { - auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); - obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); - }), - allow_raw_pointers()); + .function("apply", optional_override([](PathConstraintMixTimeline &obj, Skeleton &skeleton, + float lastTime, float time, std::vector &stdPEvents, float alpha, + MixBlend blend, MixDirection direction) { + auto pEvents = VECTOR_STD2SP_POINTER(stdPEvents); + obj.apply(skeleton, lastTime, time, &pEvents, alpha, blend, direction); + }), allow_raw_pointers()); class_("TrackEntry") .constructor<>() @@ -1132,14 +1404,16 @@ EMSCRIPTEN_BINDINGS(spine) { .function("getDefaultMix", &AnimationStateData::getDefaultMix) .function("setDefaultMix", &AnimationStateData::setDefaultMix) .function("getSkeletonData", &AnimationStateData::getSkeletonData, allow_raw_pointers()) - .function("setMix", optional_override([](AnimationStateData &obj, const std::string &fromName, const std::string &toName, float duration) { return obj.setMix(STRING_STD2SP(fromName), STRING_STD2SP(toName), duration); })) - .function("setMixWith", optional_override([](AnimationStateData &obj, Animation *from, Animation *to, float duration) { return obj.setMix(from, to, duration); }), allow_raw_pointers()) + .function("setMix", optional_override([](AnimationStateData &obj, const std::string& fromName, const std::string& toName, float duration) { + return obj.setMix(STRING_STD2SP(fromName), STRING_STD2SP(toName), duration);})) + .function("setMixWith", optional_override([](AnimationStateData &obj, Animation* from, Animation* to, float duration) { + return obj.setMix(from, to, duration);}), allow_raw_pointers()) .function("getMix", &AnimationStateData::getMix, allow_raw_pointers()); class_("AnimationState") .constructor() .function("getData", &AnimationState::getData, allow_raw_pointers()) - .function("getTracks", optional_override([](AnimationState &obj) { return VECTOR_SP2STD(obj.getTracks()); }), allow_raw_pointers()) + .function("getTracks", &AnimationState::getTracks, allow_raw_pointer()) .function("getTimeScale", &AnimationState::getTimeScale) .function("setTimeScale", &AnimationState::setTimeScale) .function("update", &AnimationState::update) @@ -1154,13 +1428,15 @@ EMSCRIPTEN_BINDINGS(spine) { .function("addEmptyAnimation", &AnimationState::addEmptyAnimation, allow_raw_pointers()) .function("setEmptyAnimations", &AnimationState::setEmptyAnimations) .function("getCurrent", &AnimationState::getCurrent, allow_raw_pointer()) - .function("setListener", optional_override([](AnimationState &obj, AnimationStateListener inValue) { obj.setListener(inValue); }), allow_raw_pointers()) - .function("setListenerObject", optional_override([](AnimationState &obj, AnimationStateListenerObject *inValue) { obj.setListener(inValue); }), allow_raw_pointers()) + .function("setListener", optional_override([](AnimationState &obj, AnimationStateListener inValue) { + obj.setListener(inValue); }),allow_raw_pointers()) + .function("setListenerObject", optional_override([](AnimationState &obj, AnimationStateListenerObject *inValue) { + obj.setListener(inValue); }),allow_raw_pointers()) .function("disableQueue", &AnimationState::disableQueue) .function("enableQueue", &AnimationState::enableQueue); - //.function("addListener", &AnimationState::addListener) - //.function("removeListener", &AnimationState::removeListener) - //.function("clearListeners", &AnimationState::clearListeners) // no have clearListeners + //.function("addListener", &AnimationState::addListener) + //.function("removeListener", &AnimationState::removeListener) + //.function("clearListeners", &AnimationState::clearListeners) // no have clearListeners //private // class_("EventQueue") @@ -1185,15 +1461,16 @@ EMSCRIPTEN_BINDINGS(spine) { class_("Skeleton") .constructor() .function("getData", &Skeleton::getData, allow_raw_pointer()) - .function("getBones", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getBones()); }), allow_raw_pointers()) - .function("getSlots", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getSlots()); }), allow_raw_pointers()) - .function("getDrawOrder", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getDrawOrder()); }), allow_raw_pointers()) - .function("getIkConstraints", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getIkConstraints()); }), allow_raw_pointers()) - .function("getTransformConstraints", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getTransformConstraints()); }), allow_raw_pointers()) - .function("getPathConstraints", optional_override([](Skeleton &obj) { return VECTOR_SP2STD(obj.getPathConstraints()); }), allow_raw_pointers()) + .function("getBones", &Skeleton::getBones, allow_raw_pointer()) + .function("getSlots", &Skeleton::getSlots, allow_raw_pointer()) + .function("getDrawOrder", &Skeleton::getDrawOrder, allow_raw_pointer()) + .function("getIkConstraints", &Skeleton::getIkConstraints, allow_raw_pointer()) + .function("getTransformConstraints", &Skeleton::getTransformConstraints, allow_raw_pointer()) + .function("getPathConstraints", &Skeleton::getPathConstraints, allow_raw_pointer()) .function("getUpdateCacheList", &Skeleton::getUpdateCacheList, allow_raw_pointer()) .function("getSkin", &Skeleton::getSkin, allow_raw_pointer()) - .function("getColor", optional_override([](Skeleton &obj) { return &obj.getColor(); }), allow_raw_pointers()) + .function("getColor", optional_override([](Skeleton &obj){ + return &obj.getColor(); }), allow_raw_pointers()) .function("getTime", &Skeleton::getTime) .function("setTime", &Skeleton::setTime) .function("getScaleX", &Skeleton::getScaleX) @@ -1210,15 +1487,23 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setBonesToSetupPose", &Skeleton::setBonesToSetupPose) .function("setSlotsToSetupPose", &Skeleton::setSlotsToSetupPose) .function("getRootBone", &Skeleton::getRootBone, allow_raw_pointer()) - .function("findBone", optional_override([](Skeleton &obj, const std::string &name) { return obj.findBone(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findBoneIndex", optional_override([](Skeleton &obj, const std::string &name) { return obj.findBoneIndex(STRING_STD2SP(name)); })) - .function("findSlot", optional_override([](Skeleton &obj, const std::string &name) { return obj.findSlot(STRING_STD2SP(name)); }), allow_raw_pointers()) - .function("findSlotIndex", optional_override([](Skeleton &obj, const std::string &name) { return obj.findSlotIndex(STRING_STD2SP(name)); })) - .function("setSkinByName", optional_override([](Skeleton &obj, const std::string &name) { return obj.setSkin(STRING_STD2SP(name)); })) + .function("findBone", optional_override([](Skeleton &obj, const std::string& name) { + return obj.findBone(STRING_STD2SP(name));}), allow_raw_pointers()) + .function("findBoneIndex", optional_override([](Skeleton &obj, const std::string& name) { + return obj.findBoneIndex(STRING_STD2SP(name));})) + .function("findSlot", optional_override([](Skeleton &obj, const std::string& name) { + return obj.findSlot(STRING_STD2SP(name));}), allow_raw_pointers()) + .function("findSlotIndex", optional_override([](Skeleton &obj, const std::string& name) { + return obj.findSlotIndex(STRING_STD2SP(name));})) + .function("setSkinByName", optional_override([](Skeleton &obj, const std::string& name) { + return obj.setSkin(STRING_STD2SP(name));})) .function("setSkin", static_cast(&Skeleton::setSkin), allow_raw_pointer()) - .function("getAttachmentByName", optional_override([](Skeleton &obj, const std::string &slotName, const std::string &attachmentName) { return obj.getAttachment(STRING_STD2SP(slotName), STRING_STD2SP(attachmentName)); }), allow_raw_pointers()) - .function("getAttachment", optional_override([](Skeleton &obj, int slotIndex, const std::string &attachmentName) { return obj.getAttachment(slotIndex, STRING_STD2SP(attachmentName)); }), allow_raw_pointers()) - .function("setAttachment", optional_override([](Skeleton &obj, const std::string &slotName, const std::string &attachmentName) { return obj.setAttachment(STRING_STD2SP(slotName), STRING_STD2SP(attachmentName)); })) + .function("getAttachmentByName", optional_override([](Skeleton &obj, const std::string& slotName, const std::string& attachmentName) { + return obj.getAttachment(STRING_STD2SP(slotName), STRING_STD2SP(attachmentName));}), allow_raw_pointers()) + .function("getAttachment", optional_override([](Skeleton &obj, int slotIndex, const std::string& attachmentName) { + return obj.getAttachment(slotIndex, STRING_STD2SP(attachmentName));}),allow_raw_pointers()) + .function("setAttachment", optional_override([](Skeleton &obj, const std::string& slotName, const std::string& attachmentName) { + return obj.setAttachment(STRING_STD2SP(slotName), STRING_STD2SP(attachmentName));})) .function("findIkConstraint", optional_override([](Skeleton &obj, const std::string &name) { return obj.findIkConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) .function("findTransformConstraint", optional_override([](Skeleton &obj, const std::string &name) { return obj.findTransformConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) .function("findPathConstraint", optional_override([](Skeleton &obj, const std::string &name) { return obj.findPathConstraint(STRING_STD2SP(name)); }), allow_raw_pointers()) @@ -1242,7 +1527,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_("VertexEffect") .function("begin", &VertexEffect::begin, pure_virtual()) - .function("transform", optional_override([](VertexEffect &obj, float x, float y) { obj.transform(x, y); }), pure_virtual()) + .function("transform", optional_override([](VertexEffect &obj, float x, float y) { + obj.transform(x, y); }), pure_virtual()) .function("end", &VertexEffect::end, pure_virtual()); class_>("JitterEffect") @@ -1252,13 +1538,15 @@ EMSCRIPTEN_BINDINGS(spine) { .function("getJitterY", &JitterVertexEffect::getJitterY) .function("setJitterY", &JitterVertexEffect::setJitterY) .function("begin", &JitterVertexEffect::begin) - .function("transform", optional_override([](VertexEffect &obj, float x, float y) { obj.transform(x, y); }), pure_virtual()) + .function("transform", optional_override([](VertexEffect &obj, float x, float y) { + obj.transform(x, y); }), pure_virtual()) .function("end", &JitterVertexEffect::end); class_>("SwirlEffect") .constructor() .function("begin", &SwirlVertexEffect::begin) - .function("transform", optional_override([](VertexEffect &obj, float x, float y) { obj.transform(x, y); }), pure_virtual()) + .function("transform", optional_override([](VertexEffect &obj, float x, float y) { + obj.transform(x, y); }), pure_virtual()) .function("end", &SwirlVertexEffect::end) .function("getCenterX", &SwirlVertexEffect::getCenterX) .function("setCenterX", &SwirlVertexEffect::setCenterX) @@ -1285,7 +1573,8 @@ EMSCRIPTEN_BINDINGS(spine) { .property("iCount", &SpineModel::iCount) .property("vPtr", &SpineModel::vPtr) .property("iPtr", &SpineModel::iPtr) - .function("getMeshes", &SpineModel::getMeshes); + .function("getData", &SpineModel::getData, allow_raw_pointer>()); + //.function("getMeshes", &SpineModel::getMeshes, allow_raw_pointer>()); class_("SpineDebugShape") .property("type", &SpineDebugShape::type) @@ -1297,6 +1586,10 @@ EMSCRIPTEN_BINDINGS(spine) { register_vector("VectorDebugShape"); class_("SkeletonInstance") .constructor<>() + .property("isCache", &SpineSkeletonInstance::isCache) + .property("dtRate", &SpineSkeletonInstance::dtRate) + .property("isDelete", &SpineSkeletonInstance::isDelete) + .property("enable", &SpineSkeletonInstance::enable) .function("initSkeleton", &SpineSkeletonInstance::initSkeleton, allow_raw_pointers()) .function("setAnimation", &SpineSkeletonInstance::setAnimation, allow_raw_pointers()) .function("setSkin", &SpineSkeletonInstance::setSkin) @@ -1315,21 +1608,26 @@ EMSCRIPTEN_BINDINGS(spine) { .function("getDebugShapes", &SpineSkeletonInstance::getDebugShapes) .function("resizeSlotRegion", &SpineSkeletonInstance::resizeSlotRegion) .function("setSlotTexture", &SpineSkeletonInstance::setSlotTexture); + + class_("SkeletonSystem") + .class_function("getCount", &SpineSkeletonSystem::getCount) + .class_function("updateAnimation", &SpineSkeletonSystem::updateAnimation) + .class_function("updateRenderData", &SpineSkeletonSystem::updateRenderData); } EMSCRIPTEN_BINDINGS(cocos_spine) { class_("SpineWasmUtil") - .class_function("spineWasmInit", &SpineWasmUtil::spineWasmInit) - .class_function("spineWasmDestroy", &SpineWasmUtil::spineWasmDestroy) - .class_function("queryStoreMemory", &SpineWasmUtil::queryStoreMemory) - .class_function("querySpineSkeletonDataByUUID", &SpineWasmUtil::querySpineSkeletonDataByUUID, allow_raw_pointers()) - .class_function("createSpineSkeletonDataWithJson", &SpineWasmUtil::createSpineSkeletonDataWithJson, allow_raw_pointers()) - .class_function("createSpineSkeletonDataWithBinary", &SpineWasmUtil::createSpineSkeletonDataWithBinary, allow_raw_pointers()) - .class_function("registerSpineSkeletonDataWithUUID", &SpineWasmUtil::registerSpineSkeletonDataWithUUID, allow_raw_pointers()) - .class_function("destroySpineSkeletonDataWithUUID", &SpineWasmUtil::destroySpineSkeletonDataWithUUID) - .class_function("destroySpineInstance", &SpineWasmUtil::destroySpineInstance, allow_raw_pointers()) - .class_function("getCurrentListenerID", &SpineWasmUtil::getCurrentListenerID) - .class_function("getCurrentEventType", &SpineWasmUtil::getCurrentEventType) - .class_function("getCurrentTrackEntry", &SpineWasmUtil::getCurrentTrackEntry, allow_raw_pointers()) - .class_function("getCurrentEvent", &SpineWasmUtil::getCurrentEvent, allow_raw_pointers()); + .class_function("spineWasmInit", &SpineWasmUtil::spineWasmInit) + .class_function("spineWasmDestroy", &SpineWasmUtil::spineWasmDestroy) + .class_function("queryStoreMemory", &SpineWasmUtil::queryStoreMemory) + .class_function("querySpineSkeletonDataByUUID", &SpineWasmUtil::querySpineSkeletonDataByUUID, allow_raw_pointers()) + .class_function("createSpineSkeletonDataWithJson", &SpineWasmUtil::createSpineSkeletonDataWithJson, allow_raw_pointers()) + .class_function("createSpineSkeletonDataWithBinary", &SpineWasmUtil::createSpineSkeletonDataWithBinary, allow_raw_pointers()) + .class_function("registerSpineSkeletonDataWithUUID", &SpineWasmUtil::registerSpineSkeletonDataWithUUID, allow_raw_pointers()) + .class_function("destroySpineSkeletonDataWithUUID", &SpineWasmUtil::destroySpineSkeletonDataWithUUID) + .class_function("destroySpineInstance", &SpineWasmUtil::destroySpineInstance, allow_raw_pointers()) + .class_function("getCurrentListenerID", &SpineWasmUtil::getCurrentListenerID) + .class_function("getCurrentEventType", &SpineWasmUtil::getCurrentEventType) + .class_function("getCurrentTrackEntry", &SpineWasmUtil::getCurrentTrackEntry, allow_raw_pointers()) + .class_function("getCurrentEvent", &SpineWasmUtil::getCurrentEvent, allow_raw_pointers()); } diff --git a/native/cocos/editor-support/spine-wasm/spine-wasm.cpp b/native/cocos/editor-support/spine-wasm/spine-wasm.cpp index bea63bc7adb..273e83fc59e 100644 --- a/native/cocos/editor-support/spine-wasm/spine-wasm.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-wasm.cpp @@ -84,8 +84,9 @@ void SpineWasmUtil::destroySpineSkeletonDataWithUUID(const std::string& uuid) { void SpineWasmUtil::destroySpineInstance(SpineSkeletonInstance* instance) { if (instance) { - delete instance; - instance = nullptr; + //delete instance; + instance->isDelete = true; + //instance = nullptr; } } diff --git a/native/cocos/editor-support/spine/Skin.h b/native/cocos/editor-support/spine/Skin.h index 2fd2eb5cf6a..7ce6574e18b 100644 --- a/native/cocos/editor-support/spine/Skin.h +++ b/native/cocos/editor-support/spine/Skin.h @@ -55,7 +55,7 @@ class SP_API Skin : public SpineObject { size_t _slotIndex; String _name; Attachment *_attachment; - + //Entry(); Entry(size_t slotIndex, const String &name, Attachment *attachment) : _slotIndex(slotIndex), _name(name), _attachment(attachment) { From 385f7eb971919338b55e6cdad7b481c02c35091e Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 14:58:57 +0800 Subject: [PATCH 02/18] Optimize array swapping from WASM to TS. --- cocos/spine/lib/spine-core.d.ts | 1 - cocos/spine/lib/spine-define.ts | 63 ++++--- .../spine-wasm/spine-type-export.cpp | 160 +++++++++++++----- .../editor-support/spine/EventTimeline.cpp | 2 +- .../editor-support/spine/EventTimeline.h | 2 +- 5 files changed, 149 insertions(+), 79 deletions(-) diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index 0efbaa4bf3f..ed509b26781 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -1155,7 +1155,6 @@ declare namespace spine { updateOffset(): void; computeWorldVertices(bone: Bone, worldVertices: ArrayLike, offset: number, stride: number): void; copy(): Attachment; - private _uvs: ArrayLike | undefined; } class JitterEffect implements VertexEffect { jitterX: number; diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index 03b7bb3a545..56afb9e83a2 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -26,20 +26,28 @@ import spine from './spine-core.js'; import { js } from '../../core'; -import { array, value } from 'cocos/core/utils/js.js'; +import { array } from 'cocos/core/utils/js.js'; + + +function resizeArray(array, newSize) { + if (newSize == array.length) return array; + if (newSize < array.length) return array.slice(0, newSize); + else return new Array(newSize); +} + +function getVectorArray(self: any, array: any, getPropVector: any) { + const vectors = getPropVector.call(self); + const count = vectors.size(); + array = resizeArray(array, count); + for (let i = 0; i < count; i++) array[i] = vectors.get(i); + return array; +} function overrideDefineArrayProp (prototype: any, getPropVector: any, name: string): void { + let array : any[] = new Array(100); Object.defineProperty(prototype, name, { get (): any[] { - const array: any[] = []; - const vectors = getPropVector.call(this); - const count = vectors.size(); - for (let i = 0; i < count; i++) { - const objPtr = vectors.get(i); - array.push(objPtr); - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return array; + return getVectorArray(this, array, getPropVector); }, }); } @@ -66,17 +74,10 @@ function overrideDefineArrayArrayProp (prototype: any, getPropVector: any, name: } function overrideDefineArrayFunction (prototype: any, getPropVector: any, name: string): void { + let array : any[] = new Array(100); Object.defineProperty(prototype, name, { value () { - const array: any[] = []; - const vectors = getPropVector.call(this); - const count = vectors.size(); - for (let i = 0; i < count; i++) { - const objPtr = vectors.get(i); - array.push(objPtr); - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return array; + return getVectorArray(this, array, getPropVector); }, }); } @@ -792,13 +793,14 @@ function overrideProperty_RegionAttachment (): void { overrideDefineArrayProp(prototype, prototype.getOffset, 'offset'); const getUVs = prototype.getUVs; const setUVs = prototype.setUVs; + let uvs = new Array(8); Object.defineProperty(prototype, 'uvs', { get (): any { - if(this._uvs == undefined) this._uvs = new Array(8); const vectors = getUVs.call(this); const count = vectors.size(); - for (let i = 0; i < count; i++) this._uvs[i] = vectors.get(i); - return this._uvs; + uvs = resizeArray(uvs, count); + for (let i = 0; i < count; i++) uvs[i] = vectors.get(i); + return uvs; }, set (value: number[]) { setUVs.call(this, value[0], value[1], value[2], value[3], value[4] == 1); @@ -1319,27 +1321,24 @@ function overrideProperty_Skin (): void { overrideDefineArrayProp(prototype, prototype.getAttachments, 'attachments'); overrideDefineArrayProp(prototype, prototype.getConstraints, 'constraints'); overrideDefineArrayFunction(prototype, prototype.getAttachments, 'getAttachments'); - const originGetAttachmentsForSlot = prototype.getAttachmentsForSlot; + const originGetAttachmentsForSlot = prototype.getAttachmentsForSlot; Object.defineProperty(prototype, 'getAttachmentsForSlot', { value (slotIndex: number, attachments: Array) { const vectors = originGetAttachmentsForSlot.call(this, slotIndex); const count = vectors.size(); - for (let i = 0; i < count; i++) { - const objPtr = vectors.get(i); - attachments.push(objPtr); - } + attachments = resizeArray(attachments, count); + for (let i = 0; i < count; i++) attachments[i] = vectors.get(i); vectors.delete(); }, }); const originFindNamesForSlot = prototype.findNamesForSlot; + const names = new Array(5); Object.defineProperty(prototype, 'findNamesForSlot', { value (slotIndex: number, names: Array) { const vectors = originFindNamesForSlot.call(this, slotIndex); const count = vectors.size(); - for (let i = 0; i < count; i++) { - const objPtr = vectors.get(i); - names.push(objPtr); - } + names = resizeArray(names, count); + for (let i = 0; i < count; i++) names[i] = vectors.get(i); vectors.delete(); }, }); @@ -1813,7 +1812,7 @@ function overrideProperty_Skeleton (): void { overrideDefineArrayProp(prototype, prototype.getIkConstraints, 'ikConstraints'); overrideDefineArrayProp(prototype, prototype.getTransformConstraints, 'transformConstraints'); overrideDefineArrayProp(prototype, prototype.getPathConstraints, 'pathConstraints'); - overrideDefineArrayProp(prototype, prototype.getUpdateCache, '_updateCache'); + overrideDefineArrayProp(prototype, prototype.getUpdateCacheList, '_updateCache'); } function overrideProperty_JitterEffect (): void { diff --git a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp index c435a162b54..9119d74fd44 100644 --- a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp @@ -109,6 +109,7 @@ using SPVectorFloat = Vector; using SPVectorVectorFloat = Vector>; using SPVectorInt = Vector; using SPVectorVectorInt = Vector>; +using SPVectorSize_t = Vector; using SPVectorBonePtr = Vector; using SPVectorBoneDataPtr = Vector; using SPVectorUnsignedShort = Vector; @@ -192,6 +193,24 @@ EMSCRIPTEN_BINDINGS(spine) { obj[index] = value; })); + class_("SPVectorSize_t") + .constructor<>() + .function("resize", &SPVectorSize_t::setSize) + .function("size", &SPVectorSize_t::size) + .function("get", &SPVectorSize_t::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorSize_t &obj, size_t index, size_t value) { + obj[index] = value; + })); + + class_("SPVectorUnsignedShort") + .constructor<>() + .function("resize", &SPVectorUnsignedShort::setSize) + .function("size", &SPVectorUnsignedShort::size) + .function("get", &SPVectorUnsignedShort::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorUnsignedShort &obj, int index, int value) { + obj[index] = value; + })); + class_("SPVectorBonePtr") .constructor<>() .function("resize", &SPVectorBonePtr::setSize) @@ -309,6 +328,15 @@ EMSCRIPTEN_BINDINGS(spine) { obj[index] = value; }), allow_raw_pointer()); + class_("SPVectorUpdatablePtr") + .constructor<>() + .function("resize", &SPVectorUpdatablePtr::setSize) + .function("size", &SPVectorUpdatablePtr::size) + .function("get", &SPVectorUpdatablePtr::operator[], allow_raw_pointers()) + .function("set",optional_override([](SPVectorUpdatablePtr &obj, int index, Updatable *value) { + obj[index] = value; + }), allow_raw_pointer()); + class_("Vector2") .constructor<>() @@ -502,7 +530,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("IkConstraintData") .constructor() - .function("getBones", &IkConstraintData::getBones, allow_raw_pointer()) + .function("getBones", optional_override([](IkConstraintData &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &IkConstraintData::getTarget, allow_raw_pointer()) .function("setTarget", &IkConstraintData::setTarget, allow_raw_pointer()) .function("getBendDirection", &IkConstraintData::getBendDirection) @@ -520,7 +549,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("PathConstraintData") .constructor() - .function("getBones", &PathConstraintData::getBones, allow_raw_pointer()) + .function("getBones",optional_override([](PathConstraintData &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &PathConstraintData::getTarget, allow_raw_pointer()) .function("setTarget", &PathConstraintData::setTarget, allow_raw_pointer()) .function("getPositionMode", &PathConstraintData::getPositionMode) @@ -605,8 +635,10 @@ EMSCRIPTEN_BINDINGS(spine) { // pure_virtual and raw pointer class_>("VertexAttachment") .function("getId", &VertexAttachment::getId) - .function("getBones", &VertexAttachment::getBones, allow_raw_pointer()) - .function("getVertices", &VertexAttachment::getVertices, allow_raw_pointer()) + .function("getBones", optional_override([](VertexAttachment &obj){ + return &obj.getBones(); }), allow_raw_pointer()) + .function("getVertices", optional_override([](VertexAttachment &obj){ + return &obj.getVertices(); }), allow_raw_pointer()) .function("getWorldVerticesLength", &VertexAttachment::getWorldVerticesLength) .function("setWorldVerticesLength", &VertexAttachment::setWorldVerticesLength) .function("getDeformAttachment", &VertexAttachment::getDeformAttachment, allow_raw_pointer()) @@ -634,9 +666,12 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setPath", optional_override([](MeshAttachment &obj, const std::string &path) { const String &pathSP = STRING_STD2SP(path); obj.setPath(pathSP); })) - .function("getRegionUVs", &MeshAttachment::getRegionUVs, allow_raw_pointer()) - .function("getUVs", &MeshAttachment::getUVs, allow_raw_pointer()) - .function("getTriangles", &MeshAttachment::getTriangles, allow_raw_pointer()) + .function("getRegionUVs", optional_override([](MeshAttachment &obj) { + return &obj.getRegionUVs(); }), allow_raw_pointer()) + .function("getUVs", optional_override([](MeshAttachment &obj) { + return &obj.getUVs(); }), allow_raw_pointer()) + .function("getTriangles", optional_override([](MeshAttachment &obj) { + return &obj.getTriangles(); }), allow_raw_pointer()) .function("getColor", optional_override([](MeshAttachment &obj) { return &obj.getColor(); }), allow_raw_pointers()) .function("getWidth", &MeshAttachment::getWidth) @@ -645,7 +680,8 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setHeight", &MeshAttachment::setHeight) .function("getHullLength", &MeshAttachment::getHullLength) .function("setHullLength", &MeshAttachment::setHullLength) - .function("getEdges", &MeshAttachment::getEdges, allow_raw_pointer()) + .function("getEdges", optional_override([](MeshAttachment &obj) { + return &obj.getEdges(); }), allow_raw_pointer()) .function("updateUVs", &MeshAttachment::updateUVs) .function("getParentMesh", &MeshAttachment::getParentMesh, allow_raw_pointers()) .function("setParentMesh", &MeshAttachment::setParentMesh, allow_raw_pointers()) @@ -654,7 +690,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("PathAttachment") .constructor() - .function("getLengths", &PathAttachment::getLengths, allow_raw_pointer()) + .function("getLengths", optional_override([](PathAttachment &obj) { + return &obj.getLengths(); }), allow_raw_pointer()) .function("getClosed", &PathAttachment::isClosed) .function("setClosed", &PathAttachment::setClosed) .function("getConstantSpeed", &PathAttachment::isConstantSpeed) @@ -698,9 +735,11 @@ EMSCRIPTEN_BINDINGS(spine) { const String &pathSP = STRING_STD2SP(path); obj.setPath(pathSP); })) .function("getRendererObject", &RegionAttachment::getRendererObject, allow_raw_pointers()) - .function("getOffset", &RegionAttachment::getOffset, allow_raw_pointer()) + .function("getOffset", optional_override([](RegionAttachment &obj) { + return &obj.getOffset(); }), allow_raw_pointer()) .function("setUVs", &RegionAttachment::setUVs) - .function("getUVs", &RegionAttachment::getUVs, allow_raw_pointer()) + .function("getUVs", optional_override([](RegionAttachment &obj) { + return &obj.getUVs(); }), allow_raw_pointer()) .function("updateOffset", &RegionAttachment::updateOffset) .function("computeWorldVertices", select_overload&, size_t, size_t)> (&RegionAttachment::computeWorldVertices), allow_raw_pointer()) @@ -781,7 +820,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("IkConstraint") .constructor() .function("getData", &IkConstraint::getData, allow_raw_pointers()) - .function("getBones", &IkConstraint::getBones, allow_raw_pointer()) + .function("getBones", optional_override([](IkConstraint &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &IkConstraint::getTarget, allow_raw_pointer()) .function("setTarget", &IkConstraint::setTarget, allow_raw_pointer()) .function("getBendDirection", &IkConstraint::getBendDirection) @@ -813,7 +853,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("PathConstraint") .constructor() .function("getData", &PathConstraint::getData, allow_raw_pointers()) - .function("getBones", &PathConstraint::getBones, allow_raw_pointer()) + .function("getBones", optional_override([](PathConstraint &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &PathConstraint::getTarget, allow_raw_pointer()) .function("setTarget", &PathConstraint::setTarget, allow_raw_pointer()) .function("getPosition", &PathConstraint::getPosition) @@ -832,7 +873,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("TransformConstraintData") .constructor() - .function("getBones", &TransformConstraintData::getBones, allow_raw_pointer()) + .function("getBones", optional_override([](TransformConstraintData &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &TransformConstraintData::getTarget, allow_raw_pointers()) .function("getRotateMix", &TransformConstraintData::getRotateMix) .function("getTranslateMix", &TransformConstraintData::getTranslateMix) @@ -850,7 +892,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("TransformConstraint") .constructor() .function("getData", &TransformConstraint::getData, allow_raw_pointers()) - .function("getBones", &TransformConstraint::getBones, allow_raw_pointer()) + .function("getBones", optional_override([](TransformConstraint &obj) { + return &obj.getBones(); }), allow_raw_pointer()) .function("getTarget", &TransformConstraint::getTarget, allow_raw_pointers()) .function("getRotateMix", &TransformConstraint::getRotateMix) .function("setRotateMix", &TransformConstraint::setRotateMix) @@ -874,7 +917,8 @@ EMSCRIPTEN_BINDINGS(spine) { return &obj.getSkeleton(); }), allow_raw_pointers()) .function("getParent", optional_override([](Bone &obj) { return obj.getParent(); }), allow_raw_pointers()) - .function("getChildren", &Bone::getChildren, allow_raw_pointer()) + .function("getChildren", optional_override([](Bone &obj) { + return &obj.getChildren(); }), allow_raw_pointer()) .function("getX", &Bone::getX) .function("setX", &Bone::setX) .function("getY", &Bone::getY) @@ -997,8 +1041,10 @@ EMSCRIPTEN_BINDINGS(spine) { .constructor() .function("getName", optional_override([](Skin &obj) { return STRING_SP2STD(obj.getName()); })) - .function("getBones", &Skin::getBones, allow_raw_pointer()) - .function("getConstraints", &Skin::getConstraints, allow_raw_pointer()) + .function("getBones", optional_override([](Skin &obj) { + return &obj.getBones(); }), allow_raw_pointer()) + .function("getConstraints", optional_override([](Skin &obj) { + return &obj.getConstraints(); }), allow_raw_pointer()) .function("setAttachment", optional_override([](Skin &obj, size_t index, const std::string &name, Attachment *attachment) { return obj.setAttachment(index, STRING_STD2SP(name), attachment); @@ -1061,16 +1107,24 @@ EMSCRIPTEN_BINDINGS(spine) { .function("getName", optional_override([](SkeletonData &obj) { return STRING_SP2STD(obj.getName()); })) .function("setName", &SkeletonData::setName) - .function("getBones", &SkeletonData::getBones, allow_raw_pointer()) - .function("getSlots", &SkeletonData::getSlots, allow_raw_pointer()) - .function("getSkins", &SkeletonData::getSkins, allow_raw_pointer()) + .function("getBones", optional_override([](SkeletonData &obj) { + return &obj.getBones(); }), allow_raw_pointer()) + .function("getSlots", optional_override([](SkeletonData &obj) { + return &obj.getSlots(); }), allow_raw_pointer()) + .function("getSkins", optional_override([](SkeletonData &obj) { + return &obj.getSkins(); }), allow_raw_pointer()) .function("getDefaultSkin", &SkeletonData::getDefaultSkin, allow_raw_pointers()) .function("setDefaultSkin", &SkeletonData::setDefaultSkin, allow_raw_pointers()) - .function("getEvents", &SkeletonData::getEvents, allow_raw_pointer()) - .function("getAnimations", &SkeletonData::getAnimations, allow_raw_pointer()) - .function("getIkConstraints", &SkeletonData::getIkConstraints, allow_raw_pointer()) - .function("getTransformConstraints", &SkeletonData::getTransformConstraints, allow_raw_pointer()) - .function("getPathConstraints", &SkeletonData::getPathConstraints, allow_raw_pointer()) + .function("getEvents", optional_override([](SkeletonData &obj) { + return &obj.getEvents(); }), allow_raw_pointer()) + .function("getAnimations", optional_override([](SkeletonData &obj) { + return &obj.getAnimations(); }), allow_raw_pointer()) + .function("getIkConstraints", optional_override([](SkeletonData &obj) { + return &obj.getIkConstraints(); }), allow_raw_pointer()) + .function("getTransformConstraints", optional_override([](SkeletonData &obj) { + return &obj.getTransformConstraints(); }), allow_raw_pointer()) + .function("getPathConstraints", optional_override([](SkeletonData &obj) { + return &obj.getPathConstraints(); }), allow_raw_pointer()) .function("getX", &SkeletonData::getX) .function("setX", &SkeletonData::setX) .function("getY", &SkeletonData::getY) @@ -1125,7 +1179,8 @@ EMSCRIPTEN_BINDINGS(spine) { obj.apply(skeleton, lastTime, time, loop, &pEvents, alpha, blend, direction); })) .function("getName", optional_override([](Animation &obj) { return STRING_SP2STD(obj.getName()); })) - .function("getTimelines", &Animation::getTimelines, allow_raw_pointer()) + .function("getTimelines", optional_override([](Animation &obj) { + return &obj.getTimelines(); }), allow_raw_pointer()) .function("hasTimeline", &Animation::hasTimeline) .function("getDuration", &Animation::getDuration) .function("setDuration", &Animation::setDuration); @@ -1191,7 +1246,8 @@ EMSCRIPTEN_BINDINGS(spine) { //.class_property("ENTRIES", &RotateTimeline::ENTRIES) not bind .function("getBoneIndex", &RotateTimeline::getBoneIndex) .function("setBoneIndex", &RotateTimeline::setBoneIndex) - .function("getFrames", &RotateTimeline::getFrames, allow_raw_pointer()) + .function("getFrames", optional_override([](RotateTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) .function("getPropertyId", &RotateTimeline::getPropertyId) .function("setFrame", &RotateTimeline::setFrame) .function("apply", optional_override([](RotateTimeline &obj, Skeleton &skeleton, @@ -1206,7 +1262,8 @@ EMSCRIPTEN_BINDINGS(spine) { .class_property("ENTRIES", &ColorTimeline::ENTRIES) .function("getSlotIndex", &ColorTimeline::getSlotIndex) .function("setSlotIndex", &ColorTimeline::setSlotIndex) - .function("getFrames", &ColorTimeline::getFrames, allow_raw_pointer()) + .function("getFrames", optional_override([](ColorTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) .function("getPropertyId", &ColorTimeline::getPropertyId) .function("setFrame", &ColorTimeline::setFrame) .function("apply", optional_override([](ColorTimeline &obj, Skeleton &skeleton, @@ -1234,7 +1291,8 @@ EMSCRIPTEN_BINDINGS(spine) { .constructor() .function("getSlotIndex", &AttachmentTimeline::getSlotIndex) .function("setSlotIndex", &AttachmentTimeline::setSlotIndex) - .function("getFrames", &AttachmentTimeline::getFrames, allow_raw_pointer()) + .function("getFrames", optional_override([](AttachmentTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) .function("getAttachmentNames",optional_override([](AttachmentTimeline &obj) { Vector attachmentNames = obj.getAttachmentNames(); return VECTOR_SP2STD_STRING(attachmentNames); }), allow_raw_pointers()) @@ -1257,8 +1315,10 @@ EMSCRIPTEN_BINDINGS(spine) { .function("setSlotIndex", &DeformTimeline::setSlotIndex) .function("getAttachment", &DeformTimeline::getAttachment, allow_raw_pointers()) .function("setAttachment", &DeformTimeline::setAttachment, allow_raw_pointers()) - .function("getFrames", &DeformTimeline::getFrames, allow_raw_pointer()) - .function("getFrameVertices", &DeformTimeline::getVertices, allow_raw_pointer()) + .function("getFrames", optional_override([](DeformTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) + .function("getFrameVertices", optional_override([](DeformTimeline &obj) { + return &obj.getVertices(); }), allow_raw_pointer()) .function("getPropertyId", &DeformTimeline::getPropertyId) .function("setFrame", optional_override([](DeformTimeline &obj, int frameIndex, float time, std::vector &vertices){ Vector sp_vertices = VECTOR_STD2SP(vertices); @@ -1273,8 +1333,10 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("EventTimeline") .constructor() - .function("getFrames", &EventTimeline::getFrames, allow_raw_pointer()) - .function("getEvents", &EventTimeline::getEvents, allow_raw_pointer()) + .function("getFrames", optional_override([](EventTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) + .function("getEvents", optional_override([](EventTimeline &obj) { + return &obj.getEvents(); }), allow_raw_pointer()) .function("getPropertyId", &EventTimeline::getPropertyId) .function("getFrameCount", &EventTimeline::getFrameCount) .function("setFrame", &EventTimeline::setFrame, allow_raw_pointers()) @@ -1287,10 +1349,12 @@ EMSCRIPTEN_BINDINGS(spine) { class_>("DrawOrderTimeline") .constructor() - .function("getFrames", &DrawOrderTimeline::getFrames, allow_raw_pointer()) + .function("getFrames", optional_override([](DrawOrderTimeline &obj) { + return &obj.getFrames(); }), allow_raw_pointer()) .function("getPropertyId", &DrawOrderTimeline::getPropertyId) .function("getFrameCount", &DrawOrderTimeline::getFrameCount) - .function("getDrawOrders", &DrawOrderTimeline::getDrawOrders, allow_raw_pointer()) + .function("getDrawOrders", optional_override([](DrawOrderTimeline &obj) { + return &obj.getDrawOrders(); }), allow_raw_pointer()) .function("setFrame", &DrawOrderTimeline::setFrame, allow_raw_pointers()) .function("apply", optional_override([](DrawOrderTimeline &obj, Skeleton &skeleton, float lastTime, float time, std::vector &stdPEvents, float alpha, @@ -1413,7 +1477,8 @@ EMSCRIPTEN_BINDINGS(spine) { class_("AnimationState") .constructor() .function("getData", &AnimationState::getData, allow_raw_pointers()) - .function("getTracks", &AnimationState::getTracks, allow_raw_pointer()) + .function("getTracks", optional_override([](AnimationState &obj) { + return &obj.getTracks(); }), allow_raw_pointer()) .function("getTimeScale", &AnimationState::getTimeScale) .function("setTimeScale", &AnimationState::setTimeScale) .function("update", &AnimationState::update) @@ -1461,13 +1526,20 @@ EMSCRIPTEN_BINDINGS(spine) { class_("Skeleton") .constructor() .function("getData", &Skeleton::getData, allow_raw_pointer()) - .function("getBones", &Skeleton::getBones, allow_raw_pointer()) - .function("getSlots", &Skeleton::getSlots, allow_raw_pointer()) - .function("getDrawOrder", &Skeleton::getDrawOrder, allow_raw_pointer()) - .function("getIkConstraints", &Skeleton::getIkConstraints, allow_raw_pointer()) - .function("getTransformConstraints", &Skeleton::getTransformConstraints, allow_raw_pointer()) - .function("getPathConstraints", &Skeleton::getPathConstraints, allow_raw_pointer()) - .function("getUpdateCacheList", &Skeleton::getUpdateCacheList, allow_raw_pointer()) + .function("getBones", optional_override([](Skeleton &obj){ + return &obj.getBones(); }), allow_raw_pointer()) + .function("getSlots", optional_override([](Skeleton &obj){ + return &obj.getSlots(); }), allow_raw_pointer()) + .function("getDrawOrder", optional_override([](Skeleton &obj){ + return &obj.getDrawOrder(); }), allow_raw_pointer()) + .function("getIkConstraints", optional_override([](Skeleton &obj){ + return &obj.getIkConstraints(); }), allow_raw_pointer()) + .function("getTransformConstraints", optional_override([](Skeleton &obj){ + return &obj.getTransformConstraints(); }), allow_raw_pointer()) + .function("getPathConstraints", optional_override([](Skeleton &obj){ + return &obj.getPathConstraints(); }), allow_raw_pointer()) + .function("getUpdateCacheList", optional_override([](Skeleton &obj){ + return &obj.getUpdateCacheList(); }), allow_raw_pointer()) .function("getSkin", &Skeleton::getSkin, allow_raw_pointer()) .function("getColor", optional_override([](Skeleton &obj){ return &obj.getColor(); }), allow_raw_pointers()) diff --git a/native/cocos/editor-support/spine/EventTimeline.cpp b/native/cocos/editor-support/spine/EventTimeline.cpp index 05c44587689..c3f01276355 100644 --- a/native/cocos/editor-support/spine/EventTimeline.cpp +++ b/native/cocos/editor-support/spine/EventTimeline.cpp @@ -103,7 +103,7 @@ void EventTimeline::setFrame(size_t frameIndex, Event *event) { _events[frameIndex] = event; } -Vector EventTimeline::getFrames() { return _frames; } +Vector &EventTimeline::getFrames() { return _frames; } Vector &EventTimeline::getEvents() { return _events; } diff --git a/native/cocos/editor-support/spine/EventTimeline.h b/native/cocos/editor-support/spine/EventTimeline.h index 42d569d6ede..17fe1958eb0 100644 --- a/native/cocos/editor-support/spine/EventTimeline.h +++ b/native/cocos/editor-support/spine/EventTimeline.h @@ -51,7 +51,7 @@ class SP_API EventTimeline : public Timeline { /// Sets the time and value of the specified keyframe. void setFrame(size_t frameIndex, Event* event); - Vector getFrames(); + Vector& getFrames(); Vector& getEvents(); size_t getFrameCount(); From e6723c680120e12ba27f7228b037b07a6473d118 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 15:00:01 +0800 Subject: [PATCH 03/18] add cached objects to avoid duplication Create arrays. --- cocos/spine/lib/spine-define.ts | 53 +++++++++++-------- .../editor-support/spine-wasm/CMakeLists.txt | 4 +- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index 56afb9e83a2..f617db5083d 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -30,43 +30,45 @@ import { array } from 'cocos/core/utils/js.js'; function resizeArray(array, newSize) { + if (!array) return new Array(newSize); if (newSize == array.length) return array; if (newSize < array.length) return array.slice(0, newSize); else return new Array(newSize); } -function getVectorArray(self: any, array: any, getPropVector: any) { - const vectors = getPropVector.call(self); - const count = vectors.size(); - array = resizeArray(array, count); - for (let i = 0; i < count; i++) array[i] = vectors.get(i); - return array; -} - function overrideDefineArrayProp (prototype: any, getPropVector: any, name: string): void { - let array : any[] = new Array(100); + const _name = `_${name}`; Object.defineProperty(prototype, name, { get (): any[] { - return getVectorArray(this, array, getPropVector); + const vectors = getPropVector.call(this); + const count = vectors.size(); + let array = this[_name]; + array = resizeArray(array, count); + //if (array[0]) return array; + for (let i = 0; i < count; i++) array[i] = vectors.get(i); + this[_name] = array; + return array; }, }); } function overrideDefineArrayArrayProp (prototype: any, getPropVector: any, name: string): void { + const _name = `_${name}`; Object.defineProperty(prototype, name, { get (): any[] { - const array: any[] = []; const vectors = getPropVector.call(this); const count = vectors.size(); + let array = this[_name]; + array = resizeArray(array, count); for (let i = 0; i < count; i++) { const vectorI = vectors.get(i); const countJ = vectorI.size(); - const arrayJ: any[] = []; - for (let j = 0; j < countJ; j++) { - arrayJ.push(vectorI.get(j)); - } - array.push(arrayJ); + let arrayJ: any[] = array[i]; + arrayJ = resizeArray(arrayJ, countJ); + for (let j = 0; j < countJ; j++) arrayJ[j] = vectorI.get(j); + array[i] = arrayJ; } + this[_name] = array; // eslint-disable-next-line @typescript-eslint/no-unsafe-return return array; }, @@ -74,10 +76,16 @@ function overrideDefineArrayArrayProp (prototype: any, getPropVector: any, name: } function overrideDefineArrayFunction (prototype: any, getPropVector: any, name: string): void { - let array : any[] = new Array(100); + const _name = `_${name}`; Object.defineProperty(prototype, name, { value () { - return getVectorArray(this, array, getPropVector); + const vectors = getPropVector.call(this); + const count = vectors.size(); + let array = this[_name]; + array = resizeArray(array, count); + for (let i = 0; i < count; i++) array[i] = vectors.get(i); + this[_name] = array; + return array; }, }); } @@ -793,13 +801,15 @@ function overrideProperty_RegionAttachment (): void { overrideDefineArrayProp(prototype, prototype.getOffset, 'offset'); const getUVs = prototype.getUVs; const setUVs = prototype.setUVs; - let uvs = new Array(8); + const _uvs = '_uvs'; Object.defineProperty(prototype, 'uvs', { get (): any { const vectors = getUVs.call(this); const count = vectors.size(); - uvs = resizeArray(uvs, count); - for (let i = 0; i < count; i++) uvs[i] = vectors.get(i); + let array = prototype[_uvs]; + array = resizeArray(array, count); + for (let i = 0; i < count; i++) array[i] = vectors.get(i); + prototype[_uvs] = array; return uvs; }, set (value: number[]) { @@ -1332,7 +1342,6 @@ function overrideProperty_Skin (): void { }, }); const originFindNamesForSlot = prototype.findNamesForSlot; - const names = new Array(5); Object.defineProperty(prototype, 'findNamesForSlot', { value (slotIndex: number, names: Array) { const vectors = originFindNamesForSlot.call(this, slotIndex); diff --git a/native/cocos/editor-support/spine-wasm/CMakeLists.txt b/native/cocos/editor-support/spine-wasm/CMakeLists.txt index b76f1dcadc1..5b4a24b9fcd 100644 --- a/native/cocos/editor-support/spine-wasm/CMakeLists.txt +++ b/native/cocos/editor-support/spine-wasm/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_BUILD_TYPE "Debug") +set(CMAKE_BUILD_TYPE "Release") set(APP_NAME "spine" CACHE STRING "Project Name") project(${APP_NAME}_wasm) @@ -21,7 +21,7 @@ file(GLOB COCOS_ADAPTER_SRC "./*.cpp") add_executable(${APP_NAME} ${SPINE_CORE_SRC} ${COCOS_ADAPTER_SRC} ) #add_executable(${APP_NAME} ${COCOS_ADAPTER_SRC}) -set(EMS_LINK_FLAGS "-00 -g3 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ +set(EMS_LINK_FLAGS "-03 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ -flto --no-entry --bind -s USE_ES6_IMPORT_META=0 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORT_NAME='spineWasm' \ -s ENVIRONMENT=web -s FILESYSTEM=0 -s NO_EXIT_RUNTIME=1 -s LLD_REPORT_UNDEFINED \ -s MIN_SAFARI_VERSION=110000 \ From c38202c399bf56776eb0e421a800743c77af98f6 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 15:00:29 +0800 Subject: [PATCH 04/18] Fix cache mode & edit mode display exception. --- cocos/spine/assembler/simple.ts | 40 ++++--------------- cocos/spine/lib/spine-define.ts | 2 +- cocos/spine/skeleton-cache.ts | 12 ++++++ cocos/spine/skeleton-system.ts | 3 +- cocos/spine/skeleton.ts | 2 +- .../spine-wasm/spine-type-export.cpp | 1 + 6 files changed, 25 insertions(+), 35 deletions(-) diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index 81b6036bf83..a3f631f779c 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -149,11 +149,12 @@ function updateComponentRenderData (comp: Skeleton, batcher: Batcher2D): void { } function realTimeTraverse (comp: Skeleton): void { - const floatStride = (_useTint ? _byteStrideTwoColor : _byteStrideOneColor) / Float32Array.BYTES_PER_ELEMENT; + const floatStride = (comp.useTint ? _byteStrideTwoColor : _byteStrideOneColor) / Float32Array.BYTES_PER_ELEMENT; const model = comp.updateRenderData(); - if (!model) return; const vc = model.vCount as number; const ic = model.iCount as number; + if (vc < 1 || ic < 1) return; + const rd = comp.renderData!; if (rd.vertexCount !== vc || rd.indexCount !== ic) { rd.resize(vc, ic); @@ -163,15 +164,16 @@ function realTimeTraverse (comp: Skeleton): void { comp._iLength = Uint16Array.BYTES_PER_ELEMENT * ic; comp._iBuffer = new Uint8Array(rd.indices.buffer); } - if (vc < 1 || ic < 1) return; + let vbuf = rd.chunk.vb; const vPtr = model.vPtr; - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; - comp._vBuffer?.set(HEAPU8.subarray(vPtr, vPtr + comp._vLength), 0); const iPtr = model.iPtr; const ibuf = rd.indices!; + const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; + + comp._vBuffer?.set(HEAPU8.subarray(vPtr, vPtr + comp._vLength), 0); comp._iBuffer?.set(HEAPU8.subarray(iPtr, iPtr + comp._iLength), 0); + const chunkOffset = rd.chunk.vertexOffset; for (let i = 0; i < ic; i++) ibuf[i] += chunkOffset; @@ -187,31 +189,6 @@ function realTimeTraverse (comp: Skeleton): void { indexOffset += indexCount; } - /* - const meshes = model.getMeshes(); - const count = meshes.size(); - let indexOffset = 0; - let indexCount = 0; - for (let i = 0; i < count; i++) { - const mesh = meshes.get(i); - const material = _getSlotMaterial(mesh.blendMode, comp); - const textureID = mesh.textureID; - indexCount = mesh.iCount; - comp.requestDrawData(material, textureID, indexOffset, indexCount); - indexOffset += indexCount; - } - */ - /* - let indexOffset = 0; - let indexCount = 0; - for (let i = 0; i < 1; i++) { - const material = _getSlotMaterial(0, comp); - const textureID = 0 - indexCount = 1029; - comp.requestDrawData(material, textureID, indexOffset, indexCount); - indexOffset += indexCount; - } - */ // if enableBatch apply worldMatrix if (comp.enableBatch) { const worldMat = comp.node.worldMatrix; @@ -360,7 +337,6 @@ function cacheTraverse (comp: Skeleton): void { if (comp.enableBatch) { const worldMat = comp.node.worldMatrix; let index = 0; - const tempVecPos = new Vec3(0, 0, 0); for (let i = 0; i < vc; i++) { index = i * floatStride; tempVecPos.x = vbuf[index]; diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index f617db5083d..e0786a8d62a 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -810,7 +810,7 @@ function overrideProperty_RegionAttachment (): void { array = resizeArray(array, count); for (let i = 0; i < count; i++) array[i] = vectors.get(i); prototype[_uvs] = array; - return uvs; + return array; }, set (value: number[]) { setUVs.call(this, value[0], value[1], value[2], value[3], value[4] == 1); diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index 290c231578b..da69a273846 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -189,6 +189,7 @@ export class AnimationCache { modelData.vData = vUint8Buf; modelData.iData = iUint16Buf; + /* const meshes = model.getMeshes(); const count = meshes.size(); for (let i = 0; i < count; i++) { @@ -199,6 +200,17 @@ export class AnimationCache { meshData.textureID = mesh.textureID; modelData.meshes.push(meshData); } + */ + + const data = model.getData(); + const count = data.size(); + for (let i = 0; i < count; i += 6) { + const meshData = new SpineDrawItem(); + meshData.iCount = data.get(i+3); + meshData.blendMode = data.get(i+4); + meshData.textureID = data.get(i+5); + modelData.meshes.push(meshData); + } const bones = this._skeleton.bones; const boneInfosArray: FrameBoneInfo[] = []; diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index e35555a7a64..9a00527db21 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -22,6 +22,7 @@ THE SOFTWARE. */ +import { EDITOR_NOT_IN_PREVIEW } from 'internal:constants'; import { director } from '../game/director'; import { System } from '../core'; import { Skeleton } from './skeleton'; @@ -79,7 +80,7 @@ export class SkeletonSystem extends System { return; } this.index++; - spine.SkeletonSystem.updateAnimation(dt); + if(!EDITOR_NOT_IN_PREVIEW) spine.SkeletonSystem.updateAnimation(dt); this._skeletons.forEach((skeleton) => { skeleton.updateAnimation(dt); skeleton.syncAttachedNode(); diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index a81916438d3..26632761295 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -1016,7 +1016,7 @@ export class Skeleton extends UIRenderer { } this._updateCache(dt); } else { - //this._instance.updateAnimation(dt); + if(EDITOR_NOT_IN_PREVIEW) this._instance.updateAnimation(dt); } } diff --git a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp index 9119d74fd44..445f4f9a26f 100644 --- a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp @@ -1645,6 +1645,7 @@ EMSCRIPTEN_BINDINGS(spine) { .property("iCount", &SpineModel::iCount) .property("vPtr", &SpineModel::vPtr) .property("iPtr", &SpineModel::iPtr) + //.property("data", &SpineModel::data, allow_raw_pointer>()); .function("getData", &SpineModel::getData, allow_raw_pointer>()); //.function("getMeshes", &SpineModel::getMeshes, allow_raw_pointer>()); From cd69338077234fe4ea71cb1a568a029ecc5ca806 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 15:01:10 +0800 Subject: [PATCH 05/18] Optimize the process related to updating skeletal data. --- cocos/spine/assembler/simple.ts | 1 + cocos/spine/attach-util.ts | 27 ++++++++++++------- cocos/spine/skeleton-system.ts | 2 +- .../spine-wasm/spine-skeleton-instance.cpp | 5 +--- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index a3f631f779c..21eed420b4d 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -145,6 +145,7 @@ function updateComponentRenderData (comp: Skeleton, batcher: Batcher2D): void { } const rd = comp.renderData!; const accessor = _useTint ? _tintAccessor : _accessor; + comp.syncAttachedNode(); if (rd.vertexCount > 0 || rd.indexCount > 0) accessor.getMeshBuffer(rd.chunk.bufferId).setDirty(); } diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index fc70ebabb96..de8bff0c598 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -62,28 +62,37 @@ export class AttachUtil { if (!boneInfos || boneInfos.length < 1) { return; } + + const sockets = skeletonComp!.sockets; const socketNodes = skeletonComp!.socketNodes; - const keysToDelete = []; + //const keysToDelete = []; + + /* + for (let l = sockets.length - 1; l >= 0; l--) { + const sock = sockets[l]; + const boneNode = sock.target; + if (!boneNode) continue; + } + */ for (const [boneIdx, boneNode] of socketNodes) { + + /* if (!boneNode || !boneNode.isValid) { keysToDelete.push(boneIdx); continue; } + */ const bone = boneInfos[boneIdx]; - if (!bone) { - boneNode.removeFromParent(); - boneNode.destroy(); - keysToDelete.push(boneIdx); - continue; - } - - this.matrixHandle(boneNode, bone); + if (bone) this.matrixHandle(boneNode, bone); } + + /* for (const boneIdx of keysToDelete) { socketNodes.delete(boneIdx); } + */ } matrixHandle (node: Node, bone: any): void { diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index 9a00527db21..4e4a2f6de81 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -83,7 +83,7 @@ export class SkeletonSystem extends System { if(!EDITOR_NOT_IN_PREVIEW) spine.SkeletonSystem.updateAnimation(dt); this._skeletons.forEach((skeleton) => { skeleton.updateAnimation(dt); - skeleton.syncAttachedNode(); + //skeleton.syncAttachedNode(); }); //this.index % 500 == 0 && console.log('spine update :', this.index , `count:${spine.SkeletonSystem.getCount()}`); } diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp index b98ea8f0609..b90cbd9517d 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp @@ -83,7 +83,6 @@ void SpineSkeletonInstance::updateAnimation(float dltTime) { _skeleton->update(dltTime); _animState->update(dltTime); _animState->apply(*_skeleton); - _skeleton->updateWorldTransform(); //preUpdateRenderData(); } @@ -106,6 +105,7 @@ SpineModel *SpineSkeletonInstance::updateRenderData() { if (_userData.debugMode) { _debugShapes.clear(); } + _skeleton->updateWorldTransform(); SpineMeshData::reset(); _model->clearMeshes(); if (_userData.useTint) { @@ -113,11 +113,8 @@ SpineModel *SpineSkeletonInstance::updateRenderData() { } else { _model->byteStride = sizeof(V3F_T2F_C4B); } - collectMeshData(); - _model->setBufferPtr(SpineMeshData::vb(), SpineMeshData::ib()); - return _model; } From 785ee19733ae3c5662ee48a30132472d49f1cd84 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 15:01:55 +0800 Subject: [PATCH 06/18] update attach-util. --- cocos/spine/attach-util.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index de8bff0c598..f39449e258f 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -67,13 +67,16 @@ export class AttachUtil { const socketNodes = skeletonComp!.socketNodes; //const keysToDelete = []; - /* + for (let l = sockets.length - 1; l >= 0; l--) { const sock = sockets[l]; const boneNode = sock.target; if (!boneNode) continue; + const bone = boneInfos[sock.boneIndex]; + if (bone) this.matrixHandle(boneNode, bone); } - */ + + /* for (const [boneIdx, boneNode] of socketNodes) { @@ -84,10 +87,10 @@ export class AttachUtil { } */ - const bone = boneInfos[boneIdx]; - if (bone) this.matrixHandle(boneNode, bone); - } - + //const bone = boneInfos[boneIdx]; + //if (bone) this.matrixHandle(boneNode, bone); + //} + */ /* for (const boneIdx of keysToDelete) { socketNodes.delete(boneIdx); From f93cab8e1cfba7ed6b519a2c4df0a60aa22492cb Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 17:22:18 +0800 Subject: [PATCH 07/18] optimize spine attach node logic. --- cocos/spine/attach-util.ts | 73 +++++++++++++++----------------------- cocos/spine/skeleton.ts | 5 +-- 2 files changed, 31 insertions(+), 47 deletions(-) diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index f39449e258f..bbbb10b90d0 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -35,67 +35,50 @@ const tempMat4 = new Mat4(); * @class sp.AttachUtil */ export class AttachUtil { - protected _inited = false; - protected skeletonBones: spine.Bone[] | null = []; + protected isInitialized = false; + protected skeletonBones: spine.Bone[] | FrameBoneInfo[] | undefined; + protected socketNodes: Map | undefined; + private keysToDelete:number[] = []; constructor () { - this._inited = false; + this.isInitialized = false; } init (skeletonComp: Skeleton): void { - this._inited = true; - this.skeletonBones = skeletonComp._skeleton.bones; + this.isInitialized = false; + if (!skeletonComp || skeletonComp.socketNodes.size === 0) return; + const isCached = skeletonComp.isAnimationCached(); + this.skeletonBones = isCached && skeletonComp._curFrame ? skeletonComp._curFrame.boneInfos : skeletonComp._skeleton.bones; + if (!this.skeletonBones || this.skeletonBones.length < 1) return; + this.socketNodes = skeletonComp.socketNodes; + if (this.socketNodes.size <= 0) return; + this.isInitialized = true; + this._syncAttachedNode(); } reset (): void { - this._inited = false; - this.skeletonBones = null; + this.isInitialized = false; + this.skeletonBones = undefined; + this.socketNodes = undefined; + this.keysToDelete.length = 0; } - _syncAttachedNode (skeletonComp: Skeleton): void { - if (!this._inited || skeletonComp!.socketNodes.size === 0) { - return; - } - const isCached = skeletonComp!.isAnimationCached(); - const boneInfos = isCached && skeletonComp!._curFrame ? skeletonComp!._curFrame.boneInfos : this.skeletonBones; - - if (!boneInfos || boneInfos.length < 1) { - return; - } - - const sockets = skeletonComp!.sockets; - const socketNodes = skeletonComp!.socketNodes; - //const keysToDelete = []; - - - for (let l = sockets.length - 1; l >= 0; l--) { - const sock = sockets[l]; - const boneNode = sock.target; - if (!boneNode) continue; - const bone = boneInfos[sock.boneIndex]; - if (bone) this.matrixHandle(boneNode, bone); - } - - /* - + _syncAttachedNode (): void { + if(!this.isInitialized) return; + const socketNodes = this.socketNodes!; for (const [boneIdx, boneNode] of socketNodes) { - - /* if (!boneNode || !boneNode.isValid) { - keysToDelete.push(boneIdx); + this.keysToDelete.push(boneIdx); continue; } - */ - - //const bone = boneInfos[boneIdx]; - //if (bone) this.matrixHandle(boneNode, bone); - //} - */ - /* - for (const boneIdx of keysToDelete) { + const bone = this.skeletonBones![boneIdx]; + if (bone) this.matrixHandle(boneNode, bone); + } + if (this.keysToDelete.length <= 0) return; + for (const boneIdx of this.keysToDelete) { socketNodes.delete(boneIdx); } - */ + this.keysToDelete.length = 0; } matrixHandle (node: Node, bone: any): void { diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 26632761295..ec3fc83119b 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -559,7 +559,7 @@ export class Skeleton extends UIRenderer { } this._sockets = val; this._updateSocketBindings(); - this.syncAttachedNode(); + this.attachUtil.init(this); } /** @@ -1268,7 +1268,7 @@ export class Skeleton extends UIRenderer { */ public syncAttachedNode (): void { // sync attached node matrix - this.attachUtil._syncAttachedNode(this); + this.attachUtil._syncAttachedNode(); } /** @@ -1295,6 +1295,7 @@ export class Skeleton extends UIRenderer { this._cacheMode = cacheMode; //this.setSkin(this.defaultSkin); this._instance.isCache = this.isAnimationCached(); + this.attachUtil.init(this); this._updateSkeletonData(); this.setSkin(this.defaultSkin); this._updateUseTint(); From d6d04cbc013afffb7fd511dd56f03c5959c7490c Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 17:57:48 +0800 Subject: [PATCH 08/18] fix code formatting. --- cocos/spine/assembler/simple.ts | 18 +++++------------- cocos/spine/attach-util.ts | 4 ++-- cocos/spine/lib/spine-core.d.ts | 2 +- cocos/spine/lib/spine-define.ts | 26 +++++++++----------------- cocos/spine/skeleton-cache.ts | 19 +++---------------- cocos/spine/skeleton-system.ts | 4 +--- cocos/spine/skeleton.ts | 21 ++++++++++----------- 7 files changed, 31 insertions(+), 63 deletions(-) diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index 21eed420b4d..c99dc74fcc6 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -87,13 +87,6 @@ function _getSlotMaterial (blendMode: number, comp: Skeleton): MaterialInstance } export const simple: IAssembler = { - - fillBuffers (render: UIRenderable, batcher: Batcher2D) { - - }, - updateColor (render: UIRenderable) { - - }, vCount: 32767, ensureAccessor (useTint: boolean) { let accessor = useTint ? _tintAccessor : _accessor; @@ -160,13 +153,13 @@ function realTimeTraverse (comp: Skeleton): void { if (rd.vertexCount !== vc || rd.indexCount !== ic) { rd.resize(vc, ic); rd.indices = new Uint16Array(ic); - comp._vLength = vc * Float32Array.BYTES_PER_ELEMENT * floatStride; + comp._vLength = vc * Float32Array.BYTES_PER_ELEMENT * floatStride; comp._vBuffer = new Uint8Array(rd.chunk.vb.buffer, rd.chunk.vb.byteOffset, Float32Array.BYTES_PER_ELEMENT * rd.chunk.vb.length); comp._iLength = Uint16Array.BYTES_PER_ELEMENT * ic; comp._iBuffer = new Uint8Array(rd.indices.buffer); } - let vbuf = rd.chunk.vb; + const vbuf = rd.chunk.vb; const vPtr = model.vPtr; const iPtr = model.iPtr; const ibuf = rd.indices!; @@ -174,7 +167,6 @@ function realTimeTraverse (comp: Skeleton): void { comp._vBuffer?.set(HEAPU8.subarray(vPtr, vPtr + comp._vLength), 0); comp._iBuffer?.set(HEAPU8.subarray(iPtr, iPtr + comp._iLength), 0); - const chunkOffset = rd.chunk.vertexOffset; for (let i = 0; i < ic; i++) ibuf[i] += chunkOffset; @@ -184,8 +176,8 @@ function realTimeTraverse (comp: Skeleton): void { let indexCount = 0; for (let i = 0; i < count; i += 6) { indexCount = data.get(i+3); - const material = _getSlotMaterial(data.get(i+4), comp); - const textureID = data.get(i+5); + const material = _getSlotMaterial(data.get(i + 4), comp); + const textureID: number = data.get(i + 5); comp.requestDrawData(material, textureID, indexOffset, indexCount); indexOffset += indexCount; } @@ -201,7 +193,7 @@ function realTimeTraverse (comp: Skeleton): void { tempVecPos.transformMat4(worldMat); vbuf[index] = tempVecPos.x; vbuf[index + 1] = tempVecPos.y; - vbuf[index + 2] = 0 + vbuf[index + 2] = 0; } } diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index bbbb10b90d0..3a319d199cc 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -38,7 +38,7 @@ export class AttachUtil { protected isInitialized = false; protected skeletonBones: spine.Bone[] | FrameBoneInfo[] | undefined; protected socketNodes: Map | undefined; - private keysToDelete:number[] = []; + private keysToDelete: number[] = []; constructor () { this.isInitialized = false; @@ -64,7 +64,7 @@ export class AttachUtil { } _syncAttachedNode (): void { - if(!this.isInitialized) return; + if (!this.isInitialized) return; const socketNodes = this.socketNodes!; for (const [boneIdx, boneNode] of socketNodes) { if (!boneNode || !boneNode.isValid) { diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index ed509b26781..b4f1a654220 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -1179,7 +1179,7 @@ declare namespace spine { } class SkeletonSystem { - public static updateAnimation(deltaTime:number): void; + public static updateAnimation(deltaTime: number): void; public static updateRenderData(): void; public static getCount(): number; } diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index e0786a8d62a..bdf9898c9a4 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -26,12 +26,10 @@ import spine from './spine-core.js'; import { js } from '../../core'; -import { array } from 'cocos/core/utils/js.js'; - -function resizeArray(array, newSize) { +function resizeArray (array, newSize) { if (!array) return new Array(newSize); - if (newSize == array.length) return array; + if (newSize === array.length) return array; if (newSize < array.length) return array.slice(0, newSize); else return new Array(newSize); } @@ -96,13 +94,7 @@ function overrideDefinePtrStringFunction (prototype: any, getPtr: any, name: str let str = ''; const ptr = getPtr.call(this); const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; - /* - let length = this.length + ptr; - for (let i = ptr; i < length; ++i) { - str += String.fromCharCode(HEAPU8[i]); - } - */ - let length = this.length; + const length = this.length; const buffer = HEAPU8.subarray(ptr, ptr + length); str = String.fromCharCode(...buffer); return str; @@ -203,8 +195,8 @@ function overrideProperty_String (): void { { proto: prototype, property: 'str', - getter: prototype.str - } + getter: prototype.str, + }, ]; propertyPolyfills.forEach((prop): void => { js.get(prop.proto, prop.property, prop.getter); @@ -225,7 +217,7 @@ function overrideProperty_Vector2 (): void { proto: prototype, property: 'y', getter: prototype.getY, - setter: prototype.setY + setter: prototype.setY, }, ]; propertyPolyfills.forEach((prop): void => { @@ -813,8 +805,8 @@ function overrideProperty_RegionAttachment (): void { return array; }, set (value: number[]) { - setUVs.call(this, value[0], value[1], value[2], value[3], value[4] == 1); - } + setUVs.call(this, value[0], value[1], value[2], value[3], value[4] === 1); + }, }); const originComputeWorldVertices = prototype.computeWorldVertices; @@ -1331,7 +1323,7 @@ function overrideProperty_Skin (): void { overrideDefineArrayProp(prototype, prototype.getAttachments, 'attachments'); overrideDefineArrayProp(prototype, prototype.getConstraints, 'constraints'); overrideDefineArrayFunction(prototype, prototype.getAttachments, 'getAttachments'); - const originGetAttachmentsForSlot = prototype.getAttachmentsForSlot; + const originGetAttachmentsForSlot = prototype.getAttachmentsForSlot; Object.defineProperty(prototype, 'getAttachmentsForSlot', { value (slotIndex: number, attachments: Array) { const vectors = originGetAttachmentsForSlot.call(this, slotIndex); diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index da69a273846..9cdb02105fb 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -189,26 +189,13 @@ export class AnimationCache { modelData.vData = vUint8Buf; modelData.iData = iUint16Buf; - /* - const meshes = model.getMeshes(); - const count = meshes.size(); - for (let i = 0; i < count; i++) { - const mesh = meshes.get(i); - const meshData = new SpineDrawItem(); - meshData.iCount = mesh.iCount; - meshData.blendMode = mesh.blendMode; - meshData.textureID = mesh.textureID; - modelData.meshes.push(meshData); - } - */ - const data = model.getData(); const count = data.size(); for (let i = 0; i < count; i += 6) { const meshData = new SpineDrawItem(); - meshData.iCount = data.get(i+3); - meshData.blendMode = data.get(i+4); - meshData.textureID = data.get(i+5); + meshData.iCount = data.get(i + 3); + meshData.blendMode = data.get(i + 4); + meshData.textureID = data.get(i + 5); modelData.meshes.push(meshData); } diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index 4e4a2f6de81..4d003e15f2e 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -80,12 +80,10 @@ export class SkeletonSystem extends System { return; } this.index++; - if(!EDITOR_NOT_IN_PREVIEW) spine.SkeletonSystem.updateAnimation(dt); + if (!EDITOR_NOT_IN_PREVIEW) spine.SkeletonSystem.updateAnimation(dt); this._skeletons.forEach((skeleton) => { skeleton.updateAnimation(dt); - //skeleton.syncAttachedNode(); }); - //this.index % 500 == 0 && console.log('spine update :', this.index , `count:${spine.SkeletonSystem.getCount()}`); } public prepareRenderData (): void { diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index ec3fc83119b..edb250a0f10 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -302,11 +302,11 @@ export class Skeleton extends UIRenderer { private _slotTextures: Map | null = null; _vLength = 0; - _vBuffer:Uint8Array | null = null; + _vBuffer: Uint8Array | null = null; _iLength = 0; - _iBuffer:Uint8Array | null = null; - _model:any | undefined; - _tempColor:Color = new Color(1, 1, 1, 1); + _iBuffer: Uint8Array | null = null; + _model: any | undefined; + _tempColor: Color = new Color(1, 1, 1, 1); constructor () { super(); @@ -508,7 +508,7 @@ export class Skeleton extends UIRenderer { set timeScale (value) { if (value !== this._timeScale) { this._timeScale = value; - if(this._instance) { + if (this._instance) { this._instance.dtRate = this._timeScale * timeScale; } } @@ -559,7 +559,7 @@ export class Skeleton extends UIRenderer { } this._sockets = val; this._updateSocketBindings(); - this.attachUtil.init(this); + this.attachUtil.init(this); } /** @@ -683,7 +683,6 @@ export class Skeleton extends UIRenderer { super.onDisable(); this._instance.enable = false; SkeletonSystem.getInstance().remove(this); - } public onDestroy (): void { @@ -1612,10 +1611,10 @@ export class Skeleton extends UIRenderer { const b = this._color.b / 255.0; const a = this.node._uiProps.opacity; - if (this._tempColor.r == r || - this._tempColor.g == g || - this._tempColor.b == b) - return; + if (this._tempColor.r === r || + this._tempColor.g === g || + this._tempColor.b === b) + { return; } this._tempColor.set(r, g, b, this._tempColor.a); this._instance.setColor(r, g, b, a); } From b65d5d46322824464d896a62c51e8bcddc1d4896 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 18:15:23 +0800 Subject: [PATCH 09/18] Fix code formatting. --- cocos/spine/assembler/simple.ts | 2 +- cocos/spine/lib/spine-core.d.ts | 2 +- cocos/spine/skeleton.ts | 12 +++++------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index c99dc74fcc6..45fb119ad8e 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -175,7 +175,7 @@ function realTimeTraverse (comp: Skeleton): void { let indexOffset = 0; let indexCount = 0; for (let i = 0; i < count; i += 6) { - indexCount = data.get(i+3); + indexCount = data.get(i + 3); const material = _getSlotMaterial(data.get(i + 4), comp); const textureID: number = data.get(i + 5); comp.requestDrawData(material, textureID, indexOffset, indexCount); diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index b4f1a654220..81ad182f431 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -700,7 +700,7 @@ declare namespace spine { scale: number; private linkedMeshes; constructor(attachmentLoader: AttachmentLoader); - readSkeletonData(json: string | any): SkeletonData; + readSkeletonData(json: any): SkeletonData; readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment; readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void; readAnimation(map: any, name: string, skeletonData: SkeletonData): void; diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index edb250a0f10..c188de758f7 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -305,7 +305,7 @@ export class Skeleton extends UIRenderer { _vBuffer: Uint8Array | null = null; _iLength = 0; _iBuffer: Uint8Array | null = null; - _model: any | undefined; + _model: any; _tempColor: Color = new Color(1, 1, 1, 1); constructor () { @@ -1015,7 +1015,7 @@ export class Skeleton extends UIRenderer { } this._updateCache(dt); } else { - if(EDITOR_NOT_IN_PREVIEW) this._instance.updateAnimation(dt); + if (EDITOR_NOT_IN_PREVIEW) this._instance.updateAnimation(dt); } } @@ -1610,11 +1610,9 @@ export class Skeleton extends UIRenderer { const g = this._color.g / 255.0; const b = this._color.b / 255.0; const a = this.node._uiProps.opacity; - - if (this._tempColor.r === r || - this._tempColor.g === g || - this._tempColor.b === b) - { return; } + if (this._tempColor.r === r && this._tempColor.g === g && this._tempColor.b === b) { + return; + } this._tempColor.set(r, g, b, this._tempColor.a); this._instance.setColor(r, g, b, a); } From 0944eea583b5f8b9b18ac5ecd6e46358fa57629e Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 18:33:18 +0800 Subject: [PATCH 10/18] Optimize color refresh logic. --- cocos/spine/skeleton.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index c188de758f7..784b59ad236 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -134,6 +134,13 @@ export interface SkeletonDrawData { indexCount: number; } +export interface TempColor { + r:number; + g:number; + b:number; + a:number; +} + /** * @en * The Sockets attached to bones, synchronous transform with spine animation. @@ -306,7 +313,7 @@ export class Skeleton extends UIRenderer { _iLength = 0; _iBuffer: Uint8Array | null = null; _model: any; - _tempColor: Color = new Color(1, 1, 1, 1); + _tempColor: TempColor = {r: 0, g: 0, b: 0, a: 0}; constructor () { super(); @@ -1605,15 +1612,21 @@ export class Skeleton extends UIRenderer { * @engineInternal */ public _updateColor (): void { + const a = this.node._uiProps.opacity; + if (this._tempColor.r === this._color.r && + this._tempColor.g === this.color.g && + this._tempColor.b === this.color.b && + this._tempColor.a === a) { + return; + } this.node._uiProps.colorDirty = true; + this._tempColor.r = this._color.r; + this._tempColor.g = this._color.g; + this._tempColor.b = this._color.b; + this._tempColor.a = a; const r = this._color.r / 255.0; const g = this._color.g / 255.0; const b = this._color.b / 255.0; - const a = this.node._uiProps.opacity; - if (this._tempColor.r === r && this._tempColor.g === g && this._tempColor.b === b) { - return; - } - this._tempColor.set(r, g, b, this._tempColor.a); this._instance.setColor(r, g, b, a); } From befeaba689787555df56733f98538531bd504753 Mon Sep 17 00:00:00 2001 From: Canvas Date: Mon, 9 Oct 2023 18:45:24 +0800 Subject: [PATCH 11/18] Fix code formatting. --- cocos/spine/skeleton.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 784b59ad236..8205b802acd 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -135,10 +135,10 @@ export interface SkeletonDrawData { } export interface TempColor { - r:number; - g:number; - b:number; - a:number; + r: number; + g: number; + b: number; + a: number; } /** @@ -1613,10 +1613,7 @@ export class Skeleton extends UIRenderer { */ public _updateColor (): void { const a = this.node._uiProps.opacity; - if (this._tempColor.r === this._color.r && - this._tempColor.g === this.color.g && - this._tempColor.b === this.color.b && - this._tempColor.a === a) { + if (this._tempColor.r === this._color.r && this._tempColor.g === this.color.g && this._tempColor.b === this.color.b && this._tempColor.a === a) { return; } this.node._uiProps.colorDirty = true; From 63639b0012e42246ef943da0849697000e0ee1e8 Mon Sep 17 00:00:00 2001 From: Canvas Date: Tue, 10 Oct 2023 13:59:50 +0800 Subject: [PATCH 12/18] fix code formatting. --- cocos/spine/lib/spine-define.ts | 3 +-- cocos/spine/skeleton-cache.ts | 4 ++-- cocos/spine/skeleton.ts | 6 ++++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index bdf9898c9a4..a398085563d 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -27,7 +27,7 @@ import spine from './spine-core.js'; import { js } from '../../core'; -function resizeArray (array, newSize) { +function resizeArray (array, newSize): Array { if (!array) return new Array(newSize); if (newSize === array.length) return array; if (newSize < array.length) return array.slice(0, newSize); @@ -42,7 +42,6 @@ function overrideDefineArrayProp (prototype: any, getPropVector: any, name: stri const count = vectors.size(); let array = this[_name]; array = resizeArray(array, count); - //if (array[0]) return array; for (let i = 0; i < count; i++) array[i] = vectors.get(i); this[_name] = array; return array; diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index 9cdb02105fb..a342f3c3e19 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -163,8 +163,8 @@ export class AnimationCache { } private updateRenderData (index: number, model: any): void { - const vc = model.vCount; - const ic = model.iCount; + const vc: number = model.vCount; + const ic: number = model.iCount; const floatStride = (_useTint ? _byteStrideTwoColor : _byteStrideOneColor) / Float32Array.BYTES_PER_ELEMENT; const vUint8Buf = new Uint8Array(Float32Array.BYTES_PER_ELEMENT * floatStride * vc); const iUint16Buf = new Uint16Array(ic); diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 8205b802acd..1d93937d891 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -313,7 +313,7 @@ export class Skeleton extends UIRenderer { _iLength = 0; _iBuffer: Uint8Array | null = null; _model: any; - _tempColor: TempColor = {r: 0, g: 0, b: 0, a: 0}; + _tempColor: TempColor = { r: 0, g: 0, b: 0, a: 0 }; constructor () { super(); @@ -1037,7 +1037,9 @@ export class Skeleton extends UIRenderer { // It has no event object. if (this._accTime === 0 && this._playCount === 0) { this._startEntry.animation.name = this._animationName; - if (this._listener && this._listener.start) this._listener.start(this._startEntry); + if (this._listener && this._listener.start) { + this._listener.start(this._startEntry); + } } this._accTime += dt; From 7f217c25c6751e0aa370042e38ef9b78dc4eee4d Mon Sep 17 00:00:00 2001 From: Canvas Date: Wed, 11 Oct 2023 17:41:13 +0800 Subject: [PATCH 13/18] Fix spine cache mode memory leak. --- cocos/spine/assembler/simple.ts | 2 - cocos/spine/attach-util.ts | 13 +++--- cocos/spine/skeleton-cache.ts | 31 +++++++------ cocos/spine/skeleton.ts | 45 ++++++++++--------- .../editor-support/spine-wasm/spine-model.cpp | 1 + 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index 45fb119ad8e..20fa8ffe7c3 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -22,7 +22,6 @@ THE SOFTWARE. */ -import { UIRenderable } from '../../2d'; import { IAssembler } from '../../2d/renderer/base'; import { Batcher2D } from '../../2d/renderer/batcher-2d'; @@ -36,7 +35,6 @@ import { director } from '../../game'; import spine from '../lib/spine-core.js'; import { Color, Vec3 } from '../../core'; import { MaterialInstance } from '../../render-scene'; -import { SkeletonSystem } from '../skeleton-system'; const _slotColor = new Color(0, 0, 255, 255); const _boneColor = new Color(255, 0, 0, 255); diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index 3a319d199cc..2a47e17de62 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -26,6 +26,7 @@ import { Mat4 } from '../core'; import { Skeleton } from './skeleton'; import { Node } from '../scene-graph'; import spine from './lib/spine-core'; +import { FrameBoneInfo } from './skeleton-cache'; const tempMat4 = new Mat4(); @@ -36,8 +37,8 @@ const tempMat4 = new Mat4(); */ export class AttachUtil { protected isInitialized = false; - protected skeletonBones: spine.Bone[] | FrameBoneInfo[] | undefined; - protected socketNodes: Map | undefined; + protected skeletonBones: spine.Bone[] | FrameBoneInfo[] | null = null; + protected socketNodes: Map | null = null; private keysToDelete: number[] = []; constructor () { @@ -46,20 +47,20 @@ export class AttachUtil { init (skeletonComp: Skeleton): void { this.isInitialized = false; - if (!skeletonComp || skeletonComp.socketNodes.size === 0) return; + if (!skeletonComp || skeletonComp.socketNodes?.size === 0) return; const isCached = skeletonComp.isAnimationCached(); this.skeletonBones = isCached && skeletonComp._curFrame ? skeletonComp._curFrame.boneInfos : skeletonComp._skeleton.bones; if (!this.skeletonBones || this.skeletonBones.length < 1) return; this.socketNodes = skeletonComp.socketNodes; - if (this.socketNodes.size <= 0) return; + if (!this.socketNodes || this.socketNodes.size <= 0) return; this.isInitialized = true; this._syncAttachedNode(); } reset (): void { this.isInitialized = false; - this.skeletonBones = undefined; - this.socketNodes = undefined; + this.skeletonBones = null; + this.socketNodes = null; this.keysToDelete.length = 0; } diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index a342f3c3e19..ed1cbd4629a 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -36,7 +36,7 @@ const _useTint = true; const _byteStrideOneColor = getAttributeStride(vfmtPosUvColor4B); const _byteStrideTwoColor = getAttributeStride(vfmtPosUvTwoColor4B); -class FrameBoneInfo { +export class FrameBoneInfo { a = 0; b = 0; c = 0; @@ -46,9 +46,9 @@ class FrameBoneInfo { } export interface SkeletonCacheItemInfo { - skeleton: spine.Skeleton; - clipper: spine.SkeletonClipping; - state: spine.AnimationState; + skeleton: spine.Skeleton | null; + clipper: spine.SkeletonClipping | null; + state: spine.AnimationState | null; listener: TrackEntryListeners; curAnimationCache: AnimationCache | null; animationsCache: { [key: string]: AnimationCache }; @@ -97,6 +97,7 @@ export class AnimationCache { this._inited = false; this._invalid = true; this._instance = new spine.SkeletonInstance(); + this._instance.isCache = true; this._skeletonData = data; this._skeleton = this._instance.initSkeleton(data); this._instance.setUseTint(_useTint); @@ -169,19 +170,17 @@ export class AnimationCache { const vUint8Buf = new Uint8Array(Float32Array.BYTES_PER_ELEMENT * floatStride * vc); const iUint16Buf = new Uint16Array(ic); + const HEAPU8 = spine.wasmUtil.wasm.HEAPU8; const vPtr = model.vPtr; const vLength = vc * Float32Array.BYTES_PER_ELEMENT * floatStride; // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const vData = spine.wasmUtil.wasm.HEAPU8.subarray(vPtr, vPtr + vLength); - - vUint8Buf.set(vData); + vUint8Buf.set(HEAPU8.subarray(vPtr, vPtr + vLength)); const iPtr = model.iPtr; const iLength = Uint16Array.BYTES_PER_ELEMENT * ic; // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - const iData = spine.wasmUtil.wasm.HEAPU8.subarray(iPtr, iPtr + iLength); const iUint8Buf = new Uint8Array(iUint16Buf.buffer); - iUint8Buf.set(iData); + iUint8Buf.set(HEAPU8.subarray(iPtr, iPtr + iLength)); const modelData = new SpineModel(); modelData.vCount = vc; @@ -300,7 +299,7 @@ export class AnimationCache { this.invalidAllFrame(); } - public destory (): void { + public destroy (): void { spine.wasmUtil.destroySpineInstance(this._instance); } } @@ -358,10 +357,10 @@ class SkeletonCache { public getSkeletonCache (uuid: string, skeletonData: spine.SkeletonData): SkeletonCacheItemInfo { let skeletonInfo = this._skeletonCache[uuid]; if (!skeletonInfo) { - const skeleton = new spine.Skeleton(skeletonData); - const clipper = new spine.SkeletonClipping(); - const stateData = new spine.AnimationStateData(skeleton.data); - const state = new spine.AnimationState(stateData); + const skeleton = null; //new spine.Skeleton(skeletonData); + const clipper = null; //new spine.SkeletonClipping(); + //const stateData = null; //new spine.AnimationStateData(skeleton.data); + const state = null; //new spine.AnimationState(stateData); const listener = new TrackEntryListeners(); this._skeletonCache[uuid] = skeletonInfo = { @@ -416,14 +415,14 @@ class SkeletonCache { const animationPool = this._animationPool; for (const key in animationPool) { if (key.includes(uuid)) { - animationPool[key].destory(); + animationPool[key].destroy(); delete animationPool[key]; } } } else { const animationPool = this._animationPool; for (const key in animationPool) { - animationPool[key].destory(); + animationPool[key].destroy(); delete animationPool[key]; } } diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 1d93937d891..4202b489986 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -223,8 +223,6 @@ export class Skeleton extends UIRenderer { @serializable protected _cacheMode = AnimationCacheMode.REALTIME; @serializable - protected _defaultCacheMode: AnimationCacheMode = AnimationCacheMode.REALTIME; - @serializable protected _sockets: SpineSocket[] = []; @serializable protected _useTint = false; @@ -475,11 +473,11 @@ export class Skeleton extends UIRenderer { @editable @type(AnimationCacheMode) get defaultCacheMode (): AnimationCacheMode { - return this._defaultCacheMode; + return this._cacheMode; } set defaultCacheMode (mode: AnimationCacheMode) { - this._defaultCacheMode = mode; - this.setAnimationCacheMode(this._defaultCacheMode); + this._cacheMode = mode; + this.setAnimationCacheMode(this._cacheMode); } /** @@ -613,7 +611,7 @@ export class Skeleton extends UIRenderer { this.markForUpdateRenderData(); } } - get socketNodes (): Map { return this._socketNodes; } + get socketNodes (): Map | null { return this._socketNodes; } /** * @en The name of current playing animation. @@ -699,19 +697,17 @@ export class Skeleton extends UIRenderer { this._vBuffer = null; this._iBuffer = null; this.attachUtil.reset(); - this.attachUtil = null; - this._textures = null; + //this._textures.length = 0; this._slotTextures?.clear(); this._slotTextures = null; this._cachedSockets.clear(); - this._cachedSockets = null; this._socketNodes.clear(); - this._socketNodes = null; + //if (this._cacheMode == AnimationCacheMode.PRIVATE_CACHE) this._animCache?.destroy(); + this._animCache = null; SkeletonSystem.getInstance().remove(this); if (!JSB) { spine.wasmUtil.destroySpineInstance(this._instance); } - this._instance = null; super.onDestroy(); } /** @@ -737,17 +733,19 @@ export class Skeleton extends UIRenderer { } this._instance.dtRate = this._timeScale * timeScale; this._needUpdateSkeltonData = false; - const data = this.skeletonData?.getRuntimeData(); - if (!data) return; - this.setSkeletonData(data); - if (this.defaultSkin) this.setSkin(this.defaultSkin); - this._textures = skeletonData.textures; + //const data = this.skeletonData?.getRuntimeData(); + //if (!data) return; + //this.setSkeletonData(data); this._runtimeData = skeletonData.getRuntimeData(); if (!this._runtimeData) return; this.setSkeletonData(this._runtimeData); + + if (this.defaultSkin) this.setSkin(this.defaultSkin); + this._textures = skeletonData.textures; + this._refreshInspector(); if (this.defaultAnimation) this.animation = this.defaultAnimation.toString(); - if (this.defaultSkin) this.setSkin(this.defaultSkin); + //if (this.defaultSkin) this.setSkin(this.defaultSkin); this._updateUseTint(); this._indexBoneSockets(); this._updateSocketBindings(); @@ -782,7 +780,10 @@ export class Skeleton extends UIRenderer { } if (this.skeletonData) { const skeletonInfo = this._skeletonCache!.getSkeletonCache(this.skeletonData.uuid, skeletonData); - this._skeleton = skeletonInfo.skeleton; + if (skeletonInfo.skeleton == null) { + skeletonInfo.skeleton = this._instance.initSkeleton(skeletonData); + } + this._skeleton = skeletonInfo.skeleton!; } } else { this._skeleton = this._instance.initSkeleton(skeletonData); @@ -1303,11 +1304,11 @@ export class Skeleton extends UIRenderer { this._cacheMode = cacheMode; //this.setSkin(this.defaultSkin); this._instance.isCache = this.isAnimationCached(); - this.attachUtil.init(this); + //this.attachUtil.init(this); this._updateSkeletonData(); - this.setSkin(this.defaultSkin); - this._updateUseTint(); - this._updateSocketBindings(); + //this.setSkin(this.defaultSkin); + //this._updateUseTint(); + //this._updateSocketBindings(); this.markForUpdateRenderData(); } } diff --git a/native/cocos/editor-support/spine-wasm/spine-model.cpp b/native/cocos/editor-support/spine-wasm/spine-model.cpp index b8f2671c7f6..8692b3e6f7a 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-model.cpp @@ -6,6 +6,7 @@ SpineModel::SpineModel() { SpineModel::~SpineModel() { delete SpineModel::data; + SpineModel::data = nullptr; } /* From 4832457dc068389b9a6c76e62bc25f14791030c7 Mon Sep 17 00:00:00 2001 From: Canvas Date: Wed, 11 Oct 2023 18:12:23 +0800 Subject: [PATCH 14/18] remove unneeded code. --- cocos/spine/skeleton-cache.ts | 7 +- cocos/spine/skeleton-system.ts | 2 - .../editor-support/spine-wasm/spine-model.cpp | 43 ----------- .../editor-support/spine-wasm/spine-model.h | 3 - .../spine-wasm/spine-type-export.cpp | 73 ------------------- 5 files changed, 3 insertions(+), 125 deletions(-) diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index ed1cbd4629a..df85fea5169 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -357,10 +357,9 @@ class SkeletonCache { public getSkeletonCache (uuid: string, skeletonData: spine.SkeletonData): SkeletonCacheItemInfo { let skeletonInfo = this._skeletonCache[uuid]; if (!skeletonInfo) { - const skeleton = null; //new spine.Skeleton(skeletonData); - const clipper = null; //new spine.SkeletonClipping(); - //const stateData = null; //new spine.AnimationStateData(skeleton.data); - const state = null; //new spine.AnimationState(stateData); + const skeleton = null; + const clipper = null; + const state = null; const listener = new TrackEntryListeners(); this._skeletonCache[uuid] = skeletonInfo = { diff --git a/cocos/spine/skeleton-system.ts b/cocos/spine/skeleton-system.ts index 4d003e15f2e..88d9e9ae64f 100644 --- a/cocos/spine/skeleton-system.ts +++ b/cocos/spine/skeleton-system.ts @@ -74,12 +74,10 @@ export class SkeletonSystem extends System { } } - index = 0; postUpdate (dt: number): void { if (!this._skeletons) { return; } - this.index++; if (!EDITOR_NOT_IN_PREVIEW) spine.SkeletonSystem.updateAnimation(dt); this._skeletons.forEach((skeleton) => { skeleton.updateAnimation(dt); diff --git a/native/cocos/editor-support/spine-wasm/spine-model.cpp b/native/cocos/editor-support/spine-wasm/spine-model.cpp index 8692b3e6f7a..b191eca7968 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-model.cpp @@ -9,41 +9,6 @@ SpineModel::~SpineModel() { SpineModel::data = nullptr; } -/* -void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { - bool canMerge = false; - auto count = meshArray.size(); - if (needMerge && count >= 1) { - auto* lastMesh = &meshArray[count - 1]; - if (lastMesh->blendMode == mesh.blendMode && lastMesh->textureID == mesh.textureID) { - canMerge = true; - lastMesh->vCount += mesh.vCount; - lastMesh->iCount += mesh.iCount; - } - } - if (!canMerge) { - auto mergeMesh = SlotMesh(mesh.vBuf, mesh.iBuf, mesh.vCount, mesh.iCount); - mergeMesh.blendMode = mesh.blendMode; - mergeMesh.textureID = mesh.textureID; - meshArray.push_back(mergeMesh); - } - auto indexCount = mesh.iCount; - uint16_t* iiPtr = mesh.iBuf; - for (uint16_t i = 0; i < indexCount; i++) { - iiPtr[i] += vCount; - } - - auto vertexCount = mesh.vCount; - float* floatPtr = (float*)mesh.vBuf; - int floatStride = this->byteStride / 4; - for (int i = 0; i < vertexCount; i++) { - floatPtr[floatStride * i + 2] = 0; - } - vCount += vertexCount; - iCount += indexCount; -} -*/ - void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { bool canMerge = false; auto count = data->size(); @@ -81,10 +46,6 @@ void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { } void SpineModel::clearMeshes() { - //for (auto it = meshArray.begin(); it != meshArray.end(); ++it) { - // delete &(*it); - //} - //meshArray.clear(); data->resize(0); vCount = 0; iCount = 0; @@ -94,10 +55,6 @@ std::vector* SpineModel::getData() { return data; } -//std::vector* SpineModel::getMeshes() { -// return &meshArray; -//} - void SpineModel::setBufferPtr(uint8_t* vp, uint16_t* ip) { vPtr = (uint32_t)vp; iPtr = (uint32_t)ip; diff --git a/native/cocos/editor-support/spine-wasm/spine-model.h b/native/cocos/editor-support/spine-wasm/spine-model.h index e8af1d1e019..bb278bc856d 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.h +++ b/native/cocos/editor-support/spine-wasm/spine-model.h @@ -35,7 +35,6 @@ class SpineModel { void setBufferPtr(uint8_t* vp, uint16_t* ip); std::vector* data; std::vector* getData(); - //std::vector* getMeshes(); public: uint32_t vCount; @@ -43,8 +42,6 @@ class SpineModel { uint32_t vPtr; uint32_t iPtr; uint32_t byteStride; - //std::vector meshArray{}; - }; #endif \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp index 445f4f9a26f..d6ecbbd8df9 100644 --- a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp @@ -22,27 +22,6 @@ const spine::String STRING_STD2SP(const std::string &str) { return spString; } -/* -template -std::vector VECTOR_SP2STD(Vector &container) { - int count = container.size(); - std::vector stdVector(count); - for (int i = 0; i < count; i++) { - stdVector[i] = container[i]; - } - return stdVector; -} - -std::vector VECTOR_SP2STD_SIZE_T(Vector &container) { - int count = container.size(); - std::vector stdVector(count); - for (int i = 0; i < count; i++) { - stdVector[i] = container[i]; - } - return stdVector; -} -*/ - const std::vector VECTOR_SP2STD_STRING(Vector &container) { int count = container.size(); std::vector stdVector(count); @@ -52,29 +31,6 @@ const std::vector VECTOR_SP2STD_STRING(Vector &container) { return stdVector; } -/* -template -std::vector> VECTOR_2_SP2STD(Vector> &container) { - int count = container.size(); - std::vector> stdVector(count); - for (int i = 0; i < count; i++) { - stdVector[i] = VECTOR_SP2STD(container[i]); - } - return stdVector; -} - - -template -std::vector VECTOR_SP2STD2(Vector container) { - int count = container.size(); - std::vector stdVector(count); - for (int i = 0; i < count; i++) { - stdVector[i] = container[i]; - } - return stdVector; -} -*/ - template Vector VECTOR_STD2SP(std::vector &container) { int count = container.size(); @@ -126,9 +82,6 @@ using SPVectorTimelinePtr = Vector; using SPVectorTrackEntryPtr = Vector; using SPVectorUpdatablePtr = Vector; -//using SPVectorEntry = Vector; -//using SPVectorVectorEntry = Vector>; - } // namespace EMSCRIPTEN_BINDINGS(spine) { @@ -348,31 +301,7 @@ EMSCRIPTEN_BINDINGS(spine) { .function("set", &Vector2::set) .function("length", &Vector2::length) .function("normalize", &Vector2::normalize); -/* - class_("SPVectorEntry") - .function("size", &SPVectorEntry::size) - .function("get", &SPVectorEntry::operator[], allow_raw_pointers()); - - class_("SPVectorVectorEntry") - .function("size", &SPVectorVectorEntry::size) - .function("get", &SPVectorVectorEntry::operator[], allow_raw_pointers()); - - - class_("AttachmentMap") - .function("get", &Skin::AttachmentMap::get, allow_raw_pointers()); - - - class_("Entries") - .function("hasNext", &Skin::AttachmentMap::Entries::hasNext) - .function("next", &Skin::AttachmentMap::Entries::next); - value_object("Entry") - //.constructor<>() - //.constructor() - .field("_slotIndex",&Skin::AttachmentMap::Entry::_slotIndex) - .field("_name",&Skin::AttachmentMap::Entry::_name); - ///.field("_attachment", &Skin::AttachmentMap::Entry::_attachment, allow_raw_pointer()); - */ class_("String") .function("length", &String::length) .function("isEmpty", &String::isEmpty) @@ -1645,9 +1574,7 @@ EMSCRIPTEN_BINDINGS(spine) { .property("iCount", &SpineModel::iCount) .property("vPtr", &SpineModel::vPtr) .property("iPtr", &SpineModel::iPtr) - //.property("data", &SpineModel::data, allow_raw_pointer>()); .function("getData", &SpineModel::getData, allow_raw_pointer>()); - //.function("getMeshes", &SpineModel::getMeshes, allow_raw_pointer>()); class_("SpineDebugShape") .property("type", &SpineDebugShape::type) From ba361de37dfeb2d0d8dc7355dc7ce03393de5326 Mon Sep 17 00:00:00 2001 From: Canvas Date: Wed, 11 Oct 2023 18:16:06 +0800 Subject: [PATCH 15/18] remove unneeded code & fix code format. --- cocos/spine/attach-util.ts | 32 +++++++++---------- .../editor-support/spine-wasm/CMakeLists.txt | 2 +- .../spine-wasm/spine-skeleton-instance.cpp | 20 ------------ .../spine-wasm/spine-skeleton-instance.h | 8 ++--- .../spine-wasm/spine-skeleton-system.cpp | 8 ++--- 5 files changed, 23 insertions(+), 47 deletions(-) diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index 2a47e17de62..7d8ca92ed6c 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -36,43 +36,43 @@ const tempMat4 = new Mat4(); * @class sp.AttachUtil */ export class AttachUtil { - protected isInitialized = false; - protected skeletonBones: spine.Bone[] | FrameBoneInfo[] | null = null; - protected socketNodes: Map | null = null; + protected _isInitialized = false; + protected _skeletonBones: spine.Bone[] | FrameBoneInfo[] | null = null; + protected _socketNodes: Map | null = null; private keysToDelete: number[] = []; constructor () { - this.isInitialized = false; + this._isInitialized = false; } init (skeletonComp: Skeleton): void { - this.isInitialized = false; + this._isInitialized = false; if (!skeletonComp || skeletonComp.socketNodes?.size === 0) return; const isCached = skeletonComp.isAnimationCached(); - this.skeletonBones = isCached && skeletonComp._curFrame ? skeletonComp._curFrame.boneInfos : skeletonComp._skeleton.bones; - if (!this.skeletonBones || this.skeletonBones.length < 1) return; - this.socketNodes = skeletonComp.socketNodes; - if (!this.socketNodes || this.socketNodes.size <= 0) return; - this.isInitialized = true; + this._skeletonBones = isCached && skeletonComp._curFrame ? skeletonComp._curFrame.boneInfos : skeletonComp._skeleton.bones; + if (!this._skeletonBones || this._skeletonBones.length < 1) return; + this._socketNodes = skeletonComp.socketNodes; + if (!this._socketNodes || this._socketNodes.size <= 0) return; + this._isInitialized = true; this._syncAttachedNode(); } reset (): void { - this.isInitialized = false; - this.skeletonBones = null; - this.socketNodes = null; + this._isInitialized = false; + this._skeletonBones = null; + this._socketNodes = null; this.keysToDelete.length = 0; } _syncAttachedNode (): void { - if (!this.isInitialized) return; - const socketNodes = this.socketNodes!; + if (!this._isInitialized) return; + const socketNodes = this._socketNodes!; for (const [boneIdx, boneNode] of socketNodes) { if (!boneNode || !boneNode.isValid) { this.keysToDelete.push(boneIdx); continue; } - const bone = this.skeletonBones![boneIdx]; + const bone = this._skeletonBones![boneIdx]; if (bone) this.matrixHandle(boneNode, bone); } if (this.keysToDelete.length <= 0) return; diff --git a/native/cocos/editor-support/spine-wasm/CMakeLists.txt b/native/cocos/editor-support/spine-wasm/CMakeLists.txt index 5b4a24b9fcd..079c34083d3 100644 --- a/native/cocos/editor-support/spine-wasm/CMakeLists.txt +++ b/native/cocos/editor-support/spine-wasm/CMakeLists.txt @@ -21,7 +21,7 @@ file(GLOB COCOS_ADAPTER_SRC "./*.cpp") add_executable(${APP_NAME} ${SPINE_CORE_SRC} ${COCOS_ADAPTER_SRC} ) #add_executable(${APP_NAME} ${COCOS_ADAPTER_SRC}) -set(EMS_LINK_FLAGS "-03 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ +set(EMS_LINK_FLAGS "-O3 -s WASM=1 -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s DYNAMIC_EXECUTION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ -flto --no-entry --bind -s USE_ES6_IMPORT_META=0 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORT_NAME='spineWasm' \ -s ENVIRONMENT=web -s FILESYSTEM=0 -s NO_EXIT_RUNTIME=1 -s LLD_REPORT_UNDEFINED \ -s MIN_SAFARI_VERSION=110000 \ diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp index b90cbd9517d..c9a92049e9b 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp @@ -46,8 +46,6 @@ Skeleton *SpineSkeletonInstance::initSkeleton(SkeletonData *data) { _clipper = new SkeletonClipping(); _skeleton->setToSetupPose(); _skeleton->updateWorldTransform(); - //LogUtil::PrintToJs("initSkeleton ok."); - _animState->setRendererObject(this); _animState->setListener(animationCallback); return _skeleton; @@ -57,7 +55,6 @@ TrackEntry *SpineSkeletonInstance::setAnimation(float trackIndex, const std::str if (!_skeleton) return nullptr; spine::Animation *animation = _skeleton->getData()->findAnimation(name.c_str()); if (!animation) { - //LogUtil::PrintToJs("Spine: Animation not found:!!!"); _animState->clearTracks(); _skeleton->setToSetupPose(); return nullptr; @@ -74,7 +71,6 @@ void SpineSkeletonInstance::setSkin(const std::string &name) { _skeleton->setSlotsToSetupPose(); _animState->apply(*_skeleton); _skeleton->updateWorldTransform(); - //LogUtil::PrintToJs(name.c_str()); } void SpineSkeletonInstance::updateAnimation(float dltTime) { @@ -83,22 +79,6 @@ void SpineSkeletonInstance::updateAnimation(float dltTime) { _skeleton->update(dltTime); _animState->update(dltTime); _animState->apply(*_skeleton); - //preUpdateRenderData(); -} - -void SpineSkeletonInstance::preUpdateRenderData() { - if (_userData.debugMode) { - _debugShapes.clear(); - } - //SpineMeshData::reset(); - _model->clearMeshes(); - if (_userData.useTint) { - _model->byteStride = sizeof(V3F_T2F_C4B_C4B); - } else { - _model->byteStride = sizeof(V3F_T2F_C4B); - } - _model->setBufferPtr(SpineMeshData::vb(), SpineMeshData::ib()); - collectMeshData(); } SpineModel *SpineSkeletonInstance::updateRenderData() { diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h index 5d8c0b2ce32..7f1432ee175 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h @@ -63,10 +63,10 @@ class SpineSkeletonInstance { std::vector &getDebugShapes(); void resizeSlotRegion(const std::string &slotName, uint32_t width, uint32_t height, bool createNew = false); void setSlotTexture(const std::string &slotName, uint32_t index); - bool isCache = false; - bool enable = true; - float dtRate = 1; - bool isDelete = false; + bool isCache{false}; + bool enable{true}; + float dtRate{1.0F}; + bool isDelete{false}; private: void collectMeshData(); diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp index 9e8ce792485..86412c0ba9b 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-system.cpp @@ -7,7 +7,6 @@ using namespace spine; std::vector SpineSkeletonSystem::vectorSpines; void SpineSkeletonSystem::updateAnimation(float deltaTime) { - //SpineMeshData::reset(); auto count = static_cast(vectorSpines.size()); for (int i = count - 1; i >= 0; --i) { SpineSkeletonInstance* spineInstance = vectorSpines[i]; @@ -21,7 +20,6 @@ void SpineSkeletonSystem::updateAnimation(float deltaTime) { if (!spineInstance->isCache) { spineInstance->updateAnimation(deltaTime); } - } } @@ -41,16 +39,14 @@ void SpineSkeletonSystem::updateRenderData() { } } -void SpineSkeletonSystem::addSpineInstance(SpineSkeletonInstance* instance) -{ +void SpineSkeletonSystem::addSpineInstance(SpineSkeletonInstance* instance) { if(vectorSpines.size() == vectorSpines.capacity()){ vectorSpines.reserve(vectorSpines.size() + 20); } vectorSpines.push_back(instance); } -void SpineSkeletonSystem::removeSpineInstance(SpineSkeletonInstance* instance) -{ +void SpineSkeletonSystem::removeSpineInstance(SpineSkeletonInstance* instance) { auto it = std::find(vectorSpines.begin(), vectorSpines.end(), instance); if (it != vectorSpines.end()) { vectorSpines.erase(it); From 276092553413f2257bc2de0ecc3eca6fa369aee8 Mon Sep 17 00:00:00 2001 From: Canvas Date: Wed, 11 Oct 2023 18:19:02 +0800 Subject: [PATCH 16/18] fix code formatting. --- cocos/spine/attach-util.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cocos/spine/attach-util.ts b/cocos/spine/attach-util.ts index 7d8ca92ed6c..531ea355600 100644 --- a/cocos/spine/attach-util.ts +++ b/cocos/spine/attach-util.ts @@ -39,7 +39,7 @@ export class AttachUtil { protected _isInitialized = false; protected _skeletonBones: spine.Bone[] | FrameBoneInfo[] | null = null; protected _socketNodes: Map | null = null; - private keysToDelete: number[] = []; + private _keysToDelete: number[] = []; constructor () { this._isInitialized = false; @@ -61,7 +61,7 @@ export class AttachUtil { this._isInitialized = false; this._skeletonBones = null; this._socketNodes = null; - this.keysToDelete.length = 0; + this._keysToDelete.length = 0; } _syncAttachedNode (): void { @@ -69,17 +69,17 @@ export class AttachUtil { const socketNodes = this._socketNodes!; for (const [boneIdx, boneNode] of socketNodes) { if (!boneNode || !boneNode.isValid) { - this.keysToDelete.push(boneIdx); + this._keysToDelete.push(boneIdx); continue; } const bone = this._skeletonBones![boneIdx]; if (bone) this.matrixHandle(boneNode, bone); } - if (this.keysToDelete.length <= 0) return; - for (const boneIdx of this.keysToDelete) { + if (this._keysToDelete.length <= 0) return; + for (const boneIdx of this._keysToDelete) { socketNodes.delete(boneIdx); } - this.keysToDelete.length = 0; + this._keysToDelete.length = 0; } matrixHandle (node: Node, bone: any): void { From 9f827b03552d9cb6d5d99e8545123ccfeb7504f4 Mon Sep 17 00:00:00 2001 From: Canvas Date: Thu, 12 Oct 2023 11:03:38 +0800 Subject: [PATCH 17/18] fix code formatting. --- cocos/spine/skeleton.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index 4202b489986..9bbada5502e 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -1023,7 +1023,9 @@ export class Skeleton extends UIRenderer { } this._updateCache(dt); } else { - if (EDITOR_NOT_IN_PREVIEW) this._instance.updateAnimation(dt); + if (EDITOR_NOT_IN_PREVIEW) { + this._instance.updateAnimation(dt); + } } } @@ -1616,6 +1618,7 @@ export class Skeleton extends UIRenderer { */ public _updateColor (): void { const a = this.node._uiProps.opacity; + // eslint-disable-next-line max-len if (this._tempColor.r === this._color.r && this._tempColor.g === this.color.g && this._tempColor.b === this.color.b && this._tempColor.a === a) { return; } From 4f911f30132b8a32a2d5be3f22e20e515e5cc492 Mon Sep 17 00:00:00 2001 From: Canvas Date: Thu, 12 Oct 2023 11:33:19 +0800 Subject: [PATCH 18/18] optimize computeWorldVertices to avoid every call to new SPVectorFloat();. --- cocos/spine/lib/spine-define.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index a398085563d..ae740ef011c 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -590,15 +590,14 @@ function overrideProperty_VertexAttachment (): void { overrideDefineArrayProp(prototype, prototype.getBones, 'bones'); overrideDefineArrayProp(prototype, prototype.getVertices, 'vertices'); const originComputeWorldVertices = prototype.computeWorldVertices; + const vectors = new spine.SPVectorFloat(); Object.defineProperty(prototype, 'computeWorldVertices', { value (slot: spine.Slot, start: number, count: number, worldVertices: number[], offset: number, stride: number) { - const vectors = new spine.SPVectorFloat(); const length = worldVertices.length; vectors.resize(length, 0); for (let i = 0; i < length; i++) vectors.set(i, worldVertices[i]); originComputeWorldVertices.call(this, slot, start, count, vectors, offset, stride); for (let i = 0; i < length; i++) worldVertices[i] = vectors.get(i); - vectors.delete(); }, }); } @@ -809,15 +808,14 @@ function overrideProperty_RegionAttachment (): void { }); const originComputeWorldVertices = prototype.computeWorldVertices; + const vectors = new spine.SPVectorFloat(); Object.defineProperty(prototype, 'computeWorldVertices', { value (bone: spine.Bone, worldVertices: number[], offset: number, stride: number) { - const vectors = new spine.SPVectorFloat(); const length = worldVertices.length; vectors.resize(length, 0); for (let i = 0; i < length; i++) vectors.set(i, worldVertices[i]); originComputeWorldVertices.call(this, bone, vectors, offset, stride); for (let i = 0; i < length; i++) worldVertices[i] = vectors.get(i); - vectors.delete(); }, }); }