mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2024-12-26 03:38:29 +00:00
800 lines
32 KiB
Diff
800 lines
32 KiB
Diff
|
From 311adb9248bd23ed8fe5d282b8c1aa02b5d0cfba Mon Sep 17 00:00:00 2001
|
||
|
From: SmallMain <smallmain@outlook.com>
|
||
|
Date: Tue, 21 Jun 2022 12:01:39 +0800
|
||
|
Subject: [PATCH 10/15] =?UTF-8?q?Spine=20=E7=BB=84=E4=BB=B6=E6=94=AF?=
|
||
|
=?UTF-8?q?=E6=8C=81=E5=A4=9A=E7=BA=B9=E7=90=86=E6=B8=B2=E6=9F=93=E3=80=81?=
|
||
|
=?UTF-8?q?=E5=8A=A8=E6=80=81=E5=9B=BE=E9=9B=86=E3=80=81=E4=B8=8E=E5=85=B6?=
|
||
|
=?UTF-8?q?=E5=AE=83=E7=BB=84=E4=BB=B6=E5=90=88=E6=89=B9=E3=80=81region=20?=
|
||
|
=?UTF-8?q?=E6=8D=A2=E8=A3=85=E5=B9=B6=E5=A2=9E=E5=8A=A0=E6=8D=A2=E8=A3=85?=
|
||
|
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=20API=20=E6=8E=A5=E5=8F=A3?=
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
---
|
||
|
engine/cocos2d/core/assets/CCSpriteFrame.js | 1 +
|
||
|
.../core/renderer/webgl/mesh-buffer.js | 46 +++
|
||
|
engine/extensions/spine/Skeleton.js | 68 ++++-
|
||
|
engine/extensions/spine/lib/spine.js | 14 +-
|
||
|
engine/extensions/spine/skeleton-data.js | 114 ++++++-
|
||
|
engine/extensions/spine/spine-assembler.js | 278 ++++++++++++++----
|
||
|
6 files changed, 455 insertions(+), 66 deletions(-)
|
||
|
|
||
|
diff --git a/engine/cocos2d/core/assets/CCSpriteFrame.js b/engine/cocos2d/core/assets/CCSpriteFrame.js
|
||
|
index 37837bd..7038378 100644
|
||
|
--- a/engine/cocos2d/core/assets/CCSpriteFrame.js
|
||
|
+++ b/engine/cocos2d/core/assets/CCSpriteFrame.js
|
||
|
@@ -651,6 +651,7 @@ let SpriteFrame = cc.Class(/** @lends cc.SpriteFrame# */{
|
||
|
this._texture = this._original._texture;
|
||
|
this._original = null;
|
||
|
this._calculateUV();
|
||
|
+ this.emit("_resetDynamicAtlasFrame");
|
||
|
},
|
||
|
|
||
|
_calculateUV () {
|
||
|
diff --git a/engine/cocos2d/core/renderer/webgl/mesh-buffer.js b/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
|
||
|
index f8d300f..d0a998f 100644
|
||
|
--- a/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
|
||
|
+++ b/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
|
||
|
@@ -187,6 +187,52 @@ let MeshBuffer = cc.Class({
|
||
|
this.requestStatic(vertexCount, indiceCount);
|
||
|
return this._offsetInfo;
|
||
|
},
|
||
|
+
|
||
|
+ requestForSpine(vertexCount, indiceCount) {
|
||
|
+ if (this._batcher._buffer !== this) {
|
||
|
+ this._batcher._flush();
|
||
|
+ this._batcher._buffer = this;
|
||
|
+ }
|
||
|
+
|
||
|
+ this.requestStaticForSpine(vertexCount, indiceCount);
|
||
|
+ return this._offsetInfo;
|
||
|
+ },
|
||
|
+
|
||
|
+ requestStaticForSpine(vertexCount, indiceCount) {
|
||
|
+
|
||
|
+ this.checkAndSwitchBuffer(vertexCount);
|
||
|
+
|
||
|
+ let byteOffset = this.byteOffset + vertexCount * this._vertexBytes;
|
||
|
+ let indiceOffset = this.indiceOffset + indiceCount;
|
||
|
+
|
||
|
+ let byteLength = this._vData.byteLength;
|
||
|
+ let indiceLength = this._iData.length;
|
||
|
+ if (byteOffset > byteLength || indiceOffset > indiceLength) {
|
||
|
+ while (byteLength < byteOffset || indiceLength < indiceOffset) {
|
||
|
+ this._initVDataCount *= 2;
|
||
|
+ this._initIDataCount *= 2;
|
||
|
+
|
||
|
+ byteLength = this._initVDataCount * 4;
|
||
|
+ indiceLength = this._initIDataCount;
|
||
|
+ }
|
||
|
+
|
||
|
+ this._reallocBuffer();
|
||
|
+ }
|
||
|
+
|
||
|
+ let offsetInfo = this._offsetInfo;
|
||
|
+ offsetInfo.vertexOffset = this.vertexOffset;
|
||
|
+ offsetInfo.indiceOffset = this.indiceOffset;
|
||
|
+ offsetInfo.byteOffset = this.byteOffset;
|
||
|
+ },
|
||
|
+
|
||
|
+ adjustForSpine(vertexCount, indiceCount) {
|
||
|
+ this.vertexOffset += vertexCount;
|
||
|
+ this.indiceOffset += indiceCount;
|
||
|
+
|
||
|
+ this.byteOffset = this.byteOffset + vertexCount * this._vertexBytes;
|
||
|
+
|
||
|
+ this._dirty = true;
|
||
|
+ },
|
||
|
|
||
|
_reallocBuffer () {
|
||
|
this._reallocVData(true);
|
||
|
diff --git a/engine/extensions/spine/Skeleton.js b/engine/extensions/spine/Skeleton.js
|
||
|
index da54c8c..42046fc 100644
|
||
|
--- a/engine/extensions/spine/Skeleton.js
|
||
|
+++ b/engine/extensions/spine/Skeleton.js
|
||
|
@@ -427,7 +427,16 @@ sp.Skeleton = cc.Class({
|
||
|
// Play times
|
||
|
_playTimes : 0,
|
||
|
// Is animation complete.
|
||
|
- _isAniComplete : true,
|
||
|
+ _isAniComplete: true,
|
||
|
+
|
||
|
+ autoSwitchMaterial: {
|
||
|
+ type: RenderComponent.EnableType,
|
||
|
+ default: RenderComponent.EnableType.GLOBAL,
|
||
|
+ },
|
||
|
+ allowDynamicAtlas: {
|
||
|
+ type: RenderComponent.EnableType,
|
||
|
+ default: RenderComponent.EnableType.GLOBAL,
|
||
|
+ },
|
||
|
},
|
||
|
|
||
|
// CONSTRUCTOR
|
||
|
@@ -443,6 +452,7 @@ sp.Skeleton = cc.Class({
|
||
|
this._startEntry = {animation : {name : ""}, trackIndex : 0};
|
||
|
this._endEntry = {animation : {name : ""}, trackIndex : 0};
|
||
|
this.attachUtil = new AttachUtil();
|
||
|
+ this._dataDirty = true;
|
||
|
},
|
||
|
|
||
|
// override base class _getDefaultMaterial to modify default material
|
||
|
@@ -455,8 +465,11 @@ sp.Skeleton = cc.Class({
|
||
|
let useTint = this.useTint || (this.isAnimationCached() && !CC_NATIVERENDERER);
|
||
|
let baseMaterial = this.getMaterial(0);
|
||
|
if (baseMaterial) {
|
||
|
- baseMaterial.define('USE_TINT', useTint);
|
||
|
- baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
|
||
|
+ const isMultiSupport = baseMaterial.material.isMultiSupport();
|
||
|
+ if (!isMultiSupport) {
|
||
|
+ baseMaterial.define('USE_TINT', useTint);
|
||
|
+ baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
|
||
|
+ }
|
||
|
|
||
|
let srcBlendFactor = this.premultipliedAlpha ? cc.gfx.BLEND_ONE : cc.gfx.BLEND_SRC_ALPHA;
|
||
|
let dstBlendFactor = cc.gfx.BLEND_ONE_MINUS_SRC_ALPHA;
|
||
|
@@ -468,6 +481,11 @@ sp.Skeleton = cc.Class({
|
||
|
cc.gfx.BLEND_FUNC_ADD,
|
||
|
dstBlendFactor, dstBlendFactor
|
||
|
);
|
||
|
+
|
||
|
+ if (isMultiSupport) {
|
||
|
+ if (this.useTint) this.useTint = false;
|
||
|
+ if (!this.enableBatch) this.enableBatch = true;
|
||
|
+ }
|
||
|
}
|
||
|
this._materialCache = {};
|
||
|
},
|
||
|
@@ -493,7 +511,11 @@ sp.Skeleton = cc.Class({
|
||
|
let baseMaterial = this.getMaterial(0);
|
||
|
if (baseMaterial) {
|
||
|
let useTint = this.useTint || (this.isAnimationCached() && !CC_NATIVERENDERER);
|
||
|
- baseMaterial.define('USE_TINT', useTint);
|
||
|
+ if (!baseMaterial.material.isMultiSupport()) {
|
||
|
+ baseMaterial.define('USE_TINT', useTint);
|
||
|
+ } else {
|
||
|
+ if (this.useTint) this.useTint = false;
|
||
|
+ }
|
||
|
}
|
||
|
this._materialCache = {};
|
||
|
},
|
||
|
@@ -502,7 +524,11 @@ sp.Skeleton = cc.Class({
|
||
|
_updateBatch () {
|
||
|
let baseMaterial = this.getMaterial(0);
|
||
|
if (baseMaterial) {
|
||
|
- baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
|
||
|
+ if (!baseMaterial.material.isMultiSupport()) {
|
||
|
+ baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
|
||
|
+ } else {
|
||
|
+ if (!this.enableBatch) this.enableBatch = true;
|
||
|
+ }
|
||
|
}
|
||
|
this._materialCache = {};
|
||
|
},
|
||
|
@@ -955,6 +981,37 @@ sp.Skeleton = cc.Class({
|
||
|
this.invalidAnimationCache();
|
||
|
},
|
||
|
|
||
|
+ /**
|
||
|
+ * 获取 attachment 的 region
|
||
|
+ */
|
||
|
+ getRegion(slotName, attachmentName) {
|
||
|
+ const attachment = this.getAttachment(slotName, attachmentName);
|
||
|
+ if (attachment) {
|
||
|
+ return attachment.region;
|
||
|
+ }
|
||
|
+ return null;
|
||
|
+ },
|
||
|
+
|
||
|
+ /**
|
||
|
+ * 修改 attachment 的 region
|
||
|
+ */
|
||
|
+ setRegion(slotName, attachmentName, region) {
|
||
|
+ const attachment = this.getAttachment(slotName, attachmentName);
|
||
|
+ if (attachment) {
|
||
|
+ attachment.region = region;
|
||
|
+ if (attachment instanceof sp.spine.MeshAttachment) {
|
||
|
+ attachment.updateUVs();
|
||
|
+ } else if (attachment instanceof sp.spine.RegionAttachment) {
|
||
|
+ attachment.setRegion(region);
|
||
|
+ attachment.updateOffset();
|
||
|
+ }
|
||
|
+ this._dataDirty = true;
|
||
|
+ this.invalidAnimationCache();
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ return false;
|
||
|
+ },
|
||
|
+
|
||
|
/**
|
||
|
* Return the renderer of attachment.
|
||
|
* @method getTextureAtlas
|
||
|
@@ -1335,6 +1392,7 @@ sp.Skeleton = cc.Class({
|
||
|
this.attachUtil._associateAttachedNode();
|
||
|
this._preCacheMode = this._cacheMode;
|
||
|
this.animation = this.defaultAnimation;
|
||
|
+ this._dataDirty = true;
|
||
|
},
|
||
|
|
||
|
_refreshInspector () {
|
||
|
diff --git a/engine/extensions/spine/lib/spine.js b/engine/extensions/spine/lib/spine.js
|
||
|
index 857b433..fa12640 100644
|
||
|
--- a/engine/extensions/spine/lib/spine.js
|
||
|
+++ b/engine/extensions/spine/lib/spine.js
|
||
|
@@ -8004,7 +8004,7 @@ var spine;
|
||
|
RegionAttachment.prototype.setRegion = function (region) {
|
||
|
this.region = region;
|
||
|
var uvs = this.uvs;
|
||
|
- if (region.rotate) {
|
||
|
+ if (region.degrees === 90) {
|
||
|
uvs[2] = region.u;
|
||
|
uvs[3] = region.v2;
|
||
|
uvs[4] = region.u;
|
||
|
@@ -8013,8 +8013,16 @@ var spine;
|
||
|
uvs[7] = region.v;
|
||
|
uvs[0] = region.u2;
|
||
|
uvs[1] = region.v2;
|
||
|
- }
|
||
|
- else {
|
||
|
+ } else if (region.degrees === 270) {
|
||
|
+ uvs[6] = region.u;
|
||
|
+ uvs[7] = region.v2;
|
||
|
+ uvs[0] = region.u;
|
||
|
+ uvs[1] = region.v;
|
||
|
+ uvs[2] = region.u2;
|
||
|
+ uvs[3] = region.v;
|
||
|
+ uvs[4] = region.u2;
|
||
|
+ uvs[5] = region.v2;
|
||
|
+ } else {
|
||
|
uvs[0] = region.u;
|
||
|
uvs[1] = region.v2;
|
||
|
uvs[2] = region.u;
|
||
|
diff --git a/engine/extensions/spine/skeleton-data.js b/engine/extensions/spine/skeleton-data.js
|
||
|
index a7bdb10..9f233ed 100644
|
||
|
--- a/engine/extensions/spine/skeleton-data.js
|
||
|
+++ b/engine/extensions/spine/skeleton-data.js
|
||
|
@@ -139,6 +139,74 @@ let SkeletonData = cc.Class({
|
||
|
|
||
|
statics: {
|
||
|
preventDeferredLoadDependents: true,
|
||
|
+
|
||
|
+ createRegion(spriteFrame, original = undefined) {
|
||
|
+ const region = new sp.spine.TextureAtlasRegion();
|
||
|
+
|
||
|
+ const texture = spriteFrame.getTexture();
|
||
|
+ const rect = spriteFrame.getRect();
|
||
|
+ const origSize = spriteFrame.getOriginalSize();
|
||
|
+ const _offset = spriteFrame.getOffset();
|
||
|
+ const rotate = spriteFrame.isRotated();
|
||
|
+ const offset = cc.v2(
|
||
|
+ (origSize.width - rect.width) * 0.5 + _offset.x,
|
||
|
+ (origSize.height - rect.height) * 0.5 + _offset.y,
|
||
|
+ );
|
||
|
+ const degrees = rotate ? 270 : 0;
|
||
|
+
|
||
|
+ if (original) {
|
||
|
+ region.name = original.name;
|
||
|
+ region.page = original.page;
|
||
|
+ }
|
||
|
+
|
||
|
+ region.x = rect.x;
|
||
|
+ region.y = rect.y;
|
||
|
+ region.width = rect.width;
|
||
|
+ region.height = rect.height;
|
||
|
+ region.originalWidth = origSize.width;
|
||
|
+ region.originalHeight = origSize.height;
|
||
|
+ region.offsetX = offset.x;
|
||
|
+ region.offsetY = offset.y;
|
||
|
+ region.rotate = degrees != 0;
|
||
|
+ region.degrees = degrees;
|
||
|
+
|
||
|
+ const skelTex = new sp.SkeletonTexture({
|
||
|
+ width: texture.width,
|
||
|
+ height: texture.height,
|
||
|
+ });
|
||
|
+ skelTex.setRealTexture(texture);
|
||
|
+ region.texture = skelTex;
|
||
|
+
|
||
|
+ this.updateRegionUV(region);
|
||
|
+
|
||
|
+ return region;
|
||
|
+ },
|
||
|
+
|
||
|
+ updateRegionUV(region) {
|
||
|
+ const texture = region.texture._texture;
|
||
|
+ if (region.rotate) {
|
||
|
+ region.u = region.x / texture.width;
|
||
|
+ region.v = region.y / texture.height;
|
||
|
+ region.u2 = (region.x + region.height) / texture.width;
|
||
|
+ region.v2 = (region.y + region.width) / texture.height;
|
||
|
+ } else {
|
||
|
+ region.u = region.x / texture.width;
|
||
|
+ region.v = region.y / texture.height;
|
||
|
+ region.u2 = (region.x + region.width) / texture.width;
|
||
|
+ region.v2 = (region.y + region.height) / texture.height;
|
||
|
+ }
|
||
|
+ },
|
||
|
+
|
||
|
+ createSpriteFrame(region) {
|
||
|
+ const frame = new cc.SpriteFrame(
|
||
|
+ region.texture._texture,
|
||
|
+ cc.rect(region.x, region.y, region.width, region.height),
|
||
|
+ region.rotate, // 如果 region 不是 0 或 270 则会出现问题
|
||
|
+ cc.v2(region.offsetX - (region.originalWidth - region.width) * 0.5, region.offsetY - (region.originalHeight - region.height) * 0.5),
|
||
|
+ cc.size(region.originalWidth, region.originalHeight),
|
||
|
+ );
|
||
|
+ return frame;
|
||
|
+ },
|
||
|
},
|
||
|
|
||
|
// PUBLIC
|
||
|
@@ -166,6 +234,7 @@ let SkeletonData = cc.Class({
|
||
|
this._skinsEnum = null;
|
||
|
this._animsEnum = null;
|
||
|
}
|
||
|
+ this._cloneId = 0;
|
||
|
},
|
||
|
|
||
|
ensureTexturesLoaded (loaded, caller) {
|
||
|
@@ -322,7 +391,50 @@ let SkeletonData = cc.Class({
|
||
|
return this._atlasCache = new sp.spine.TextureAtlas(this.atlasText, this._getTexture.bind(this));
|
||
|
},
|
||
|
|
||
|
- destroy () {
|
||
|
+ /**
|
||
|
+ * 克隆 SkeletonData
|
||
|
+ */
|
||
|
+ clone: function () {
|
||
|
+ const cloned = new SkeletonData();
|
||
|
+ cloned._cloneId = this._cloneId + 1;
|
||
|
+ const suffix = '(clone ' + String(cloned._cloneId) + ')';
|
||
|
+ cloned._uuid = this._uuid + suffix;
|
||
|
+ cloned.name = this.name + suffix;
|
||
|
+ cloned.scale = this.scale;
|
||
|
+ cloned.textureNames = this.textureNames;
|
||
|
+ cloned.textures = this.textures;
|
||
|
+ cloned._atlasText = this._atlasText;
|
||
|
+ cloned._skeletonJson = this._skeletonJson;
|
||
|
+ cloned._buffer = this._buffer;
|
||
|
+
|
||
|
+ return cloned;
|
||
|
+ },
|
||
|
+
|
||
|
+ destroy() {
|
||
|
+ // 删除动态图集
|
||
|
+ if (this._atlasCache) {
|
||
|
+ const regions = this._atlasCache.regions;
|
||
|
+ for (const region of regions) {
|
||
|
+ if (region._spriteFrame) {
|
||
|
+ region._spriteFrame.destroy();
|
||
|
+ region._spriteFrame = null;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (this._skeletonCache) {
|
||
|
+ const skins = this._skeletonCache.skins;
|
||
|
+ for (const skin of skins) {
|
||
|
+ for (const attachments of skin.attachments) {
|
||
|
+ for (const key in attachments) {
|
||
|
+ const region = attachments[key].region;
|
||
|
+ if (region && region._spriteFrame) {
|
||
|
+ region._spriteFrame.destroy();
|
||
|
+ region._spriteFrame = null;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
SkeletonCache.removeSkeleton(this._uuid);
|
||
|
this._super();
|
||
|
},
|
||
|
diff --git a/engine/extensions/spine/spine-assembler.js b/engine/extensions/spine/spine-assembler.js
|
||
|
index 652af54..36c91f0 100644
|
||
|
--- a/engine/extensions/spine/spine-assembler.js
|
||
|
+++ b/engine/extensions/spine/spine-assembler.js
|
||
|
@@ -30,6 +30,7 @@ const spine = require('./lib/spine');
|
||
|
const RenderFlow = require('../../cocos2d/core/renderer/render-flow');
|
||
|
const VertexFormat = require('../../cocos2d/core/renderer/webgl/vertex-format')
|
||
|
const VFOneColor = VertexFormat.vfmtPosUvColor;
|
||
|
+const VFOneColorTexId = VertexFormat.vfmtPosUvColorTexId;
|
||
|
const VFTwoColor = VertexFormat.vfmtPosUvTwoColor;
|
||
|
const gfx = cc.gfx;
|
||
|
|
||
|
@@ -58,6 +59,8 @@ let _multiplier;
|
||
|
let _slotRangeStart;
|
||
|
let _slotRangeEnd;
|
||
|
let _useTint;
|
||
|
+let _useMulti;
|
||
|
+let _texId;
|
||
|
let _debugSlots;
|
||
|
let _debugBones;
|
||
|
let _debugMesh;
|
||
|
@@ -105,34 +108,67 @@ function _getSlotMaterial (tex, blendMode) {
|
||
|
let baseMaterial = _comp._materials[0];
|
||
|
if (!baseMaterial) return null;
|
||
|
|
||
|
- // The key use to find corresponding material
|
||
|
- let key = tex.getId() + src + dst + _useTint + useModel;
|
||
|
- let materialCache = _comp._materialCache;
|
||
|
- let material = materialCache[key];
|
||
|
- if (!material) {
|
||
|
- if (!materialCache.baseMaterial) {
|
||
|
- material = baseMaterial;
|
||
|
- materialCache.baseMaterial = baseMaterial;
|
||
|
- } else {
|
||
|
- material = cc.MaterialVariant.create(baseMaterial);
|
||
|
+ if (_useMulti) {
|
||
|
+ let key = tex.getId() + src + dst;
|
||
|
+ let materialCache = _comp._materialCache;
|
||
|
+ let materialInfo = materialCache[key];
|
||
|
+ if (!materialInfo) {
|
||
|
+ let texId = baseMaterial.material.getMultiHandler().getIndex(tex.getImpl());
|
||
|
+ if (!materialCache.baseMaterial) {
|
||
|
+ materialInfo = { material: baseMaterial, texId: texId };
|
||
|
+ materialCache.baseMaterial = materialInfo;
|
||
|
+ } else {
|
||
|
+ materialInfo = { material: cc.MaterialVariant.create(baseMaterial), texId: texId };
|
||
|
+ }
|
||
|
+
|
||
|
+ if (texId === -1) {
|
||
|
+ materialInfo.material.setProperty('texture', tex);
|
||
|
+ materialInfo.texId = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ // update blend function
|
||
|
+ materialInfo.material.setBlend(
|
||
|
+ true,
|
||
|
+ gfx.BLEND_FUNC_ADD,
|
||
|
+ src, dst,
|
||
|
+ gfx.BLEND_FUNC_ADD,
|
||
|
+ src, dst
|
||
|
+ );
|
||
|
+ materialCache[key] = materialInfo;
|
||
|
}
|
||
|
-
|
||
|
- material.define('CC_USE_MODEL', useModel);
|
||
|
- material.define('USE_TINT', _useTint);
|
||
|
- // update texture
|
||
|
- material.setProperty('texture', tex);
|
||
|
-
|
||
|
- // update blend function
|
||
|
- material.setBlend(
|
||
|
- true,
|
||
|
- gfx.BLEND_FUNC_ADD,
|
||
|
- src, dst,
|
||
|
- gfx.BLEND_FUNC_ADD,
|
||
|
- src, dst
|
||
|
- );
|
||
|
- materialCache[key] = material;
|
||
|
+ _texId = materialInfo.texId;
|
||
|
+ return materialInfo.material;
|
||
|
+ } else {
|
||
|
+ // The key use to find corresponding material
|
||
|
+ let key = tex.getId() + src + dst + _useTint + useModel;
|
||
|
+ let materialCache = _comp._materialCache;
|
||
|
+ let material = materialCache[key];
|
||
|
+ if (!material) {
|
||
|
+ if (!materialCache.baseMaterial) {
|
||
|
+ material = baseMaterial;
|
||
|
+ materialCache.baseMaterial = baseMaterial;
|
||
|
+ } else {
|
||
|
+ material = cc.MaterialVariant.create(baseMaterial);
|
||
|
+ }
|
||
|
+
|
||
|
+ material.define('CC_USE_MODEL', useModel);
|
||
|
+ material.define('USE_TINT', _useTint);
|
||
|
+ // update texture
|
||
|
+ material.setProperty('texture', tex);
|
||
|
+
|
||
|
+ // update blend function
|
||
|
+ material.setBlend(
|
||
|
+ true,
|
||
|
+ gfx.BLEND_FUNC_ADD,
|
||
|
+ src, dst,
|
||
|
+ gfx.BLEND_FUNC_ADD,
|
||
|
+ src, dst
|
||
|
+ );
|
||
|
+ materialCache[key] = material;
|
||
|
+ }
|
||
|
+
|
||
|
+ return material;
|
||
|
}
|
||
|
- return material;
|
||
|
}
|
||
|
|
||
|
function _handleColor (color) {
|
||
|
@@ -162,12 +198,112 @@ function _spineColorToInt32 (spineColor) {
|
||
|
export default class SpineAssembler extends Assembler {
|
||
|
updateRenderData (comp) {
|
||
|
if (comp.isAnimationCached()) return;
|
||
|
+
|
||
|
+ if (comp._dataDirty) {
|
||
|
+ // 自动合图
|
||
|
+ this.packDynamicAtlasForSpine(comp);
|
||
|
+
|
||
|
+ // 自动切换材质
|
||
|
+ const autoSwitchMaterial = comp.autoSwitchMaterial;
|
||
|
+ if ((cc.sp.autoSwitchMaterial && autoSwitchMaterial === 0) || autoSwitchMaterial === 1) {
|
||
|
+ const material = comp._materials[0];
|
||
|
+ if (!material) return false;
|
||
|
+
|
||
|
+ const skins = comp.skeletonData._skeletonCache.skins;
|
||
|
+ for (const skin of skins) {
|
||
|
+ for (const attachment of skin.attachments) {
|
||
|
+ for (const key in attachment) {
|
||
|
+ const region = attachment[key].region;
|
||
|
+ if (region && region.texture) {
|
||
|
+ this.checkAndSwitchMaterial(comp, region.texture._texture, material);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ comp._dataDirty = false;
|
||
|
+ }
|
||
|
+
|
||
|
let skeleton = comp._skeleton;
|
||
|
if (skeleton) {
|
||
|
skeleton.updateWorldTransform();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ packDynamicAtlasForSpine(comp) {
|
||
|
+ if (CC_TEST) return false;
|
||
|
+
|
||
|
+ const allowDynamicAtlas = comp.allowDynamicAtlas;
|
||
|
+ if ((cc.sp.allowDynamicAtlas && allowDynamicAtlas === 0) || allowDynamicAtlas === 1) {
|
||
|
+ if (cc.dynamicAtlasManager) {
|
||
|
+ const skins = comp.skeletonData._skeletonCache.skins;
|
||
|
+ for (const skin of skins) {
|
||
|
+ for (const attachments of skin.attachments) {
|
||
|
+ for (const key in attachments) {
|
||
|
+ const attachment = attachments[key];
|
||
|
+ const region = attachment.region;
|
||
|
+ if (region && !region._original && region.texture && region.texture._texture.packable) {
|
||
|
+ if (region._spriteFrame) {
|
||
|
+ region._spriteFrame.destroy();
|
||
|
+ region._spriteFrame = null;
|
||
|
+ }
|
||
|
+ const frame = sp.SkeletonData.createSpriteFrame(region);
|
||
|
+ const packedFrame = cc.dynamicAtlasManager.insertSpriteFrame(frame);
|
||
|
+ if (packedFrame) {
|
||
|
+ frame._setDynamicAtlasFrame(packedFrame);
|
||
|
+
|
||
|
+ region._original = {
|
||
|
+ _texture: region.texture,
|
||
|
+ _x: region.x,
|
||
|
+ _y: region.y,
|
||
|
+ };
|
||
|
+
|
||
|
+ region.texture = new sp.SkeletonTexture({
|
||
|
+ width: packedFrame.texture.width,
|
||
|
+ height: packedFrame.texture.height,
|
||
|
+ });
|
||
|
+ region.texture.setRealTexture(packedFrame.texture);
|
||
|
+
|
||
|
+ region.x = packedFrame.x;
|
||
|
+ region.y = packedFrame.y;
|
||
|
+
|
||
|
+ // update uv
|
||
|
+ sp.SkeletonData.updateRegionUV(region);
|
||
|
+ if (attachment instanceof sp.spine.MeshAttachment) {
|
||
|
+ attachment.updateUVs();
|
||
|
+ } else {
|
||
|
+ attachment.setRegion(region);
|
||
|
+ attachment.updateOffset();
|
||
|
+ }
|
||
|
+
|
||
|
+ frame.once("_resetDynamicAtlasFrame", () => {
|
||
|
+ region.x = region._original._x;
|
||
|
+ region.y = region._original._y;
|
||
|
+ region.texture = region._original._texture;
|
||
|
+ region._original = null;
|
||
|
+
|
||
|
+ // update uv
|
||
|
+ sp.SkeletonData.updateRegionUV(region);
|
||
|
+ if (attachment instanceof sp.spine.MeshAttachment) {
|
||
|
+ attachment.updateUVs();
|
||
|
+ } else {
|
||
|
+ attachment.setRegion(region);
|
||
|
+ attachment.updateOffset();
|
||
|
+ }
|
||
|
+ });
|
||
|
+ region._spriteFrame = frame;
|
||
|
+ } else {
|
||
|
+ frame.destroy();
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
fillVertices (skeletonColor, attachmentColor, slotColor, clipper, slot) {
|
||
|
|
||
|
let vbuf = _buffer._vData,
|
||
|
@@ -207,16 +343,24 @@ export default class SpineAssembler extends Assembler {
|
||
|
vbuf[v + 1] = _tempPos.y; // y
|
||
|
vbuf[v + 2] = _tempUv.x; // u
|
||
|
vbuf[v + 3] = _tempUv.y; // v
|
||
|
- uintVData[v + 4] = _spineColorToInt32(_finalColor); // light color
|
||
|
- _useTint && (uintVData[v + 5] = _spineColorToInt32(_darkColor)); // dark color
|
||
|
+ uintVData[v + 4] = _spineColorToInt32(_finalColor); // light color
|
||
|
+ if (_useMulti) {
|
||
|
+ vbuf[v + 5] = _texId;
|
||
|
+ } else {
|
||
|
+ _useTint && (uintVData[v + 5] = _spineColorToInt32(_darkColor)); // dark color
|
||
|
+ }
|
||
|
}
|
||
|
} else {
|
||
|
_finalColor32 = _spineColorToInt32(_finalColor);
|
||
|
_darkColor32 = _spineColorToInt32(_darkColor);
|
||
|
|
||
|
for (let v = _vertexFloatOffset, n = _vertexFloatOffset + _vertexFloatCount; v < n; v += _perVertexSize) {
|
||
|
- uintVData[v + 4] = _finalColor32; // light color
|
||
|
- _useTint && (uintVData[v + 5] = _darkColor32); // dark color
|
||
|
+ uintVData[v + 4] = _finalColor32; // light color
|
||
|
+ if (_useMulti) {
|
||
|
+ vbuf[v + 5] = _texId;
|
||
|
+ } else {
|
||
|
+ _useTint && (uintVData[v + 5] = _darkColor32); // dark color
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
@@ -229,7 +373,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
_indexCount = clippedTriangles.length;
|
||
|
_vertexFloatCount = clippedVertices.length / _perClipVertexSize * _perVertexSize;
|
||
|
|
||
|
- offsetInfo = _buffer.request(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
+ offsetInfo = _buffer.requestForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
_indexOffset = offsetInfo.indiceOffset,
|
||
|
_vertexOffset = offsetInfo.vertexOffset,
|
||
|
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
|
||
|
@@ -260,8 +404,12 @@ export default class SpineAssembler extends Assembler {
|
||
|
vbuf[offset + 2] = _tempUv.x; // u
|
||
|
vbuf[offset + 3] = _tempUv.y; // v
|
||
|
uintVData[offset + 4] = _spineColorToInt32(_finalColor);
|
||
|
- if (_useTint) {
|
||
|
- uintVData[offset + 5] = _spineColorToInt32(_darkColor);
|
||
|
+ if (_useMulti) {
|
||
|
+ vbuf[offset + 5] = _texId;
|
||
|
+ } else {
|
||
|
+ if (_useTint) {
|
||
|
+ uintVData[offset + 5] = _spineColorToInt32(_darkColor);
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
@@ -273,10 +421,13 @@ export default class SpineAssembler extends Assembler {
|
||
|
|
||
|
_finalColor32 = ((clippedVertices[v + 5]<<24) >>> 0) + (clippedVertices[v + 4]<<16) + (clippedVertices[v + 3]<<8) + clippedVertices[v + 2];
|
||
|
uintVData[offset + 4] = _finalColor32;
|
||
|
-
|
||
|
- if (_useTint) {
|
||
|
- _darkColor32 = ((clippedVertices[v + 11]<<24) >>> 0) + (clippedVertices[v + 10]<<16) + (clippedVertices[v + 9]<<8) + clippedVertices[v + 8];
|
||
|
- uintVData[offset + 5] = _darkColor32;
|
||
|
+ if (_useMulti) {
|
||
|
+ vbuf[offset + 5] = _texId;
|
||
|
+ } else {
|
||
|
+ if (_useTint) {
|
||
|
+ _darkColor32 = ((clippedVertices[v + 11] << 24) >>> 0) + (clippedVertices[v + 10] << 16) + (clippedVertices[v + 9] << 8) + clippedVertices[v + 8];
|
||
|
+ uintVData[offset + 5] = _darkColor32;
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -312,7 +463,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
}
|
||
|
|
||
|
// x y u v r1 g1 b1 a1 r2 g2 b2 a2 or x y u v r g b a
|
||
|
- _perClipVertexSize = _useTint ? 12 : 8;
|
||
|
+ _perClipVertexSize = _useMulti ? 12 : (_useTint ? 12 : 8);
|
||
|
|
||
|
_vertexFloatCount = 0;
|
||
|
_vertexFloatOffset = 0;
|
||
|
@@ -384,7 +535,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
_vertexFloatCount = 4 * _perVertexSize;
|
||
|
_indexCount = 6;
|
||
|
|
||
|
- offsetInfo = _buffer.request(4, 6);
|
||
|
+ offsetInfo = _buffer.requestForSpine(4, 6);
|
||
|
_indexOffset = offsetInfo.indiceOffset,
|
||
|
_vertexOffset = offsetInfo.vertexOffset,
|
||
|
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
|
||
|
@@ -413,7 +564,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
_vertexFloatCount = (attachment.worldVerticesLength >> 1) * _perVertexSize;
|
||
|
_indexCount = triangles.length;
|
||
|
|
||
|
- offsetInfo = _buffer.request(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
+ offsetInfo = _buffer.requestForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
_indexOffset = offsetInfo.indiceOffset,
|
||
|
_vertexOffset = offsetInfo.vertexOffset,
|
||
|
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
|
||
|
@@ -485,7 +636,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
vbuf[ii + 1] = _x * _m01 + _y * _m05 + _m13;
|
||
|
}
|
||
|
}
|
||
|
- _buffer.adjust(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
+ _buffer.adjustForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
|
||
|
}
|
||
|
|
||
|
clipper.clipEndWithSlot(slot);
|
||
|
@@ -569,7 +720,7 @@ export default class SpineAssembler extends Assembler {
|
||
|
_vertexCount = segInfo.vertexCount;
|
||
|
_indexCount = segInfo.indexCount;
|
||
|
|
||
|
- offsetInfo = _buffer.request(_vertexCount, _indexCount);
|
||
|
+ offsetInfo = _buffer.requestForSpine(_vertexCount, _indexCount);
|
||
|
_indexOffset = offsetInfo.indiceOffset;
|
||
|
_vertexOffset = offsetInfo.vertexOffset;
|
||
|
_vfOffset = offsetInfo.byteOffset >> 2;
|
||
|
@@ -599,19 +750,28 @@ export default class SpineAssembler extends Assembler {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- _buffer.adjust(_vertexCount, _indexCount);
|
||
|
- if ( !_needColor ) continue;
|
||
|
+ _buffer.adjustForSpine(_vertexCount, _indexCount);
|
||
|
|
||
|
- // handle color
|
||
|
- let frameColorOffset = frameVFOffset - segVFCount;
|
||
|
- for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6, frameColorOffset += 6) {
|
||
|
- if (frameColorOffset >= maxVFOffset) {
|
||
|
- nowColor = colors[colorOffset++];
|
||
|
- _handleColor(nowColor);
|
||
|
- maxVFOffset = nowColor.vfOffset;
|
||
|
+ if (_needColor) {
|
||
|
+ // handle color
|
||
|
+ let frameColorOffset = frameVFOffset - segVFCount;
|
||
|
+ for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6, frameColorOffset += 6) {
|
||
|
+ if (frameColorOffset >= maxVFOffset) {
|
||
|
+ nowColor = colors[colorOffset++];
|
||
|
+ _handleColor(nowColor);
|
||
|
+ maxVFOffset = nowColor.vfOffset;
|
||
|
+ }
|
||
|
+ uintbuf[ii] = _finalColor32;
|
||
|
+ if (_useMulti) {
|
||
|
+ vbuf[ii + 1] = _texId;
|
||
|
+ } else {
|
||
|
+ uintbuf[ii + 1] = _darkColor32;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ } else if (_useMulti) {
|
||
|
+ for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6) {
|
||
|
+ vbuf[ii + 1] = _texId;
|
||
|
}
|
||
|
- uintbuf[ii] = _finalColor32;
|
||
|
- uintbuf[ii + 1] = _darkColor32;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -628,13 +788,17 @@ export default class SpineAssembler extends Assembler {
|
||
|
_nodeB = nodeColor.b / 255;
|
||
|
_nodeA = nodeColor.a / 255;
|
||
|
|
||
|
- _useTint = comp.useTint || comp.isAnimationCached();
|
||
|
- _vertexFormat = _useTint? VFTwoColor : VFOneColor;
|
||
|
+ let baseMaterial = comp._materials[0];
|
||
|
+ if (!baseMaterial) return;
|
||
|
+
|
||
|
+ _useMulti = baseMaterial.material.isMultiSupport();
|
||
|
+ _useTint = !_useMulti && (comp.useTint || comp.isAnimationCached());
|
||
|
+ _vertexFormat = _useMulti ? VFOneColorTexId : (_useTint ? VFTwoColor : VFOneColor);
|
||
|
// x y u v color1 color2 or x y u v color
|
||
|
- _perVertexSize = _useTint ? 6 : 5;
|
||
|
+ _perVertexSize = _useMulti ? 6 :(_useTint ? 6 : 5);
|
||
|
|
||
|
_node = comp.node;
|
||
|
- _buffer = renderer.getBuffer('spine', _vertexFormat);
|
||
|
+ _buffer = renderer.getBuffer('mesh', _vertexFormat);
|
||
|
_renderer = renderer;
|
||
|
_comp = comp;
|
||
|
|
||
|
--
|
||
|
2.32.0 (Apple Git-132)
|
||
|
|