初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,521 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
const MaxCacheTime = 30;
const FrameTime = 1 / 60;
let _vertices = [];
let _indices = [];
let _boneInfoOffset = 0;
let _vertexOffset = 0;
let _indexOffset = 0;
let _vfOffset = 0;
let _preTexUrl = null;
let _preBlendMode = null;
let _segVCount = 0;
let _segICount = 0;
let _segOffset = 0;
let _colorOffset = 0;
let _preColor = null;
let _x, _y;
//Cache all frames in an animation
let AnimationCache = cc.Class({
ctor () {
this._privateMode = false;
this._inited = false;
this._invalid = true;
this._enableCacheAttachedInfo = false;
this.frames = [];
this.totalTime = 0;
this.isCompleted = false;
this._frameIdx = -1;
this._armatureInfo = null;
this._animationName = null;
this._tempSegments = null;
this._tempColors = null;
this._tempBoneInfos = null;
},
init (armatureInfo, animationName) {
this._inited = true;
this._armatureInfo = armatureInfo;
this._animationName = animationName;
},
// Clear texture quote.
clear () {
this._inited = false;
for (let i = 0, n = this.frames.length; i < n; i++) {
let frame = this.frames[i];
frame.segments.length = 0;
}
this.invalidAllFrame();
},
begin () {
if (!this._invalid) return;
let armatureInfo = this._armatureInfo;
let curAnimationCache = armatureInfo.curAnimationCache;
if (curAnimationCache && curAnimationCache != this) {
if (this._privateMode) {
curAnimationCache.invalidAllFrame();
} else {
curAnimationCache.updateToFrame();
}
}
let armature = armatureInfo.armature;
let animation = armature.animation;
animation.play(this._animationName, 1);
armatureInfo.curAnimationCache = this;
this._invalid = false;
this._frameIdx = -1;
this.totalTime = 0;
this.isCompleted = false;
},
end () {
if (!this._needToUpdate()) {
this._armatureInfo.curAnimationCache = null;
this.frames.length = this._frameIdx + 1;
this.isCompleted = true;
}
},
_needToUpdate (toFrameIdx) {
let armatureInfo = this._armatureInfo;
let armature = armatureInfo.armature;
let animation = armature.animation;
return !animation.isCompleted &&
this.totalTime < MaxCacheTime &&
(toFrameIdx == undefined || this._frameIdx < toFrameIdx);
},
updateToFrame (toFrameIdx) {
if (!this._inited) return;
this.begin();
if (!this._needToUpdate(toFrameIdx)) return;
let armatureInfo = this._armatureInfo;
let armature = armatureInfo.armature;
do {
// Solid update frame rate 1/60.
armature.advanceTime(FrameTime);
this._frameIdx++;
this._updateFrame(armature, this._frameIdx);
this.totalTime += FrameTime;
} while (this._needToUpdate(toFrameIdx));
this.end();
},
isInited () {
return this._inited;
},
isInvalid () {
return this._invalid;
},
invalidAllFrame () {
this.isCompleted = false;
this._invalid = true;
},
updateAllFrame () {
this.invalidAllFrame();
this.updateToFrame();
},
enableCacheAttachedInfo () {
if (!this._enableCacheAttachedInfo) {
this._enableCacheAttachedInfo = true;
this.invalidAllFrame();
}
},
_updateFrame (armature, index) {
_vfOffset = 0;
_boneInfoOffset = 0;
_indexOffset = 0;
_vertexOffset = 0;
_preTexUrl = null;
_preBlendMode = null;
_segVCount = 0;
_segICount = 0;
_segOffset = 0;
_colorOffset = 0;
_preColor = null;
this.frames[index] = this.frames[index] || {
segments : [],
colors : [],
boneInfos : [],
vertices : null,
uintVert : null,
indices : null,
};
let frame = this.frames[index];
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.
// Handle pre color.
if (_colorOffset > 0) {
colors[_colorOffset - 1].vfOffset = _vfOffset;
}
colors.length = _colorOffset;
boneInfos.length = _boneInfoOffset;
// Handle pre segment
let preSegOffset = _segOffset - 1;
if (preSegOffset >= 0) {
if (_segICount > 0) {
let preSegInfo = segments[preSegOffset];
preSegInfo.indexCount = _segICount;
preSegInfo.vfCount = _segVCount * 5;
preSegInfo.vertexCount = _segVCount;
segments.length = _segOffset;
} else {
segments.length = _segOffset - 1;
}
}
// Discard all segments.
if (segments.length === 0) return;
// Fill vertices
let vertices = frame.vertices;
let uintVert = frame.uintVert;
if (!vertices || vertices.length < _vfOffset) {
vertices = frame.vertices = new Float32Array(_vfOffset);
uintVert = frame.uintVert = new Uint32Array(vertices.buffer);
}
for (let i = 0, j = 0; i < _vfOffset;) {
vertices[i++] = _vertices[j++]; // x
vertices[i++] = _vertices[j++]; // y
vertices[i++] = _vertices[j++]; // u
vertices[i++] = _vertices[j++]; // v
uintVert[i++] = _vertices[j++]; // color
}
// Fill indices
let indices = frame.indices;
if (!indices || indices.length < _indexOffset) {
indices = frame.indices = new Uint16Array(_indexOffset);
}
for (let i = 0; i < _indexOffset; i++) {
indices[i] = _indices[i];
}
frame.vertices = vertices;
frame.uintVert = uintVert;
frame.indices = indices;
},
_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;
}
texture = slot.getTexture();
if (!texture) continue;
if (_preTexUrl !== texture.nativeUrl || _preBlendMode !== slot._blendMode) {
_preTexUrl = texture.nativeUrl;
_preBlendMode = slot._blendMode;
// Handle pre segment.
preSegOffset = _segOffset - 1;
if (preSegOffset >= 0) {
if (_segICount > 0) {
preSegInfo = segments[preSegOffset];
preSegInfo.indexCount = _segICount;
preSegInfo.vertexCount = _segVCount;
preSegInfo.vfCount = _segVCount * 5;
} else {
// Discard pre segment.
_segOffset--;
}
}
// Handle now segment.
segments[_segOffset] = {
tex : texture,
blendMode : slot._blendMode,
indexCount : 0,
vertexCount : 0,
vfCount : 0
};
_segOffset++;
_segICount = 0;
_segVCount = 0;
}
colorVal = ((slotColor.a * parentOpacity << 24) >>> 0) + (slotColor.b << 16) + (slotColor.g << 8) + slotColor.r;
if (_preColor !== colorVal) {
_preColor = colorVal;
if (_colorOffset > 0) {
colors[_colorOffset - 1].vfOffset = _vfOffset;
}
colors[_colorOffset++] = {
r : slotColor.r,
g : slotColor.g,
b : slotColor.b,
a : slotColor.a * parentOpacity,
vfOffset : 0
}
}
slotVertices = slot._localVertices;
slotIndices = slot._indices;
slotMatrix = slot._worldMatrix;
slotMatrixm = slotMatrix.m;
for (let j = 0, vl = slotVertices.length; j < vl;) {
_x = slotVertices[j++];
_y = slotVertices[j++];
gVertices[_vfOffset++] = _x * slotMatrixm[0] + _y * slotMatrixm[4] + slotMatrixm[12];
gVertices[_vfOffset++] = _x * slotMatrixm[1] + _y * slotMatrixm[5] + slotMatrixm[13];
gVertices[_vfOffset++] = slotVertices[j++];
gVertices[_vfOffset++] = slotVertices[j++];
gVertices[_vfOffset++] = colorVal;
}
// This place must use segment vertex count to calculate vertex offset.
// Assembler will calculate vertex offset again for different segment.
for (let ii = 0, il = slotIndices.length; ii < il; ii ++) {
gIndices[_indexOffset++] = _segVCount + slotIndices[ii];
}
_vertexOffset = _vfOffset / 5;
_segICount += slotIndices.length;
_segVCount += slotVertices.length / 4;
}
},
});
let ArmatureCache = cc.Class({
ctor () {
this._privateMode = false;
this._animationPool = {};
this._armatureCache = {};
},
enablePrivateMode () {
this._privateMode = true;
},
// If cache is private, cache will be destroy when dragonbones node destroy.
dispose () {
for (var key in this._armatureCache) {
var armatureInfo = this._armatureCache[key];
if (armatureInfo) {
let armature = armatureInfo.armature;
armature && armature.dispose();
}
}
this._armatureCache = null;
this._animationPool = null;
},
_removeArmature (armatureKey) {
var armatureInfo = this._armatureCache[armatureKey];
let animationsCache = armatureInfo.animationsCache;
for (var aniKey in animationsCache) {
// Clear cache texture, and put cache into pool.
// No need to create TypedArray next time.
let animationCache = animationsCache[aniKey];
if (!animationCache) continue;
this._animationPool[armatureKey + "#" + aniKey] = animationCache;
animationCache.clear();
}
let armature = armatureInfo.armature;
armature && armature.dispose();
delete this._armatureCache[armatureKey];
},
// When db assets be destroy, remove armature from db cache.
resetArmature (uuid) {
for (var armatureKey in this._armatureCache) {
if (armatureKey.indexOf(uuid) == -1) continue;
this._removeArmature(armatureKey);
}
},
getArmatureCache (armatureName, armatureKey, atlasUUID) {
let armatureInfo = this._armatureCache[armatureKey];
let armature;
if (!armatureInfo) {
let factory = dragonBones.CCFactory.getInstance();
let proxy = factory.buildArmatureDisplay(armatureName, armatureKey, "", atlasUUID);
if (!proxy || !proxy._armature) return;
armature = proxy._armature;
// If armature has child armature, can not be cache, because it's
// animation data can not be precompute.
if (!ArmatureCache.canCache(armature)) {
armature.dispose();
return;
}
this._armatureCache[armatureKey] = {
armature : armature,
// Cache all kinds of animation frame.
// When armature is dispose, clear all animation cache.
animationsCache : {},
curAnimationCache: null,
};
} else {
armature = armatureInfo.armature;
}
return armature;
},
getAnimationCache (armatureKey, animationName) {
let armatureInfo = this._armatureCache[armatureKey];
if (!armatureInfo) return null;
let animationsCache = armatureInfo.animationsCache;
return animationsCache[animationName];
},
initAnimationCache (armatureKey, animationName) {
if (!animationName) return null;
let armatureInfo = this._armatureCache[armatureKey];
let armature = armatureInfo && armatureInfo.armature;
if (!armature) return null;
let animation = armature.animation;
let hasAni = animation.hasAnimation(animationName);
if (!hasAni) return null;
let animationsCache = armatureInfo.animationsCache;
let animationCache = animationsCache[animationName];
if (!animationCache) {
// If cache exist in pool, then just use it.
let poolKey = armatureKey + "#" + animationName;
animationCache = this._animationPool[poolKey];
if (animationCache) {
delete this._animationPool[poolKey];
} else {
animationCache = new AnimationCache();
animationCache._privateMode = this._privateMode;
}
animationCache.init(armatureInfo, animationName);
animationsCache[animationName] = animationCache;
}
return animationCache;
},
invalidAnimationCache (armatureKey) {
let armatureInfo = this._armatureCache[armatureKey];
let armature = armatureInfo && armatureInfo.armature;
if (!armature) return null;
let animationsCache = armatureInfo.animationsCache;
for (var aniKey in animationsCache) {
let animationCache = animationsCache[aniKey];
animationCache.invalidAllFrame();
}
},
updateAnimationCache (armatureKey, animationName) {
if (animationName) {
let animationCache = this.initAnimationCache(armatureKey, animationName);
if (!animationCache) return;
animationCache.updateAllFrame();
} else {
let armatureInfo = this._armatureCache[armatureKey];
let armature = armatureInfo && armatureInfo.armature;
if (!armature) return null;
let animationsCache = armatureInfo.animationsCache;
for (var aniKey in animationsCache) {
let animationCache = animationsCache[aniKey];
animationCache.updateAllFrame();
}
}
},
});
ArmatureCache.FrameTime = FrameTime;
ArmatureCache.sharedCache = new ArmatureCache();
ArmatureCache.canCache = function (armature) {
let slots = armature._slots;
for (let i = 0, l = slots.length; i < l; i++) {
let slot = slots[i];
if (slot.childArmature) {
return false;
}
}
return true;
},
module.exports = ArmatureCache;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,506 @@
/****************************************************************************
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
import Mat4 from '../../cocos2d/core/value-types/mat4';
const RenderFlow = require('../../cocos2d/core/renderer/render-flow');
const FLAG_TRANSFORM = RenderFlow.FLAG_TRANSFORM;
const EmptyHandle = function () {}
const ATTACHED_ROOT_NAME = 'ATTACHED_NODE_TREE';
const ATTACHED_PRE_NAME = 'ATTACHED_NODE:';
const limitNode = function (node) {
// attached node's world matrix update per frame
Object.defineProperty(node, '_worldMatDirty', {
get () { return true; },
set (value) {/* do nothing */}
});
// shield world matrix calculate interface
node._calculWorldMatrix = EmptyHandle;
node._mulMat = EmptyHandle;
};
let _tempMat4 = new Mat4();
/**
* @module dragonBones
*/
/**
* !#en Attach node tool
* !#zh 挂点工具类
* @class dragonBones.AttachUtil
*/
let AttachUtil = cc.Class({
name: 'dragonBones.AttachUtil',
ctor () {
this._inited = false;
this._armature = null;
this._armatureNode = null;
this._armatureDisplay = null;
this._attachedRootNode = null;
this._attachedNodeArray = [];
this._boneIndexToNode = {};
},
init (armatureDisplay) {
this._inited = true;
this._armature = armatureDisplay._armature;
this._armatureNode = armatureDisplay.node;
this._armatureDisplay = armatureDisplay;
},
reset () {
this._inited = false;
this._armature = null;
this._armatureNode = null;
this._armatureDisplay = null;
},
_prepareAttachNode () {
let armature = this._armature;
if (!armature) {
return;
}
let rootNode = this._armatureNode.getChildByName(ATTACHED_ROOT_NAME);
if (!rootNode || !rootNode.isValid) {
rootNode = new cc.Node(ATTACHED_ROOT_NAME);
limitNode(rootNode);
this._armatureNode.addChild(rootNode);
}
let isCached = this._armatureDisplay.isAnimationCached();
if (isCached && this._armatureDisplay._frameCache) {
this._armatureDisplay._frameCache.enableCacheAttachedInfo();
}
this._attachedRootNode = rootNode;
return rootNode;
},
_buildBoneAttachedNode (bone, boneIndex) {
let boneNodeName = ATTACHED_PRE_NAME + bone.name;
let boneNode = new cc.Node(boneNodeName);
this._buildBoneRelation(boneNode, bone, boneIndex);
return boneNode;
},
_buildBoneRelation (boneNode, bone, boneIndex) {
limitNode(boneNode);
boneNode._bone = bone;
boneNode._boneIndex = boneIndex;
this._attachedNodeArray.push(boneNode);
this._boneIndexToNode[boneIndex] = boneNode;
},
/**
* !#en Gets attached root node.
* !#zh 获取挂接节点树的根节点
* @method getAttachedRootNode
* @return {cc.Node}
*/
getAttachedRootNode () {
return this._attachedRootNode;
},
/**
* !#en Gets attached node which you want.
* !#zh 获得对应的挂点
* @method getAttachedNodes
* @param {String} boneName
* @return {Node[]}
*/
getAttachedNodes (boneName) {
let nodeArray = this._attachedNodeArray;
let res = [];
if (!this._inited) return res;
for (let i = 0, n = nodeArray.length; i < n; i++) {
let boneNode = nodeArray[i];
if (!boneNode || !boneNode.isValid) continue;
if (boneNode.name === ATTACHED_PRE_NAME + boneName) {
res.push(boneNode);
}
}
return res;
},
_rebuildNodeArray () {
let findMap = this._boneIndexToNode = {};
let oldNodeArray = this._attachedNodeArray;
let nodeArray = this._attachedNodeArray = [];
for (let i = 0, n = oldNodeArray.length; i < n; i++) {
let boneNode = oldNodeArray[i];
if (!boneNode || !boneNode.isValid || boneNode._toRemove) continue;
nodeArray.push(boneNode);
findMap[boneNode._boneIndex] = boneNode;
}
},
_sortNodeArray () {
let nodeArray = this._attachedNodeArray;
nodeArray.sort(function (a, b) {
return a._boneIndex < b._boneIndex? -1 : 1;
});
},
_getNodeByBoneIndex (boneIndex) {
let findMap = this._boneIndexToNode;
let boneNode = findMap[boneIndex];
if (!boneNode || !boneNode.isValid) return null;
return boneNode;
},
/**
* !#en Destroy attached node which you want.
* !#zh 销毁对应的挂点
* @method destroyAttachedNodes
* @param {String} boneName
*/
destroyAttachedNodes (boneName) {
if (!this._inited) return;
let nodeArray = this._attachedNodeArray;
let markTree = function (rootNode) {
let children = rootNode.children;
for (let i = 0, n = children.length; i < n; i++) {
let c = children[i];
if (c) markTree(c);
}
rootNode._toRemove = true;
}
for (let i = 0, n = nodeArray.length; i < n; i++) {
let boneNode = nodeArray[i];
if (!boneNode || !boneNode.isValid) continue;
let delName = boneNode.name.split(ATTACHED_PRE_NAME)[1];
if (delName === boneName) {
markTree(boneNode);
boneNode.removeFromParent(true);
boneNode.destroy();
nodeArray[i] = null;
}
}
this._rebuildNodeArray();
},
/**
* !#en Traverse all bones to generate the minimum node tree containing the given bone names, NOTE that make sure the skeleton has initialized before calling this interface.
* !#zh 遍历所有插槽,生成包含所有给定插槽名称的最小节点树,注意,调用该接口前请确保骨骼动画已经初始化好。
* @method generateAttachedNodes
* @param {String} boneName
* @return {Node[]} attached node array
*/
generateAttachedNodes (boneName) {
let targetNodes = [];
if (!this._inited) return targetNodes;
let rootNode = this._prepareAttachNode();
if (!rootNode) return targetNodes;
let boneIndex = 0;
let res = [];
let attachedTraverse = function (armature) {
if (!armature) return;
let bones = armature.getBones(), bone;
for(let i = 0, l = bones.length; i < l; i++) {
bone = bones[i];
bone._boneIndex = boneIndex++;
if (boneName === bone.name) {
res.push(bone);
}
}
let slots = armature.getSlots(), slot;
for (let i = 0, l = slots.length; i < l; i++) {
slot = slots[i];
if (slot.childArmature) {
attachedTraverse(slot.childArmature);
}
}
}.bind(this);
attachedTraverse(this._armature);
let buildBoneTree = function (bone) {
if (!bone) return;
let boneNode = this._getNodeByBoneIndex(bone._boneIndex);
if (boneNode) return boneNode;
boneNode = this._buildBoneAttachedNode(bone, bone._boneIndex);
let subArmatureParentBone = null;
if (bone.armature.parent) {
let parentSlot = bone.armature.parent;
subArmatureParentBone = parentSlot.parent;
}
let parentBoneNode = buildBoneTree(bone.parent || subArmatureParentBone) || rootNode;
boneNode.parent = parentBoneNode;
if (bone.parent) {
boneNode._rootNode = parentBoneNode._rootNode;
} else {
boneNode._rootNode = parentBoneNode;
}
return boneNode;
}.bind(this);
for (let i = 0, n = res.length; i < n; i++) {
let targetNode = buildBoneTree(res[i]);
if (targetNode) {
targetNodes.push(targetNode);
}
}
this._sortNodeArray();
return targetNodes;
},
/**
* !#en Destroy all attached node.
* !#zh 销毁所有挂点
* @method destroyAllAttachedNodes
*/
destroyAllAttachedNodes () {
this._attachedRootNode = null;
this._attachedNodeArray.length = 0;
this._boneIndexToNode = {};
if (!this._inited) return;
let rootNode = this._armatureNode.getChildByName(ATTACHED_ROOT_NAME);
if (rootNode) {
rootNode.removeFromParent(true);
rootNode.destroy();
rootNode = null;
}
},
/**
* !#en Traverse all bones to generate a tree containing all bones nodes, NOTE that make sure the skeleton has initialized before calling this interface.
* !#zh 遍历所有插槽,生成包含所有插槽的节点树,注意,调用该接口前请确保骨骼动画已经初始化好。
* @method generateAllAttachedNodes
* @return {cc.Node} root node
*/
generateAllAttachedNodes () {
if (!this._inited) return;
// clear all records
this._boneIndexToNode = {};
this._attachedNodeArray.length = 0;
let rootNode = this._prepareAttachNode();
if (!rootNode) return;
let boneIndex = 0;
let attachedTraverse = function (armature) {
if (!armature) return;
let subArmatureParentNode = rootNode;
if (armature.parent) {
let parentSlot = armature.parent;
let parentBone = parentSlot.parent;
subArmatureParentNode = parentBone._attachedNode;
}
let bones = armature.getBones(), bone;
for(let i = 0, l = bones.length; i < l; i++) {
let curBoneIndex = boneIndex++;
bone = bones[i];
bone._attachedNode = null;
let parentNode = null;
if (bone.parent) {
parentNode = bone.parent._attachedNode;
} else {
parentNode = subArmatureParentNode;
}
if (parentNode) {
let boneNode = parentNode.getChildByName(ATTACHED_PRE_NAME + bone.name);
if (!boneNode || !boneNode.isValid) {
boneNode = this._buildBoneAttachedNode(bone, curBoneIndex);
parentNode.addChild(boneNode);
} else {
this._buildBoneRelation(boneNode, bone, curBoneIndex);
}
boneNode._rootNode = subArmatureParentNode;
bone._attachedNode = boneNode;
}
}
let slots = armature.getSlots(), slot;
for (let i = 0, l = slots.length; i < l; i++) {
slot = slots[i];
if (slot.childArmature) {
attachedTraverse(slot.childArmature);
}
}
}.bind(this);
attachedTraverse(this._armature);
return rootNode;
},
_hasAttachedNode () {
if (!this._inited) return false;
let attachedRootNode = this._armatureNode.getChildByName(ATTACHED_ROOT_NAME);
return !!attachedRootNode;
},
_associateAttachedNode () {
if (!this._inited) return;
let rootNode = this._armatureNode.getChildByName(ATTACHED_ROOT_NAME);
if (!rootNode || !rootNode.isValid) return;
this._attachedRootNode = rootNode;
// clear all records
this._boneIndexToNode = {};
let nodeArray = this._attachedNodeArray;
nodeArray.length = 0;
let armature = this._armature;
if (!armature) {
return;
}
limitNode(rootNode);
if (!CC_NATIVERENDERER) {
let isCached = this._armatureDisplay.isAnimationCached();
if (isCached && this._armatureDisplay._frameCache) {
this._armatureDisplay._frameCache.enableCacheAttachedInfo();
}
}
let boneIndex = 0;
let attachedTraverse = function (armature) {
if (!armature) return;
let subArmatureParentNode = rootNode;
if (armature.parent) {
let parentSlot = armature.parent;
let parentBone = parentSlot.parent;
subArmatureParentNode = parentBone._attachedNode;
}
let bones = armature.getBones(), bone;
for(let i = 0, l = bones.length; i < l; i++) {
let curBoneIndex = boneIndex++;
bone = bones[i];
bone._attachedNode = null;
let parentNode = null;
if (bone.parent) {
parentNode = bone.parent._attachedNode;
} else {
parentNode = subArmatureParentNode;
}
if (parentNode) {
let boneNode = parentNode.getChildByName(ATTACHED_PRE_NAME + bone.name);
if (boneNode && boneNode.isValid) {
this._buildBoneRelation(boneNode, bone, curBoneIndex);
boneNode._rootNode = subArmatureParentNode;
bone._attachedNode = boneNode;
}
}
}
let slots = armature.getSlots(), slot;
for (let i = 0, l = slots.length; i < l; i++) {
slot = slots[i];
if (slot.childArmature) {
attachedTraverse(slot.childArmature);
}
}
}.bind(this);
attachedTraverse(armature);
},
_syncAttachedNode () {
if (!this._inited) return;
let rootNode = this._attachedRootNode;
let nodeArray = this._attachedNodeArray;
if (!rootNode || !rootNode.isValid) {
this._attachedRootNode = null;
nodeArray.length = 0;
return;
}
let rootMatrix = this._armatureNode._worldMatrix;
Mat4.copy(rootNode._worldMatrix, rootMatrix);
rootNode._renderFlag &= ~FLAG_TRANSFORM;
let boneInfos = null;
let isCached = this._armatureDisplay.isAnimationCached();
if (isCached) {
boneInfos = this._armatureDisplay._curFrame && this._armatureDisplay._curFrame.boneInfos;
if (!boneInfos) return;
}
let mulMat = this._armatureNode._mulMat;
let matrixHandle = function (nodeMat, parentMat, boneMat) {
let tm = _tempMat4.m;
tm[0] = boneMat.a;
tm[1] = boneMat.b;
tm[4] = -boneMat.c;
tm[5] = -boneMat.d;
tm[12] = boneMat.tx;
tm[13] = boneMat.ty;
mulMat(nodeMat, parentMat, _tempMat4);
};
let nodeArrayDirty = false;
for (let i = 0, n = nodeArray.length; i < n; i++) {
let boneNode = nodeArray[i];
// Node has been destroy
if (!boneNode || !boneNode.isValid) {
nodeArray[i] = null;
nodeArrayDirty = true;
continue;
}
let bone = isCached ? boneInfos[boneNode._boneIndex] : boneNode._bone;
// Bone has been destroy
if (!bone || bone._isInPool) {
boneNode.removeFromParent(true);
boneNode.destroy();
nodeArray[i] = null;
nodeArrayDirty = true;
continue;
}
matrixHandle(boneNode._worldMatrix, boneNode._rootNode._worldMatrix, bone.globalTransformMatrix);
boneNode._renderFlag &= ~FLAG_TRANSFORM;
}
if (nodeArrayDirty) {
this._rebuildNodeArray();
}
},
});
module.exports = dragonBones.AttachUtil = AttachUtil;

