no message
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ArmatureCache.h"
|
||||
#include "CCFactory.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
float ArmatureCache::FrameTime = 1.0F / 60.0F;
|
||||
float ArmatureCache::MaxCacheTime = 120.0F;
|
||||
|
||||
ArmatureCache::SegmentData::SegmentData() = default;
|
||||
|
||||
ArmatureCache::SegmentData::~SegmentData() {
|
||||
CC_SAFE_RELEASE_NULL(_texture);
|
||||
}
|
||||
|
||||
void ArmatureCache::SegmentData::setTexture(cc::middleware::Texture2D *value) {
|
||||
CC_SAFE_ADD_REF(value);
|
||||
CC_SAFE_RELEASE(_texture);
|
||||
_texture = value;
|
||||
}
|
||||
|
||||
cc::middleware::Texture2D *ArmatureCache::SegmentData::getTexture() const {
|
||||
return _texture;
|
||||
}
|
||||
|
||||
ArmatureCache::FrameData::FrameData() = default;
|
||||
|
||||
ArmatureCache::FrameData::~FrameData() {
|
||||
for (auto &bone : _bones) {
|
||||
delete bone;
|
||||
}
|
||||
_bones.clear();
|
||||
|
||||
for (auto &color : _colors) {
|
||||
delete color;
|
||||
}
|
||||
_colors.clear();
|
||||
|
||||
for (auto &segment : _segments) {
|
||||
delete segment;
|
||||
}
|
||||
_segments.clear();
|
||||
}
|
||||
|
||||
ArmatureCache::BoneData *ArmatureCache::FrameData::buildBoneData(std::size_t index) {
|
||||
if (index > _bones.size()) return nullptr;
|
||||
if (index == _bones.size()) {
|
||||
auto *boneData = new BoneData;
|
||||
_bones.push_back(boneData);
|
||||
}
|
||||
return _bones[index];
|
||||
}
|
||||
|
||||
std::size_t ArmatureCache::FrameData::getBoneCount() const {
|
||||
return _bones.size();
|
||||
}
|
||||
|
||||
ArmatureCache::ColorData *ArmatureCache::FrameData::buildColorData(std::size_t index) {
|
||||
if (index > _colors.size()) return nullptr;
|
||||
if (index == _colors.size()) {
|
||||
auto *colorData = new ColorData;
|
||||
_colors.push_back(colorData);
|
||||
}
|
||||
return _colors[index];
|
||||
}
|
||||
|
||||
std::size_t ArmatureCache::FrameData::getColorCount() const {
|
||||
return _colors.size();
|
||||
}
|
||||
|
||||
ArmatureCache::SegmentData *ArmatureCache::FrameData::buildSegmentData(std::size_t index) {
|
||||
if (index > _segments.size()) return nullptr;
|
||||
if (index == _segments.size()) {
|
||||
auto *segmentData = new SegmentData;
|
||||
_segments.push_back(segmentData);
|
||||
}
|
||||
return _segments[index];
|
||||
}
|
||||
|
||||
std::size_t ArmatureCache::FrameData::getSegmentCount() const {
|
||||
return _segments.size();
|
||||
}
|
||||
|
||||
ArmatureCache::AnimationData::AnimationData() = default;
|
||||
|
||||
ArmatureCache::AnimationData::~AnimationData() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void ArmatureCache::AnimationData::reset() {
|
||||
for (auto &frame : _frames) {
|
||||
delete frame;
|
||||
}
|
||||
_frames.clear();
|
||||
_isComplete = false;
|
||||
_totalTime = 0.0F;
|
||||
}
|
||||
|
||||
bool ArmatureCache::AnimationData::needUpdate(int toFrameIdx) const {
|
||||
return !_isComplete && _totalTime <= MaxCacheTime && (toFrameIdx == -1 || _frames.size() < toFrameIdx + 1);
|
||||
}
|
||||
|
||||
ArmatureCache::FrameData *ArmatureCache::AnimationData::buildFrameData(std::size_t frameIdx) {
|
||||
if (frameIdx > _frames.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (frameIdx == _frames.size()) {
|
||||
auto *frameData = new FrameData();
|
||||
_frames.push_back(frameData);
|
||||
}
|
||||
return _frames[frameIdx];
|
||||
}
|
||||
|
||||
ArmatureCache::FrameData *ArmatureCache::AnimationData::getFrameData(std::size_t frameIdx) const {
|
||||
if (frameIdx >= _frames.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _frames[frameIdx];
|
||||
}
|
||||
|
||||
std::size_t ArmatureCache::AnimationData::getFrameCount() const {
|
||||
return _frames.size();
|
||||
}
|
||||
|
||||
ArmatureCache::ArmatureCache(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID) {
|
||||
_armatureDisplay = dragonBones::CCFactory::getFactory()->buildArmatureDisplay(armatureName, armatureKey, "", atlasUUID);
|
||||
if (_armatureDisplay) {
|
||||
_armatureDisplay->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
ArmatureCache::~ArmatureCache() {
|
||||
if (_armatureDisplay) {
|
||||
_armatureDisplay->release();
|
||||
_armatureDisplay = nullptr;
|
||||
}
|
||||
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
delete animationCache.second;
|
||||
}
|
||||
_animationCaches.clear();
|
||||
}
|
||||
|
||||
ArmatureCache::AnimationData *ArmatureCache::buildAnimationData(const std::string &animationName) {
|
||||
if (!_armatureDisplay) return nullptr;
|
||||
|
||||
AnimationData *aniData = nullptr;
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
auto *armature = _armatureDisplay->getArmature();
|
||||
auto *animation = armature->getAnimation();
|
||||
auto hasAni = animation->hasAnimation(animationName);
|
||||
if (!hasAni) return nullptr;
|
||||
|
||||
aniData = new AnimationData();
|
||||
aniData->_animationName = animationName;
|
||||
_animationCaches[animationName] = aniData;
|
||||
} else {
|
||||
aniData = it->second;
|
||||
}
|
||||
return aniData;
|
||||
}
|
||||
|
||||
ArmatureCache::AnimationData *ArmatureCache::getAnimationData(const std::string &animationName) {
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void ArmatureCache::updateToFrame(const std::string &animationName, int toFrameIdx /*= -1*/) {
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AnimationData *animationData = it->second;
|
||||
if (!animationData || !animationData->needUpdate(toFrameIdx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_curAnimationName != animationName) {
|
||||
updateToFrame(_curAnimationName);
|
||||
_curAnimationName = animationName;
|
||||
}
|
||||
|
||||
auto *armature = _armatureDisplay->getArmature();
|
||||
auto *animation = armature->getAnimation();
|
||||
|
||||
// init animation
|
||||
if (animationData->getFrameCount() == 0) {
|
||||
animation->play(animationName, 1);
|
||||
}
|
||||
|
||||
do {
|
||||
armature->advanceTime(FrameTime);
|
||||
renderAnimationFrame(animationData);
|
||||
animationData->_totalTime += FrameTime;
|
||||
if (animation->isCompleted()) {
|
||||
animationData->_isComplete = true;
|
||||
}
|
||||
} while (animationData->needUpdate(toFrameIdx));
|
||||
}
|
||||
|
||||
void ArmatureCache::renderAnimationFrame(AnimationData *animationData) {
|
||||
std::size_t frameIndex = animationData->getFrameCount();
|
||||
_frameData = animationData->buildFrameData(frameIndex);
|
||||
|
||||
_preColor = Color4B(0, 0, 0, 0);
|
||||
_color = Color4B(255, 255, 255, 255);
|
||||
|
||||
_preBlendMode = -1;
|
||||
_preTextureIndex = -1;
|
||||
_curTextureIndex = -1;
|
||||
_preISegWritePos = -1;
|
||||
_curISegLen = 0;
|
||||
_curVSegLen = 0;
|
||||
_materialLen = 0;
|
||||
|
||||
auto *armature = _armatureDisplay->getArmature();
|
||||
traverseArmature(armature);
|
||||
|
||||
if (_preISegWritePos != -1) {
|
||||
SegmentData *preSegmentData = _frameData->buildSegmentData(_materialLen - 1);
|
||||
preSegmentData->indexCount = _curISegLen;
|
||||
preSegmentData->vertexFloatCount = _curVSegLen;
|
||||
}
|
||||
|
||||
auto colorCount = _frameData->getColorCount();
|
||||
if (colorCount > 0) {
|
||||
ColorData *preColorData = _frameData->buildColorData(colorCount - 1);
|
||||
preColorData->vertexFloatOffset = static_cast<int>(_frameData->vb.getCurPos()) / sizeof(float);
|
||||
}
|
||||
|
||||
_frameData = nullptr;
|
||||
}
|
||||
|
||||
void ArmatureCache::traverseArmature(Armature *armature, float parentOpacity /*= 1.0f*/) {
|
||||
middleware::IOBuffer &vb = _frameData->vb;
|
||||
middleware::IOBuffer &ib = _frameData->ib;
|
||||
|
||||
const auto &bones = armature->getBones();
|
||||
Bone *bone = nullptr;
|
||||
const auto &slots = armature->getSlots();
|
||||
CCSlot *slot = nullptr;
|
||||
// range [0.0, 1.0]
|
||||
Color4B preColor(0, 0, 0, 0);
|
||||
Color4B color;
|
||||
middleware::Texture2D *texture = nullptr;
|
||||
|
||||
auto flush = [&]() {
|
||||
// fill pre segment count field
|
||||
if (_preISegWritePos != -1) {
|
||||
SegmentData *preSegmentData = _frameData->buildSegmentData(_materialLen - 1);
|
||||
preSegmentData->indexCount = _curISegLen;
|
||||
preSegmentData->vertexFloatCount = _curVSegLen;
|
||||
}
|
||||
|
||||
SegmentData *segmentData = _frameData->buildSegmentData(_materialLen);
|
||||
segmentData->setTexture(texture);
|
||||
segmentData->blendMode = static_cast<int>(slot->_blendMode);
|
||||
|
||||
// save new segment count pos field
|
||||
_preISegWritePos = static_cast<int>(ib.getCurPos() / sizeof(uint16_t));
|
||||
// reset pre blend mode to current
|
||||
_preBlendMode = static_cast<int>(slot->_blendMode);
|
||||
// reset pre texture index to current
|
||||
_preTextureIndex = _curTextureIndex;
|
||||
// reset index segmentation count
|
||||
_curISegLen = 0;
|
||||
// reset vertex segmentation count
|
||||
_curVSegLen = 0;
|
||||
// material length increased
|
||||
_materialLen++;
|
||||
};
|
||||
|
||||
for (auto *i : bones) {
|
||||
bone = i;
|
||||
auto boneCount = _frameData->getBoneCount();
|
||||
BoneData *boneData = _frameData->buildBoneData(boneCount);
|
||||
auto &boneOriginMat = bone->globalTransformMatrix;
|
||||
auto &matm = boneData->globalTransformMatrix.m;
|
||||
matm[0] = boneOriginMat.a;
|
||||
matm[1] = boneOriginMat.b;
|
||||
matm[4] = -boneOriginMat.c;
|
||||
matm[5] = -boneOriginMat.d;
|
||||
matm[12] = boneOriginMat.tx;
|
||||
matm[13] = boneOriginMat.ty;
|
||||
}
|
||||
|
||||
for (auto *i : slots) {
|
||||
slot = dynamic_cast<CCSlot *>(i); // TODO(zhakasi): refine the logic
|
||||
if (slot == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!slot->getVisible()) {
|
||||
continue;
|
||||
}
|
||||
slot->updateWorldMatrix();
|
||||
|
||||
Mat4 *worldMatrix = &slot->worldMatrix;
|
||||
|
||||
// If slots has child armature,will traverse child first.
|
||||
Armature *childArmature = slot->getChildArmature();
|
||||
if (childArmature != nullptr) {
|
||||
traverseArmature(childArmature, parentOpacity * static_cast<float>(slot->color.a) / 255.0F);
|
||||
continue;
|
||||
}
|
||||
|
||||
texture = slot->getTexture();
|
||||
if (!texture) continue;
|
||||
_curTextureIndex = texture->getRealTextureIndex();
|
||||
|
||||
auto vbSize = slot->triangles.vertCount * sizeof(middleware::V3F_T2F_C4B);
|
||||
vb.checkSpace(vbSize, true);
|
||||
|
||||
// If texture or blendMode change,will change material.
|
||||
if (_preTextureIndex != _curTextureIndex || _preBlendMode != static_cast<int>(slot->_blendMode)) {
|
||||
flush();
|
||||
}
|
||||
|
||||
// Calculation vertex color.
|
||||
color.a = static_cast<uint8_t>(slot->color.a * parentOpacity);
|
||||
color.r = static_cast<uint8_t>(slot->color.r);
|
||||
color.g = static_cast<uint8_t>(slot->color.g);
|
||||
color.b = static_cast<uint8_t>(slot->color.b);
|
||||
|
||||
if (preColor != color) {
|
||||
preColor = color;
|
||||
auto colorCount = _frameData->getColorCount();
|
||||
if (colorCount > 0) {
|
||||
ColorData *preColorData = _frameData->buildColorData(colorCount - 1);
|
||||
preColorData->vertexFloatOffset = vb.getCurPos() / sizeof(float);
|
||||
}
|
||||
ColorData *colorData = _frameData->buildColorData(colorCount);
|
||||
colorData->color = color;
|
||||
}
|
||||
|
||||
// Transform component matrix to global matrix
|
||||
middleware::Triangles &triangles = slot->triangles;
|
||||
middleware::V3F_T2F_C4B *worldTriangles = slot->worldVerts;
|
||||
|
||||
for (int v = 0, w = 0, vn = triangles.vertCount; v < vn; ++v, w += 2) {
|
||||
middleware::V3F_T2F_C4B *vertex = triangles.verts + v;
|
||||
middleware::V3F_T2F_C4B *worldVertex = worldTriangles + v;
|
||||
|
||||
vertex->vertex.z = 0; //reset for z value
|
||||
worldVertex->vertex.transformMat4(vertex->vertex, *worldMatrix);
|
||||
|
||||
worldVertex->color.r = color.r;
|
||||
worldVertex->color.g = color.g;
|
||||
worldVertex->color.b = color.b;
|
||||
worldVertex->color.a = color.a;
|
||||
}
|
||||
|
||||
vb.writeBytes(reinterpret_cast<char *>(worldTriangles), vbSize);
|
||||
|
||||
auto ibSize = triangles.indexCount * sizeof(uint16_t);
|
||||
ib.checkSpace(ibSize, true);
|
||||
|
||||
auto vertexOffset = _curVSegLen / VF_XYZUVC;
|
||||
for (int ii = 0, nn = triangles.indexCount; ii < nn; ii++) {
|
||||
ib.writeUint16(triangles.indices[ii] + vertexOffset);
|
||||
}
|
||||
|
||||
_curISegLen += triangles.indexCount;
|
||||
_curVSegLen += static_cast<int32_t>(vbSize / sizeof(float));
|
||||
} // End slot traverse
|
||||
}
|
||||
|
||||
void ArmatureCache::resetAllAnimationData() {
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
animationCache.second->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ArmatureCache::resetAnimationData(const std::string &animationName) {
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
if (animationCache.second->_animationName == animationName) {
|
||||
animationCache.second->reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCArmatureDisplay *ArmatureCache::getArmatureDisplay() {
|
||||
return _armatureDisplay;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
158
cocos/editor-support/dragonbones-creator-support/ArmatureCache.h
Normal file
158
cocos/editor-support/dragonbones-creator-support/ArmatureCache.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CCArmatureDisplay.h"
|
||||
#include "IOBuffer.h"
|
||||
#include "base/RefCounted.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
class ArmatureCache : public cc::RefCounted {
|
||||
public:
|
||||
struct SegmentData {
|
||||
friend class ArmatureCache;
|
||||
|
||||
SegmentData();
|
||||
~SegmentData();
|
||||
|
||||
void setTexture(cc::middleware::Texture2D *value);
|
||||
cc::middleware::Texture2D *getTexture() const;
|
||||
|
||||
public:
|
||||
int blendMode = 0;
|
||||
std::size_t indexCount = 0;
|
||||
std::size_t vertexFloatCount = 0;
|
||||
|
||||
private:
|
||||
cc::middleware::Texture2D *_texture = nullptr;
|
||||
};
|
||||
|
||||
struct BoneData {
|
||||
cc::Mat4 globalTransformMatrix;
|
||||
};
|
||||
|
||||
struct ColorData {
|
||||
cc::middleware::Color4B color;
|
||||
std::size_t vertexFloatOffset = 0;
|
||||
};
|
||||
|
||||
struct FrameData {
|
||||
friend class ArmatureCache;
|
||||
|
||||
FrameData();
|
||||
~FrameData();
|
||||
|
||||
const std::vector<BoneData *> &getBones() const {
|
||||
return _bones;
|
||||
}
|
||||
std::size_t getBoneCount() const;
|
||||
|
||||
const std::vector<ColorData *> &getColors() const {
|
||||
return _colors;
|
||||
}
|
||||
std::size_t getColorCount() const;
|
||||
|
||||
const std::vector<SegmentData *> &getSegments() const {
|
||||
return _segments;
|
||||
}
|
||||
std::size_t getSegmentCount() const;
|
||||
|
||||
private:
|
||||
// if segment data is empty, it will build new one.
|
||||
SegmentData *buildSegmentData(std::size_t index);
|
||||
// if color data is empty, it will build new one.
|
||||
ColorData *buildColorData(std::size_t index);
|
||||
// if bone data is empty, it will build new one.
|
||||
BoneData *buildBoneData(std::size_t index);
|
||||
|
||||
std::vector<BoneData *> _bones;
|
||||
std::vector<ColorData *> _colors;
|
||||
std::vector<SegmentData *> _segments;
|
||||
|
||||
public:
|
||||
cc::middleware::IOBuffer ib;
|
||||
cc::middleware::IOBuffer vb;
|
||||
};
|
||||
|
||||
struct AnimationData {
|
||||
friend class ArmatureCache;
|
||||
|
||||
AnimationData();
|
||||
~AnimationData();
|
||||
void reset();
|
||||
|
||||
FrameData *getFrameData(std::size_t frameIdx) const;
|
||||
std::size_t getFrameCount() const;
|
||||
|
||||
bool isComplete() const { return _isComplete; }
|
||||
bool needUpdate(int toFrameIdx) const;
|
||||
|
||||
private:
|
||||
// if frame is empty, it will build new one.
|
||||
FrameData *buildFrameData(std::size_t frameIdx);
|
||||
|
||||
std::string _animationName;
|
||||
bool _isComplete = false;
|
||||
float _totalTime = 0.0F;
|
||||
std::vector<FrameData *> _frames;
|
||||
};
|
||||
|
||||
ArmatureCache(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID);
|
||||
~ArmatureCache() override;
|
||||
|
||||
void updateToFrame(const std::string &animationName, int toFrameIdx = -1);
|
||||
// if animation data is empty, it will build new one.
|
||||
AnimationData *buildAnimationData(const std::string &animationName);
|
||||
AnimationData *getAnimationData(const std::string &animationName);
|
||||
CCArmatureDisplay *getArmatureDisplay();
|
||||
|
||||
void resetAllAnimationData();
|
||||
void resetAnimationData(const std::string &animationName);
|
||||
|
||||
private:
|
||||
void renderAnimationFrame(AnimationData *animationData);
|
||||
void traverseArmature(Armature *armature, float parentOpacity = 1.0F);
|
||||
|
||||
public:
|
||||
static float FrameTime; // NOLINT
|
||||
static float MaxCacheTime; // NOLINT
|
||||
|
||||
private:
|
||||
FrameData *_frameData = nullptr;
|
||||
cc::middleware::Color4F _preColor = cc::middleware::Color4F(-1.0F, -1.0F, -1.0F, -1.0F);
|
||||
cc::middleware::Color4F _color = cc::middleware::Color4F(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
CCArmatureDisplay *_armatureDisplay = nullptr;
|
||||
int _preBlendMode = -1;
|
||||
int _preTextureIndex = -1;
|
||||
int _curTextureIndex = -1;
|
||||
int _preISegWritePos = -1;
|
||||
int _curISegLen = 0;
|
||||
int _curVSegLen = 0;
|
||||
int _materialLen = 0;
|
||||
std::string _curAnimationName;
|
||||
std::map<std::string, AnimationData *> _animationCaches;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ArmatureCacheMgr.h"
|
||||
#include "base/DeferredReleasePool.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
ArmatureCacheMgr *ArmatureCacheMgr::_instance = nullptr;
|
||||
ArmatureCache *ArmatureCacheMgr::buildArmatureCache(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID) {
|
||||
ArmatureCache *animation = _caches.at(armatureKey);
|
||||
if (!animation) {
|
||||
animation = new ArmatureCache(armatureName, armatureKey, atlasUUID);
|
||||
animation->addRef();
|
||||
_caches.insert(armatureKey, animation);
|
||||
cc::DeferredReleasePool::add(animation);
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
void ArmatureCacheMgr::removeArmatureCache(const std::string &armatureKey) {
|
||||
for (auto it = _caches.begin(); it != _caches.end();) {
|
||||
auto found = it->first.find(armatureKey);
|
||||
if (found != std::string::npos) {
|
||||
it = _caches.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ArmatureCache.h"
|
||||
#include "base/RefMap.h"
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
class ArmatureCacheMgr {
|
||||
public:
|
||||
static ArmatureCacheMgr *getInstance() {
|
||||
if (_instance == nullptr) {
|
||||
_instance = new ArmatureCacheMgr();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if (_instance) {
|
||||
delete _instance;
|
||||
_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void removeArmatureCache(const std::string &armatureKey);
|
||||
ArmatureCache *buildArmatureCache(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID);
|
||||
|
||||
private:
|
||||
static ArmatureCacheMgr *_instance;
|
||||
cc::RefMap<std::string, ArmatureCache *> _caches;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,464 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CCArmatureCacheDisplay.h"
|
||||
#include "2d/renderer/RenderDrawInfo.h"
|
||||
#include "2d/renderer/RenderEntity.h"
|
||||
#include "ArmatureCacheMgr.h"
|
||||
#include "CCFactory.h"
|
||||
#include "MiddlewareManager.h"
|
||||
#include "SharedBufferManager.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "math/Math.h"
|
||||
#include "renderer/core/MaterialInstance.h"
|
||||
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
using namespace cc::gfx; // NOLINT(google-build-using-namespace)
|
||||
|
||||
static const std::string TECH_STAGE = "opaque";
|
||||
static const std::string TEXTURE_KEY = "texture";
|
||||
static const std::string START_EVENT = "start";
|
||||
static const std::string LOOP_COMPLETE_EVENT = "loopComplete";
|
||||
static const std::string COMPLETE_EVENT = "complete";
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
CCArmatureCacheDisplay::CCArmatureCacheDisplay(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID, bool isShare) {
|
||||
_eventObject = BaseObject::borrowObject<EventObject>();
|
||||
|
||||
if (isShare) {
|
||||
_armatureCache = ArmatureCacheMgr::getInstance()->buildArmatureCache(armatureName, armatureKey, atlasUUID);
|
||||
_armatureCache->addRef();
|
||||
} else {
|
||||
_armatureCache = new ArmatureCache(armatureName, armatureKey, atlasUUID);
|
||||
_armatureCache->addRef();
|
||||
}
|
||||
|
||||
// store global TypedArray begin and end offset
|
||||
_sharedBufferOffset = new IOTypedArray(se::Object::TypedArrayType::UINT32, sizeof(uint32_t) * 2);
|
||||
}
|
||||
|
||||
CCArmatureCacheDisplay::~CCArmatureCacheDisplay() {
|
||||
dispose();
|
||||
|
||||
if (_sharedBufferOffset) {
|
||||
delete _sharedBufferOffset;
|
||||
_sharedBufferOffset = nullptr;
|
||||
}
|
||||
for (auto *draw : _drawInfoArray) {
|
||||
CC_SAFE_DELETE(draw);
|
||||
}
|
||||
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::dispose() {
|
||||
if (_armatureCache) {
|
||||
_armatureCache->release();
|
||||
_armatureCache = nullptr;
|
||||
}
|
||||
if (_eventObject) {
|
||||
_eventObject->returnToPool();
|
||||
_eventObject = nullptr;
|
||||
}
|
||||
|
||||
stopSchedule();
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::update(float dt) {
|
||||
auto gTimeScale = dragonBones::CCFactory::getFactory()->getTimeScale();
|
||||
dt *= _timeScale * gTimeScale;
|
||||
|
||||
if (_isAniComplete || !_animationData) {
|
||||
if (_animationData && !_animationData->isComplete()) {
|
||||
_armatureCache->updateToFrame(_animationName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_accTime <= 0.00001 && _playCount == 0) {
|
||||
_eventObject->type = EventObject::START;
|
||||
dispatchDBEvent(START_EVENT, _eventObject);
|
||||
}
|
||||
|
||||
_accTime += dt;
|
||||
int frameIdx = floor(_accTime / ArmatureCache::FrameTime);
|
||||
if (!_animationData->isComplete()) {
|
||||
_armatureCache->updateToFrame(_animationName, frameIdx);
|
||||
}
|
||||
|
||||
int finalFrameIndex = static_cast<int>(_animationData->getFrameCount()) - 1;
|
||||
if (_animationData->isComplete() && frameIdx >= finalFrameIndex) {
|
||||
_playCount++;
|
||||
_accTime = 0.0F;
|
||||
if (_playTimes > 0 && _playCount >= _playTimes) {
|
||||
frameIdx = finalFrameIndex;
|
||||
_playCount = 0;
|
||||
_isAniComplete = true;
|
||||
} else {
|
||||
frameIdx = 0;
|
||||
}
|
||||
|
||||
_eventObject->type = EventObject::COMPLETE;
|
||||
dispatchDBEvent(COMPLETE_EVENT, _eventObject);
|
||||
|
||||
_eventObject->type = EventObject::LOOP_COMPLETE;
|
||||
dispatchDBEvent(LOOP_COMPLETE_EVENT, _eventObject);
|
||||
}
|
||||
_curFrameIndex = frameIdx;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::render(float /*dt*/) {
|
||||
if (!_animationData) return;
|
||||
ArmatureCache::FrameData *frameData = _animationData->getFrameData(_curFrameIndex);
|
||||
if (!frameData) return;
|
||||
|
||||
auto *mgr = MiddlewareManager::getInstance();
|
||||
if (!mgr->isRendering) return;
|
||||
auto *entity = _entity;
|
||||
entity->clearDynamicRenderDrawInfos();
|
||||
|
||||
const auto &segments = frameData->getSegments();
|
||||
const auto &colors = frameData->getColors();
|
||||
|
||||
_sharedBufferOffset->reset();
|
||||
_sharedBufferOffset->clear();
|
||||
|
||||
auto *attachMgr = mgr->getAttachInfoMgr();
|
||||
auto *attachInfo = attachMgr->getBuffer();
|
||||
if (!attachInfo) return;
|
||||
|
||||
// store attach info offset
|
||||
_sharedBufferOffset->writeUint32(static_cast<uint32_t>(attachInfo->getCurPos()) / sizeof(uint32_t));
|
||||
|
||||
if (segments.empty() || colors.empty()) return;
|
||||
|
||||
middleware::MeshBuffer *mb = mgr->getMeshBuffer(VF_XYZUVC);
|
||||
middleware::IOBuffer &vb = mb->getVB();
|
||||
middleware::IOBuffer &ib = mb->getIB();
|
||||
const auto &srcVB = frameData->vb;
|
||||
const auto &srcIB = frameData->ib;
|
||||
auto &nodeWorldMat = entity->getNode()->getWorldMatrix();
|
||||
|
||||
int colorOffset = 0;
|
||||
ArmatureCache::ColorData *nowColor = colors[colorOffset++];
|
||||
auto maxVFOffset = nowColor->vertexFloatOffset;
|
||||
|
||||
Color4B color;
|
||||
|
||||
float tempR = 0.0F;
|
||||
float tempG = 0.0F;
|
||||
float tempB = 0.0F;
|
||||
float tempA = 0.0F;
|
||||
float multiplier = 1.0F;
|
||||
std::size_t srcVertexBytesOffset = 0;
|
||||
std::size_t srcIndexBytesOffset = 0;
|
||||
std::size_t vertexBytes = 0;
|
||||
std::size_t indexBytes = 0;
|
||||
BlendMode blendMode = BlendMode::Normal;
|
||||
std::size_t dstVertexOffset = 0;
|
||||
std::size_t dstIndexOffset = 0;
|
||||
float *dstVertexBuffer = nullptr;
|
||||
unsigned int *dstColorBuffer = nullptr;
|
||||
uint16_t *dstIndexBuffer = nullptr;
|
||||
bool needColor = false;
|
||||
int curBlendSrc = -1;
|
||||
int curBlendDst = -1;
|
||||
cc::Texture2D *curTexture = nullptr;
|
||||
RenderDrawInfo *curDrawInfo = nullptr;
|
||||
|
||||
if (abs(_nodeColor.r - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.g - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.b - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.a - 1.0F) > 0.0001F ||
|
||||
_premultipliedAlpha) {
|
||||
needColor = true;
|
||||
}
|
||||
|
||||
auto handleColor = [&](ArmatureCache::ColorData *colorData) {
|
||||
tempA = colorData->color.a * _nodeColor.a;
|
||||
multiplier = _premultipliedAlpha ? tempA / 255.0f : 1.0f;
|
||||
tempR = _nodeColor.r * multiplier;
|
||||
tempG = _nodeColor.g * multiplier;
|
||||
tempB = _nodeColor.b * multiplier;
|
||||
|
||||
color.a = (uint8_t)floorf(tempA);
|
||||
color.r = (uint8_t)floorf(colorData->color.r * tempR);
|
||||
color.g = (uint8_t)floorf(colorData->color.g * tempG);
|
||||
color.b = (uint8_t)floorf(colorData->color.b * tempB);
|
||||
};
|
||||
|
||||
handleColor(nowColor);
|
||||
int segmentCount = 0;
|
||||
for (auto *segment : segments) {
|
||||
vertexBytes = segment->vertexFloatCount * sizeof(float);
|
||||
curDrawInfo = requestDrawInfo(segmentCount++);
|
||||
entity->addDynamicRenderDrawInfo(curDrawInfo);
|
||||
// fill new texture index
|
||||
curTexture = static_cast<cc::Texture2D *>(segment->getTexture()->getRealTexture());
|
||||
gfx::Texture *texture = curTexture->getGFXTexture();
|
||||
gfx::Sampler *sampler = curTexture->getGFXSampler();
|
||||
curDrawInfo->setTexture(texture);
|
||||
curDrawInfo->setSampler(sampler);
|
||||
|
||||
blendMode = static_cast<BlendMode>(segment->blendMode);
|
||||
switch (blendMode) {
|
||||
case BlendMode::Add:
|
||||
curBlendSrc = static_cast<int>(_premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE);
|
||||
break;
|
||||
case BlendMode::Multiply:
|
||||
curBlendSrc = static_cast<int>(BlendFactor::DST_COLOR);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case BlendMode::Screen:
|
||||
curBlendSrc = static_cast<int>(BlendFactor::ONE);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_COLOR);
|
||||
break;
|
||||
default:
|
||||
curBlendSrc = static_cast<int>(_premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
// fill new blend src and dst
|
||||
auto *material = requestMaterial(curBlendSrc, curBlendDst);
|
||||
curDrawInfo->setMaterial(material);
|
||||
|
||||
// fill vertex buffer
|
||||
vb.checkSpace(vertexBytes, true);
|
||||
dstVertexOffset = vb.getCurPos() / sizeof(V3F_T2F_C4B);
|
||||
dstVertexBuffer = reinterpret_cast<float *>(vb.getCurBuffer());
|
||||
dstColorBuffer = reinterpret_cast<unsigned int *>(vb.getCurBuffer());
|
||||
vb.writeBytes(reinterpret_cast<char *>(srcVB.getBuffer()) + srcVertexBytesOffset, vertexBytes);
|
||||
// batch handle
|
||||
cc::Vec3 *point = nullptr;
|
||||
|
||||
for (auto posIndex = 0; posIndex < segment->vertexFloatCount; posIndex += VF_XYZUVC) {
|
||||
point = reinterpret_cast<cc::Vec3 *>(dstVertexBuffer + posIndex);
|
||||
point->z = 0;
|
||||
point->transformMat4(*point, nodeWorldMat);
|
||||
}
|
||||
// handle vertex color
|
||||
if (needColor) {
|
||||
auto frameFloatOffset = srcVertexBytesOffset / sizeof(float);
|
||||
for (auto colorIndex = 0; colorIndex < segment->vertexFloatCount; colorIndex += VF_XYZUVC, frameFloatOffset += VF_XYZUVC) {
|
||||
if (frameFloatOffset >= maxVFOffset) {
|
||||
nowColor = colors[colorOffset++];
|
||||
handleColor(nowColor);
|
||||
maxVFOffset = nowColor->vertexFloatOffset;
|
||||
}
|
||||
memcpy(dstColorBuffer + colorIndex + 5, &color, sizeof(color));
|
||||
}
|
||||
}
|
||||
|
||||
// move src vertex buffer offset
|
||||
srcVertexBytesOffset += vertexBytes;
|
||||
|
||||
// fill index buffer
|
||||
indexBytes = segment->indexCount * sizeof(uint16_t);
|
||||
ib.checkSpace(indexBytes, true);
|
||||
dstIndexOffset = static_cast<int>(ib.getCurPos()) / sizeof(uint16_t);
|
||||
dstIndexBuffer = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
ib.writeBytes(reinterpret_cast<char *>(srcIB.getBuffer()) + srcIndexBytesOffset, indexBytes);
|
||||
for (auto indexPos = 0; indexPos < segment->indexCount; indexPos++) {
|
||||
dstIndexBuffer[indexPos] += dstVertexOffset;
|
||||
}
|
||||
srcIndexBytesOffset += indexBytes;
|
||||
|
||||
// fill new index and vertex buffer id
|
||||
UIMeshBuffer *uiMeshBuffer = mb->getUIMeshBuffer();
|
||||
curDrawInfo->setMeshBuffer(uiMeshBuffer);
|
||||
|
||||
// fill new index offset
|
||||
curDrawInfo->setIndexOffset(dstIndexOffset);
|
||||
// fill new indice segamentation count
|
||||
curDrawInfo->setIbCount(segment->indexCount);
|
||||
}
|
||||
|
||||
if (_useAttach) {
|
||||
const auto &bonesData = frameData->getBones();
|
||||
auto boneCount = frameData->getBoneCount();
|
||||
|
||||
for (int i = 0; i < boneCount; i++) {
|
||||
auto *bone = bonesData[i];
|
||||
attachInfo->checkSpace(sizeof(cc::Mat4), true);
|
||||
attachInfo->writeBytes(reinterpret_cast<const char *>(&bone->globalTransformMatrix), sizeof(cc::Mat4));
|
||||
}
|
||||
}
|
||||
}
|
||||
void CCArmatureCacheDisplay::beginSchedule() {
|
||||
MiddlewareManager::getInstance()->addTimer(this);
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::stopSchedule() {
|
||||
MiddlewareManager::getInstance()->removeTimer(this);
|
||||
|
||||
if (_sharedBufferOffset) {
|
||||
_sharedBufferOffset->reset();
|
||||
_sharedBufferOffset->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::onEnable() {
|
||||
beginSchedule();
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::onDisable() {
|
||||
stopSchedule();
|
||||
}
|
||||
|
||||
Armature *CCArmatureCacheDisplay::getArmature() const {
|
||||
auto *armatureDisplay = _armatureCache->getArmatureDisplay();
|
||||
return armatureDisplay->getArmature();
|
||||
}
|
||||
|
||||
Animation *CCArmatureCacheDisplay::getAnimation() const {
|
||||
auto *armature = getArmature();
|
||||
return armature->getAnimation();
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::playAnimation(const std::string &name, int playTimes) {
|
||||
_playTimes = playTimes;
|
||||
_animationName = name;
|
||||
_animationData = _armatureCache->buildAnimationData(_animationName);
|
||||
_isAniComplete = false;
|
||||
_accTime = 0.0F;
|
||||
_playCount = 0;
|
||||
_curFrameIndex = 0;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::addDBEventListener(const std::string &type) {
|
||||
_listenerIDMap[type] = true;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::removeDBEventListener(const std::string &type) {
|
||||
auto it = _listenerIDMap.find(type);
|
||||
if (it != _listenerIDMap.end()) {
|
||||
_listenerIDMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::dispatchDBEvent(const std::string &type, EventObject *value) {
|
||||
auto it = _listenerIDMap.find(type);
|
||||
if (it == _listenerIDMap.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dbEventCallback) {
|
||||
_dbEventCallback(value);
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::updateAnimationCache(const std::string &animationName) {
|
||||
_armatureCache->resetAnimationData(animationName);
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::updateAllAnimationCache() {
|
||||
_armatureCache->resetAllAnimationData();
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::setColor(float r, float g, float b, float a) {
|
||||
_nodeColor.r = r / 255.0F;
|
||||
_nodeColor.g = g / 255.0F;
|
||||
_nodeColor.b = b / 255.0F;
|
||||
_nodeColor.a = a / 255.0F;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::setAttachEnabled(bool enabled) {
|
||||
_useAttach = enabled;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::setBatchEnabled(bool enabled) {
|
||||
if (enabled != _enableBatch) {
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
_enableBatch = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
se_object_ptr CCArmatureCacheDisplay::getSharedBufferOffset() const {
|
||||
if (_sharedBufferOffset) {
|
||||
return _sharedBufferOffset->getTypeArray();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::setRenderEntity(cc::RenderEntity *entity) {
|
||||
_entity = entity;
|
||||
}
|
||||
|
||||
void CCArmatureCacheDisplay::setMaterial(cc::Material *material) {
|
||||
_material = material;
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
}
|
||||
|
||||
cc::RenderDrawInfo *CCArmatureCacheDisplay::requestDrawInfo(int idx) {
|
||||
if (_drawInfoArray.size() < idx + 1) {
|
||||
cc::RenderDrawInfo *draw = new cc::RenderDrawInfo();
|
||||
draw->setDrawInfoType(static_cast<uint32_t>(RenderDrawInfoType::MIDDLEWARE));
|
||||
_drawInfoArray.push_back(draw);
|
||||
}
|
||||
return _drawInfoArray[idx];
|
||||
}
|
||||
|
||||
cc::Material *CCArmatureCacheDisplay::requestMaterial(uint16_t blendSrc, uint16_t blendDst) {
|
||||
uint32_t key = static_cast<uint32_t>(blendSrc) << 16 | static_cast<uint32_t>(blendDst);
|
||||
if (_materialCaches.find(key) == _materialCaches.end()) {
|
||||
const IMaterialInstanceInfo info{
|
||||
(Material *)_material,
|
||||
0};
|
||||
MaterialInstance *materialInstance = new MaterialInstance(info);
|
||||
PassOverrides overrides;
|
||||
BlendStateInfo stateInfo;
|
||||
stateInfo.blendColor = gfx::Color{1.0F, 1.0F, 1.0F, 1.0F};
|
||||
BlendTargetInfo targetInfo;
|
||||
targetInfo.blendEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendAlphaEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendSrc = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDst = (gfx::BlendFactor)blendDst;
|
||||
targetInfo.blendSrcAlpha = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDstAlpha = (gfx::BlendFactor)blendDst;
|
||||
BlendTargetInfoList targetList{targetInfo};
|
||||
stateInfo.targets = targetList;
|
||||
overrides.blendState = stateInfo;
|
||||
materialInstance->overridePipelineStates(overrides);
|
||||
const MacroRecord macros{{"USE_LOCAL", false}};
|
||||
materialInstance->recompileShaders(macros);
|
||||
_materialCaches[key] = materialInstance;
|
||||
}
|
||||
return _materialCaches[key];
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ArmatureCache.h"
|
||||
#include "CCArmatureDisplay.h"
|
||||
#include "base/RefCounted.h"
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
|
||||
namespace cc {
|
||||
class RenderEntity;
|
||||
class RenderDrawInfo;
|
||||
class Material;
|
||||
}; // namespace cc
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
class CCArmatureCacheDisplay : public cc::RefCounted, public cc::middleware::IMiddleware {
|
||||
public:
|
||||
CCArmatureCacheDisplay(const std::string &armatureName, const std::string &armatureKey, const std::string &atlasUUID, bool isShare);
|
||||
~CCArmatureCacheDisplay() override;
|
||||
void dispose();
|
||||
|
||||
void update(float dt) override;
|
||||
void render(float dt) override;
|
||||
|
||||
void setTimeScale(float scale) {
|
||||
_timeScale = scale;
|
||||
}
|
||||
|
||||
float getTimeScale() const {
|
||||
return _timeScale;
|
||||
}
|
||||
|
||||
void beginSchedule();
|
||||
void stopSchedule();
|
||||
void onEnable();
|
||||
void onDisable();
|
||||
|
||||
Armature *getArmature() const;
|
||||
Animation *getAnimation() const;
|
||||
|
||||
void setColor(float r, float g, float b, float a);
|
||||
void setBatchEnabled(bool enabled);
|
||||
void setAttachEnabled(bool enabled);
|
||||
|
||||
void setOpacityModifyRGB(bool value) {
|
||||
_premultipliedAlpha = value;
|
||||
}
|
||||
|
||||
using dbEventCallback = std::function<void(EventObject *)>;
|
||||
void setDBEventCallback(dbEventCallback callback) {
|
||||
_dbEventCallback = std::move(callback);
|
||||
}
|
||||
void addDBEventListener(const std::string &type);
|
||||
void removeDBEventListener(const std::string &type);
|
||||
void dispatchDBEvent(const std::string &type, EventObject *value);
|
||||
|
||||
void playAnimation(const std::string &name, int playTimes);
|
||||
void updateAnimationCache(const std::string &animationName);
|
||||
void updateAllAnimationCache();
|
||||
|
||||
/**
|
||||
* @return shared buffer offset, it's a Uint32Array
|
||||
* format |render info offset|attach info offset|
|
||||
*/
|
||||
se_object_ptr getSharedBufferOffset() const;
|
||||
|
||||
cc::RenderDrawInfo *requestDrawInfo(int idx);
|
||||
cc::Material *requestMaterial(uint16_t blendSrc, uint16_t blendDst);
|
||||
void setMaterial(cc::Material *material);
|
||||
void setRenderEntity(cc::RenderEntity *entity);
|
||||
|
||||
private:
|
||||
float _timeScale = 1;
|
||||
int _curFrameIndex = -1;
|
||||
float _accTime = 0.0F;
|
||||
int _playCount = 0;
|
||||
int _playTimes = 0;
|
||||
bool _isAniComplete = true;
|
||||
std::string _animationName;
|
||||
|
||||
Armature *_armature = nullptr;
|
||||
ArmatureCache::AnimationData *_animationData = nullptr;
|
||||
std::map<std::string, bool> _listenerIDMap;
|
||||
|
||||
bool _useAttach = false;
|
||||
bool _enableBatch = true;
|
||||
cc::middleware::Color4F _nodeColor = cc::middleware::Color4F::WHITE;
|
||||
|
||||
bool _premultipliedAlpha = false;
|
||||
dbEventCallback _dbEventCallback = nullptr;
|
||||
ArmatureCache *_armatureCache = nullptr;
|
||||
EventObject *_eventObject;
|
||||
|
||||
cc::middleware::IOTypedArray *_sharedBufferOffset = nullptr;
|
||||
|
||||
cc::RenderEntity *_entity = nullptr;
|
||||
cc::Material *_material = nullptr;
|
||||
ccstd::vector<cc::RenderDrawInfo *> _drawInfoArray;
|
||||
ccstd::unordered_map<uint32_t, cc::Material *> _materialCaches;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,466 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
#include "2d/renderer/RenderDrawInfo.h"
|
||||
#include "2d/renderer/RenderEntity.h"
|
||||
#include "MiddlewareMacro.h"
|
||||
#include "SharedBufferManager.h"
|
||||
#include "base/DeferredReleasePool.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "dragonbones-creator-support/CCSlot.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "math/Math.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "renderer/core/MaterialInstance.h"
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
|
||||
static const std::string TECH_STAGE = "opaque";
|
||||
static const std::string TEXTURE_KEY = "texture";
|
||||
namespace cc {
|
||||
|
||||
}
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
CCArmatureDisplay *CCArmatureDisplay::create() {
|
||||
return new (std::nothrow) CCArmatureDisplay();
|
||||
}
|
||||
|
||||
CCArmatureDisplay::CCArmatureDisplay() {
|
||||
_sharedBufferOffset = new IOTypedArray(se::Object::TypedArrayType::UINT32, sizeof(uint32_t) * 2);
|
||||
}
|
||||
|
||||
CCArmatureDisplay::~CCArmatureDisplay() {
|
||||
dispose();
|
||||
|
||||
if (_debugBuffer) {
|
||||
delete _debugBuffer;
|
||||
_debugBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (_sharedBufferOffset) {
|
||||
delete _sharedBufferOffset;
|
||||
_sharedBufferOffset = nullptr;
|
||||
}
|
||||
for (auto *draw : _drawInfoArray) {
|
||||
CC_SAFE_DELETE(draw);
|
||||
}
|
||||
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::dispose() {
|
||||
if (_armature != nullptr) {
|
||||
_armature->dispose();
|
||||
_armature = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::dbInit(Armature *armature) {
|
||||
_armature = armature;
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::dbClear() {
|
||||
_armature = nullptr;
|
||||
release();
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::dbUpdate() {}
|
||||
|
||||
void CCArmatureDisplay::dbRender() {
|
||||
_sharedBufferOffset->reset();
|
||||
_sharedBufferOffset->clear();
|
||||
|
||||
if (this->_armature->getParent()) {
|
||||
return;
|
||||
}
|
||||
if (!_entity) {
|
||||
return;
|
||||
}
|
||||
auto *entity = _entity;
|
||||
entity->clearDynamicRenderDrawInfos();
|
||||
|
||||
auto *mgr = MiddlewareManager::getInstance();
|
||||
if (!mgr->isRendering) return;
|
||||
|
||||
auto *attachMgr = mgr->getAttachInfoMgr();
|
||||
auto *attachInfo = attachMgr->getBuffer();
|
||||
if (!attachInfo) return;
|
||||
|
||||
// store attach info offset
|
||||
_sharedBufferOffset->writeUint32(static_cast<uint32_t>(attachInfo->getCurPos()) / sizeof(uint32_t));
|
||||
|
||||
_preBlendMode = -1;
|
||||
_preISegWritePos = -1;
|
||||
_curISegLen = 0;
|
||||
|
||||
_debugSlotsLen = 0;
|
||||
_materialLen = 0;
|
||||
_preTexture = nullptr;
|
||||
_curTexture = nullptr;
|
||||
_curDrawInfo = nullptr;
|
||||
|
||||
// Traverse all aramture to fill vertex and index buffer.
|
||||
traverseArmature(_armature);
|
||||
|
||||
if (_curDrawInfo) _curDrawInfo->setIbCount(_curISegLen);
|
||||
|
||||
if (_useAttach || _debugDraw) {
|
||||
const auto &bones = _armature->getBones();
|
||||
std::size_t count = bones.size();
|
||||
|
||||
cc::Mat4 boneMat = cc::Mat4::IDENTITY;
|
||||
|
||||
if (_debugDraw) {
|
||||
// If enable debug draw,then init debug buffer.
|
||||
if (_debugBuffer == nullptr) {
|
||||
_debugBuffer = new IOTypedArray(se::Object::TypedArrayType::FLOAT32, MAX_DEBUG_BUFFER_SIZE);
|
||||
}
|
||||
_debugBuffer->reset();
|
||||
_debugBuffer->writeFloat32(static_cast<float>(count) * 4);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Bone *bone = static_cast<Bone *>(bones[i]);
|
||||
|
||||
float boneLen = 5;
|
||||
if (bone->_boneData->length > boneLen) {
|
||||
boneLen = bone->_boneData->length;
|
||||
}
|
||||
|
||||
boneMat.m[0] = bone->globalTransformMatrix.a;
|
||||
boneMat.m[1] = bone->globalTransformMatrix.b;
|
||||
boneMat.m[4] = -bone->globalTransformMatrix.c;
|
||||
boneMat.m[5] = -bone->globalTransformMatrix.d;
|
||||
boneMat.m[12] = bone->globalTransformMatrix.tx;
|
||||
boneMat.m[13] = bone->globalTransformMatrix.ty;
|
||||
attachInfo->checkSpace(sizeof(boneMat), true);
|
||||
attachInfo->writeBytes(reinterpret_cast<const char *>(&boneMat), sizeof(boneMat));
|
||||
|
||||
if (_debugDraw) {
|
||||
float bx = bone->globalTransformMatrix.tx;
|
||||
float by = bone->globalTransformMatrix.ty;
|
||||
float endx = bx + bone->globalTransformMatrix.a * boneLen;
|
||||
float endy = by + bone->globalTransformMatrix.b * boneLen;
|
||||
_debugBuffer->writeFloat32(bx);
|
||||
_debugBuffer->writeFloat32(by);
|
||||
_debugBuffer->writeFloat32(endx);
|
||||
_debugBuffer->writeFloat32(endy);
|
||||
}
|
||||
}
|
||||
|
||||
if (_debugBuffer && _debugBuffer->isOutRange()) {
|
||||
_debugBuffer->writeFloat32(0, 0);
|
||||
CC_LOG_INFO("Dragonbones debug data is too large,debug buffer has no space to put in it!!!!!!!!!!");
|
||||
CC_LOG_INFO("You can adjust MAX_DEBUG_BUFFER_SIZE in MiddlewareMacro");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cc::Vec2 &CCArmatureDisplay::convertToRootSpace(float x, float y) const {
|
||||
auto *slot = reinterpret_cast<CCSlot *>(_armature->getParent());
|
||||
if (!slot) {
|
||||
_tmpVec2.set(x, y);
|
||||
return _tmpVec2;
|
||||
}
|
||||
|
||||
slot->updateWorldMatrix();
|
||||
cc::Mat4 &worldMatrix = slot->worldMatrix;
|
||||
_tmpVec2.x = x * worldMatrix.m[0] + y * worldMatrix.m[4] + worldMatrix.m[12];
|
||||
_tmpVec2.y = x * worldMatrix.m[1] + y * worldMatrix.m[5] + worldMatrix.m[13];
|
||||
return _tmpVec2;
|
||||
}
|
||||
|
||||
CCArmatureDisplay *CCArmatureDisplay::getRootDisplay() {
|
||||
Slot *slot = _armature->getParent();
|
||||
if (!slot) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Slot *parentSlot = slot->_armature->getParent();
|
||||
while (parentSlot) {
|
||||
slot = parentSlot;
|
||||
parentSlot = parentSlot->_armature->getParent();
|
||||
}
|
||||
return static_cast<CCArmatureDisplay *>(slot->_armature->getDisplay());
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::traverseArmature(Armature *armature, float parentOpacity) {
|
||||
static cc::Mat4 matrixTemp;
|
||||
auto &nodeWorldMat = _entity->getNode()->getWorldMatrix();
|
||||
|
||||
// data store in buffer which 0 to 3 is render order, left data is node world matrix
|
||||
const auto &slots = armature->getSlots();
|
||||
auto *mgr = MiddlewareManager::getInstance();
|
||||
|
||||
middleware::MeshBuffer *mb = mgr->getMeshBuffer(VF_XYZUVC);
|
||||
IOBuffer &vb = mb->getVB();
|
||||
IOBuffer &ib = mb->getIB();
|
||||
|
||||
float realOpacity = _nodeColor.a;
|
||||
|
||||
auto *attachMgr = mgr->getAttachInfoMgr();
|
||||
auto *attachInfo = attachMgr->getBuffer();
|
||||
if (!attachInfo) return;
|
||||
|
||||
// range [0.0, 255.0]
|
||||
Color4B color(0, 0, 0, 0);
|
||||
CCSlot *slot = nullptr;
|
||||
int isFull = 0;
|
||||
|
||||
auto flush = [&]() {
|
||||
// fill pre segment count field
|
||||
if (_curDrawInfo) _curDrawInfo->setIbCount(_curISegLen);
|
||||
|
||||
_curDrawInfo = requestDrawInfo(_materialLen);
|
||||
_entity->addDynamicRenderDrawInfo(_curDrawInfo);
|
||||
// prepare to fill new segment field
|
||||
switch (slot->_blendMode) {
|
||||
case BlendMode::Add:
|
||||
_curBlendSrc = static_cast<int>(_premultipliedAlpha ? gfx::BlendFactor::ONE : gfx::BlendFactor::SRC_ALPHA);
|
||||
_curBlendDst = static_cast<int>(gfx::BlendFactor::ONE);
|
||||
break;
|
||||
case BlendMode::Multiply:
|
||||
_curBlendSrc = static_cast<int>(gfx::BlendFactor::DST_COLOR);
|
||||
_curBlendDst = static_cast<int>(gfx::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case BlendMode::Screen:
|
||||
_curBlendSrc = static_cast<int>(gfx::BlendFactor::ONE);
|
||||
_curBlendDst = static_cast<int>(gfx::BlendFactor::ONE_MINUS_SRC_COLOR);
|
||||
break;
|
||||
default:
|
||||
_curBlendSrc = static_cast<int>(_premultipliedAlpha ? gfx::BlendFactor::ONE : gfx::BlendFactor::SRC_ALPHA);
|
||||
_curBlendDst = static_cast<int>(gfx::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
|
||||
auto *material = requestMaterial(_curBlendSrc, _curBlendDst);
|
||||
_curDrawInfo->setMaterial(material);
|
||||
gfx::Texture *texture = _curTexture->getGFXTexture();
|
||||
gfx::Sampler *sampler = _curTexture->getGFXSampler();
|
||||
_curDrawInfo->setTexture(texture);
|
||||
_curDrawInfo->setSampler(sampler);
|
||||
UIMeshBuffer *uiMeshBuffer = mb->getUIMeshBuffer();
|
||||
_curDrawInfo->setMeshBuffer(uiMeshBuffer);
|
||||
_curDrawInfo->setIndexOffset(static_cast<uint32_t>(ib.getCurPos()) / sizeof(uint16_t));
|
||||
|
||||
// reset pre blend mode to current
|
||||
_preBlendMode = static_cast<int>(slot->_blendMode);
|
||||
// reset pre texture index to current
|
||||
_preTexture = _curTexture;
|
||||
|
||||
// reset index segmentation count
|
||||
_curISegLen = 0;
|
||||
// material length increased
|
||||
_materialLen++;
|
||||
};
|
||||
|
||||
for (auto *i : slots) {
|
||||
isFull = 0;
|
||||
slot = dynamic_cast<CCSlot *>(i); //TODO(zhakasi): refine the logic
|
||||
if (slot == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!slot->getVisible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
slot->updateWorldMatrix();
|
||||
|
||||
// If slots has child armature,will traverse child first.
|
||||
Armature *childArmature = slot->getChildArmature();
|
||||
if (childArmature != nullptr) {
|
||||
traverseArmature(childArmature, parentOpacity * static_cast<float>(slot->color.a) / 255.0F);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!slot->getTexture()) continue;
|
||||
_curTexture = static_cast<cc::Texture2D *>(slot->getTexture()->getRealTexture());
|
||||
auto vbSize = slot->triangles.vertCount * sizeof(middleware::V3F_T2F_C4B);
|
||||
isFull |= vb.checkSpace(vbSize, true);
|
||||
|
||||
// If texture or blendMode change,will change material.
|
||||
if (_preTexture != _curTexture || _preBlendMode != static_cast<int>(slot->_blendMode) || isFull) {
|
||||
flush();
|
||||
}
|
||||
|
||||
// Calculation vertex color.
|
||||
color.a = (uint8_t)(realOpacity * static_cast<float>(slot->color.a) * parentOpacity);
|
||||
float multiplier = _premultipliedAlpha ? color.a / 255.0F : 1.0F;
|
||||
color.r = _nodeColor.r * slot->color.r * multiplier;
|
||||
color.g = _nodeColor.g * slot->color.g * multiplier;
|
||||
color.b = _nodeColor.b * slot->color.b * multiplier;
|
||||
|
||||
// Transform component matrix to global matrix
|
||||
middleware::Triangles &triangles = slot->triangles;
|
||||
cc::Mat4 *worldMatrix = &slot->worldMatrix;
|
||||
cc::Mat4::multiply(nodeWorldMat, *worldMatrix, &matrixTemp);
|
||||
worldMatrix = &matrixTemp;
|
||||
|
||||
middleware::V3F_T2F_C4B *worldTriangles = slot->worldVerts;
|
||||
|
||||
for (int v = 0, w = 0, vn = triangles.vertCount; v < vn; ++v, w += 2) {
|
||||
middleware::V3F_T2F_C4B *vertex = triangles.verts + v;
|
||||
middleware::V3F_T2F_C4B *worldVertex = worldTriangles + v;
|
||||
|
||||
vertex->vertex.z = 0; //reset for z value
|
||||
worldVertex->vertex.transformMat4(vertex->vertex, *worldMatrix);
|
||||
|
||||
worldVertex->color = color;
|
||||
}
|
||||
|
||||
// Fill MiddlewareManager vertex buffer
|
||||
auto vertexOffset = vb.getCurPos() / sizeof(middleware::V3F_T2F_C4B);
|
||||
vb.writeBytes(reinterpret_cast<char *>(worldTriangles), vbSize);
|
||||
|
||||
auto ibSize = triangles.indexCount * sizeof(uint16_t);
|
||||
ib.checkSpace(ibSize, true);
|
||||
// If vertex buffer current offset is zero,fill it directly or recalculate vertex offset.
|
||||
if (vertexOffset > 0) {
|
||||
for (int ii = 0, nn = triangles.indexCount; ii < nn; ii++) {
|
||||
ib.writeUint16(triangles.indices[ii] + vertexOffset);
|
||||
}
|
||||
} else {
|
||||
ib.writeBytes(reinterpret_cast<char *>(triangles.indices), ibSize);
|
||||
}
|
||||
|
||||
// Record this turn index segmentation count,it will store in material buffer in the end.
|
||||
_curISegLen += triangles.indexCount;
|
||||
}
|
||||
}
|
||||
|
||||
bool CCArmatureDisplay::hasDBEventListener(const std::string &type) const {
|
||||
auto it = _listenerIDMap.find(type);
|
||||
return it != _listenerIDMap.end();
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::addDBEventListener(const std::string &type, const std::function<void(EventObject *)> & /*listener*/) {
|
||||
_listenerIDMap[type] = true;
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::dispatchDBEvent(const std::string &type, EventObject *value) {
|
||||
auto it = _listenerIDMap.find(type);
|
||||
if (it == _listenerIDMap.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dbEventCallback) {
|
||||
_dbEventCallback(value);
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::removeDBEventListener(const std::string &type, const std::function<void(EventObject *)> & /*listener*/) {
|
||||
auto it = _listenerIDMap.find(type);
|
||||
if (it != _listenerIDMap.end()) {
|
||||
_listenerIDMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
se_object_ptr CCArmatureDisplay::getDebugData() const {
|
||||
if (_debugBuffer) {
|
||||
return _debugBuffer->getTypeArray();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::setColor(float r, float g, float b, float a) {
|
||||
_nodeColor.r = r / 255.0F;
|
||||
_nodeColor.g = g / 255.0F;
|
||||
_nodeColor.b = b / 255.0F;
|
||||
_nodeColor.a = a / 255.0F;
|
||||
}
|
||||
|
||||
se_object_ptr CCArmatureDisplay::getSharedBufferOffset() const {
|
||||
if (_sharedBufferOffset) {
|
||||
return _sharedBufferOffset->getTypeArray();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::setBatchEnabled(bool enabled) {
|
||||
if (enabled != _enableBatch) {
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
_enableBatch = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::setRenderEntity(cc::RenderEntity *entity) {
|
||||
_entity = entity;
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::setMaterial(cc::Material *material) {
|
||||
_material = material;
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
}
|
||||
|
||||
cc::RenderDrawInfo *CCArmatureDisplay::requestDrawInfo(int idx) {
|
||||
if (_drawInfoArray.size() < idx + 1) {
|
||||
cc::RenderDrawInfo *draw = new cc::RenderDrawInfo();
|
||||
draw->setDrawInfoType(static_cast<uint32_t>(RenderDrawInfoType::MIDDLEWARE));
|
||||
_drawInfoArray.push_back(draw);
|
||||
}
|
||||
return _drawInfoArray[idx];
|
||||
}
|
||||
|
||||
cc::Material *CCArmatureDisplay::requestMaterial(uint16_t blendSrc, uint16_t blendDst) {
|
||||
uint32_t key = static_cast<uint32_t>(blendSrc) << 16 | static_cast<uint32_t>(blendDst);
|
||||
if (_materialCaches.find(key) == _materialCaches.end()) {
|
||||
const IMaterialInstanceInfo info{
|
||||
(Material *)_material,
|
||||
0};
|
||||
MaterialInstance *materialInstance = new MaterialInstance(info);
|
||||
PassOverrides overrides;
|
||||
BlendStateInfo stateInfo;
|
||||
stateInfo.blendColor = gfx::Color{1.0F, 1.0F, 1.0F, 1.0F};
|
||||
BlendTargetInfo targetInfo;
|
||||
targetInfo.blendEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendAlphaEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendSrc = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDst = (gfx::BlendFactor)blendDst;
|
||||
targetInfo.blendSrcAlpha = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDstAlpha = (gfx::BlendFactor)blendDst;
|
||||
BlendTargetInfoList targetList{targetInfo};
|
||||
stateInfo.targets = targetList;
|
||||
overrides.blendState = stateInfo;
|
||||
materialInstance->overridePipelineStates(overrides);
|
||||
const MacroRecord macros{{"USE_LOCAL", false}};
|
||||
materialInstance->recompileShaders(macros);
|
||||
_materialCaches[key] = materialInstance;
|
||||
}
|
||||
return _materialCaches[key];
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,211 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DRAGONBONES_CC_ARMATURE_DISPLAY_CONTAINER_H
|
||||
#define DRAGONBONES_CC_ARMATURE_DISPLAY_CONTAINER_H
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "IOTypedArray.h"
|
||||
#include "MiddlewareManager.h"
|
||||
#include "base/RefCounted.h"
|
||||
#include "base/RefMap.h"
|
||||
#include "bindings/event/EventDispatcher.h"
|
||||
#include "dragonbones-creator-support/CCSlot.h"
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
#include "middleware-adapter.h"
|
||||
|
||||
namespace cc {
|
||||
class RenderEntity;
|
||||
class RenderDrawInfo;
|
||||
class Material;
|
||||
class Texture2D;
|
||||
}; // namespace cc
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* CCArmatureDisplay is a armature tree.It can add or remove a childArmature.
|
||||
* It will not save vertices and indices.Only CCSlot will save these info.
|
||||
* And CCArmatureDisplay will traverse all tree node and calculate render data.
|
||||
*/
|
||||
class CCArmatureDisplay : public cc::RefCounted, public virtual IArmatureProxy {
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(CCArmatureDisplay)
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static CCArmatureDisplay *create();
|
||||
|
||||
private:
|
||||
void traverseArmature(Armature *armature, float parentOpacity = 1.0F);
|
||||
|
||||
protected:
|
||||
bool _debugDraw = false;
|
||||
Armature *_armature = nullptr;
|
||||
|
||||
public:
|
||||
CCArmatureDisplay();
|
||||
~CCArmatureDisplay() override;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dbInit(Armature *armature) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dbClear() override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dbUpdate() override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dbRender() override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dispose() override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
bool hasDBEventListener(const std::string &type) const override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void dispatchDBEvent(const std::string &type, EventObject *value) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void addDBEventListener(const std::string &type, const std::function<void(EventObject *)> &listener) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void removeDBEventListener(const std::string &type, const std::function<void(EventObject *)> &listener) override;
|
||||
|
||||
using dbEventCallback = std::function<void(EventObject *)>;
|
||||
void setDBEventCallback(dbEventCallback callback) {
|
||||
_dbEventCallback = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
inline Armature *getArmature() const override {
|
||||
return _armature;
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
inline Animation *getAnimation() const override {
|
||||
return _armature->getAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return debug data,it's a Float32Array,
|
||||
* format |debug bones length|[beginX|beginY|toX|toY|...loop...]
|
||||
*/
|
||||
se_object_ptr getDebugData() const;
|
||||
/**
|
||||
* @return shared buffer offset, it's a Uint32Array
|
||||
* format |render info offset|attach info offset|
|
||||
*/
|
||||
se_object_ptr getSharedBufferOffset() const;
|
||||
|
||||
void setColor(float r, float g, float b, float a);
|
||||
|
||||
void setDebugBonesEnabled(bool enabled) {
|
||||
_debugDraw = enabled;
|
||||
}
|
||||
|
||||
void setBatchEnabled(bool enabled);
|
||||
|
||||
void setAttachEnabled(bool enabled) {
|
||||
_useAttach = enabled;
|
||||
}
|
||||
|
||||
void setOpacityModifyRGB(bool value) {
|
||||
_premultipliedAlpha = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert component position to global position.
|
||||
* @param[in] pos Component position
|
||||
* @return Global position
|
||||
*/
|
||||
const cc::Vec2 &convertToRootSpace(float x, float y) const;
|
||||
|
||||
/**
|
||||
* @return root display,if this diplay is root,then return itself.
|
||||
*/
|
||||
CCArmatureDisplay *getRootDisplay();
|
||||
|
||||
cc::RenderDrawInfo *requestDrawInfo(int idx);
|
||||
cc::Material *requestMaterial(uint16_t blendSrc, uint16_t blendDst);
|
||||
void setMaterial(cc::Material *material);
|
||||
void setRenderEntity(cc::RenderEntity *entity);
|
||||
|
||||
private:
|
||||
std::map<std::string, bool> _listenerIDMap;
|
||||
int _preBlendMode = -1;
|
||||
int _curBlendSrc = -1;
|
||||
int _curBlendDst = -1;
|
||||
cc::Texture2D *_preTexture = nullptr;
|
||||
cc::Texture2D *_curTexture = nullptr;
|
||||
cc::RenderDrawInfo *_curDrawInfo = nullptr;
|
||||
|
||||
int _preISegWritePos = -1;
|
||||
int _curISegLen = 0;
|
||||
|
||||
int _debugSlotsLen = 0;
|
||||
int _materialLen = 0;
|
||||
|
||||
bool _useAttach = false;
|
||||
bool _premultipliedAlpha = false;
|
||||
bool _enableBatch = false;
|
||||
|
||||
// NOTE: We bind Vec2 to make JS deserialization works, we need to return const reference in convertToRootSpace method,
|
||||
// because returning Vec2 JSB object on stack to JS will let JS get mess data.
|
||||
mutable cc::Vec2 _tmpVec2;
|
||||
//
|
||||
cc::middleware::Color4F _nodeColor = cc::middleware::Color4F::WHITE;
|
||||
dbEventCallback _dbEventCallback = nullptr;
|
||||
|
||||
cc::middleware::IOTypedArray *_sharedBufferOffset = nullptr;
|
||||
cc::middleware::IOTypedArray *_debugBuffer = nullptr;
|
||||
|
||||
cc::RenderEntity *_entity = nullptr;
|
||||
cc::Material *_material = nullptr;
|
||||
ccstd::vector<cc::RenderDrawInfo *> _drawInfoArray;
|
||||
ccstd::unordered_map<uint32_t, cc::Material *> _materialCaches;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif // DRAGONBONES_CC_ARMATURE_DISPLAY_CONTAINER_H
|
||||
@@ -0,0 +1,36 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DRAGONBONES_CC_HEADERS_H
|
||||
#define DRAGONBONES_CC_HEADERS_H
|
||||
|
||||
#include "dragonbones-creator-support/ArmatureCacheMgr.h"
|
||||
#include "dragonbones-creator-support/CCArmatureCacheDisplay.h"
|
||||
#include "dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
#include "dragonbones-creator-support/CCFactory.h"
|
||||
#include "dragonbones-creator-support/CCSlot.h"
|
||||
#include "dragonbones-creator-support/CCTextureAtlasData.h"
|
||||
|
||||
#endif // DRAGONBONES_CC_HEADERS_H
|
||||
210
cocos/editor-support/dragonbones-creator-support/CCFactory.cpp
Normal file
210
cocos/editor-support/dragonbones-creator-support/CCFactory.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "dragonbones-creator-support/CCFactory.h"
|
||||
#include "dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
#include "dragonbones-creator-support/CCSlot.h"
|
||||
#include "dragonbones-creator-support/CCTextureAtlasData.h"
|
||||
#include "platform/FileUtils.h"
|
||||
|
||||
using namespace cc;
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
DragonBones *CCFactory::_dragonBonesInstance = nullptr;
|
||||
CCFactory *CCFactory::_factory = nullptr;
|
||||
|
||||
TextureAtlasData *CCFactory::_buildTextureAtlasData(TextureAtlasData *textureAtlasData, void *textureAtlas) const {
|
||||
if (textureAtlasData != nullptr) {
|
||||
const auto pos = _prevPath.find_last_of("/");
|
||||
if (pos != std::string::npos) {
|
||||
const auto basePath = _prevPath.substr(0, pos + 1);
|
||||
textureAtlasData->imagePath = basePath + textureAtlasData->imagePath;
|
||||
}
|
||||
|
||||
if (textureAtlas != nullptr) {
|
||||
static_cast<CCTextureAtlasData *>(textureAtlasData)->setRenderTexture(static_cast<middleware::Texture2D *>(textureAtlas));
|
||||
}
|
||||
} else {
|
||||
textureAtlasData = BaseObject::borrowObject<CCTextureAtlasData>();
|
||||
}
|
||||
|
||||
return textureAtlasData;
|
||||
}
|
||||
|
||||
Armature *CCFactory::_buildArmature(const BuildArmaturePackage &dataPackage) const {
|
||||
const auto armature = BaseObject::borrowObject<Armature>();
|
||||
const auto armatureDisplay = CCArmatureDisplay::create();
|
||||
|
||||
// will release when armature destructor
|
||||
armatureDisplay->addRef();
|
||||
|
||||
armature->init(
|
||||
dataPackage.armature,
|
||||
armatureDisplay, armatureDisplay, _dragonBones);
|
||||
|
||||
return armature;
|
||||
}
|
||||
|
||||
Slot *CCFactory::_buildSlot(const BuildArmaturePackage &dataPackage, const SlotData *slotData, Armature *armature) const {
|
||||
const auto slot = BaseObject::borrowObject<CCSlot>();
|
||||
|
||||
slot->init(
|
||||
slotData, armature,
|
||||
slot, slot);
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
DragonBonesData *CCFactory::loadDragonBonesData(const std::string &filePath, const std::string &name, float scale) {
|
||||
if (!name.empty()) {
|
||||
const auto existedData = getDragonBonesData(name);
|
||||
if (existedData) {
|
||||
return existedData;
|
||||
}
|
||||
}
|
||||
|
||||
const auto fullpath = cc::FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
if (cc::FileUtils::getInstance()->isFileExist(filePath)) {
|
||||
const auto pos = fullpath.find(".json");
|
||||
|
||||
if (pos != std::string::npos) {
|
||||
const auto data = cc::FileUtils::getInstance()->getStringFromFile(filePath);
|
||||
|
||||
return parseDragonBonesData(data.c_str(), name, scale);
|
||||
} else {
|
||||
cc::Data cocos2dData;
|
||||
cc::FileUtils::getInstance()->getContents(fullpath, &cocos2dData);
|
||||
uint8_t *binary = cocos2dData.takeBuffer();
|
||||
// NOTE: binary is freed in DragonBonesData::_onClear
|
||||
return parseDragonBonesData(reinterpret_cast<char *>(binary), name, scale);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DragonBonesData *CCFactory::parseDragonBonesDataByPath(const std::string &filePath, const std::string &name, float scale) {
|
||||
if (!name.empty()) {
|
||||
const auto existedData = getDragonBonesData(name);
|
||||
if (existedData) {
|
||||
return existedData;
|
||||
}
|
||||
}
|
||||
|
||||
const auto dbbinPos = filePath.find(".dbbin");
|
||||
if (dbbinPos != std::string::npos) {
|
||||
const auto fullpath = cc::FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
if (cc::FileUtils::getInstance()->isFileExist(filePath)) {
|
||||
cc::Data cocos2dData;
|
||||
cc::FileUtils::getInstance()->getContents(fullpath, &cocos2dData);
|
||||
uint8_t *binary = cocos2dData.takeBuffer();
|
||||
// NOTE: binary is freed in DragonBonesData::_onClear
|
||||
return parseDragonBonesData(reinterpret_cast<char *>(binary), name, scale);
|
||||
}
|
||||
} else {
|
||||
return parseDragonBonesData(filePath.c_str(), name, scale);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DragonBonesData *CCFactory::getDragonBonesDataByUUID(const std::string &uuid) {
|
||||
DragonBonesData *bonesData = nullptr;
|
||||
for (auto it = _dragonBonesDataMap.begin(); it != _dragonBonesDataMap.end();) {
|
||||
if (it->first.find(uuid) != std::string::npos) {
|
||||
bonesData = it->second;
|
||||
break;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
return bonesData;
|
||||
}
|
||||
|
||||
void CCFactory::removeDragonBonesDataByUUID(const std::string &uuid, bool disposeData) {
|
||||
for (auto it = _dragonBonesDataMap.begin(); it != _dragonBonesDataMap.end();) {
|
||||
if (it->first.find(uuid) != std::string::npos) {
|
||||
if (disposeData) {
|
||||
it->second->returnToPool();
|
||||
}
|
||||
it = _dragonBonesDataMap.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextureAtlasData *CCFactory::loadTextureAtlasData(const std::string &filePath, const std::string &name, float scale) {
|
||||
_prevPath = cc::FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
const auto data = cc::FileUtils::getInstance()->getStringFromFile(_prevPath);
|
||||
if (data.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return static_cast<CCTextureAtlasData *>(BaseFactory::parseTextureAtlasData(data.c_str(), nullptr, name, scale));
|
||||
}
|
||||
|
||||
CCArmatureDisplay *CCFactory::buildArmatureDisplay(const std::string &armatureName, const std::string &dragonBonesName, const std::string &skinName, const std::string &textureAtlasName) const {
|
||||
const auto armature = buildArmature(armatureName, dragonBonesName, skinName, textureAtlasName);
|
||||
if (armature != nullptr) {
|
||||
return static_cast<CCArmatureDisplay *>(armature->getDisplay());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCFactory::removeTextureAtlasDataByIndex(const std::string &name, int textureIndex) {
|
||||
const auto iterator = _textureAtlasDataMap.find(name);
|
||||
if (iterator != _textureAtlasDataMap.end()) {
|
||||
auto &textureAtlasDataList = iterator->second;
|
||||
for (auto it = textureAtlasDataList.begin(); it != textureAtlasDataList.end(); it++) {
|
||||
middleware::Texture2D *texture = ((CCTextureAtlasData *)*it)->getRenderTexture();
|
||||
if (texture && texture->getRealTextureIndex() == textureIndex) {
|
||||
textureAtlasDataList.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (textureAtlasDataList.size() == 0) {
|
||||
_textureAtlasDataMap.erase(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCTextureAtlasData *CCFactory::getTextureAtlasDataByIndex(const std::string &name, int textureIndex) const {
|
||||
const auto iterator = _textureAtlasDataMap.find(name);
|
||||
if (iterator != _textureAtlasDataMap.end()) {
|
||||
auto &textureAtlasDataList = iterator->second;
|
||||
for (auto it = textureAtlasDataList.begin(); it != textureAtlasDataList.end(); it++) {
|
||||
middleware::Texture2D *texture = ((CCTextureAtlasData *)*it)->getRenderTexture();
|
||||
if (texture && texture->getRealTextureIndex() == textureIndex) {
|
||||
return (CCTextureAtlasData *)*it;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
255
cocos/editor-support/dragonbones-creator-support/CCFactory.h
Normal file
255
cocos/editor-support/dragonbones-creator-support/CCFactory.h
Normal file
@@ -0,0 +1,255 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DRAGONBONES_CC_FACTORY_H
|
||||
#define DRAGONBONES_CC_FACTORY_H
|
||||
|
||||
#include "MiddlewareManager.h"
|
||||
#include "dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
class CCTextureAtlasData;
|
||||
|
||||
/**
|
||||
* The Cocos2d factory.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* Cocos2d 工厂。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class CCFactory : public BaseFactory, public cc::middleware::IMiddleware {
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(CCFactory)
|
||||
|
||||
private:
|
||||
static DragonBones *_dragonBonesInstance;
|
||||
static CCFactory *_factory;
|
||||
|
||||
public:
|
||||
static bool isInit() {
|
||||
return _factory != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* A global factory instance that can be used directly.
|
||||
* @version DragonBones 4.7
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* 一个可以直接使用的全局工厂实例。
|
||||
* @version DragonBones 4.7
|
||||
* @language zh_CN
|
||||
*/
|
||||
static CCFactory *getFactory() {
|
||||
if (CCFactory::_factory == nullptr) {
|
||||
CCFactory::_factory = new CCFactory();
|
||||
}
|
||||
|
||||
return CCFactory::_factory;
|
||||
}
|
||||
|
||||
static void destroyFactory() {
|
||||
if (_dragonBonesInstance) {
|
||||
delete _dragonBonesInstance;
|
||||
_dragonBonesInstance = nullptr;
|
||||
}
|
||||
|
||||
if (_factory) {
|
||||
delete _factory;
|
||||
_factory = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string _prevPath;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
CCFactory() : _prevPath() {
|
||||
if (_dragonBonesInstance == nullptr) {
|
||||
const auto eventManager = CCArmatureDisplay::create();
|
||||
eventManager->addRef();
|
||||
|
||||
_dragonBonesInstance = new DragonBones(eventManager);
|
||||
|
||||
cc::middleware::MiddlewareManager::getInstance()->addTimer(this);
|
||||
}
|
||||
|
||||
_dragonBones = _dragonBonesInstance;
|
||||
}
|
||||
|
||||
virtual void update(float dt) override {
|
||||
_dragonBonesInstance->advanceTime(dt);
|
||||
}
|
||||
|
||||
virtual void render(float dt) override {
|
||||
_dragonBonesInstance->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @note When script engine clean up is trigger,will stop dragonbones timer.
|
||||
*/
|
||||
void stopSchedule() {
|
||||
cc::middleware::MiddlewareManager::getInstance()->removeTimer(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Destructor call by jsb_dragonbones_manual,when script engine clean up is trigger.
|
||||
*/
|
||||
virtual ~CCFactory() {
|
||||
clear(false);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual TextureAtlasData *_buildTextureAtlasData(TextureAtlasData *textureAtlasData, void *textureAtlas) const override;
|
||||
virtual Armature *_buildArmature(const BuildArmaturePackage &dataPackage) const override;
|
||||
virtual Slot *_buildSlot(const BuildArmaturePackage &dataPackage, const SlotData *slotData, Armature *armature) const override;
|
||||
|
||||
public:
|
||||
virtual DragonBonesData *loadDragonBonesData(const std::string &filePath, const std::string &name = "", float scale = 1.0f);
|
||||
/**
|
||||
* - Load and parse a texture atlas data and texture from the local and cache them to the factory.
|
||||
* @param filePath - The file path of texture atlas data.
|
||||
* @param name - Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead)
|
||||
* @param scale - Specify a scaling value for the map set. (Not scaled by default)
|
||||
* @returns The TextureAtlasData instance.
|
||||
* @version DragonBones 4.5
|
||||
* @example
|
||||
* <pre>
|
||||
* factory.loadTextureAtlasData("hero_tex.json");
|
||||
* </pre>
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 从本地加载并解析一个贴图集数据和贴图并缓存到工厂中。
|
||||
* @param filePath - 贴图集数据文件路径。
|
||||
* @param name - 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
|
||||
* @param scale - 为贴图集指定一个缩放值。 (默认不缩放)
|
||||
* @returns TextureAtlasData 实例。
|
||||
* @version DragonBones 4.5
|
||||
* @example
|
||||
* <pre>
|
||||
* factory.loadTextureAtlasData("hero_tex.json");
|
||||
* </pre>
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual TextureAtlasData *loadTextureAtlasData(const std::string &filePath, const std::string &name = "", float scale = 1.0f);
|
||||
/**
|
||||
* - Create a armature from cached DragonBonesData instances and TextureAtlasData instances, then use the {@link #clock} to update it.
|
||||
* The difference is that the armature created by {@link #buildArmature} is not WorldClock instance update.
|
||||
* @param armatureName - The armature data name.
|
||||
* @param dragonBonesName - The cached name of the DragonBonesData instance. (If not set, all DragonBonesData instances are retrieved, and when multiple DragonBonesData instances contain a the same name armature data, it may not be possible to accurately create a specific armature)
|
||||
* @param skinName - The skin name, you can set a different ArmatureData name to share it's skin data. (If not set, use the default skin data)
|
||||
* @returns The armature display container.
|
||||
* @version DragonBones 4.5
|
||||
* @example
|
||||
* <pre>
|
||||
* let armatureDisplay = factory.buildArmatureDisplay("armatureName", "dragonBonesName");
|
||||
* </pre>
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 通过缓存的 DragonBonesData 实例和 TextureAtlasData 实例创建一个骨架,并用 {@link #clock} 更新该骨架。
|
||||
* 区别在于由 {@link #buildArmature} 创建的骨架没有 WorldClock 实例驱动。
|
||||
* @param armatureName - 骨架数据名称。
|
||||
* @param dragonBonesName - DragonBonesData 实例的缓存名称。 (如果未设置,将检索所有的 DragonBonesData 实例,当多个 DragonBonesData 实例中包含同名的骨架数据时,可能无法准确的创建出特定的骨架)
|
||||
* @param skinName - 皮肤名称,可以设置一个其他骨架数据名称来共享其皮肤数据。 (如果未设置,则使用默认的皮肤数据)
|
||||
* @returns 骨架的显示容器。
|
||||
* @version DragonBones 4.5
|
||||
* @example
|
||||
* <pre>
|
||||
* let armatureDisplay = factory.buildArmatureDisplay("armatureName", "dragonBonesName");
|
||||
* </pre>
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual CCArmatureDisplay *buildArmatureDisplay(const std::string &armatureName, const std::string &dragonBonesName = "", const std::string &skinName = "", const std::string &textureAtlasName = "") const;
|
||||
/**
|
||||
* - A global sound event manager.
|
||||
* Sound events can be listened to uniformly from the manager.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 全局声音事件管理器。
|
||||
* 声音事件可以从该管理器统一侦听。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual CCArmatureDisplay *getSoundEventManager() const {
|
||||
return dynamic_cast<CCArmatureDisplay *>(static_cast<IArmatureProxy *>(_dragonBones->getEventManager()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, please refer to {@link #clock}.
|
||||
* @deprecated
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* 已废弃,请参考 {@link #clock}。
|
||||
* @deprecated
|
||||
* @language zh_CN
|
||||
*/
|
||||
static WorldClock *getClock() {
|
||||
return _dragonBonesInstance->getClock();
|
||||
}
|
||||
|
||||
void add(Armature *armature) {
|
||||
_dragonBonesInstance->getClock()->add(armature);
|
||||
}
|
||||
|
||||
void remove(Armature *armature) {
|
||||
_dragonBonesInstance->getClock()->remove(armature);
|
||||
}
|
||||
|
||||
void setTimeScale(float timeScale) {
|
||||
_dragonBonesInstance->getClock()->timeScale = timeScale;
|
||||
}
|
||||
|
||||
float getTimeScale() {
|
||||
return _dragonBonesInstance->getClock()->timeScale;
|
||||
}
|
||||
|
||||
DragonBones *getDragonBones() {
|
||||
return _dragonBonesInstance;
|
||||
}
|
||||
|
||||
DragonBonesData *getDragonBonesDataByUUID(const std::string &uuid);
|
||||
|
||||
void removeTextureAtlasDataByIndex(const std::string &name, int textureIndex);
|
||||
void removeDragonBonesDataByUUID(const std::string &uuid, bool disposeData = true);
|
||||
|
||||
CCTextureAtlasData *getTextureAtlasDataByIndex(const std::string &name, int textureIndex) const;
|
||||
DragonBonesData *parseDragonBonesDataByPath(const std::string &filePath, const std::string &name = "", float scale = 1.0f);
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif // DRAGONBONES_CC_FACTORY_H
|
||||
455
cocos/editor-support/dragonbones-creator-support/CCSlot.cpp
Normal file
455
cocos/editor-support/dragonbones-creator-support/CCSlot.cpp
Normal file
@@ -0,0 +1,455 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "dragonbones-creator-support/CCSlot.h"
|
||||
#include "dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
#include "dragonbones-creator-support/CCTextureAtlasData.h"
|
||||
|
||||
using namespace cc;
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void CCSlot::_onClear() {
|
||||
Slot::_onClear();
|
||||
disposeTriangles();
|
||||
_localMatrix.setIdentity();
|
||||
worldMatrix.setIdentity();
|
||||
_worldMatDirty = true;
|
||||
}
|
||||
|
||||
void CCSlot::disposeTriangles() {
|
||||
if (worldVerts) {
|
||||
delete[] worldVerts;
|
||||
worldVerts = nullptr;
|
||||
}
|
||||
if (triangles.verts) {
|
||||
delete[] triangles.verts;
|
||||
triangles.verts = nullptr;
|
||||
}
|
||||
if (triangles.indices) {
|
||||
delete[] triangles.indices;
|
||||
triangles.indices = nullptr;
|
||||
}
|
||||
triangles.indexCount = 0;
|
||||
triangles.vertCount = 0;
|
||||
}
|
||||
|
||||
void CCSlot::adjustTriangles(const unsigned vertexCount, const unsigned indicesCount) {
|
||||
if (triangles.vertCount < vertexCount) {
|
||||
if (triangles.verts) {
|
||||
delete[] triangles.verts;
|
||||
}
|
||||
triangles.verts = new middleware::V3F_T2F_C4B[vertexCount];
|
||||
|
||||
if (worldVerts) {
|
||||
delete[] worldVerts;
|
||||
}
|
||||
worldVerts = new middleware::V3F_T2F_C4B[vertexCount];
|
||||
}
|
||||
triangles.vertCount = vertexCount;
|
||||
|
||||
if (triangles.indexCount < indicesCount) {
|
||||
if (triangles.indices) {
|
||||
delete[] triangles.indices;
|
||||
}
|
||||
triangles.indices = new unsigned short[indicesCount];
|
||||
}
|
||||
triangles.indexCount = indicesCount;
|
||||
}
|
||||
|
||||
void CCSlot::_initDisplay(void *value, bool isRetain) {
|
||||
}
|
||||
|
||||
void CCSlot::_disposeDisplay(void *value, bool isRelease) {
|
||||
}
|
||||
|
||||
void CCSlot::_onUpdateDisplay() {
|
||||
}
|
||||
|
||||
void CCSlot::_addDisplay() {
|
||||
_visible = true;
|
||||
}
|
||||
|
||||
void CCSlot::_replaceDisplay(void *value, bool isArmatureDisplay) {
|
||||
}
|
||||
|
||||
void CCSlot::_removeDisplay() {
|
||||
_visible = false;
|
||||
}
|
||||
|
||||
void CCSlot::_updateZOrder() {
|
||||
}
|
||||
|
||||
void CCSlot::_updateVisible() {
|
||||
_visible = _parent->getVisible();
|
||||
}
|
||||
|
||||
middleware::Texture2D *CCSlot::getTexture() const {
|
||||
const auto currentTextureData = static_cast<CCTextureData *>(_textureData);
|
||||
if (!currentTextureData || !currentTextureData->spriteFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
return currentTextureData->spriteFrame->getTexture();
|
||||
}
|
||||
|
||||
void CCSlot::_updateFrame() {
|
||||
const auto currentVerticesData = (_deformVertices != nullptr && _display == _meshDisplay) ? _deformVertices->verticesData : nullptr;
|
||||
const auto currentTextureData = static_cast<CCTextureData *>(_textureData);
|
||||
|
||||
if (_displayIndex >= 0 && _display != nullptr && currentTextureData != nullptr) {
|
||||
if (currentTextureData->spriteFrame != nullptr) {
|
||||
const auto ®ion = currentTextureData->region;
|
||||
const auto texture = currentTextureData->spriteFrame->getTexture();
|
||||
const auto textureWidth = texture->getPixelsWide();
|
||||
const auto textureHeight = texture->getPixelsHigh();
|
||||
|
||||
if (currentVerticesData != nullptr) // Mesh.
|
||||
{
|
||||
const auto data = currentVerticesData->data;
|
||||
const auto intArray = data->intArray;
|
||||
const auto floatArray = data->floatArray;
|
||||
const unsigned vertexCount = intArray[currentVerticesData->offset + (unsigned)BinaryOffset::MeshVertexCount];
|
||||
const unsigned triangleCount = intArray[currentVerticesData->offset + (unsigned)BinaryOffset::MeshTriangleCount];
|
||||
int vertexOffset = intArray[currentVerticesData->offset + (unsigned)BinaryOffset::MeshFloatOffset];
|
||||
|
||||
if (vertexOffset < 0) {
|
||||
vertexOffset += 65536; // Fixed out of bouds bug.
|
||||
}
|
||||
|
||||
const unsigned uvOffset = vertexOffset + vertexCount * 2;
|
||||
const unsigned indicesCount = triangleCount * 3;
|
||||
adjustTriangles(vertexCount, indicesCount);
|
||||
auto vertices = triangles.verts;
|
||||
auto vertexIndices = triangles.indices;
|
||||
|
||||
boundsRect.x = 999999.0f;
|
||||
boundsRect.y = 999999.0f;
|
||||
boundsRect.width = -999999.0f;
|
||||
boundsRect.height = -999999.0f;
|
||||
|
||||
for (std::size_t i = 0, l = vertexCount * 2; i < l; i += 2) {
|
||||
const auto iH = i / 2;
|
||||
const auto x = floatArray[vertexOffset + i];
|
||||
const auto y = floatArray[vertexOffset + i + 1];
|
||||
auto u = floatArray[uvOffset + i];
|
||||
auto v = floatArray[uvOffset + i + 1];
|
||||
middleware::V3F_T2F_C4B &vertexData = vertices[iH];
|
||||
vertexData.vertex.x = x;
|
||||
vertexData.vertex.y = -y;
|
||||
|
||||
if (currentTextureData->rotated) {
|
||||
vertexData.texCoord.u = (region.x + (1.0f - v) * region.width) / textureWidth;
|
||||
vertexData.texCoord.v = (region.y + u * region.height) / textureHeight;
|
||||
} else {
|
||||
vertexData.texCoord.u = (region.x + u * region.width) / textureWidth;
|
||||
vertexData.texCoord.v = (region.y + v * region.height) / textureHeight;
|
||||
}
|
||||
|
||||
vertexData.color = cc::middleware::Color4B::WHITE;
|
||||
|
||||
if (boundsRect.x > x) {
|
||||
boundsRect.x = x;
|
||||
}
|
||||
|
||||
if (boundsRect.width < x) {
|
||||
boundsRect.width = x;
|
||||
}
|
||||
|
||||
if (boundsRect.y > -y) {
|
||||
boundsRect.y = -y;
|
||||
}
|
||||
|
||||
if (boundsRect.height < -y) {
|
||||
boundsRect.height = -y;
|
||||
}
|
||||
}
|
||||
|
||||
boundsRect.width -= boundsRect.x;
|
||||
boundsRect.height -= boundsRect.y;
|
||||
|
||||
for (std::size_t i = 0; i < triangleCount * 3; ++i) {
|
||||
vertexIndices[i] = intArray[currentVerticesData->offset + (unsigned)BinaryOffset::MeshVertexIndices + i];
|
||||
}
|
||||
|
||||
const auto isSkinned = currentVerticesData->weight != nullptr;
|
||||
if (isSkinned) {
|
||||
_identityTransform();
|
||||
}
|
||||
} else {
|
||||
adjustTriangles(4, 6);
|
||||
|
||||
auto vertices = triangles.verts;
|
||||
auto vertexIndices = triangles.indices;
|
||||
|
||||
float l = region.x / textureWidth;
|
||||
float b = (region.y + region.height) / textureHeight;
|
||||
float r = (region.x + region.width) / textureWidth;
|
||||
float t = region.y / textureHeight;
|
||||
|
||||
vertices[0].texCoord.u = l;
|
||||
vertices[0].texCoord.v = b;
|
||||
vertices[1].texCoord.u = r;
|
||||
vertices[1].texCoord.v = b;
|
||||
vertices[2].texCoord.u = l;
|
||||
vertices[2].texCoord.v = t;
|
||||
vertices[3].texCoord.u = r;
|
||||
vertices[3].texCoord.v = t;
|
||||
|
||||
vertices[0].vertex.x = vertices[2].vertex.x = 0;
|
||||
vertices[1].vertex.x = vertices[3].vertex.x = region.width;
|
||||
vertices[0].vertex.y = vertices[1].vertex.y = 0;
|
||||
vertices[2].vertex.y = vertices[3].vertex.y = region.height;
|
||||
|
||||
vertexIndices[0] = 0;
|
||||
vertexIndices[1] = 1;
|
||||
vertexIndices[2] = 2;
|
||||
vertexIndices[3] = 1;
|
||||
vertexIndices[4] = 3;
|
||||
vertexIndices[5] = 2;
|
||||
}
|
||||
|
||||
memcpy(worldVerts, triangles.verts, triangles.vertCount * sizeof(middleware::V3F_T2F_C4B));
|
||||
|
||||
_visibleDirty = true;
|
||||
_blendModeDirty = true; // Relpace texture will override blendMode and color.
|
||||
_colorDirty = true;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSlot::_updateMesh() {
|
||||
const auto scale = _armature->_armatureData->scale;
|
||||
const auto &deformVertices = _deformVertices->vertices;
|
||||
const auto &bones = _deformVertices->bones;
|
||||
const auto verticesData = _deformVertices->verticesData;
|
||||
const auto weightData = verticesData->weight;
|
||||
|
||||
const auto hasFFD = !deformVertices.empty();
|
||||
const auto textureData = static_cast<CCTextureData *>(_textureData);
|
||||
const auto vertices = triangles.verts;
|
||||
|
||||
boundsRect.x = 999999.0f;
|
||||
boundsRect.y = 999999.0f;
|
||||
boundsRect.width = -999999.0f;
|
||||
boundsRect.height = -999999.0f;
|
||||
|
||||
if (!textureData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (weightData != nullptr) {
|
||||
const auto data = verticesData->data;
|
||||
const auto intArray = data->intArray;
|
||||
const auto floatArray = data->floatArray;
|
||||
const auto vertexCount = (std::size_t)intArray[verticesData->offset + (unsigned)BinaryOffset::MeshVertexCount];
|
||||
int weightFloatOffset = intArray[weightData->offset + (unsigned)BinaryOffset::WeigthFloatOffset];
|
||||
|
||||
if (vertexCount > triangles.vertCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (weightFloatOffset < 0) {
|
||||
weightFloatOffset += 65536; // Fixed out of bouds bug.
|
||||
}
|
||||
|
||||
for (
|
||||
std::size_t i = 0, iB = weightData->offset + (unsigned)BinaryOffset::WeigthBoneIndices + bones.size(), iV = (std::size_t)weightFloatOffset, iF = 0;
|
||||
i < vertexCount;
|
||||
++i) {
|
||||
const auto boneCount = (std::size_t)intArray[iB++];
|
||||
auto xG = 0.0f, yG = 0.0f;
|
||||
for (std::size_t j = 0; j < boneCount; ++j) {
|
||||
const auto boneIndex = (unsigned)intArray[iB++];
|
||||
const auto bone = bones[boneIndex];
|
||||
if (bone != nullptr) {
|
||||
const auto &matrix = bone->globalTransformMatrix;
|
||||
const auto weight = floatArray[iV++];
|
||||
auto xL = floatArray[iV++] * scale;
|
||||
auto yL = floatArray[iV++] * scale;
|
||||
|
||||
if (hasFFD) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
auto &vertex = vertices[i];
|
||||
auto &vertexPosition = vertex.vertex;
|
||||
|
||||
vertexPosition.x = xG;
|
||||
vertexPosition.y = -yG;
|
||||
|
||||
if (boundsRect.x > xG) {
|
||||
boundsRect.x = xG;
|
||||
}
|
||||
|
||||
if (boundsRect.width < xG) {
|
||||
boundsRect.width = xG;
|
||||
}
|
||||
|
||||
if (boundsRect.y > -yG) {
|
||||
boundsRect.y = -yG;
|
||||
}
|
||||
|
||||
if (boundsRect.height < -yG) {
|
||||
boundsRect.height = -yG;
|
||||
}
|
||||
}
|
||||
} else if (hasFFD) {
|
||||
const auto data = verticesData->data;
|
||||
const auto intArray = data->intArray;
|
||||
const auto floatArray = data->floatArray;
|
||||
const auto vertexCount = (std::size_t)intArray[verticesData->offset + (unsigned)BinaryOffset::MeshVertexCount];
|
||||
std::size_t vertexOffset = (std::size_t)intArray[verticesData->offset + (unsigned)BinaryOffset::MeshFloatOffset];
|
||||
|
||||
if (vertexCount > triangles.vertCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vertexOffset < 0) {
|
||||
vertexOffset += 65536; // Fixed out of bouds bug.
|
||||
}
|
||||
|
||||
for (std::size_t i = 0, l = vertexCount * 2; i < l; i += 2) {
|
||||
const auto iH = i / 2;
|
||||
const auto xG = floatArray[vertexOffset + i] * scale + deformVertices[i];
|
||||
const auto yG = floatArray[vertexOffset + i + 1] * scale + deformVertices[i + 1];
|
||||
|
||||
auto &vertex = vertices[iH];
|
||||
auto &vertexPosition = vertex.vertex;
|
||||
|
||||
vertexPosition.x = xG;
|
||||
vertexPosition.y = -yG;
|
||||
|
||||
if (boundsRect.x > xG) {
|
||||
boundsRect.x = xG;
|
||||
}
|
||||
|
||||
if (boundsRect.width < xG) {
|
||||
boundsRect.width = xG;
|
||||
}
|
||||
|
||||
if (boundsRect.y > -yG) {
|
||||
boundsRect.y = -yG;
|
||||
}
|
||||
|
||||
if (boundsRect.height < -yG) {
|
||||
boundsRect.height = -yG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boundsRect.width -= boundsRect.x;
|
||||
boundsRect.height -= boundsRect.y;
|
||||
|
||||
if (weightData != nullptr) {
|
||||
_identityTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CCSlot::_updateTransform() {
|
||||
_localMatrix.m[0] = globalTransformMatrix.a;
|
||||
_localMatrix.m[1] = globalTransformMatrix.b;
|
||||
_localMatrix.m[4] = -globalTransformMatrix.c;
|
||||
_localMatrix.m[5] = -globalTransformMatrix.d;
|
||||
|
||||
if (_childArmature) {
|
||||
_localMatrix.m[12] = globalTransformMatrix.tx;
|
||||
_localMatrix.m[13] = globalTransformMatrix.ty;
|
||||
} else {
|
||||
_localMatrix.m[12] = globalTransformMatrix.tx - (globalTransformMatrix.a * _pivotX - globalTransformMatrix.c * _pivotY);
|
||||
_localMatrix.m[13] = globalTransformMatrix.ty - (globalTransformMatrix.b * _pivotX - globalTransformMatrix.d * _pivotY);
|
||||
}
|
||||
|
||||
_worldMatDirty = true;
|
||||
}
|
||||
|
||||
void CCSlot::updateWorldMatrix() {
|
||||
if (!_armature) return;
|
||||
|
||||
CCSlot *parent = (CCSlot *)_armature->getParent();
|
||||
if (parent) {
|
||||
parent->updateWorldMatrix();
|
||||
}
|
||||
|
||||
if (_worldMatDirty) {
|
||||
calculWorldMatrix();
|
||||
|
||||
Armature *childArmature = getChildArmature();
|
||||
if (!childArmature) return;
|
||||
|
||||
auto &slots = childArmature->getSlots();
|
||||
for (int i = 0; i < slots.size(); i++) {
|
||||
CCSlot *slot = (CCSlot *)slots[i];
|
||||
slot->_worldMatDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSlot::calculWorldMatrix() {
|
||||
CCSlot *parent = (CCSlot *)_armature->getParent();
|
||||
if (parent) {
|
||||
worldMatrix = parent->worldMatrix * _localMatrix;
|
||||
} else {
|
||||
worldMatrix = _localMatrix;
|
||||
}
|
||||
|
||||
_worldMatDirty = false;
|
||||
}
|
||||
|
||||
void CCSlot::_identityTransform() {
|
||||
_localMatrix.m[0] = 1.0f;
|
||||
_localMatrix.m[1] = 0.0f;
|
||||
_localMatrix.m[4] = -0.0f;
|
||||
_localMatrix.m[5] = -1.0f;
|
||||
_localMatrix.m[12] = 0.0f;
|
||||
_localMatrix.m[13] = 0.0f;
|
||||
|
||||
_worldMatDirty = true;
|
||||
}
|
||||
|
||||
void CCSlot::_updateBlendMode() {
|
||||
if (_childArmature != nullptr) {
|
||||
for (const auto slot : _childArmature->getSlots()) {
|
||||
slot->_blendMode = _blendMode;
|
||||
slot->_updateBlendMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSlot::_updateColor() {
|
||||
color.r = _colorTransform.redMultiplier * 255.0f;
|
||||
color.g = _colorTransform.greenMultiplier * 255.0f;
|
||||
color.b = _colorTransform.blueMultiplier * 255.0f;
|
||||
color.a = _colorTransform.alphaMultiplier * 255.0f;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
95
cocos/editor-support/dragonbones-creator-support/CCSlot.h
Normal file
95
cocos/editor-support/dragonbones-creator-support/CCSlot.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DRAGONBONES_CC_SLOT_H
|
||||
#define DRAGONBONES_CC_SLOT_H
|
||||
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
#include "math/Geometry.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "middleware-adapter.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* The Cocos2d slot.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* Cocos2d 插槽。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class CCSlot : public Slot {
|
||||
BIND_CLASS_TYPE_A(CCSlot);
|
||||
|
||||
public:
|
||||
// Global matrix (相对于骨骼部件)
|
||||
cc::Mat4 worldMatrix;
|
||||
// Global matrix dirty flag
|
||||
bool _worldMatDirty = true;
|
||||
// Slot triangles
|
||||
cc::middleware::Triangles triangles;
|
||||
// Slot vertex transform to World vertex
|
||||
cc::middleware::V3F_T2F_C4B *worldVerts = nullptr;
|
||||
cc::middleware::Color4B color;
|
||||
cc::Rect boundsRect;
|
||||
|
||||
private:
|
||||
cc::Mat4 _localMatrix;
|
||||
|
||||
private:
|
||||
void disposeTriangles();
|
||||
void calculWorldMatrix();
|
||||
void adjustTriangles(const unsigned vertexCount, const unsigned indicesCount);
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
virtual void _initDisplay(void *value, bool isRetain) override;
|
||||
virtual void _disposeDisplay(void *value, bool isRelease) override;
|
||||
virtual void _onUpdateDisplay() override;
|
||||
virtual void _addDisplay() override;
|
||||
virtual void _replaceDisplay(void *value, bool isArmatureDisplay) override;
|
||||
virtual void _removeDisplay() override;
|
||||
virtual void _updateZOrder() override;
|
||||
|
||||
public:
|
||||
virtual void _updateVisible() override;
|
||||
virtual void _updateBlendMode() override;
|
||||
virtual void _updateColor() override;
|
||||
void updateWorldMatrix();
|
||||
cc::middleware::Texture2D *getTexture() const;
|
||||
|
||||
protected:
|
||||
virtual void _updateFrame() override;
|
||||
virtual void _updateMesh() override;
|
||||
virtual void _updateTransform() override;
|
||||
virtual void _identityTransform() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif // DRAGONBONES_CC_SLOT_H
|
||||
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "dragonbones-creator-support/CCTextureAtlasData.h"
|
||||
|
||||
using namespace cc;
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void CCTextureAtlasData::_onClear() {
|
||||
TextureAtlasData::_onClear();
|
||||
|
||||
if (_renderTexture != nullptr) {
|
||||
_renderTexture->release();
|
||||
_renderTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TextureData *CCTextureAtlasData::createTexture() const {
|
||||
return (TextureData *)BaseObject::borrowObject<CCTextureData>();
|
||||
}
|
||||
|
||||
void CCTextureAtlasData::setRenderTexture(middleware::Texture2D *value) {
|
||||
if (_renderTexture == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
_renderTexture = value;
|
||||
|
||||
if (_renderTexture != nullptr) {
|
||||
_renderTexture->addRef();
|
||||
|
||||
for (const auto &pair : textures) {
|
||||
const auto textureData = static_cast<CCTextureData *>(pair.second);
|
||||
|
||||
if (textureData->spriteFrame == nullptr) {
|
||||
cc::Rect rect(
|
||||
textureData->region.x, textureData->region.y,
|
||||
textureData->rotated ? textureData->region.height : textureData->region.width,
|
||||
textureData->rotated ? textureData->region.width : textureData->region.height);
|
||||
cc::Vec2 offset(0.0f, 0.0f);
|
||||
cc::Size originSize(rect.width, rect.height);
|
||||
textureData->spriteFrame = middleware::SpriteFrame::createWithTexture(_renderTexture, rect, textureData->rotated, offset, originSize); // TODO multiply textureAtlas
|
||||
textureData->spriteFrame->addRef();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const auto &pair : textures) {
|
||||
const auto textureData = static_cast<CCTextureData *>(pair.second);
|
||||
|
||||
if (textureData->spriteFrame != nullptr) {
|
||||
textureData->spriteFrame->release();
|
||||
textureData->spriteFrame = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCTextureData::_onClear() {
|
||||
TextureData::_onClear();
|
||||
|
||||
if (spriteFrame != nullptr) {
|
||||
spriteFrame->release();
|
||||
spriteFrame = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2012-2020 DragonBones team and other contributors
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DRAGONBONES_CC_TEXTUREATLAS_DATA_H
|
||||
#define DRAGONBONES_CC_TEXTUREATLAS_DATA_H
|
||||
|
||||
#include "dragonbones/DragonBonesHeaders.h"
|
||||
#include "middleware-adapter.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* The Cocos2d texture atlas data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* Cocos2d 贴图集数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class CCTextureAtlasData : public TextureAtlasData {
|
||||
BIND_CLASS_TYPE_B(CCTextureAtlasData);
|
||||
|
||||
private:
|
||||
cc::middleware::Texture2D *_renderTexture;
|
||||
|
||||
public:
|
||||
CCTextureAtlasData() : _renderTexture(nullptr) {
|
||||
_onClear();
|
||||
}
|
||||
virtual ~CCTextureAtlasData() {
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual TextureData *createTexture() const override;
|
||||
/**
|
||||
* The Cocos2d texture.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* Cocos2d 贴图。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline cc::middleware::Texture2D *getRenderTexture() const {
|
||||
return _renderTexture;
|
||||
}
|
||||
void setRenderTexture(cc::middleware::Texture2D *value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class CCTextureData : public TextureData {
|
||||
BIND_CLASS_TYPE_B(CCTextureData);
|
||||
|
||||
public:
|
||||
cc::middleware::SpriteFrame *spriteFrame;
|
||||
|
||||
CCTextureData() : spriteFrame(nullptr) {
|
||||
_onClear();
|
||||
}
|
||||
virtual ~CCTextureData() {
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif // DRAGONBONES_CC_TEXTUREATLAS_DATA_H
|
||||
Reference in New Issue
Block a user