cocos-enhance-kit/patches/v1.0.0/0010-Spine-region-API.patch
2022-06-21 23:22:06 +08:00

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)