View File

@@ -0,0 +1,125 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
let EventTarget = require('../../cocos2d/core/event/event-target');
dragonBones.CCArmatureDisplay = cc.Class({
name: 'dragonBones.CCArmatureDisplay',
properties: {
// adapt old api
node: {
get () {
return this;
}
},
},
ctor () {
this._eventTarget = new EventTarget();
},
setEventTarget (eventTarget) {
this._eventTarget = eventTarget;
},
getRootDisplay () {
var parentSlot = this._armature._parent;
if (!parentSlot) {
return this;
}
var slot;
while (parentSlot)
{
slot = parentSlot;
parentSlot = parentSlot._armature._parent;
}
return slot._armature.getDisplay();
},
convertToRootSpace (pos) {
var slot = this._armature._parent;
if (!slot)
{
return pos;
}
slot.updateWorldMatrix();
let worldMatrix = slot._worldMatrix;
let worldMatrixm = worldMatrix.m;
let newPos = cc.v2(0,0);
newPos.x = pos.x * worldMatrixm[0] + pos.y * worldMatrixm[4] + worldMatrixm[12];
newPos.y = pos.x * worldMatrixm[1] + pos.y * worldMatrixm[5] + worldMatrixm[13];
return newPos;
},
convertToWorldSpace (point) {
var newPos = this.convertToRootSpace(point);
var ccNode = this.getRootNode();
var finalPos = ccNode.convertToWorldSpaceAR(newPos);
return finalPos;
},
getRootNode () {
var rootDisplay = this.getRootDisplay();
return rootDisplay && rootDisplay._ccNode;
},
////////////////////////////////////
// dragonbones api
dbInit (armature) {
this._armature = armature;
},
dbClear () {
this._armature = null;
},
dbUpdate () {
},
advanceTimeBySelf (on) {
this.shouldAdvanced = !!on;
},
hasDBEventListener (type) {
return this._eventTarget.hasEventListener(type);
},
addDBEventListener (type, listener, target) {
this._eventTarget.on(type, listener, target);
},
removeDBEventListener (type, listener, target) {
this._eventTarget.off(type, listener, target);
},
dispatchDBEvent (type, eventObject) {
this._eventTarget.emit(type, eventObject);
}
////////////////////////////////////
});

