Skip to content

Commit

Permalink
Support Spine and DragonBones attach node (cocos#5854)
Browse files Browse the repository at this point in the history
* Attached node first commit

* Attached node first commit

* Attached node first commit

* Dragonbones attached node finished

* Dragonbones attached node finished

* Dragonbones attached node finished

* spine attached node finished

* Matrix4 has hole…

* Rename function

* optimize loop times

* remove matrix deep copy interface by jare request
remove reset invoke

* modify word

* material issue
  • Loading branch information
sunnylanwanjun authored and SantyWang committed Dec 13, 2019
1 parent b5408c9 commit 6be59a1
Show file tree
Hide file tree
Showing 14 changed files with 1,081 additions and 59 deletions.
8 changes: 1 addition & 7 deletions cocos2d/core/value-types/mat3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -819,13 +819,7 @@ export default class Mat3 {
m06 = 0, m07 = 0, m08 = 1
) {
if (m00 instanceof FLOAT_ARRAY_TYPE) {
// deep copy
if (m01) {
this.m = new FLOAT_ARRAY_TYPE(9);
this.m.set(m00);
} else {
this.m = m00;
}
this.m = m00;
} else {
this.m = new FLOAT_ARRAY_TYPE(9);
let m = this.m;
Expand Down
42 changes: 23 additions & 19 deletions cocos2d/core/value-types/mat4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1633,29 +1633,33 @@ export default class Mat4 extends ValueType {
)
*/
constructor (
m00: number = 1, m01: number = 0, m02: number = 0, m03: number = 0,
m00: number | FloatArray = 1, m01: number = 0, m02: number = 0, m03: number = 0,
m10: number = 0, m11: number = 1, m12: number = 0, m13: number = 0,
m20: number = 0, m21: number = 0, m22: number = 1, m23: number = 0,
m30: number = 0, m31: number = 0, m32: number = 0, m33: number = 1) {
super();
this.m = new FLOAT_ARRAY_TYPE(16);
let tm = this.m;
tm[0] = m00;
tm[1] = m01;
tm[2] = m02;
tm[3] = m03;
tm[4] = m10;
tm[5] = m11;
tm[6] = m12;
tm[7] = m13;
tm[8] = m20;
tm[9] = m21;
tm[10] = m22;
tm[11] = m23;
tm[12] = m30;
tm[13] = m31;
tm[14] = m32;
tm[15] = m33;
if (m00 instanceof FLOAT_ARRAY_TYPE) {
this.m = m00;
} else {
this.m = new FLOAT_ARRAY_TYPE(16);
let tm = this.m;
tm[0] = m00;
tm[1] = m01;
tm[2] = m02;
tm[3] = m03;
tm[4] = m10;
tm[5] = m11;
tm[6] = m12;
tm[7] = m13;
tm[8] = m20;
tm[9] = m21;
tm[10] = m22;
tm[11] = m23;
tm[12] = m30;
tm[13] = m31;
tm[14] = m32;
tm[15] = m33;
}
}

/**
Expand Down
7 changes: 3 additions & 4 deletions cocos2d/core/value-types/vec2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,10 +622,9 @@ export default class Vec2 extends ValueType {
if (x && typeof x === 'object') {
this.y = x.y || 0;
this.x = x.x || 0;
}
else {
this.x = x as number;
this.y = y;
} else {
this.x = x as number || 0;
this.y = y || 0;
}
}

Expand Down
2 changes: 1 addition & 1 deletion cocos2d/tilemap/CCTiledLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,7 @@ let TiledLayer = cc.Class({

texIdMatIdx[tilesetIdx] = i;
}

this.markForRender(true);
}
});

Expand Down
3 changes: 3 additions & 0 deletions editor/i18n/en/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,5 +432,8 @@ module.exports = {
'skeleton_animation': {
'search_animation_clips': 'Search Animation Clips',
},
'attach_util': {
"generate_attached_node": "Generate Attached Node"
}
}
};
7 changes: 5 additions & 2 deletions editor/i18n/zh/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ module.exports = {
"premultipliedAlpha": "是否启用贴图预乘",
"use_tint": "是否启用染色效果",
"enabled_batch": "是否开启合批",
"animation_cache_mode": "REALTIME 模式,实时运算,支持 Spine 所有的功能。\nSHARED_CACHE 模式,将骨骼动画及贴图数据进行缓存并共享,相当于预烘焙骨骼动画。拥有较高性能,但不支持动作融合、动作叠加,只支持动作开始和结束事件。至于内存方面,当创建 N(N>=3) 个相同骨骼、相同动作的动画时,会呈现内存优势。N 值越大,优势越明显。综上 SHARED_CACHE 模式适用于场景动画,特效,副本怪物,NPC 等,能极大提高帧率和降低内存。\nPRIVATE_CACHE 模式,与 SHARED_CACHE 类似,但不共享动画及贴图数据,所以在内存方面没有优势,仅存在性能优势。当想利用缓存模式的高性能,但又存在换装的需求,因此不能共享贴图数据时,那么 PRIVATE_CACHE 就适合你。",
"animation_cache_mode": "REALTIME 模式,实时运算,支持 Spine 所有的功能。\nSHARED_CACHE 模式,将骨骼动画及贴图数据进行缓存并共享,相当于预烘焙骨骼动画。拥有较高性能,但不支持动作融合、动作叠加,只支持动作开始和结束事件。至于内存方面,当创建 N(N>=3) 个相同骨骼、相同动作的动画时,会呈现内存优势。N 值越大,优势越明显。综上 SHARED_CACHE 模式适用于场景动画,特效,副本怪物,NPC 等,能极大提高帧率和降低内存。\nPRIVATE_CACHE 模式,与 SHARED_CACHE 类似,但不共享动画及贴图数据,所以在内存方面没有优势,仅存在性能优势。当想利用缓存模式的高性能,但又存在换装的需求,因此不能共享贴图数据时,那么 PRIVATE_CACHE 就适合你。"
},
"dragon_bones": {
"dragon_bones_asset": "骨骼信息数据,拖拽 DragonBones 导出的骨骼动画信息 json 资源到这里来开始使用",
Expand All @@ -302,7 +302,7 @@ module.exports = {
"play_times": "播放默认动画的循环次数\n-1 表示使用配置文件中的默认值\n0 表示无限循环\n>0 表示循环次数",
"debug_bones": "是否显示 bone 的 debug 信息",
"enabled_batch": "是否开启合批",
"animation_cache_mode": "REALTIME 模式,实时运算,支持 DragonBones 所有的功能。\nSHARED_CACHE 模式,将骨骼动画及贴图数据进行缓存并共享,相当于预烘焙骨骼动画。拥有较高性能,但不支持动作融合、动作叠加、骨骼嵌套,只支持动作开始和结束事件。至于内存方面,当创建 N(N>=3) 个相同骨骼、相同动作的动画时,会呈现内存优势。N 值越大,优势越明显。综上 SHARED_CACHE 模式适用于场景动画,特效,副本怪物,NPC 等,能极大提高帧率和降低内存。\nPRIVATE_CACHE 模式,与 SHARED_CACHE 类似,但不共享动画及贴图数据,所以在内存方面没有优势,仅存在性能优势。当想利用缓存模式的高性能,但又存在换装的需求,因此不能共享贴图数据时,那么 PRIVATE_CACHE 就适合你。",
"animation_cache_mode": "REALTIME 模式,实时运算,支持 DragonBones 所有的功能。\nSHARED_CACHE 模式,将骨骼动画及贴图数据进行缓存并共享,相当于预烘焙骨骼动画。拥有较高性能,但不支持动作融合、动作叠加、骨骼嵌套,只支持动作开始和结束事件。至于内存方面,当创建 N(N>=3) 个相同骨骼、相同动作的动画时,会呈现内存优势。N 值越大,优势越明显。综上 SHARED_CACHE 模式适用于场景动画,特效,副本怪物,NPC 等,能极大提高帧率和降低内存。\nPRIVATE_CACHE 模式,与 SHARED_CACHE 类似,但不共享动画及贴图数据,所以在内存方面没有优势,仅存在性能优势。当想利用缓存模式的高性能,但又存在换装的需求,因此不能共享贴图数据时,那么 PRIVATE_CACHE 就适合你。"
},
'motionStreak': {
'fadeTime': "拖尾的渐隐时间,以秒为单位",
Expand Down Expand Up @@ -436,5 +436,8 @@ module.exports = {
'skeleton_animation': {
'search_animation_clips': '搜索骨骼动画',
},
'attach_util': {
"generate_attached_node": "生成挂点"
}
}
};
34 changes: 33 additions & 1 deletion extensions/dragonbones/ArmatureCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const FrameTime = 1 / 60;

let _vertices = [];
let _indices = [];
let _boneInfoOffset = 0;
let _vertexOffset = 0;
let _indexOffset = 0;
let _vfOffset = 0;
Expand All @@ -44,6 +45,7 @@ let AnimationCache = cc.Class({
ctor () {
this._inited = false;
this._invalid = true;
this._enableCacheAttachedInfo = false;
this.frames = [];
this.totalTime = 0;
this.isCompleted = false;
Expand All @@ -53,6 +55,7 @@ let AnimationCache = cc.Class({
this._animationName = null;
this._tempSegments = null;
this._tempColors = null;
this._tempBoneInfos = null;
},

init (armatureInfo, animationName) {
Expand Down Expand Up @@ -146,8 +149,16 @@ let AnimationCache = cc.Class({
this.updateToFrame();
},

enableCacheAttachedInfo () {
if (!this._enableCacheAttachedInfo) {
this._enableCacheAttachedInfo = true;
this.invalidAllFrame();
}
},

_updateFrame (armature, index) {
_vfOffset = 0;
_boneInfoOffset = 0;
_indexOffset = 0;
_vertexOffset = 0;
_preTexUrl = null;
Expand All @@ -161,6 +172,7 @@ let AnimationCache = cc.Class({
this.frames[index] = this.frames[index] || {
segments : [],
colors : [],
boneInfos : [],
vertices : null,
uintVert : null,
indices : null,
Expand All @@ -169,6 +181,7 @@ let AnimationCache = cc.Class({

let segments = this._tempSegments = frame.segments;
let colors = this._tempColors = frame.colors;
let boneInfos = this._tempBoneInfos = frame.boneInfos;
this._traverseArmature(armature, 1.0);
// At last must handle pre color and segment.
// Because vertex count will right at the end.
Expand All @@ -177,6 +190,8 @@ let AnimationCache = cc.Class({
colors[_colorOffset - 1].vfOffset = _vfOffset;
}
colors.length = _colorOffset;
boneInfos.length = _boneInfoOffset;

// Handle pre segment
let preSegOffset = _segOffset - 1;
if (preSegOffset >= 0) {
Expand Down Expand Up @@ -228,20 +243,37 @@ let AnimationCache = cc.Class({
_traverseArmature (armature, parentOpacity) {
let colors = this._tempColors;
let segments = this._tempSegments;
let boneInfos = this._tempBoneInfos;
let gVertices = _vertices;
let gIndices = _indices;
let slotVertices, slotIndices;
let slots = armature._slots, slot, slotMatrix, slotMatrixm, slotColor, colorVal;
let texture;
let preSegOffset, preSegInfo;
let bones = armature._bones;

if (this._enableCacheAttachedInfo) {
for (let i = 0, l = bones.length; i < l; i++, _boneInfoOffset++) {
let bone = bones[i];
let boneInfo = boneInfos[_boneInfoOffset];
if (!boneInfo) {
boneInfo = boneInfos[_boneInfoOffset] = {
globalTransformMatrix: new dragonBones.Matrix(),
};
}
let boneMat = bone.globalTransformMatrix;
let cacheBoneMat = boneInfo.globalTransformMatrix;
cacheBoneMat.copyFrom(boneMat);
}
}

for (let i = 0, l = slots.length; i < l; i++) {
slot = slots[i];
if (!slot._visible || !slot._displayData) continue;

slot.updateWorldMatrix();
slotColor = slot._color;

if (slot.childArmature) {
this._traverseArmature(slot.childArmature, parentOpacity * slotColor.a / 255);
continue;
Expand Down
24 changes: 21 additions & 3 deletions extensions/dragonbones/ArmatureDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ let EventTarget = require('../../cocos2d/core/event/event-target');

const Node = require('../../cocos2d/core/CCNode');
const Graphics = require('../../cocos2d/core/graphics/graphics');
const RenderFlow = require('../../cocos2d/core/renderer/render-flow');
const FLAG_POST_RENDER = RenderFlow.FLAG_POST_RENDER;

let ArmatureCache = require('./ArmatureCache');
let AttachUtil = require('./AttachUtil');

/**
* @module dragonBones
Expand Down Expand Up @@ -97,7 +100,7 @@ let ArmatureDisplay = cc.Class({

editor: CC_EDITOR && {
menu: 'i18n:MAIN_MENU.component.renderers/DragonBones',
//help: 'app://docs/html/components/dragonbones.html', // TODO help document of dragonBones
inspector: 'packages://inspector/inspectors/comps/skeleton2d.js',
},

statics: {
Expand Down Expand Up @@ -393,6 +396,7 @@ let ArmatureDisplay = cc.Class({
this._eventTarget = new EventTarget();
this._materialCache = {};
this._inited = false;
this.attachUtil = new AttachUtil();
this._factory = dragonBones.CCFactory.getInstance();
},

Expand Down Expand Up @@ -423,12 +427,18 @@ let ArmatureDisplay = cc.Class({
}
},

// override
// override base class setMaterial to clear material cache
setMaterial (index, material) {
this._super(index, material);
this._materialCache = {};
},

// override base class disableRender to clear post render flag
disableRender () {
this._super();
this.node._renderFlag &= ~FLAG_POST_RENDER;
},

__preload () {
this._resetAssembler();
this._init();
Expand Down Expand Up @@ -482,7 +492,6 @@ let ArmatureDisplay = cc.Class({
* armatureDisplay.setAnimationCacheMode(dragonBones.ArmatureDisplay.AnimationCacheMode.SHARED_CACHE);
*/
setAnimationCacheMode (cacheMode) {
if (CC_JSB) return;
if (this._preCacheMode !== cacheMode) {
this._cacheMode = cacheMode;
this._buildArmature();
Expand Down Expand Up @@ -655,6 +664,7 @@ let ArmatureDisplay = cc.Class({
// only when component's onEnable function has been invoke, need to enable render
if (this.node && this.node._renderComponent == this) {
this.markForRender(true);
this.node._renderFlag |= FLAG_POST_RENDER;
}
},

Expand Down Expand Up @@ -710,13 +720,18 @@ let ArmatureDisplay = cc.Class({
this._displayProxy.setEventTarget(this._eventTarget);
this._armature = this._displayProxy._armature;
this._armature.animation.timeScale = this.timeScale;
// If change mode or armature, armature must insert into clock.
this._factory._dragonBones.clock.add(this._armature);
}

if (this._cacheMode !== AnimationCacheMode.REALTIME && this.debugBones) {
cc.warn("Debug bones is invalid in cached mode");
}

this._updateBatch();
this.attachUtil.init(this);
this.attachUtil._associateAttachedNode();

if (this.animationName) {
this.playAnimation(this.animationName, this.playTimes);
}
Expand Down Expand Up @@ -802,6 +817,9 @@ let ArmatureDisplay = cc.Class({
this._accTime = 0;
this._playCount = 0;
this._frameCache = cache;
if (this.attachUtil._hasAttachedNode()) {
this._frameCache.enableCacheAttachedInfo();
}
this._frameCache.updateToFrame(0);
this._playing = true;
this._curFrame = this._frameCache.frames[0];
Expand Down
Loading

0 comments on commit 6be59a1

Please sign in to comment.