View File

@@ -0,0 +1,187 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
let BaseObject = dragonBones.BaseObject,
BaseFactory = dragonBones.BaseFactory;
/**
* @module dragonBones
*/
/**
* DragonBones factory
* @class CCFactory
* @extends BaseFactory
*/
var CCFactory = dragonBones.CCFactory = cc.Class({
name: 'dragonBones.CCFactory',
extends: BaseFactory,
/**
* @method getInstance
* @return {CCFactory}
* @static
* @example
* let factory = dragonBones.CCFactory.getInstance();
*/
statics: {
_factory: null,
getInstance () {
if (!CCFactory._factory) {
CCFactory._factory = new CCFactory();
}
return CCFactory._factory;
}
},
ctor () {
let eventManager = new dragonBones.CCArmatureDisplay();
this._dragonBones = new dragonBones.DragonBones(eventManager);
if (!CC_NATIVERENDERER && !CC_EDITOR && cc.director._scheduler) {
cc.game.on(cc.game.EVENT_RESTART, this.initUpdate, this);
this.initUpdate();
}
},
initUpdate (dt) {
cc.director._scheduler.enableForTarget(this);
cc.director._scheduler.scheduleUpdate(this, cc.Scheduler.PRIORITY_SYSTEM, false);
},
update (dt) {
this._dragonBones.advanceTime(dt);
},
getDragonBonesDataByRawData (rawData) {
var dataParser = rawData instanceof ArrayBuffer ? BaseFactory._binaryParser : this._dataParser;
return dataParser.parseDragonBonesData(rawData, 1.0);
},
// Build new aramture with a new display.
buildArmatureDisplay (armatureName, dragonBonesName, skinName, textureAtlasName) {
let armature = this.buildArmature(armatureName, dragonBonesName, skinName, textureAtlasName);
return armature && armature._display;
},
// Build sub armature from an exist armature component.
// It will share dragonAsset and dragonAtlasAsset.
// But node can not share,or will cause render error.
createArmatureNode (comp, armatureName, node) {
node = node || new cc.Node();
let display = node.getComponent(dragonBones.ArmatureDisplay);
if (!display) {
display = node.addComponent(dragonBones.ArmatureDisplay);
}
node.name = armatureName;
display._armatureName = armatureName;
display._N$dragonAsset = comp.dragonAsset;
display._N$dragonAtlasAsset = comp.dragonAtlasAsset;
display._init();
return display;
},
_buildTextureAtlasData (textureAtlasData, textureAtlas) {
if (textureAtlasData) {
textureAtlasData.renderTexture = textureAtlas;
}
else {
textureAtlasData = BaseObject.borrowObject(dragonBones.CCTextureAtlasData);
}
return textureAtlasData;
},
_sortSlots () {
let slots = this._slots;
let sortedSlots = [];
for (let i = 0, l = slots.length; i < l; i++) {
let slot = slots[i];
let zOrder = slot._zOrder;
let inserted = false;
for (let j = sortedSlots.length - 1; j >= 0; j--) {
if (zOrder >= sortedSlots[j]._zOrder) {
sortedSlots.splice(j+1, 0, slot);
inserted = true;
break;
}
}
if (!inserted) {
sortedSlots.unshift(slot);
}
}
this._slots = sortedSlots;
},
_buildArmature (dataPackage) {
let armature = BaseObject.borrowObject(dragonBones.Armature);
armature._skinData = dataPackage.skin;
armature._animation = BaseObject.borrowObject(dragonBones.Animation);
armature._animation._armature = armature;
armature._animation.animations = dataPackage.armature.animations;
armature._isChildArmature = false;
// fixed dragonbones sort issue
// armature._sortSlots = this._sortSlots;
var display = new dragonBones.CCArmatureDisplay();
armature.init(dataPackage.armature,
display, display, this._dragonBones
);
return armature;
},
_buildSlot (dataPackage, slotData, displays) {
let slot = BaseObject.borrowObject(dragonBones.CCSlot);
let display = slot;
slot.init(slotData, displays, display, display);
return slot;
},
getDragonBonesDataByUUID (uuid) {
for (var name in this._dragonBonesDataMap) {
if (name.indexOf(uuid) != -1) {
return this._dragonBonesDataMap[name];
}
}
return null;
},
removeDragonBonesDataByUUID (uuid, disposeData) {
if (disposeData === void 0) { disposeData = true; }
for (var name in this._dragonBonesDataMap) {
if (name.indexOf(uuid) === -1) continue;
if (disposeData) {
this._dragonBones.bufferObject(this._dragonBonesDataMap[name]);
}
delete this._dragonBonesDataMap[name];
}
}
});

View File

@@ -0,0 +1,383 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
import Mat4 from '../../cocos2d/core/value-types/mat4';
const BinaryOffset = dragonBones.BinaryOffset;
const BoneType = dragonBones.BoneType;
dragonBones.CCSlot = cc.Class({
name: 'dragonBones.CCSlot',
extends: dragonBones.Slot,
ctor () {
this._localVertices = [];
this._indices = [];
this._matrix = cc.mat4();
this._worldMatrix = cc.mat4();
this._worldMatrixDirty = true;
this._visible = false;
this._color = cc.color();
},
_onClear () {
this._super();
this._localVertices.length = 0;
this._indices.length = 0;
Mat4.identity(this._matrix);
Mat4.identity(this._worldMatrix);
this._worldMatrixDirty = true;
this._color = cc.color();
this._visible = false;
},
statics : {
toString: function () {
return "[class dragonBones.CCSlot]";
}
},
// just for adapt to dragonbones api,no need to do any thing
_onUpdateDisplay () {
},
// just for adapt to dragonbones api,no need to do any thing
_initDisplay (value) {
},
_addDisplay () {
this._visible = true;
},
// just for adapt to dragonbones api,no need to do any thing
_replaceDisplay (value) {
},
_removeDisplay () {
this._visible = false;
},
// just for adapt to dragonbones api,no need to do any thing
_disposeDisplay (object) {
},
_updateVisible () {
this._visible = this.parent._visible;
},
// just for adapt to dragonbones api,no need to do any thing
_updateZOrder () {
},
_updateBlendMode () {
if (this._childArmature) {
let childSlots = this._childArmature.getSlots();
for (let i = 0, l = childSlots.length; i < l; i++) {
let slot = childSlots[i];
slot._blendMode = this._blendMode;
slot._updateBlendMode();
}
}
},
_updateColor () {
let c = this._color;
c.r = this._colorTransform.redMultiplier * 255;
c.g = this._colorTransform.greenMultiplier * 255;
c.b = this._colorTransform.blueMultiplier * 255;
c.a = this._colorTransform.alphaMultiplier * 255;
},
//return dragonBones.CCTexture2D
getTexture () {
return this._textureData && this._textureData.spriteFrame && this._textureData.spriteFrame.getTexture();
},
_updateFrame () {
this._indices.length = 0;
let indices = this._indices,
localVertices = this._localVertices;
let indexOffset = 0, vfOffset = 0;
let currentTextureData = this._textureData;
if (!this._display || this._displayIndex < 0 || !currentTextureData || !currentTextureData.spriteFrame) return;
let texture = currentTextureData.spriteFrame.getTexture();
let textureAtlasWidth = texture.width;
let textureAtlasHeight = texture.height;
let region = currentTextureData.region;
const currentVerticesData = (this._deformVertices !== null && this._display === this._meshDisplay) ? this._deformVertices.verticesData : null;
if (currentVerticesData) {
const data = currentVerticesData.data;
const intArray = data.intArray;
const floatArray = data.floatArray;
const vertexCount = intArray[currentVerticesData.offset + BinaryOffset.MeshVertexCount];
const triangleCount = intArray[currentVerticesData.offset + BinaryOffset.MeshTriangleCount];
let vertexOffset = intArray[currentVerticesData.offset + BinaryOffset.MeshFloatOffset];
if (vertexOffset < 0) {
vertexOffset += 65536; // Fixed out of bouds bug.
}
const uvOffset = vertexOffset + vertexCount * 2;
const scale = this._armature._armatureData.scale;
for (let i = 0, l = vertexCount * 2; i < l; i += 2) {
localVertices[vfOffset++] = floatArray[vertexOffset + i] * scale;
localVertices[vfOffset++] = -floatArray[vertexOffset + i + 1] * scale;
if (currentVerticesData.rotated) {
localVertices[vfOffset++] = (region.x + (1.0 - floatArray[uvOffset + i]) * region.width) / textureAtlasWidth;
localVertices[vfOffset++] = (region.y + floatArray[uvOffset + i + 1] * region.height) / textureAtlasHeight;
} else {
localVertices[vfOffset++] = (region.x + floatArray[uvOffset + i] * region.width) / textureAtlasWidth;
localVertices[vfOffset++] = (region.y + floatArray[uvOffset + i + 1] * region.height) / textureAtlasHeight;
}
}
for (let i = 0; i < triangleCount * 3; ++i) {
indices[indexOffset++] = intArray[currentVerticesData.offset + BinaryOffset.MeshVertexIndices + i];
}
localVertices.length = vfOffset;
indices.length = indexOffset;
let isSkinned = !!currentVerticesData.weight;
if (isSkinned) {
this._identityTransform();
}
}
else {
let l = region.x / textureAtlasWidth;
let b = (region.y + region.height) / textureAtlasHeight;
let r = (region.x + region.width) / textureAtlasWidth;
let t = region.y / textureAtlasHeight;
localVertices[vfOffset++] = 0; // 0x
localVertices[vfOffset++] = 0; // 0y
localVertices[vfOffset++] = l; // 0u
localVertices[vfOffset++] = b; // 0v
localVertices[vfOffset++] = region.width; // 1x
localVertices[vfOffset++] = 0; // 1y
localVertices[vfOffset++] = r; // 1u
localVertices[vfOffset++] = b; // 1v
localVertices[vfOffset++] = 0; // 2x
localVertices[vfOffset++] = region.height;; // 2y
localVertices[vfOffset++] = l; // 2u
localVertices[vfOffset++] = t; // 2v
localVertices[vfOffset++] = region.width; // 3x
localVertices[vfOffset++] = region.height;; // 3y
localVertices[vfOffset++] = r; // 3u
localVertices[vfOffset++] = t; // 3v
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 1;
indices[4] = 3;
indices[5] = 2;
localVertices.length = vfOffset;
indices.length = 6;
}
this._visibleDirty = true;
this._blendModeDirty = true;
this._colorDirty = true;
},
_updateMesh () {
const scale = this._armature._armatureData.scale;
const deformVertices = this._deformVertices.vertices;
const bones = this._deformVertices.bones;
const verticesData = this._deformVertices.verticesData;
const weightData = verticesData.weight;
const hasDeform = deformVertices.length > 0 && verticesData.inheritDeform;
let localVertices = this._localVertices;
if (weightData) {
const data = verticesData.data;
const intArray = data.intArray;
const floatArray = data.floatArray;
const vertexCount = intArray[verticesData.offset + BinaryOffset.MeshVertexCount];
let weightFloatOffset = intArray[weightData.offset + BinaryOffset.WeigthFloatOffset];
if (weightFloatOffset < 0) {
weightFloatOffset += 65536; // Fixed out of bouds bug.
}
for (
let i = 0, iB = weightData.offset + BinaryOffset.WeigthBoneIndices + bones.length, iV = weightFloatOffset, iF = 0, lvi = 0;
i < vertexCount;
i++, lvi+=4
) {
const boneCount = intArray[iB++];
let xG = 0.0, yG = 0.0;
for (let j = 0; j < boneCount; ++j) {
const boneIndex = intArray[iB++];
const bone = bones[boneIndex];
if (bone !== null) {
const matrix = bone.globalTransformMatrix;
const weight = floatArray[iV++];
let xL = floatArray[iV++] * scale;
let yL = floatArray[iV++] * scale;
if (hasDeform) {
xL += deformVertices[iF++];
yL += deformVertices[iF++];
}
xG += (matrix.a * xL + matrix.c * yL + matrix.tx) * weight;
yG += (matrix.b * xL + matrix.d * yL + matrix.ty) * weight;
}
}
localVertices[lvi] = xG;
localVertices[lvi + 1] = -yG;
}
}
else if (hasDeform) {
const isSurface = this._parent._boneData.type !== BoneType.Bone;
const data = verticesData.data;
const intArray = data.intArray;
const floatArray = data.floatArray;
const vertexCount = intArray[verticesData.offset + BinaryOffset.MeshVertexCount];
let vertexOffset = intArray[verticesData.offset + BinaryOffset.MeshFloatOffset];
if (vertexOffset < 0) {
vertexOffset += 65536; // Fixed out of bouds bug.
}
for (let i = 0, l = vertexCount, lvi = 0; i < l; i ++, lvi += 4) {
const x = floatArray[vertexOffset + i*2] * scale + deformVertices[i*2];
const y = floatArray[vertexOffset + i*2 + 1] * scale + deformVertices[i*2 + 1];
if (isSurface) {
const matrix = this._parent._getGlobalTransformMatrix(x, y);
localVertices[lvi] = matrix.a * x + matrix.c * y + matrix.tx;
localVertices[lvi + 1] = -matrix.b * x + matrix.d * y + matrix.ty;
}
else {
localVertices[lvi] = x;
localVertices[lvi + 1] = -y;
}
}
}
if (weightData) {
this._identityTransform();
}
},
_identityTransform() {
let m = this._matrix.m;
m[0] = 1.0;
m[1] = 0.0;
m[4] = -0.0;
m[5] = -1.0;
m[12] = 0.0;
m[13] = 0.0;
this._worldMatrixDirty = true;
},
_updateTransform () {
let t = this._matrix;
let tm = t.m;
tm[0] = this.globalTransformMatrix.a;
tm[1] = this.globalTransformMatrix.b;
tm[4] = -this.globalTransformMatrix.c;
tm[5] = -this.globalTransformMatrix.d;
if (this._childArmature) {
tm[12] = this.globalTransformMatrix.tx;
tm[13] = this.globalTransformMatrix.ty;
} else {
tm[12] = this.globalTransformMatrix.tx - (this.globalTransformMatrix.a * this._pivotX - this.globalTransformMatrix.c * this._pivotY);
tm[13] = this.globalTransformMatrix.ty - (this.globalTransformMatrix.b * this._pivotX - this.globalTransformMatrix.d * this._pivotY);
}
this._worldMatrixDirty = true;
},
updateWorldMatrix () {
if (!this._armature) return;
var parentSlot = this._armature._parent;
if (parentSlot) {
parentSlot.updateWorldMatrix();
}
if (this._worldMatrixDirty) {
this.calculWorldMatrix();
var childArmature = this.childArmature;
if (!childArmature) return;
var slots = childArmature.getSlots();
for (var i = 0,n = slots.length; i < n; i++) {
var slot = slots[i];
if (slot) {
slot._worldMatrixDirty = true;
}
}
}
},
_mulMat (out, a, b) {
let am = a.m, bm = b.m, outm = out.m;
let aa=am[0], ab=am[1], ac=am[4], ad=am[5], atx=am[12], aty=am[13];
let ba=bm[0], bb=bm[1], bc=bm[4], bd=bm[5], btx=bm[12], bty=bm[13];
if (ab !== 0 || ac !== 0) {
outm[0] = ba * aa + bb * ac;
outm[1] = ba * ab + bb * ad;
outm[4] = bc * aa + bd * ac;
outm[5] = bc * ab + bd * ad;
outm[12] = aa * btx + ac * bty + atx;
outm[13] = ab * btx + ad * bty + aty;
}
else {
outm[0] = ba * aa;
outm[1] = bb * ad;
outm[4] = bc * aa;
outm[5] = bd * ad;
outm[12] = aa * btx + atx;
outm[13] = ad * bty + aty;
}
},
calculWorldMatrix () {
var parent = this._armature._parent;
if (parent) {
this._mulMat(this._worldMatrix ,parent._worldMatrix, this._matrix);
} else {
Mat4.copy(this._worldMatrix, this._matrix);
}
this._worldMatrixDirty = false;
}
});

View File

@@ -0,0 +1,110 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
dragonBones.CCTextureAtlasData = cc.Class({
extends: dragonBones.TextureAtlasData,
name: "dragonBones.CCTextureAtlasData",
properties: {
_renderTexture: {
default: null,
serializable: false
},
renderTexture: {
get () {
return this._renderTexture;
},
set (value) {
this._renderTexture = value;
if (value) {
for (let k in this.textures) {
let textureData = this.textures[k];
if (!textureData.spriteFrame) {
let rect = null;
if (textureData.rotated) {
rect = cc.rect(textureData.region.x, textureData.region.y,
textureData.region.height, textureData.region.width);
} else {
rect = cc.rect(textureData.region.x, textureData.region.y,
textureData.region.width, textureData.region.height);
}
let offset = cc.v2(0, 0);
let size = cc.size(rect.width, rect.height);
textureData.spriteFrame = new cc.SpriteFrame();
textureData.spriteFrame.setTexture(value, rect, false, offset, size);
}
}
} else {
for (let k in this.textures) {
let textureData = this.textures[k];
textureData.spriteFrame = null;
}
}
},
}
},
statics: {
toString: function () {
return "[class dragonBones.CCTextureAtlasData]";
}
},
_onClear: function () {
dragonBones.TextureAtlasData.prototype._onClear.call(this);
this.renderTexture = null;
},
createTexture : function() {
return dragonBones.BaseObject.borrowObject(dragonBones.CCTextureData);
}
});
dragonBones.CCTextureData = cc.Class({
extends: dragonBones.TextureData,
name: "dragonBones.CCTextureData",
properties: {
spriteFrame: {
default: null,
serializable: false
},
},
statics: {
toString: function () {
return "[class dragonBones.CCTextureData]";
}
},
_onClear: function () {
dragonBones.TextureData.prototype._onClear.call(this);
this.spriteFrame = null;
}
});

View File

@@ -0,0 +1,189 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
/**
* @module dragonBones
*/
let ArmatureCache = !CC_JSB && require('./ArmatureCache').sharedCache;
/**
* !#en The skeleton data of dragonBones.
* !#zh dragonBones 的 骨骼数据。
* @class DragonBonesAsset
* @extends Asset
*/
var DragonBonesAsset = cc.Class({
name: 'dragonBones.DragonBonesAsset',
extends: cc.Asset,
ctor () {
this.reset();
},
properties: {
_dragonBonesJson : '',
/**
* !#en See http://developer.egret.com/cn/github/egret-docs/DB/dbLibs/dataFormat/index.html
* !#zh 可查看 DragonBones 官方文档 http://developer.egret.com/cn/github/egret-docs/DB/dbLibs/dataFormat/index.html
* @property {string} dragonBonesJson
*/
dragonBonesJson : {
get: function () {
return this._dragonBonesJson;
},
set: function (value) {
this._dragonBonesJson = value;
this._dragonBonesJsonData = JSON.parse(value);
this.reset();
}
},
_nativeAsset: {
get () {
return this._buffer;
},
set (bin) {
this._buffer = bin.buffer || bin;
this.reset();
},
override: true
},
},
statics: {
preventDeferredLoadDependents: true
},
createNode: CC_EDITOR && function (callback) {
var node = new cc.Node(this.name);
var armatureDisplay = node.addComponent(dragonBones.ArmatureDisplay);
armatureDisplay.dragonAsset = this;
return callback(null, node);
},
reset () {
this._clear();
if (CC_EDITOR) {
this._armaturesEnum = null;
}
},
init (factory, atlasUUID) {
if (CC_EDITOR) {
this._factory = factory || new dragonBones.CCFactory();
} else {
this._factory = factory;
}
if (!this._dragonBonesJsonData && this.dragonBonesJson) {
this._dragonBonesJsonData = JSON.parse(this.dragonBonesJson);
}
let rawData = null;
if (this._dragonBonesJsonData) {
rawData = this._dragonBonesJsonData;
} else {
rawData = this._nativeAsset;
}
// If create by manual, uuid is empty.
if (!this._uuid) {
let dbData = this._factory.getDragonBonesDataByRawData(rawData);
if (dbData) {
this._uuid = dbData.name;
} else {
cc.warn('dragonbones name is empty');
}
}
let armatureKey = this._uuid + "#" + atlasUUID;
let dragonBonesData = this._factory.getDragonBonesData(armatureKey);
if (dragonBonesData) return armatureKey;
this._factory.parseDragonBonesData(rawData, armatureKey);
return armatureKey;
},
// EDITOR
getArmatureEnum: CC_EDITOR && function () {
if (this._armaturesEnum) {
return this._armaturesEnum;
}
this.init();
let dragonBonesData = this._factory.getDragonBonesDataByUUID(this._uuid);
if (dragonBonesData) {
var armatureNames = dragonBonesData.armatureNames;
var enumDef = {};
for (var i = 0; i < armatureNames.length; i++) {
var name = armatureNames[i];
enumDef[name] = i;
}
return this._armaturesEnum = cc.Enum(enumDef);
}
return null;
},
getAnimsEnum: CC_EDITOR && function (armatureName) {
this.init();
let dragonBonesData = this._factory.getDragonBonesDataByUUID(this._uuid);
if (dragonBonesData) {
var armature = dragonBonesData.getArmature(armatureName);
if (!armature) {
return null;
}
var enumDef = { '<None>': 0 };
var anims = armature.animations;
var i = 0;
for (var animName in anims) {
if (anims.hasOwnProperty(animName)) {
enumDef[animName] = i + 1;
i++;
}
}
return cc.Enum(enumDef);
}
return null;
},
_clear () {
if (this._factory) {
ArmatureCache.resetArmature(this._uuid);
this._factory.removeDragonBonesDataByUUID(this._uuid, true);
}
},
destroy () {
this._clear();
this._super();
},
});
dragonBones.DragonBonesAsset = module.exports = DragonBonesAsset;

View File

@@ -0,0 +1,132 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
/**
* @module dragonBones
*/
let ArmatureCache = !CC_JSB && require('./ArmatureCache').sharedCache;
/**
* !#en The skeleton atlas data of dragonBones.
* !#zh dragonBones 的骨骼纹理数据。
* @class DragonBonesAtlasAsset
* @extends Asset
*/
var DragonBonesAtlasAsset = cc.Class({
name: 'dragonBones.DragonBonesAtlasAsset',
extends: cc.Asset,
ctor () {
this._clear();
},
properties: {
_atlasJson : '',
/**
* @property {string} atlasJson
*/
atlasJson: {
get: function () {
return this._atlasJson;
},
set: function (value) {
this._atlasJson = value;
this._atlasJsonData = JSON.parse(this.atlasJson);
this._clear();
}
},
_texture: {
default: null,
type: cc.Texture2D,
formerlySerializedAs: 'texture'
},
/**
* @property {Texture2D} texture
*/
texture: {
get () {
return this._texture;
},
set (value) {
this._texture = value;
this._clear();
}
},
_textureAtlasData: null,
},
statics: {
preventDeferredLoadDependents: true
},
createNode: CC_EDITOR && function (callback) {
var node = new cc.Node(this.name);
var armatureDisplay = node.addComponent(dragonBones.ArmatureDisplay);
armatureDisplay.dragonAtlasAsset = this;
return callback(null, node);
},
init (factory) {
this._factory = factory;
if (!this._atlasJsonData) {
this._atlasJsonData = JSON.parse(this.atlasJson);
}
let atlasJsonObj = this._atlasJsonData;
// If create by manual, uuid is empty.
this._uuid = this._uuid || atlasJsonObj.name;
if (this._textureAtlasData) {
factory.addTextureAtlasData(this._textureAtlasData, this._uuid);
}
else {
this._textureAtlasData = factory.parseTextureAtlasData(atlasJsonObj, this.texture, this._uuid);
}
},
_clear () {
if (CC_JSB) return;
if (this._factory) {
ArmatureCache.resetArmature(this._uuid);
this._factory.removeTextureAtlasData(this._uuid, true);
this._factory.removeDragonBonesDataByUUID(this._uuid, true);
}
this._textureAtlasData = null;
},
destroy () {
this._clear();
this._super();
},
});
dragonBones.DragonBonesAtlasAsset = module.exports = DragonBonesAtlasAsset;

View File

@@ -0,0 +1,90 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
const Fs = require('fire-fs');
const Path = require('fire-path');
const DRAGONBONES_ENCODING = { encoding: 'utf-8' };
const CustomAssetMeta = Editor.metas['custom-asset'];
class DragonBonesAtlasMeta extends CustomAssetMeta {
constructor (assetdb) {
super(assetdb);
}
static version () { return '1.0.3'; }
static defaultType () {
return 'dragonbones-atlas';
}
static validate (assetpath) {
try {
const json = Fs.readJsonSync(assetpath);
return typeof json.imagePath === 'string' && Array.isArray(json.SubTexture);
}
catch (e) {
return false;
}
}
postImport (fspath, cb) {
Fs.readFile(fspath, DRAGONBONES_ENCODING, (err, data) => {
if (err) {
return cb(err);
}
var json;
try {
json = JSON.parse(data);
}
catch (e) {
return cb(e);
}
// parse the depended texture
var imgPath = Path.resolve(Path.dirname(fspath), json.imagePath);
var textureUUID = this._assetdb.fspathToUuid(imgPath);
if (textureUUID) {
console.log('UUID is initialized for "%s".', imgPath);
}
else if (!Fs.existsSync(imgPath)) {
Editor.error('Can not find texture "%s" for atlas "%s"', json.imagePath, fspath);
}
else {
// AssetDB may call postImport more than once, we can get uuid in the next time.
console.warn('WARN: UUID not yet initialized for "%s".', json.imagePath);
}
var asset = new dragonBones.DragonBonesAtlasAsset();
asset.name = Path.basenameNoExt(fspath);
asset.atlasJson = data;
asset.texture = Editor.serialize.asAsset(textureUUID);
this._assetdb.saveAssetToLibrary(this.uuid, asset);
cb();
});
}
}
module.exports = DragonBonesAtlasMeta;

View File

@@ -0,0 +1,70 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
const Fs = require('fire-fs');
const Path = require('fire-path');
const DRAGONBONES_ENCODING = { encoding: 'utf-8' };
const CustomAssetMeta = Editor.metas['custom-asset'];
class DragonBonesMeta extends CustomAssetMeta {
constructor (assetdb) {
super(assetdb);
}
static version () { return '1.0.3'; }
static defaultType () {
return 'dragonbones';
}
static validate (assetpath) {
var json;
var text = Fs.readFileSync(assetpath, 'utf8');
try {
json = JSON.parse(text);
}
catch (e) {
return false;
}
return Array.isArray(json.armature);
}
import (fspath, cb) {
Fs.readFile(fspath, DRAGONBONES_ENCODING, (err, data) => {
if (err) {
return cb(err);
}
var asset = new dragonBones.DragonBonesAsset();
asset.name = Path.basenameNoExt(fspath);
asset.dragonBonesJson = data;
this._assetdb.saveAssetToLibrary(this.uuid, asset);
cb();
});
}
}
module.exports = DragonBonesMeta;

View File

@@ -0,0 +1,171 @@
/****************************************************************************
Copyright (c) 2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
/**
* !#en
* The global main namespace of DragonBones, all classes, functions,
* properties and constants of DragonBones are defined in this namespace
* !#zh
* DragonBones 的全局的命名空间,
* 与 DragonBones 相关的所有的类,函数,属性,常量都在这个命名空间中定义。
* @module dragonBones
* @main dragonBones
*/
/*
* Reference:
* http://dragonbones.com/cn/index.html
*/
var _global = typeof window === 'undefined' ? global : window;
if (!CC_NATIVERENDERER) {
_global.dragonBones = require('./lib/dragonBones');
}
if (_global.dragonBones !== undefined) {
/**
* !#en
* The global time scale of DragonBones.
* !#zh
* DragonBones 全局时间缩放率。
* @example
* dragonBones.timeScale = 0.8;
*/
dragonBones._timeScale = 1.0;
Object.defineProperty(dragonBones, 'timeScale', {
get () {
return this._timeScale;
},
set (value) {
this._timeScale = value;
let factory = this.CCFactory.getInstance();
factory._dragonBones.clock.timeScale = value;
},
configurable: true,
});
dragonBones.DisplayType = {
Image : 0,
Armature : 1,
Mesh : 2
};
dragonBones.ArmatureType = {
Armature : 0,
MovieClip : 1,
Stage : 2
};
dragonBones.ExtensionType = {
FFD : 0,
AdjustColor : 10,
BevelFilter : 11,
BlurFilter : 12,
DropShadowFilter : 13,
GlowFilter : 14,
GradientBevelFilter : 15,
GradientGlowFilter : 16
};
dragonBones.EventType = {
Frame : 0,
Sound : 1
};
dragonBones.ActionType = {
Play : 0,
Stop : 1,
GotoAndPlay : 2,
GotoAndStop : 3,
FadeIn : 4,
FadeOut : 5
};
dragonBones.AnimationFadeOutMode = {
None : 0,
SameLayer : 1,
SameGroup : 2,
SameLayerAndGroup : 3,
All : 4
};
dragonBones.BinaryOffset = {
WeigthBoneCount: 0,
WeigthFloatOffset: 1,
WeigthBoneIndices: 2,
MeshVertexCount: 0,
MeshTriangleCount: 1,
MeshFloatOffset: 2,
MeshWeightOffset: 3,
MeshVertexIndices: 4,
TimelineScale: 0,
TimelineOffset: 1,
TimelineKeyFrameCount: 2,
TimelineFrameValueCount: 3,
TimelineFrameValueOffset: 4,
TimelineFrameOffset: 5,
FramePosition: 0,
FrameTweenType: 1,
FrameTweenEasingOrCurveSampleCount: 2,
FrameCurveSamples: 3,
DeformMeshOffset: 0,
DeformCount: 1,
DeformValueCount: 2,
DeformValueOffset: 3,
DeformFloatOffset: 4
};
dragonBones.BoneType = {
Bone: 0,
Surface: 1
};
if (!CC_EDITOR || !Editor.isMainProcess) {
if (!CC_NATIVERENDERER) {
require('./CCFactory');
require('./CCSlot');
require('./CCTextureData');
require('./CCArmatureDisplay');
require('./ArmatureCache');
}
// require the component for dragonbones
require('./DragonBonesAsset');
require('./DragonBonesAtlasAsset');
require('./ArmatureDisplay');
require('./webgl-assembler');
} else {
require('./DragonBonesAsset');
require('./DragonBonesAtlasAsset');
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,377 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
import Assembler from '../../cocos2d/core/renderer/assembler';
import Mat4 from '../../cocos2d/core/value-types/mat4';
const Armature = require('./ArmatureDisplay');
const RenderFlow = require('../../cocos2d/core/renderer/render-flow');
const gfx = cc.gfx;
const NEED_COLOR = 0x01;
const NEED_BATCH = 0x10;
let _boneColor = cc.color(255, 0, 0, 255);
let _slotColor = cc.color(0, 0, 255, 255);
let _originColor = cc.color(0, 255, 0, 255);
let _nodeR, _nodeG, _nodeB, _nodeA,
_premultipliedAlpha, _multiply,
_mustFlush, _buffer, _node,
_renderer, _comp,
_vfOffset, _indexOffset, _vertexOffset,
_vertexCount, _indexCount,
_x, _y, _c, _r, _g, _b, _a, _handleVal,
_m00, _m04, _m12,
_m01, _m05, _m13;
function _getSlotMaterial (tex, blendMode) {
if(!tex)return null;
let src, dst;
switch (blendMode) {
case 1://additive
src = _premultipliedAlpha ? cc.macro.ONE : cc.macro.SRC_ALPHA;
dst = cc.macro.ONE;
break;
case 10://multiply
src = cc.macro.DST_COLOR;
dst = cc.macro.ONE_MINUS_SRC_ALPHA;
break;
case 12://screen
src = cc.macro.ONE;
dst = cc.macro.ONE_MINUS_SRC_COLOR;
break;
case 0://normal
default:
src = _premultipliedAlpha ? cc.macro.ONE : cc.macro.SRC_ALPHA;
dst = cc.macro.ONE_MINUS_SRC_ALPHA;
break;
}
let useModel = !_comp.enableBatch;
let baseMaterial = _comp._materials[0];
if (!baseMaterial) {
return null;
}
let materialCache = _comp._materialCache;
// The key use to find corresponding material
let key = tex.getId() + src + dst + useModel;
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.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;
}
function _handleColor (color, parentOpacity) {
_a = color.a * parentOpacity * _nodeA;
_multiply = _premultipliedAlpha? _a / 255.0 : 1.0;
_r = color.r * _nodeR * _multiply;
_g = color.g * _nodeG * _multiply;
_b = color.b * _nodeB * _multiply;
_c = ((_a<<24) >>> 0) + (_b<<16) + (_g<<8) + _r;
}
export default class ArmatureAssembler extends Assembler {
updateRenderData (comp, batchData) {}
realTimeTraverse (armature, parentMat, parentOpacity) {
let slots = armature._slots;
let vbuf, ibuf, uintbuf;
let material;
let vertices, indices;
let slotColor;
let slot;
let slotMat;
let slotMatm;
let offsetInfo;
for (let i = 0, l = slots.length; i < l; i++) {
slot = slots[i];
slotColor = slot._color;
if (!slot._visible || !slot._displayData) continue;
if (parentMat) {
slot._mulMat(slot._worldMatrix, parentMat, slot._matrix);
} else {
Mat4.copy(slot._worldMatrix, slot._matrix);
}
if (slot.childArmature) {
this.realTimeTraverse(slot.childArmature, slot._worldMatrix, parentOpacity * slotColor.a / 255);
continue;
}
material = _getSlotMaterial(slot.getTexture(), slot._blendMode);
if (!material) {
continue;
}
if (_mustFlush || material.getHash() !== _renderer.material.getHash()) {
_mustFlush = false;
_renderer._flush();
_renderer.node = _node;
_renderer.material = material;
}
_handleColor(slotColor, parentOpacity);
slotMat = slot._worldMatrix;
slotMatm = slotMat.m;
vertices = slot._localVertices;
_vertexCount = vertices.length >> 2;
indices = slot._indices;
_indexCount = indices.length;
offsetInfo = _buffer.request(_vertexCount, _indexCount);
_indexOffset = offsetInfo.indiceOffset;
_vfOffset = offsetInfo.byteOffset >> 2;
_vertexOffset = offsetInfo.vertexOffset;
vbuf = _buffer._vData;
ibuf = _buffer._iData;
uintbuf = _buffer._uintVData;
_m00 = slotMatm[0];
_m04 = slotMatm[4];
_m12 = slotMatm[12];
_m01 = slotMatm[1];
_m05 = slotMatm[5];
_m13 = slotMatm[13];
for (let vi = 0, vl = vertices.length; vi < vl;) {
_x = vertices[vi++];
_y = vertices[vi++];
vbuf[_vfOffset++] = _x * _m00 + _y * _m04 + _m12; // x
vbuf[_vfOffset++] = _x * _m01 + _y * _m05 + _m13; // y
vbuf[_vfOffset++] = vertices[vi++]; // u
vbuf[_vfOffset++] = vertices[vi++]; // v
uintbuf[_vfOffset++] = _c; // color
}
for (let ii = 0, il = indices.length; ii < il; ii ++) {
ibuf[_indexOffset++] = _vertexOffset + indices[ii];
}
}
}
cacheTraverse (frame, parentMat) {
if (!frame) return;
let segments = frame.segments;
if (segments.length == 0) return;
let vbuf, ibuf, uintbuf;
let material;
let offsetInfo;
let vertices = frame.vertices;
let indices = frame.indices;
let frameVFOffset = 0, frameIndexOffset = 0, segVFCount = 0;
if (parentMat) {
let parentMatm = parentMat.m;
_m00 = parentMatm[0];
_m01 = parentMatm[1];
_m04 = parentMatm[4];
_m05 = parentMatm[5];
_m12 = parentMatm[12];
_m13 = parentMatm[13];
}
let justTranslate = _m00 === 1 && _m01 === 0 && _m04 === 0 && _m05 === 1;
let needBatch = (_handleVal & NEED_BATCH);
let calcTranslate = needBatch && justTranslate;
let colorOffset = 0;
let colors = frame.colors;
let nowColor = colors[colorOffset++];
let maxVFOffset = nowColor.vfOffset;
_handleColor(nowColor, 1.0);
for (let i = 0, n = segments.length; i < n; i++) {
let segInfo = segments[i];
material = _getSlotMaterial(segInfo.tex, segInfo.blendMode);
if (_mustFlush || material.getHash() !== _renderer.material.getHash()) {
_mustFlush = false;
_renderer._flush();
_renderer.node = _node;
_renderer.material = material;
}
_vertexCount = segInfo.vertexCount;
_indexCount = segInfo.indexCount;
offsetInfo = _buffer.request(_vertexCount, _indexCount);
_indexOffset = offsetInfo.indiceOffset;
_vertexOffset = offsetInfo.vertexOffset;
_vfOffset = offsetInfo.byteOffset >> 2;
vbuf = _buffer._vData;
ibuf = _buffer._iData;
uintbuf = _buffer._uintVData;
for (let ii = _indexOffset, il = _indexOffset + _indexCount; ii < il; ii++) {
ibuf[ii] = _vertexOffset + indices[frameIndexOffset++];
}
segVFCount = segInfo.vfCount;
vbuf.set(vertices.subarray(frameVFOffset, frameVFOffset + segVFCount), _vfOffset);
frameVFOffset += segVFCount;
if (calcTranslate) {
for (let ii = _vfOffset, il = _vfOffset + segVFCount; ii < il; ii += 5) {
vbuf[ii] += _m12;
vbuf[ii + 1] += _m13;
}
} else if (needBatch) {
for (let ii = _vfOffset, il = _vfOffset + segVFCount; ii < il; ii += 5) {
_x = vbuf[ii];
_y = vbuf[ii + 1];
vbuf[ii] = _x * _m00 + _y * _m04 + _m12;
vbuf[ii + 1] = _x * _m01 + _y * _m05 + _m13;
}
}
if ( !(_handleVal & NEED_COLOR) ) continue;
// handle color
let frameColorOffset = frameVFOffset - segVFCount;
for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 5, frameColorOffset += 5) {
if (frameColorOffset >= maxVFOffset) {
nowColor = colors[colorOffset++];
_handleColor(nowColor, 1.0);
maxVFOffset = nowColor.vfOffset;
}
uintbuf[ii] = _c;
}
}
}
fillBuffers (comp, renderer) {
comp.node._renderFlag |= RenderFlow.FLAG_UPDATE_RENDER_DATA;
let armature = comp._armature;
if (!armature) return;
// Init temp var.
_mustFlush = true;
_premultipliedAlpha = comp.premultipliedAlpha;
_node = comp.node;
_buffer = renderer._meshBuffer;
_renderer = renderer;
_comp = comp;
_handleVal = 0;
let nodeColor = _node._color;
_nodeR = nodeColor.r / 255;
_nodeG = nodeColor.g / 255;
_nodeB = nodeColor.b / 255;
_nodeA = nodeColor.a / 255;
if (nodeColor._val !== 0xffffffff) {
_handleVal |= NEED_COLOR;
}
let worldMat = undefined;
if (_comp.enableBatch) {
worldMat = _node._worldMatrix;
_mustFlush = false;
_handleVal |= NEED_BATCH;
}
if (comp.isAnimationCached()) {
// Traverse input assembler.
this.cacheTraverse(comp._curFrame, worldMat);
} else {
// Traverse all armature.
this.realTimeTraverse(armature, worldMat, 1.0);
let graphics = comp._debugDraw;
if (comp.debugBones && graphics) {
graphics.clear();
graphics.lineWidth = 5;
graphics.strokeColor = _boneColor;
graphics.fillColor = _slotColor; // Root bone color is same as slot color.
let bones = armature.getBones();
for (let i = 0, l = bones.length; i < l; i++) {
let bone = bones[i];
let boneLength = Math.max(bone.boneData.length, 5);
let startX = bone.globalTransformMatrix.tx;
let startY = bone.globalTransformMatrix.ty;
let endX = startX + bone.globalTransformMatrix.a * boneLength;
let endY = startY + bone.globalTransformMatrix.b * boneLength;
graphics.moveTo(startX, startY);
graphics.lineTo(endX, endY);
graphics.stroke();
// Bone origins.
graphics.circle(startX, startY, Math.PI * 2);
graphics.fill();
if (i === 0) {
graphics.fillColor = _originColor;
}
}
}
}
// sync attached node matrix
renderer.worldMatDirty++;
comp.attachUtil._syncAttachedNode();
// Clear temp var.
_node = undefined;
_buffer = undefined;
_renderer = undefined;
_comp = undefined;
}
postFillBuffers (comp, renderer) {
renderer.worldMatDirty--;
}
}
Assembler.register(Armature, ArmatureAssembler);