mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2026-01-10 02:06:52 +00:00
初始化
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_HEADERS_H
|
||||
#define DRAGONBONES_HEADERS_H
|
||||
|
||||
// core
|
||||
#include "core/DragonBones.h"
|
||||
#include "core/BaseObject.h"
|
||||
|
||||
// geom
|
||||
#include "geom/Matrix.h"
|
||||
#include "geom/Transform.h"
|
||||
#include "geom/ColorTransform.h"
|
||||
#include "geom/Point.h"
|
||||
#include "geom/Rectangle.h"
|
||||
|
||||
// model
|
||||
#include "model/TextureAtlasData.h"
|
||||
#include "model/UserData.h"
|
||||
#include "model/DragonBonesData.h"
|
||||
#include "model/ArmatureData.h"
|
||||
#include "model/ConstraintData.h"
|
||||
#include "model/CanvasData.h"
|
||||
#include "model/SkinData.h"
|
||||
#include "model/DisplayData.h"
|
||||
#include "model/BoundingBoxData.h"
|
||||
#include "model/AnimationData.h"
|
||||
#include "model/AnimationConfig.h"
|
||||
|
||||
// armature
|
||||
#include "armature/IArmatureProxy.h"
|
||||
#include "armature/Armature.h"
|
||||
#include "armature/TransformObject.h"
|
||||
#include "armature/Bone.h"
|
||||
#include "armature/Slot.h"
|
||||
#include "armature/Constraint.h"
|
||||
#include "armature/DeformVertices.h"
|
||||
|
||||
// animation
|
||||
#include "animation/IAnimatable.h"
|
||||
#include "animation/WorldClock.h"
|
||||
#include "animation/Animation.h"
|
||||
#include "animation/AnimationState.h"
|
||||
#include "animation/BaseTimelineState.h"
|
||||
#include "animation/TimelineState.h"
|
||||
|
||||
// event
|
||||
#include "event/EventObject.h"
|
||||
#include "event/IEventDispatcher.h"
|
||||
|
||||
#ifndef EGRET_WASM
|
||||
|
||||
// parser
|
||||
#include "parser/DataParser.h"
|
||||
#include "parser/JSONDataParser.h"
|
||||
#include "parser/BinaryDataParser.h"
|
||||
|
||||
// factory
|
||||
#include "factory/BaseFactory.h"
|
||||
#endif // EGRET_WASM
|
||||
|
||||
#endif // DRAGONBONES_HEADERS_H
|
||||
@@ -0,0 +1,602 @@
|
||||
#include "Animation.h"
|
||||
#include "../model/DisplayData.h"
|
||||
#include "../model/AnimationConfig.h"
|
||||
#include "../model/AnimationData.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
#include "../armature/Slot.h"
|
||||
#include "AnimationState.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void Animation::_onClear()
|
||||
{
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
animationState->returnToPool();
|
||||
}
|
||||
|
||||
if (_animationConfig != nullptr)
|
||||
{
|
||||
_animationConfig->returnToPool();
|
||||
}
|
||||
|
||||
timeScale = 1.0f;
|
||||
|
||||
_animationDirty = false;
|
||||
_inheritTimeScale = 1.0f;
|
||||
_animations.clear();
|
||||
_animationNames.clear();
|
||||
_animationStates.clear();
|
||||
_armature = nullptr;
|
||||
_animationConfig = nullptr;
|
||||
_lastAnimationState = nullptr;
|
||||
}
|
||||
|
||||
void Animation::_fadeOut(AnimationConfig* animationConfig)
|
||||
{
|
||||
switch (animationConfig->fadeOutMode)
|
||||
{
|
||||
case AnimationFadeOutMode::SameLayer:
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (animationState->layer == (unsigned)animationConfig->layer)
|
||||
{
|
||||
animationState->fadeOut(animationConfig->fadeOutTime, animationConfig->pauseFadeOut);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AnimationFadeOutMode::SameGroup:
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (animationState->group == animationConfig->group)
|
||||
{
|
||||
animationState->fadeOut(animationConfig->fadeOutTime, animationConfig->pauseFadeOut);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AnimationFadeOutMode::SameLayerAndGroup:
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (animationState->layer == (unsigned)animationConfig->layer && animationState->group == animationConfig->group)
|
||||
{
|
||||
animationState->fadeOut(animationConfig->fadeOutTime, animationConfig->pauseFadeOut);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AnimationFadeOutMode::All:
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
animationState->fadeOut(animationConfig->fadeOutTime, animationConfig->pauseFadeOut);
|
||||
}
|
||||
break;
|
||||
|
||||
case AnimationFadeOutMode::None:
|
||||
case AnimationFadeOutMode::Single:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::init(Armature* armature)
|
||||
{
|
||||
if (_armature != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
_armature = armature;
|
||||
_animationConfig = BaseObject::borrowObject<AnimationConfig>();
|
||||
}
|
||||
|
||||
void Animation::advanceTime(float passedTime)
|
||||
{
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
passedTime = -passedTime;
|
||||
}
|
||||
|
||||
if (_armature->inheritAnimation && _armature->_parent != nullptr) // Inherit parent animation timeScale.
|
||||
{
|
||||
_inheritTimeScale = _armature->_parent->_armature->getAnimation()->_inheritTimeScale * timeScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
_inheritTimeScale = timeScale;
|
||||
}
|
||||
|
||||
if (_inheritTimeScale != 1.0f)
|
||||
{
|
||||
passedTime *= _inheritTimeScale;
|
||||
}
|
||||
|
||||
const auto animationStateCount = _animationStates.size();
|
||||
if (animationStateCount == 1)
|
||||
{
|
||||
const auto animationState = _animationStates[0];
|
||||
if (animationState->_fadeState > 0 && animationState->_subFadeState > 0)
|
||||
{
|
||||
_armature->_dragonBones->bufferObject(animationState);
|
||||
_animationStates.clear();
|
||||
_lastAnimationState = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto animationData = animationState->_animationData;
|
||||
const auto cacheFrameRate = animationData->cacheFrameRate;
|
||||
if (_animationDirty && cacheFrameRate > 0.0f) // Update cachedFrameIndices.
|
||||
{
|
||||
_animationDirty = false;
|
||||
|
||||
for (const auto bone : _armature->getBones())
|
||||
{
|
||||
bone->_cachedFrameIndices = animationData->getBoneCachedFrameIndices(bone->getName());
|
||||
}
|
||||
|
||||
for (const auto slot : _armature->getSlots())
|
||||
{
|
||||
const auto rawDisplayDatas = slot->getRawDisplayDatas();
|
||||
if (rawDisplayDatas != nullptr && !(*rawDisplayDatas).empty())
|
||||
{
|
||||
const auto rawDsplayData = (*rawDisplayDatas)[0];
|
||||
if (rawDsplayData != nullptr)
|
||||
{
|
||||
if (rawDsplayData->parent == _armature->getArmatureData()->defaultSkin)
|
||||
{
|
||||
slot->_cachedFrameIndices = animationData->getSlotCachedFrameIndices(slot->getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slot->_cachedFrameIndices = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
animationState->advanceTime(passedTime, cacheFrameRate);
|
||||
}
|
||||
}
|
||||
else if (animationStateCount > 1)
|
||||
{
|
||||
for (std::size_t i = 0, r = 0; i < animationStateCount; ++i)
|
||||
{
|
||||
const auto animationState = _animationStates[i];
|
||||
if (animationState->_fadeState > 0 && animationState->_subFadeState > 0)
|
||||
{
|
||||
r++;
|
||||
_armature->_dragonBones->bufferObject(animationState);
|
||||
_animationDirty = true;
|
||||
if (_lastAnimationState == animationState)
|
||||
{
|
||||
_lastAnimationState = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r > 0)
|
||||
{
|
||||
_animationStates[i - r] = animationState;
|
||||
}
|
||||
|
||||
animationState->advanceTime(passedTime, 0.0f);
|
||||
}
|
||||
|
||||
if (i == animationStateCount - 1 && r > 0)
|
||||
{
|
||||
_animationStates.resize(animationStateCount - r);
|
||||
if (_lastAnimationState == nullptr && !_animationStates.empty())
|
||||
{
|
||||
_lastAnimationState = _animationStates[_animationStates.size() - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_armature->_cacheFrameIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_armature->_cacheFrameIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::reset()
|
||||
{
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
animationState->returnToPool();
|
||||
}
|
||||
|
||||
_animationDirty = false;
|
||||
_animationConfig->clear();
|
||||
_animationStates.clear();
|
||||
_lastAnimationState = nullptr;
|
||||
}
|
||||
|
||||
void Animation::stop(const std::string& animationName)
|
||||
{
|
||||
if (!animationName.empty())
|
||||
{
|
||||
const auto animationState = getState(animationName);
|
||||
if (animationState != nullptr)
|
||||
{
|
||||
animationState->stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto animationState : _animationStates) {
|
||||
animationState->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimationState* Animation::playConfig(AnimationConfig* animationConfig)
|
||||
{
|
||||
const auto& animationName = animationConfig->animation;
|
||||
if (_animations.find(animationName) == _animations.end())
|
||||
{
|
||||
DRAGONBONES_ASSERT(
|
||||
false,
|
||||
"Non-existent animation.\n" +
|
||||
" DragonBones name: " + this->_armature->getArmatureData().parent->name +
|
||||
" Armature name: " + this->_armature->name +
|
||||
" Animation name: " + animationName
|
||||
);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto animationData = _animations[animationName];
|
||||
|
||||
if (animationConfig->fadeOutMode == AnimationFadeOutMode::Single)
|
||||
{
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (animationState->_animationData == animationData)
|
||||
{
|
||||
return animationState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (animationConfig->fadeInTime < 0.0f)
|
||||
{
|
||||
if (_animationStates.empty())
|
||||
{
|
||||
animationConfig->fadeInTime = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationConfig->fadeInTime = animationData->fadeInTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (animationConfig->fadeOutTime < 0.0f)
|
||||
{
|
||||
animationConfig->fadeOutTime = animationConfig->fadeInTime;
|
||||
}
|
||||
|
||||
if (animationConfig->timeScale <= -100.0f)
|
||||
{
|
||||
animationConfig->timeScale = 1.0f / animationData->scale;
|
||||
}
|
||||
|
||||
if (animationData->frameCount > 1)
|
||||
{
|
||||
if (animationConfig->position < 0.0f)
|
||||
{
|
||||
animationConfig->position = fmod(animationConfig->position, animationData->duration);
|
||||
animationConfig->position = animationData->duration - animationConfig->position;
|
||||
}
|
||||
else if (animationConfig->position == animationData->duration)
|
||||
{
|
||||
animationConfig->position -= 0.000001f; // Play a little time before end.
|
||||
}
|
||||
else if (animationConfig->position > animationData->duration)
|
||||
{
|
||||
animationConfig->position = fmod(animationConfig->position, animationData->duration);
|
||||
}
|
||||
|
||||
if (animationConfig->duration > 0.0f && animationConfig->position + animationConfig->duration > animationData->duration)
|
||||
{
|
||||
animationConfig->duration = animationData->duration - animationConfig->position;
|
||||
}
|
||||
|
||||
if (animationConfig->playTimes < 0)
|
||||
{
|
||||
animationConfig->playTimes = animationData->playTimes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
animationConfig->playTimes = 1;
|
||||
animationConfig->position = 0.0f;
|
||||
if (animationConfig->duration > 0.0f)
|
||||
{
|
||||
animationConfig->duration = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (animationConfig->duration == 0.0f)
|
||||
{
|
||||
animationConfig->duration = -1.0f;
|
||||
}
|
||||
|
||||
_fadeOut(animationConfig);
|
||||
|
||||
const auto animationState = BaseObject::borrowObject<AnimationState>();
|
||||
animationState->init(_armature, animationData, animationConfig);
|
||||
_animationDirty = true;
|
||||
_armature->_cacheFrameIndex = -1;
|
||||
|
||||
if (!_animationStates.empty())
|
||||
{
|
||||
auto added = false;
|
||||
for (std::size_t i = 0, l = _animationStates.size(); i < l; ++i)
|
||||
{
|
||||
if (animationState->layer > _animationStates[i]->layer)
|
||||
{
|
||||
added = true;
|
||||
auto parentInerator = std::find(_animationStates.begin(), _animationStates.end(), _animationStates[i]);
|
||||
_animationStates.insert(parentInerator, animationState);
|
||||
break;
|
||||
}
|
||||
else if (i != l - 1 && animationState->layer > _animationStates[i + 1]->layer)
|
||||
{
|
||||
added = true;
|
||||
auto parentInerator = std::find(_animationStates.begin(), _animationStates.end(), _animationStates[i]);
|
||||
_animationStates.insert(parentInerator + 1, animationState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added)
|
||||
{
|
||||
_animationStates.push_back(animationState);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationStates.push_back(animationState);
|
||||
}
|
||||
|
||||
// Child armature play same name animation.
|
||||
for (const auto slot : _armature->getSlots())
|
||||
{
|
||||
const auto childArmature = slot->getChildArmature();
|
||||
if (
|
||||
childArmature != nullptr && childArmature->inheritAnimation &&
|
||||
childArmature->getAnimation()->hasAnimation(animationName) &&
|
||||
childArmature->getAnimation()->getState(animationName) == nullptr
|
||||
)
|
||||
{
|
||||
childArmature->getAnimation()->fadeIn(animationName); //
|
||||
}
|
||||
}
|
||||
|
||||
if (animationConfig->fadeInTime <= 0.0f) // Blend animation state, update armature.
|
||||
{
|
||||
_armature->advanceTime(0.0f);
|
||||
}
|
||||
|
||||
_lastAnimationState = animationState;
|
||||
|
||||
return animationState;
|
||||
}
|
||||
|
||||
AnimationState* Animation::play(const std::string& animationName, int playTimes)
|
||||
{
|
||||
_animationConfig->clear();
|
||||
_animationConfig->resetToPose = true;
|
||||
_animationConfig->playTimes = playTimes;
|
||||
_animationConfig->fadeInTime = 0.0f;
|
||||
_animationConfig->animation = animationName;
|
||||
|
||||
if (!animationName.empty())
|
||||
{
|
||||
playConfig(_animationConfig);
|
||||
}
|
||||
else if (_lastAnimationState == nullptr)
|
||||
{
|
||||
const auto defaultAnimation = _armature->_armatureData->defaultAnimation;
|
||||
if (defaultAnimation != nullptr)
|
||||
{
|
||||
_animationConfig->animation = defaultAnimation->name;
|
||||
playConfig(_animationConfig);
|
||||
}
|
||||
}
|
||||
else if (!_lastAnimationState->isPlaying() && !_lastAnimationState->isCompleted())
|
||||
{
|
||||
_lastAnimationState->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationConfig->animation = _lastAnimationState->name;
|
||||
playConfig(_animationConfig);
|
||||
}
|
||||
|
||||
return _lastAnimationState;
|
||||
}
|
||||
#ifdef EGRET_WASM
|
||||
AnimationState* Animation::fadeIn(
|
||||
const std::string& animationName, float fadeInTime, int playTimes,
|
||||
int layer, const std::string& group, int fadeOutMode /*AnimationFadeOutMode*/
|
||||
#else
|
||||
AnimationState* Animation::fadeIn(
|
||||
const std::string& animationName, float fadeInTime, int playTimes,
|
||||
int layer, const std::string& group, AnimationFadeOutMode fadeOutMode
|
||||
#endif // EGRET_WASM
|
||||
)
|
||||
{
|
||||
_animationConfig->clear();
|
||||
_animationConfig->fadeOutMode = (AnimationFadeOutMode)fadeOutMode;
|
||||
_animationConfig->playTimes = playTimes;
|
||||
_animationConfig->layer = layer;
|
||||
_animationConfig->fadeInTime = fadeInTime;
|
||||
_animationConfig->animation = animationName;
|
||||
_animationConfig->group = group;
|
||||
|
||||
return playConfig(_animationConfig);
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndPlayByTime(const std::string& animationName, float time, int playTimes)
|
||||
{
|
||||
_animationConfig->clear();
|
||||
_animationConfig->resetToPose = true;
|
||||
_animationConfig->playTimes = playTimes;
|
||||
_animationConfig->position = time;
|
||||
_animationConfig->fadeInTime = 0.0f;
|
||||
_animationConfig->animation = animationName;
|
||||
|
||||
return playConfig(_animationConfig);
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndPlayByFrame(const std::string& animationName, unsigned frame, int playTimes)
|
||||
{
|
||||
_animationConfig->clear();
|
||||
_animationConfig->resetToPose = true;
|
||||
_animationConfig->playTimes = playTimes;
|
||||
_animationConfig->fadeInTime = 0.0f;
|
||||
_animationConfig->animation = animationName;
|
||||
|
||||
const auto animationData = mapFind(_animations, animationName);
|
||||
if (animationData != nullptr)
|
||||
{
|
||||
_animationConfig->position = animationData->duration * frame / animationData->frameCount;
|
||||
}
|
||||
|
||||
return playConfig(_animationConfig);
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndPlayByProgress(const std::string& animationName, float progress, int playTimes)
|
||||
{
|
||||
_animationConfig->clear();
|
||||
_animationConfig->resetToPose = true;
|
||||
_animationConfig->playTimes = playTimes;
|
||||
_animationConfig->fadeInTime = 0.0f;
|
||||
_animationConfig->animation = animationName;
|
||||
|
||||
const auto animationData = mapFind(_animations, animationName);
|
||||
if (animationData != nullptr) {
|
||||
_animationConfig->position = animationData->duration * (progress > 0.0f ? progress : 0.0f);
|
||||
}
|
||||
|
||||
return playConfig(_animationConfig);
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndStopByTime(const std::string& animationName, float time)
|
||||
{
|
||||
const auto animationState = gotoAndPlayByTime(animationName, time, 1);
|
||||
if (animationState != nullptr)
|
||||
{
|
||||
animationState->stop();
|
||||
}
|
||||
|
||||
return animationState;
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndStopByFrame(const std::string& animationName, unsigned frame)
|
||||
{
|
||||
const auto animationState = gotoAndPlayByFrame(animationName, frame, 1);
|
||||
if (animationState != nullptr)
|
||||
{
|
||||
animationState->stop();
|
||||
}
|
||||
|
||||
return animationState;
|
||||
}
|
||||
|
||||
AnimationState* Animation::gotoAndStopByProgress(const std::string& animationName, float progress)
|
||||
{
|
||||
const auto animationState = gotoAndPlayByProgress(animationName, progress, 1);
|
||||
if (animationState != nullptr)
|
||||
{
|
||||
animationState->stop();
|
||||
}
|
||||
|
||||
return animationState;
|
||||
}
|
||||
|
||||
AnimationState* Animation::getState(const std::string& animationName) const
|
||||
{
|
||||
int i = _animationStates.size();
|
||||
while (i--)
|
||||
{
|
||||
const auto animationState = _animationStates[i];
|
||||
if (animationState->name == animationName)
|
||||
{
|
||||
return animationState;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Animation::hasAnimation(const std::string& animationName) const
|
||||
{
|
||||
return _animations.find(animationName) != _animations.end();
|
||||
}
|
||||
|
||||
bool Animation::isPlaying() const
|
||||
{
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (animationState->isPlaying())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Animation::isCompleted() const
|
||||
{
|
||||
for (const auto animationState : _animationStates)
|
||||
{
|
||||
if (!animationState->isCompleted())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !_animationStates.empty();
|
||||
}
|
||||
|
||||
const std::string& Animation::getLastAnimationName() const
|
||||
{
|
||||
if (_lastAnimationState != nullptr)
|
||||
{
|
||||
return _lastAnimationState->name;
|
||||
}
|
||||
|
||||
static const std::string DEFAULT_NAME = "";
|
||||
return DEFAULT_NAME;
|
||||
}
|
||||
|
||||
void Animation::setAnimations(const std::map<std::string, AnimationData*>& value)
|
||||
{
|
||||
if (_animations == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_animationNames.clear();
|
||||
_animations.clear();
|
||||
|
||||
for (const auto& pair : value)
|
||||
{
|
||||
_animationNames.push_back(pair.first);
|
||||
_animations[pair.first] = pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
AnimationConfig* Animation::getAnimationConfig() const
|
||||
{
|
||||
_animationConfig->clear();
|
||||
return _animationConfig;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
478
cocos2d-x/cocos/editor-support/dragonbones/animation/Animation.h
Normal file
478
cocos2d-x/cocos/editor-support/dragonbones/animation/Animation.h
Normal file
@@ -0,0 +1,478 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ANIMATION_H
|
||||
#define DRAGONBONES_ANIMATION_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The animation player is used to play the animation data and manage the animation states.
|
||||
* @see dragonBones.AnimationData
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画播放器用来播放动画数据和管理动画状态。
|
||||
* @see dragonBones.AnimationData
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Animation final : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(Animation);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The play speed of all animations. [0: Stop, (0~1): Slow, 1: Normal, (1~N): Fast]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所有动画的播放速度。 [0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float timeScale;
|
||||
|
||||
private:
|
||||
bool _animationDirty;
|
||||
float _inheritTimeScale;
|
||||
std::vector<std::string> _animationNames;
|
||||
std::vector<AnimationState*> _animationStates;
|
||||
std::map<std::string, AnimationData*> _animations;
|
||||
Armature* _armature;
|
||||
AnimationConfig* _animationConfig;
|
||||
AnimationState* _lastAnimationState;
|
||||
|
||||
public:
|
||||
Animation() :
|
||||
_animationConfig(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~Animation()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
private:
|
||||
void _fadeOut(AnimationConfig* animationConfig);
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void init(Armature* armature);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void advanceTime(float passedTime);
|
||||
/**
|
||||
* - Clear all animations states.
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 清除所有的动画状态。
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* - Pause a specific animation state.
|
||||
* @param animationName - The name of animation state. (If not set, it will pause all animations)
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 暂停指定动画状态的播放。
|
||||
* @param animationName - 动画状态名称。 (如果未设置,则暂停所有动画)
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void stop(const std::string& animationName);
|
||||
/**
|
||||
* - Play animation with a specific animation config.
|
||||
* The API is still in the experimental phase and may encounter bugs or stability or compatibility issues when used.
|
||||
* @param animationConfig - The animation config.
|
||||
* @returns The playing animation state.
|
||||
* @see dragonBones.AnimationConfig
|
||||
* @beta
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 通过指定的动画配置来播放动画。
|
||||
* 该 API 仍在实验阶段,使用时可能遭遇 bug 或稳定性或兼容性问题。
|
||||
* @param animationConfig - 动画配置。
|
||||
* @returns 播放的动画状态。
|
||||
* @see dragonBones.AnimationConfig
|
||||
* @beta
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* playConfig(AnimationConfig* animationConfig);
|
||||
/**
|
||||
* - Play a specific animation.
|
||||
* @param animationName - The name of animation data. (If not set, The default animation will be played, or resume the animation playing from pause status, or replay the last playing animation)
|
||||
* @param playTimes - Playing repeat times. [-1: Use default value of the animation data, 0: No end loop playing, [1~N]: Repeat N times] (default: -1)
|
||||
* @returns The playing animation state.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* armature.animation.play("walk");
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放指定动画。
|
||||
* @param animationName - 动画数据名称。 (如果未设置,则播放默认动画,或将暂停状态切换为播放状态,或重新播放之前播放的动画)
|
||||
* @param playTimes - 循环播放次数。 [-1: 使用动画数据默认值, 0: 无限循环播放, [1~N]: 循环播放 N 次] (默认: -1)
|
||||
* @returns 播放的动画状态。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* armature.animation.play("walk");
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* play(const std::string& animationName = "", int playTimes = -1);
|
||||
/**
|
||||
* - Fade in a specific animation.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param fadeInTime - The fade in time. [-1: Use the default value of animation data, [0~N]: The fade in time (In seconds)] (Default: -1)
|
||||
* @param playTimes - playing repeat times. [-1: Use the default value of animation data, 0: No end loop playing, [1~N]: Repeat N times] (Default: -1)
|
||||
* @param layer - The blending layer, the animation states in high level layer will get the blending weights with high priority, when the total blending weights are more than 1.0, there will be no more weights can be allocated to the other animation states. (Default: 0)
|
||||
* @param group - The blending group name, it is typically used to specify the substitution of multiple animation states blending. (Default: null)
|
||||
* @param fadeOutMode - The fade out mode, which is typically used to specify alternate mode of multiple animation states blending. (Default: AnimationFadeOutMode.SameLayerAndGroup)
|
||||
* @returns The playing animation state.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* armature.animation.fadeIn("walk", 0.3, 0, 0, "normalGroup").resetToPose = false;
|
||||
* armature.animation.fadeIn("attack", 0.3, 1, 0, "attackGroup").resetToPose = false;
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡入播放指定的动画。
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param fadeInTime - 淡入时间。 [-1: 使用动画数据默认值, [0~N]: 淡入时间 (以秒为单位)] (默认: -1)
|
||||
* @param playTimes - 播放次数。 [-1: 使用动画数据默认值, 0: 无限循环播放, [1~N]: 循环播放 N 次] (默认: -1)
|
||||
* @param layer - 混合图层,图层高的动画状态会优先获取混合权重,当混合权重分配总和超过 1.0 时,剩余的动画状态将不能再获得权重分配。 (默认: 0)
|
||||
* @param group - 混合组名称,该属性通常用来指定多个动画状态混合时的相互替换关系。 (默认: null)
|
||||
* @param fadeOutMode - 淡出模式,该属性通常用来指定多个动画状态混合时的相互替换模式。 (默认: AnimationFadeOutMode.SameLayerAndGroup)
|
||||
* @returns 播放的动画状态。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* armature.animation.fadeIn("walk", 0.3, 0, 0, "normalGroup").resetToPose = false;
|
||||
* armature.animation.fadeIn("attack", 0.3, 1, 0, "attackGroup").resetToPose = false;
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* fadeIn(
|
||||
const std::string& animationName, float fadeInTime = -1.f, int playTimes = -1,
|
||||
int layer = 0, const std::string& group = "", AnimationFadeOutMode fadeOutMode = AnimationFadeOutMode::SameLayerAndGroup
|
||||
);
|
||||
/**
|
||||
* - Play a specific animation from the specific time.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param time - The start time point of playing. (In seconds)
|
||||
* @param playTimes - Playing repeat times. [-1: Use the default value of animation data, 0: No end loop playing, [1~N]: Repeat N times] (Default: -1)
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 从指定时间开始播放指定的动画。
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param time - 播放开始的时间。 (以秒为单位)
|
||||
* @param playTimes - 循环播放次数。 [-1: 使用动画数据默认值, 0: 无限循环播放, [1~N]: 循环播放 N 次] (默认: -1)
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndPlayByTime(const std::string& animationName, float time = 0.f, int playTimes = -1);
|
||||
/**
|
||||
* - Play a specific animation from the specific frame.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param frame - The start frame of playing.
|
||||
* @param playTimes - Playing repeat times. [-1: Use the default value of animation data, 0: No end loop playing, [1~N]: Repeat N times] (Default: -1)
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 从指定帧开始播放指定的动画。
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param frame - 播放开始的帧数。
|
||||
* @param playTimes - 播放次数。 [-1: 使用动画数据默认值, 0: 无限循环播放, [1~N]: 循环播放 N 次] (默认: -1)
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndPlayByFrame(const std::string& animationName, unsigned frame = 0, int playTimes = -1);
|
||||
/**
|
||||
* - Play a specific animation from the specific progress.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param progress - The start progress value of playing.
|
||||
* @param playTimes - Playing repeat times. [-1: Use the default value of animation data, 0: No end loop playing, [1~N]: Repeat N times] (Default: -1)
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 从指定进度开始播放指定的动画。
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param progress - 开始播放的进度。
|
||||
* @param playTimes - 播放次数。 [-1: 使用动画数据默认值, 0: 无限循环播放, [1~N]: 循环播放 N 次] (默认: -1)
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndPlayByProgress(const std::string& animationName, float progress = 0.f, int playTimes = -1);
|
||||
/**
|
||||
* - Stop a specific animation at the specific time.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param time - The stop time. (In seconds)
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 在指定时间停止指定动画播放
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param time - 停止的时间。 (以秒为单位)
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndStopByTime(const std::string& animationName, float time = 0.f);
|
||||
/**
|
||||
* - Stop a specific animation at the specific frame.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param frame - The stop frame.
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 在指定帧停止指定动画的播放
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param frame - 停止的帧数。
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndStopByFrame(const std::string& animationName, unsigned frame = 0);
|
||||
/**
|
||||
* - Stop a specific animation at the specific progress.
|
||||
* @param animationName - The name of animation data.
|
||||
* @param progress - The stop progress value.
|
||||
* @returns The played animation state.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 在指定的进度停止指定的动画播放。
|
||||
* @param animationName - 动画数据名称。
|
||||
* @param progress - 停止进度。
|
||||
* @returns 播放的动画状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* gotoAndStopByProgress(const std::string& animationName, float progress = 0.f);
|
||||
/**
|
||||
* - Get a specific animation state.
|
||||
* @param animationName - The name of animation state.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* armature.animation.play("walk");
|
||||
* let walkState = armature.animation.getState("walk");
|
||||
* walkState.timeScale = 0.5;
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取指定的动画状态
|
||||
* @param animationName - 动画状态名称。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* armature.animation.play("walk");
|
||||
* let walkState = armature.animation.getState("walk");
|
||||
* walkState.timeScale = 0.5;
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* getState(const std::string& animationName) const;
|
||||
/**
|
||||
* - Check whether a specific animation data is included.
|
||||
* @param animationName - The name of animation data.
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否包含指定的动画数据
|
||||
* @param animationName - 动画数据名称。
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool hasAnimation(const std::string& animationName) const;
|
||||
/**
|
||||
* - Get all the animation states.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取所有的动画状态
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::vector<AnimationState*>& getStates() const
|
||||
{
|
||||
return _animationStates;
|
||||
}
|
||||
/**
|
||||
* - Check whether there is an animation state is playing
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否有动画状态正在播放
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool isPlaying() const;
|
||||
/**
|
||||
* - Check whether all the animation states' playing were finished.
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否所有的动画状态均已播放完毕。
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool isCompleted() const;
|
||||
/**
|
||||
* - The name of the last playing animation state.
|
||||
* @see #lastAnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 上一个播放的动画状态名称
|
||||
* @see #lastAnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
const std::string& getLastAnimationName() const;
|
||||
/**
|
||||
* - The name of all animation data
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所有动画数据的名称
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::vector<std::string>& getAnimationNames() const
|
||||
{
|
||||
return _animationNames;
|
||||
}
|
||||
/**
|
||||
* - All animation data.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所有的动画数据。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::map<std::string, AnimationData*>& getAnimations() const
|
||||
{
|
||||
return _animations;
|
||||
}
|
||||
void setAnimations(const std::map<std::string, AnimationData*>& value);
|
||||
/**
|
||||
* - An AnimationConfig instance that can be used quickly.
|
||||
* @see dragonBones.AnimationConfig
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 一个可以快速使用的动画配置实例。
|
||||
* @see dragonBones.AnimationConfig
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationConfig* getAnimationConfig() const;
|
||||
/**
|
||||
* - The last playing animation state
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 上一个播放的动画状态
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline AnimationState* getLastAnimationState() const
|
||||
{
|
||||
return _lastAnimationState;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ANIMATION_H
|
||||
@@ -0,0 +1,952 @@
|
||||
#include "AnimationState.h"
|
||||
#include "WorldClock.h"
|
||||
#include "../model/DisplayData.h"
|
||||
#include "../model/AnimationConfig.h"
|
||||
#include "../model/AnimationData.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
#include "../armature/Slot.h"
|
||||
#include "../armature/Constraint.h"
|
||||
#include "../event/EventObject.h"
|
||||
#include "../event/IEventDispatcher.h"
|
||||
#include "TimelineState.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void AnimationState::_onClear()
|
||||
{
|
||||
for (const auto timeline : _boneTimelines)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto timeline : _slotTimelines)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto timeline : _constraintTimelines)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : _bonePoses)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
if (_actionTimeline != nullptr) {
|
||||
_actionTimeline->returnToPool();
|
||||
}
|
||||
|
||||
if (_zOrderTimeline != nullptr) {
|
||||
_zOrderTimeline->returnToPool();
|
||||
}
|
||||
|
||||
actionEnabled = false;
|
||||
additiveBlending = false;
|
||||
displayControl = false;
|
||||
resetToPose = false;
|
||||
playTimes = 1;
|
||||
layer = 0;
|
||||
timeScale = 1.0f;
|
||||
weight = 1.0f;
|
||||
autoFadeOutTime = 0.0f;
|
||||
fadeTotalTime = 0.0f;
|
||||
name = "";
|
||||
group = "";
|
||||
|
||||
_timelineDirty = 2;
|
||||
_playheadState = 0;
|
||||
_fadeState = -1;
|
||||
_subFadeState = -1;
|
||||
_position = 0.0f;
|
||||
_duration = 0.0f;
|
||||
_fadeTime = 0.0f;
|
||||
_time = 0.0f;
|
||||
_fadeProgress = 0.0f;
|
||||
_weightResult = 0.0f;
|
||||
_boneMask.clear();
|
||||
_boneTimelines.clear();
|
||||
_slotTimelines.clear();
|
||||
_constraintTimelines.clear();
|
||||
_poseTimelines.clear();
|
||||
_bonePoses.clear();
|
||||
_animationData = nullptr;
|
||||
_armature = nullptr;
|
||||
_actionTimeline = nullptr;
|
||||
_zOrderTimeline = nullptr;
|
||||
}
|
||||
|
||||
void AnimationState::_updateTimelines()
|
||||
{
|
||||
{ // Update constraint timelines.
|
||||
std::map<std::string, std::vector<ConstraintTimelineState*>> constraintTimelines;
|
||||
for (const auto timeline : _constraintTimelines) // Create constraint timelines map.
|
||||
{
|
||||
constraintTimelines[timeline->constraint->getName()].push_back(timeline);
|
||||
}
|
||||
|
||||
for (const auto constraint : _armature->_constraints)
|
||||
{
|
||||
const auto& timelineName = constraint->getName();
|
||||
const auto timelineDatas = _animationData->getConstraintTimelines(timelineName);
|
||||
const auto iterator = constraintTimelines.find(timelineName);
|
||||
|
||||
if (iterator != constraintTimelines.end()) // Remove constraint timeline from map.
|
||||
{
|
||||
constraintTimelines.erase(iterator);
|
||||
}
|
||||
else // Create new constraint timeline.
|
||||
{
|
||||
if (timelineDatas != nullptr)
|
||||
{
|
||||
for (const auto timelineData : *timelineDatas)
|
||||
{
|
||||
switch (timelineData->type)
|
||||
{
|
||||
case TimelineType::IKConstraint:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<IKConstraintTimelineState>();
|
||||
timeline->constraint = constraint;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_constraintTimelines.push_back(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (resetToPose) // Pose timeline.
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<IKConstraintTimelineState>();
|
||||
timeline->constraint = constraint;
|
||||
timeline->init(_armature, this, nullptr);
|
||||
_constraintTimelines.push_back(timeline);
|
||||
_poseTimelines.push_back(std::make_pair(timeline, BaseTimelineType::Constraint));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationState::_updateBoneAndSlotTimelines()
|
||||
{
|
||||
{ // Update bone timelines.
|
||||
std::map<std::string, std::vector<BoneTimelineState*>> boneTimelines;
|
||||
for (const auto timeline : _boneTimelines) // Create bone timelines map.
|
||||
{
|
||||
boneTimelines[timeline->bone->getName()].push_back(timeline);
|
||||
}
|
||||
|
||||
for (const auto bone : _armature->getBones())
|
||||
{
|
||||
const auto& timelineName = bone->getName();
|
||||
if (!containsBoneMask(timelineName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto timelineDatas = _animationData->getBoneTimelines(timelineName);
|
||||
const auto iterator = boneTimelines.find(timelineName);
|
||||
|
||||
if (iterator != boneTimelines.end()) // Remove bone timeline from map.
|
||||
{
|
||||
boneTimelines.erase(iterator);
|
||||
}
|
||||
else // Create new bone timeline.
|
||||
{
|
||||
const auto bonePose = _bonePoses.find(timelineName) != _bonePoses.end() ? _bonePoses[timelineName] : (_bonePoses[timelineName] = BaseObject::borrowObject<BonePose>());
|
||||
|
||||
if (timelineDatas != nullptr)
|
||||
{
|
||||
for (const auto timelineData : *timelineDatas)
|
||||
{
|
||||
switch (timelineData->type)
|
||||
{
|
||||
case TimelineType::BoneAll:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<BoneAllTimelineState>();
|
||||
timeline->bone = bone;
|
||||
timeline->bonePose = bonePose;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_boneTimelines.push_back(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
case TimelineType::BoneTranslate:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<BoneTranslateTimelineState>();
|
||||
timeline->bone = bone;
|
||||
timeline->bonePose = bonePose;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_boneTimelines.push_back(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
case TimelineType::BoneRotate:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<BoneRotateTimelineState>();
|
||||
timeline->bone = bone;
|
||||
timeline->bonePose = bonePose;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_boneTimelines.push_back(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
case TimelineType::BoneScale:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<BoneScaleTimelineState>();
|
||||
timeline->bone = bone;
|
||||
timeline->bonePose = bonePose;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_boneTimelines.push_back(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (resetToPose) // Pose timeline.
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<BoneAllTimelineState>();
|
||||
timeline->bone = bone;
|
||||
timeline->bonePose = bonePose;
|
||||
timeline->init(_armature, this, nullptr);
|
||||
_boneTimelines.push_back(timeline);
|
||||
_poseTimelines.push_back(std::make_pair(timeline, BaseTimelineType::Bone));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : boneTimelines) // Remove bone timelines.
|
||||
{
|
||||
for (const auto timeline : pair.second)
|
||||
{
|
||||
_boneTimelines.erase(std::find(_boneTimelines.begin(), _boneTimelines.end(), timeline));
|
||||
timeline->returnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Update slot timelines.
|
||||
std::map<std::string, std::vector<SlotTimelineState*>> slotTimelines;
|
||||
std::vector<unsigned> ffdFlags;
|
||||
for (const auto timeline : _slotTimelines) // Create slot timelines map.
|
||||
{
|
||||
slotTimelines[timeline->slot->getName()].push_back(timeline);
|
||||
}
|
||||
|
||||
for (const auto slot : _armature->getSlots())
|
||||
{
|
||||
const auto& boneName = slot->getParent()->getName();
|
||||
if (!containsBoneMask(boneName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& timelineName = slot->getName();
|
||||
const auto timelineDatas = _animationData->getSlotTimelines(timelineName);
|
||||
const auto iterator = slotTimelines.find(timelineName);
|
||||
|
||||
if (iterator != slotTimelines.end()) // Remove slot timeline from map.
|
||||
{
|
||||
slotTimelines.erase(iterator);
|
||||
}
|
||||
else // Create new slot timeline.
|
||||
{
|
||||
auto displayIndexFlag = false;
|
||||
auto colorFlag = false;
|
||||
ffdFlags.clear();
|
||||
|
||||
if (timelineDatas != nullptr)
|
||||
{
|
||||
for (const auto timelineData : *timelineDatas)
|
||||
{
|
||||
switch (timelineData->type)
|
||||
{
|
||||
case TimelineType::SlotDisplay:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<SlotDislayTimelineState>();
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_slotTimelines.push_back(timeline);
|
||||
displayIndexFlag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case TimelineType::SlotColor:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<SlotColorTimelineState>();
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_slotTimelines.push_back(timeline);
|
||||
colorFlag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case TimelineType::SlotDeform:
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<DeformTimelineState>();
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, timelineData);
|
||||
_slotTimelines.push_back(timeline);
|
||||
ffdFlags.push_back(timeline->vertexOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resetToPose) // Pose timeline.
|
||||
{
|
||||
if (!displayIndexFlag)
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<SlotDislayTimelineState>();
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, nullptr);
|
||||
_slotTimelines.push_back(timeline);
|
||||
_poseTimelines.push_back(std::make_pair(timeline, BaseTimelineType::Slot));
|
||||
}
|
||||
|
||||
if (!colorFlag)
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<SlotColorTimelineState>();
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, nullptr);
|
||||
_slotTimelines.push_back(timeline);
|
||||
_poseTimelines.push_back(std::make_pair(timeline, BaseTimelineType::Slot));
|
||||
}
|
||||
|
||||
if (slot->getRawDisplayDatas() != nullptr)
|
||||
{
|
||||
for (const auto displayData : *(slot->getRawDisplayDatas()))
|
||||
{
|
||||
if (displayData != nullptr && displayData->type == DisplayType::Mesh)
|
||||
{
|
||||
const auto meshOffset = static_cast<MeshDisplayData*>(displayData)->vertices.offset;
|
||||
if (std::find(ffdFlags.cbegin(), ffdFlags.cend(), meshOffset) == ffdFlags.cend())
|
||||
{
|
||||
const auto timeline = BaseObject::borrowObject<DeformTimelineState>();
|
||||
timeline->vertexOffset = meshOffset;
|
||||
timeline->slot = slot;
|
||||
timeline->init(_armature, this, nullptr);
|
||||
_slotTimelines.push_back(timeline);
|
||||
_poseTimelines.push_back(std::make_pair(timeline, BaseTimelineType::Slot));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : slotTimelines) // Remove slot timelines.
|
||||
{
|
||||
for (const auto timeline : pair.second)
|
||||
{
|
||||
_slotTimelines.erase(std::find(_slotTimelines.begin(), _slotTimelines.end(), timeline));
|
||||
timeline->returnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationState::_advanceFadeTime(float passedTime)
|
||||
{
|
||||
const auto isFadeOut = _fadeState > 0;
|
||||
|
||||
if (_subFadeState < 0)
|
||||
{
|
||||
_subFadeState = 0;
|
||||
|
||||
const auto eventType = isFadeOut ? EventObject::FADE_OUT : EventObject::FADE_IN;
|
||||
if (_armature->getProxy()->hasDBEventListener(eventType))
|
||||
{
|
||||
const auto eventObject = BaseObject::borrowObject<EventObject>();
|
||||
eventObject->type = eventType;
|
||||
eventObject->armature = _armature;
|
||||
eventObject->animationState = this;
|
||||
_armature->_dragonBones->bufferEvent(eventObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
passedTime = -passedTime;
|
||||
}
|
||||
|
||||
_fadeTime += passedTime;
|
||||
|
||||
if (_fadeTime >= fadeTotalTime)
|
||||
{
|
||||
_subFadeState = 1;
|
||||
_fadeProgress = isFadeOut ? 0.0f : 1.0f;
|
||||
}
|
||||
else if (_fadeTime > 0.0f)
|
||||
{
|
||||
_fadeProgress = isFadeOut ? (1.0f - _fadeTime / fadeTotalTime) : (_fadeTime / fadeTotalTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fadeProgress = isFadeOut ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
if (_subFadeState > 0)
|
||||
{
|
||||
if (!isFadeOut)
|
||||
{
|
||||
_playheadState |= 1; // x1
|
||||
_fadeState = 0;
|
||||
}
|
||||
|
||||
const auto eventType = isFadeOut ? EventObject::FADE_OUT_COMPLETE : EventObject::FADE_IN_COMPLETE;
|
||||
if (_armature->getProxy()->hasDBEventListener(eventType))
|
||||
{
|
||||
const auto eventObject = BaseObject::borrowObject<EventObject>();
|
||||
eventObject->type = eventType;
|
||||
eventObject->armature = _armature;
|
||||
eventObject->animationState = this;
|
||||
_armature->_dragonBones->bufferEvent(eventObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationState::init(Armature* parmature, AnimationData* panimationData, AnimationConfig* animationConfig)
|
||||
{
|
||||
if (_armature != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
_armature = parmature;
|
||||
_animationData = panimationData;
|
||||
//
|
||||
resetToPose = animationConfig->resetToPose;
|
||||
additiveBlending = animationConfig->additiveBlending;
|
||||
displayControl = animationConfig->displayControl;
|
||||
actionEnabled = animationConfig->actionEnabled;
|
||||
layer = animationConfig->layer;
|
||||
playTimes = animationConfig->playTimes;
|
||||
timeScale = animationConfig->timeScale;
|
||||
fadeTotalTime = animationConfig->fadeInTime;
|
||||
autoFadeOutTime = animationConfig->autoFadeOutTime;
|
||||
weight = animationConfig->weight;
|
||||
name = !animationConfig->name.empty() ? animationConfig->name : animationConfig->animation;
|
||||
group = animationConfig->group;
|
||||
|
||||
if (animationConfig->pauseFadeIn)
|
||||
{
|
||||
_playheadState = 2; // 10
|
||||
}
|
||||
else
|
||||
{
|
||||
_playheadState = 3; // 11
|
||||
}
|
||||
|
||||
if (animationConfig->duration < 0.0f)
|
||||
{
|
||||
_position = 0.0f;
|
||||
_duration = _animationData->duration;
|
||||
|
||||
if (animationConfig->position != 0.0f)
|
||||
{
|
||||
if (timeScale >= 0.0f)
|
||||
{
|
||||
_time = animationConfig->position;
|
||||
}
|
||||
else
|
||||
{
|
||||
_time = animationConfig->position - _duration;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_time = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_position = animationConfig->position;
|
||||
_duration = animationConfig->duration;
|
||||
_time = 0.0f;
|
||||
}
|
||||
|
||||
if (timeScale < 0.0f && _time == 0.0f)
|
||||
{
|
||||
_time = -0.000001f; // Can not cross last frame event.
|
||||
}
|
||||
|
||||
if (fadeTotalTime <= 0.0f)
|
||||
{
|
||||
_fadeProgress = 0.999999f;
|
||||
}
|
||||
|
||||
if (!animationConfig->boneMask.empty())
|
||||
{
|
||||
_boneMask.resize(animationConfig->boneMask.size());
|
||||
for (std::size_t i = 0, l = _boneMask.size(); i < l; ++i) {
|
||||
_boneMask[i] = animationConfig->boneMask[i];
|
||||
}
|
||||
}
|
||||
|
||||
_actionTimeline = BaseObject::borrowObject<ActionTimelineState>();
|
||||
_actionTimeline->init(_armature, this, _animationData->actionTimeline); //
|
||||
_actionTimeline->currentTime = _time;
|
||||
if (_actionTimeline->currentTime < 0.0f)
|
||||
{
|
||||
_actionTimeline->currentTime = _duration - _actionTimeline->currentTime;
|
||||
}
|
||||
|
||||
if (_animationData->zOrderTimeline != nullptr)
|
||||
{
|
||||
_zOrderTimeline = BaseObject::borrowObject<ZOrderTimelineState>();
|
||||
_zOrderTimeline->init(_armature, this, _animationData->zOrderTimeline);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationState::advanceTime(float passedTime, float cacheFrameRate)
|
||||
{
|
||||
// Update fade time.
|
||||
if (_fadeState != 0 || _subFadeState != 0)
|
||||
{
|
||||
_advanceFadeTime(passedTime);
|
||||
}
|
||||
|
||||
// Update time.
|
||||
if (_playheadState == 3) // 11
|
||||
{
|
||||
if (timeScale != 1.0f)
|
||||
{
|
||||
passedTime *= timeScale;
|
||||
}
|
||||
|
||||
_time += passedTime;
|
||||
}
|
||||
|
||||
if (_timelineDirty != 0)
|
||||
{
|
||||
if (_timelineDirty == 2)
|
||||
{
|
||||
_updateTimelines();
|
||||
}
|
||||
|
||||
_timelineDirty = 0;
|
||||
_updateBoneAndSlotTimelines();
|
||||
}
|
||||
|
||||
if (weight == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto isCacheEnabled = _fadeState == 0 && cacheFrameRate > 0.0f;
|
||||
auto isUpdateTimeline = true;
|
||||
auto isUpdateBoneTimeline = true;
|
||||
auto time = _time;
|
||||
_weightResult = weight * _fadeProgress;
|
||||
|
||||
if (_actionTimeline->playState <= 0)
|
||||
{
|
||||
_actionTimeline->update(time); // Update main timeline.
|
||||
}
|
||||
|
||||
if (isCacheEnabled) // Cache time internval.
|
||||
{
|
||||
const auto internval = cacheFrameRate * 2.0f;
|
||||
_actionTimeline->currentTime = (unsigned)(_actionTimeline->currentTime * internval) / internval;
|
||||
}
|
||||
|
||||
if (_zOrderTimeline != nullptr && _zOrderTimeline->playState <= 0) // Update zOrder timeline.
|
||||
{
|
||||
_zOrderTimeline->update(time);
|
||||
}
|
||||
|
||||
if (isCacheEnabled) // Update cache.
|
||||
{
|
||||
const auto cacheFrameIndex = (unsigned)(_actionTimeline->currentTime * cacheFrameRate); // uint
|
||||
if ((unsigned)_armature->_cacheFrameIndex == cacheFrameIndex) // Same cache.
|
||||
{
|
||||
isUpdateTimeline = false;
|
||||
isUpdateBoneTimeline = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_armature->_cacheFrameIndex = cacheFrameIndex;
|
||||
if (_animationData->cachedFrames[cacheFrameIndex]) // Cached.
|
||||
{
|
||||
isUpdateBoneTimeline = false;
|
||||
}
|
||||
else // Cache.
|
||||
{
|
||||
_animationData->cachedFrames[cacheFrameIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isUpdateTimeline)
|
||||
{
|
||||
if (isUpdateBoneTimeline) // Update bone timelines.
|
||||
{
|
||||
for (std::size_t i = 0, l = _boneTimelines.size(); i < l; ++i)
|
||||
{
|
||||
const auto timeline = _boneTimelines[i];
|
||||
|
||||
if (timeline->playState <= 0)
|
||||
{
|
||||
timeline->update(time);
|
||||
}
|
||||
|
||||
if (i == l - 1 || timeline->bone != _boneTimelines[i + 1]->bone)
|
||||
{
|
||||
const auto state = timeline->bone->_blendState.update(_weightResult, layer);
|
||||
if (state != 0)
|
||||
{
|
||||
timeline->blend(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (displayControl)
|
||||
{
|
||||
for (std::size_t i = 0, l = _slotTimelines.size(); i < l; ++i)
|
||||
{
|
||||
const auto timeline = _slotTimelines[i];
|
||||
const auto& displayController = timeline->slot->displayController;
|
||||
|
||||
if (
|
||||
displayController.empty() ||
|
||||
displayController == name ||
|
||||
displayController == group
|
||||
)
|
||||
{
|
||||
if (timeline->playState <= 0)
|
||||
{
|
||||
timeline->update(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0, l = _constraintTimelines.size(); i < l; ++i)
|
||||
{
|
||||
const auto timeline = _constraintTimelines[i];
|
||||
if (timeline->playState <= 0)
|
||||
{
|
||||
timeline->update(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_fadeState == 0)
|
||||
{
|
||||
if (_subFadeState > 0)
|
||||
{
|
||||
_subFadeState = 0;
|
||||
|
||||
if (!_poseTimelines.empty())
|
||||
{
|
||||
for (const auto& pair : _poseTimelines)
|
||||
{
|
||||
const auto timeline = pair.first;
|
||||
if (pair.second == BaseTimelineType::Bone)
|
||||
{
|
||||
_boneTimelines.erase(std::find(_boneTimelines.begin(), _boneTimelines.end(), timeline));
|
||||
}
|
||||
else if (pair.second == BaseTimelineType::Slot)
|
||||
{
|
||||
_slotTimelines.erase(std::find(_slotTimelines.begin(), _slotTimelines.end(), timeline));
|
||||
}
|
||||
else if (pair.second == BaseTimelineType::Constraint)
|
||||
{
|
||||
_constraintTimelines.erase(std::find(_constraintTimelines.begin(), _constraintTimelines.end(), timeline));
|
||||
}
|
||||
|
||||
timeline->returnToPool();
|
||||
}
|
||||
|
||||
_poseTimelines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (_actionTimeline->playState > 0)
|
||||
{
|
||||
if (autoFadeOutTime >= 0.0f) // Auto fade out.
|
||||
{
|
||||
fadeOut(autoFadeOutTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationState::play()
|
||||
{
|
||||
_playheadState = 3; // 11
|
||||
}
|
||||
|
||||
void AnimationState::stop()
|
||||
{
|
||||
_playheadState &= 1; // 0x
|
||||
}
|
||||
|
||||
void AnimationState::fadeOut(float fadeOutTime, bool pausePlayhead)
|
||||
{
|
||||
if (fadeOutTime < 0.0f)
|
||||
{
|
||||
fadeOutTime = 0.0f;
|
||||
}
|
||||
|
||||
if (pausePlayhead)
|
||||
{
|
||||
_playheadState &= 2; // x0
|
||||
}
|
||||
|
||||
if (_fadeState > 0)
|
||||
{
|
||||
if (fadeOutTime > fadeTotalTime - _fadeTime) // If the animation is already in fade out, the new fade out will be ignored.
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_fadeState = 1;
|
||||
_subFadeState = -1;
|
||||
|
||||
if (fadeOutTime <= 0.0f || _fadeProgress <= 0.0f)
|
||||
{
|
||||
_fadeProgress = 0.000001f; // Modify fade progress to different value.
|
||||
}
|
||||
|
||||
for (const auto timeline : _boneTimelines)
|
||||
{
|
||||
timeline->fadeOut();
|
||||
}
|
||||
|
||||
for (const auto timeline : _slotTimelines)
|
||||
{
|
||||
timeline->fadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
displayControl = false; //
|
||||
fadeTotalTime = _fadeProgress > 0.000001f ? fadeOutTime / _fadeProgress : 0.0f;
|
||||
_fadeTime = fadeTotalTime * (1.0f - _fadeProgress);
|
||||
}
|
||||
|
||||
bool AnimationState::containsBoneMask(const std::string& boneName) const
|
||||
{
|
||||
return _boneMask.empty() || std::find(_boneMask.cbegin(), _boneMask.cend(), boneName) != _boneMask.cend();
|
||||
}
|
||||
|
||||
void AnimationState::addBoneMask(const std::string& boneName, bool recursive)
|
||||
{
|
||||
const auto currentBone = _armature->getBone(boneName);
|
||||
if (currentBone == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::find(_boneMask.cbegin(), _boneMask.cend(), boneName) == _boneMask.cend())
|
||||
{
|
||||
_boneMask.push_back(boneName);
|
||||
}
|
||||
|
||||
if (recursive) // Add recursive mixing.
|
||||
{
|
||||
for (const auto bone : _armature->getBones())
|
||||
{
|
||||
if (std::find(_boneMask.cbegin(), _boneMask.cend(), bone->getName()) == _boneMask.cend() && currentBone->contains(bone))
|
||||
{
|
||||
_boneMask.push_back(bone->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_timelineDirty = 1;
|
||||
}
|
||||
|
||||
void AnimationState::removeBoneMask(const std::string& boneName, bool recursive)
|
||||
{
|
||||
{
|
||||
auto iterator = std::find(_boneMask.begin(), _boneMask.end(), boneName);
|
||||
if (iterator != _boneMask.cend()) // Remove mixing.
|
||||
{
|
||||
_boneMask.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
const auto currentBone = _armature->getBone(boneName);
|
||||
if (currentBone != nullptr)
|
||||
{
|
||||
const auto& bones = _armature->getBones();
|
||||
if (!_boneMask.empty()) // Remove recursive mixing.
|
||||
{
|
||||
for (const auto bone : bones)
|
||||
{
|
||||
auto iterator = std::find(_boneMask.begin(), _boneMask.end(), bone->getName());
|
||||
if (iterator != _boneMask.end() && currentBone->contains(bone))
|
||||
{
|
||||
_boneMask.erase(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Add unrecursive mixing.
|
||||
{
|
||||
for (const auto bone : bones)
|
||||
{
|
||||
if (bone == currentBone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentBone->contains(bone))
|
||||
{
|
||||
_boneMask.push_back(bone->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_timelineDirty = 1;
|
||||
}
|
||||
|
||||
void AnimationState::removeAllBoneMask()
|
||||
{
|
||||
_boneMask.clear();
|
||||
_timelineDirty = 1;
|
||||
}
|
||||
|
||||
bool AnimationState::isPlaying() const
|
||||
{
|
||||
return (_playheadState & 2) != 0 && _actionTimeline->playState <= 0;
|
||||
}
|
||||
|
||||
bool AnimationState::isCompleted() const
|
||||
{
|
||||
return _actionTimeline->playState > 0;
|
||||
}
|
||||
|
||||
unsigned AnimationState::getCurrentPlayTimes() const
|
||||
{
|
||||
return _actionTimeline->currentPlayTimes;
|
||||
}
|
||||
|
||||
float AnimationState::getCurrentTime() const
|
||||
{
|
||||
return _actionTimeline->currentTime;
|
||||
}
|
||||
|
||||
void AnimationState::setCurrentTime(float value)
|
||||
{
|
||||
const auto currentPlayTimes = _actionTimeline->currentPlayTimes - (_actionTimeline->playState > 0 ? 1 : 0);
|
||||
if (value < 0.0f || _duration < value)
|
||||
{
|
||||
value = fmod(value, _duration) + currentPlayTimes * _duration;
|
||||
if (value < 0.0f)
|
||||
{
|
||||
value += _duration;
|
||||
}
|
||||
}
|
||||
|
||||
if (playTimes > 0 && (unsigned)currentPlayTimes == playTimes - 1 && value == _duration)
|
||||
{
|
||||
value = _duration - 0.000001f;
|
||||
}
|
||||
|
||||
if (_time == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_time = value;
|
||||
_actionTimeline->setCurrentTime(_time);
|
||||
|
||||
if (_zOrderTimeline != nullptr)
|
||||
{
|
||||
_zOrderTimeline->playState = -1;
|
||||
}
|
||||
|
||||
for (const auto timeline : _boneTimelines)
|
||||
{
|
||||
timeline->playState = -1;
|
||||
}
|
||||
|
||||
for (const auto timeline : _slotTimelines)
|
||||
{
|
||||
timeline->playState = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void BonePose::_onClear()
|
||||
{
|
||||
current.identity();
|
||||
delta.identity();
|
||||
result.identity();
|
||||
}
|
||||
|
||||
int BlendState::update(float weight, int p_layer)
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
if (leftWeight > 0.0f)
|
||||
{
|
||||
if (layer != p_layer)
|
||||
{
|
||||
if (layerWeight >= leftWeight)
|
||||
{
|
||||
leftWeight = 0.0f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
layer = p_layer;
|
||||
leftWeight -= layerWeight;
|
||||
layerWeight = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
weight *= leftWeight;
|
||||
layerWeight += weight;
|
||||
blendWeight = weight;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
layer = p_layer;
|
||||
layerWeight = weight;
|
||||
leftWeight = 1.0f;
|
||||
blendWeight = weight;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void BlendState::clear()
|
||||
{
|
||||
dirty = false;
|
||||
layer = 0;
|
||||
leftWeight = 0.0f;
|
||||
layerWeight = 0.0f;
|
||||
blendWeight = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
@@ -0,0 +1,534 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ANIMATION_STATE_H
|
||||
#define DRAGONBONES_ANIMATION_STATE_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Transform.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The animation state is generated when the animation data is played.
|
||||
* @see dragonBones.Animation
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态由播放动画数据时产生。
|
||||
* @see dragonBones.Animation
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class AnimationState : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(AnimationState);
|
||||
|
||||
private:
|
||||
enum class BaseTimelineType {
|
||||
Bone,
|
||||
Slot,
|
||||
Constraint
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool actionEnabled;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool additiveBlending;
|
||||
/**
|
||||
* - Whether the animation state has control over the display object properties of the slots.
|
||||
* Sometimes blend a animation state does not want it to control the display object properties of the slots,
|
||||
* especially if other animation state are controlling the display object properties of the slots.
|
||||
* @default true
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态是否对插槽的显示对象属性有控制权。
|
||||
* 有时混合一个动画状态并不希望其控制插槽的显示对象属性,
|
||||
* 尤其是其他动画状态正在控制这些插槽的显示对象属性时。
|
||||
* @default true
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool displayControl;
|
||||
/**
|
||||
* - Whether to reset the objects without animation to the armature pose when the animation state is start to play.
|
||||
* This property should usually be set to false when blend multiple animation states.
|
||||
* @default true
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 开始播放动画状态时是否将没有动画的对象重置为骨架初始值。
|
||||
* 通常在混合多个动画状态时应该将该属性设置为 false。
|
||||
* @default true
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool resetToPose;
|
||||
/**
|
||||
* - The play times. [0: Loop play, [1~N]: Play N times]
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放次数。 [0: 无限循环播放, [1~N]: 循环播放 N 次]
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned playTimes;
|
||||
/**
|
||||
* - The blend layer.
|
||||
* High layer animation state will get the blend weight first.
|
||||
* When the blend weight is assigned more than 1, the remaining animation states will no longer get the weight assigned.
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合图层。
|
||||
* 图层高的动画状态会优先获取混合权重。
|
||||
* 当混合权重分配超过 1 时,剩余的动画状态将不再获得权重分配。
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned layer;
|
||||
/**
|
||||
* - The play speed.
|
||||
* The value is an overlay relationship with {@link dragonBones.Animation#timeScale}.
|
||||
* [(-N~0): Reverse play, 0: Stop play, (0~1): Slow play, 1: Normal play, (1~N): Fast play]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放速度。
|
||||
* 该值与 {@link dragonBones.Animation#timeScale} 是叠加关系。
|
||||
* [(-N~0): 倒转播放, 0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float timeScale;
|
||||
/**
|
||||
* - The blend weight.
|
||||
* @default 1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合权重。
|
||||
* @default 1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float weight;
|
||||
/**
|
||||
* - The auto fade out time when the animation state play completed.
|
||||
* [-1: Do not fade out automatically, [0~N]: The fade out time] (In seconds)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态播放完成后的自动淡出时间。
|
||||
* [-1: 不自动淡出, [0~N]: 淡出时间] (以秒为单位)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float autoFadeOutTime;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float fadeTotalTime;
|
||||
/**
|
||||
* - The name of the animation state. (Can be different from the name of the animation data)
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态名称。 (可以不同于动画数据)
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* - The blend group name of the animation state.
|
||||
* This property is typically used to specify the substitution of multiple animation states blend.
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合组名称。
|
||||
* 该属性通常用来指定多个动画状态混合时的相互替换关系。
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string group;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - xx: Play Enabled, Fade Play Enabled
|
||||
* @internal
|
||||
*/
|
||||
int _playheadState;
|
||||
/**
|
||||
* -1: Fade in, 0: Fade complete, 1: Fade out;
|
||||
* @internal
|
||||
*/
|
||||
int _fadeState;
|
||||
/**
|
||||
* -1: Fade start, 0: Fading, 1: Fade complete;
|
||||
* @internal
|
||||
*/
|
||||
int _subFadeState;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _position;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _duration;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _fadeProgress;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _weightResult;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
AnimationData* _animationData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ActionTimelineState* _actionTimeline;
|
||||
|
||||
private:
|
||||
unsigned _timelineDirty;
|
||||
float _fadeTime;
|
||||
float _time;
|
||||
std::vector<std::string> _boneMask;
|
||||
std::vector<BoneTimelineState*> _boneTimelines;
|
||||
std::vector<SlotTimelineState*> _slotTimelines;
|
||||
std::vector<ConstraintTimelineState*> _constraintTimelines;
|
||||
std::vector<std::pair<TimelineState*, BaseTimelineType>> _poseTimelines;
|
||||
std::map<std::string, BonePose*> _bonePoses;
|
||||
Armature* _armature;
|
||||
ZOrderTimelineState* _zOrderTimeline;
|
||||
|
||||
public:
|
||||
AnimationState() :
|
||||
_actionTimeline(nullptr),
|
||||
_zOrderTimeline(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
virtual ~AnimationState()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
private:
|
||||
void _updateTimelines();
|
||||
void _updateBoneAndSlotTimelines();
|
||||
void _advanceFadeTime(float passedTime);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void init(Armature* armature, AnimationData* animationData, AnimationConfig* animationConfig);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void advanceTime(float passedTime, float cacheFrameRate);
|
||||
/**
|
||||
* - Continue play.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 继续播放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void play();
|
||||
/**
|
||||
* - Stop play.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 暂停播放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void stop();
|
||||
/**
|
||||
* - Fade out the animation state.
|
||||
* @param fadeOutTime - The fade out time. (In seconds)
|
||||
* @param pausePlayhead - Whether to pause the animation playing when fade out.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡出动画状态。
|
||||
* @param fadeOutTime - 淡出时间。 (以秒为单位)
|
||||
* @param pausePlayhead - 淡出时是否暂停播放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void fadeOut(float fadeOutTime, bool pausePlayhead = true);
|
||||
/**
|
||||
* - Check if a specific bone mask is included.
|
||||
* @param boneName - The bone name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否包含特定骨骼遮罩。
|
||||
* @param boneName - 骨骼名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool containsBoneMask(const std::string& boneName) const;
|
||||
/**
|
||||
* - Add a specific bone mask.
|
||||
* @param boneName - The bone name.
|
||||
* @param recursive - Whether or not to add a mask to the bone's sub-bone.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 添加特定的骨骼遮罩。
|
||||
* @param boneName - 骨骼名称。
|
||||
* @param recursive - 是否为该骨骼的子骨骼添加遮罩。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void addBoneMask(const std::string& boneName, bool recursive = true);
|
||||
/**
|
||||
* - Remove the mask of a specific bone.
|
||||
* @param boneName - The bone name.
|
||||
* @param recursive - Whether to remove the bone's sub-bone mask.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 删除特定骨骼的遮罩。
|
||||
* @param boneName - 骨骼名称。
|
||||
* @param recursive - 是否删除该骨骼的子骨骼遮罩。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void removeBoneMask(const std::string& boneName, bool recursive = true);
|
||||
/**
|
||||
* - Remove all bone masks.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 删除所有骨骼遮罩。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void removeAllBoneMask();
|
||||
/**
|
||||
* - Whether the animation state is fading in.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否正在淡入。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool isFadeIn() const
|
||||
{
|
||||
return _fadeState < 0;
|
||||
}
|
||||
/**
|
||||
* - Whether the animation state is fading out.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否正在淡出。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool isFadeOut() const
|
||||
{
|
||||
return _fadeState > 0;
|
||||
}
|
||||
/**
|
||||
* - Whether the animation state is fade completed.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否淡入或淡出完毕。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool isFadeComplete() const
|
||||
{
|
||||
return _fadeState == 0;
|
||||
}
|
||||
/**
|
||||
* - Whether the animation state is playing.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否正在播放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool isPlaying() const;
|
||||
/**
|
||||
* - Whether the animation state is play completed.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否播放完毕。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool isCompleted() const;
|
||||
/**
|
||||
* - The times has been played.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 已经循环播放的次数。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned getCurrentPlayTimes() const;
|
||||
/**
|
||||
* - The total time. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 总播放时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline float getTotalTime() const
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
/**
|
||||
* - The time is currently playing. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 当前播放的时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float getCurrentTime() const;
|
||||
void setCurrentTime(float value);
|
||||
inline const std::string& getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* - The animation data.
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画数据。
|
||||
* @see dragonBones.AnimationData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const AnimationData* getAnimationData() const
|
||||
{
|
||||
return _animationData;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BonePose : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(BonePose);
|
||||
|
||||
public:
|
||||
Transform current;
|
||||
Transform delta;
|
||||
Transform result;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BlendState
|
||||
{
|
||||
public:
|
||||
bool dirty;
|
||||
int layer;
|
||||
float leftWeight;
|
||||
float layerWeight;
|
||||
float blendWeight;
|
||||
|
||||
/**
|
||||
* -1: First blending, 0: No blending, 1: Blending.
|
||||
*/
|
||||
int update(float weight, int p_layer);
|
||||
void clear();
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ANIMATION_STATE_H
|
||||
@@ -0,0 +1,344 @@
|
||||
#include "BaseTimelineState.h"
|
||||
#include "../model/DragonBonesData.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
#include "../model/AnimationData.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
#include "../armature/Slot.h"
|
||||
#include "AnimationState.h"
|
||||
#include "TimelineState.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void TimelineState::_onClear()
|
||||
{
|
||||
playState = -1;
|
||||
currentPlayTimes = -1;
|
||||
currentTime = -1.0f;
|
||||
|
||||
_tweenState = TweenState::None;
|
||||
_frameRate = 0;
|
||||
_frameValueOffset = 0;
|
||||
_frameCount = 0;
|
||||
_frameOffset = 0;
|
||||
_frameIndex = -1;
|
||||
_frameRateR = 0.0f;
|
||||
_position = 0.0f;
|
||||
_duration = 0.0f;
|
||||
_timeScale = 1.0f;
|
||||
_timeOffset = 0.0f;
|
||||
_dragonBonesData = nullptr;
|
||||
_animationData = nullptr;
|
||||
_timelineData = nullptr;
|
||||
_armature = nullptr;
|
||||
_animationState = nullptr;
|
||||
_actionTimeline = nullptr;
|
||||
_frameArray = nullptr;
|
||||
_frameIntArray = nullptr;
|
||||
_frameFloatArray = nullptr;
|
||||
_timelineArray = nullptr;
|
||||
_frameIndices = nullptr;
|
||||
}
|
||||
|
||||
bool TimelineState::_setCurrentTime(float passedTime)
|
||||
{
|
||||
const auto prevState = playState;
|
||||
const auto prevPlayTimes = currentPlayTimes;
|
||||
const auto prevTime = currentTime;
|
||||
|
||||
if (_actionTimeline != nullptr && _frameCount <= 1) // No frame or only one frame.
|
||||
{
|
||||
playState = _actionTimeline->playState >= 0 ? 1 : -1;
|
||||
currentPlayTimes = 1;
|
||||
currentTime = _actionTimeline->currentTime;
|
||||
}
|
||||
else if (_actionTimeline == nullptr || _timeScale != 1.0f || _timeOffset != 0.0f) // Action timeline or has scale and offset.
|
||||
{
|
||||
const auto playTimes = _animationState->playTimes;
|
||||
const auto totalTime = playTimes * _duration;
|
||||
|
||||
passedTime *= _timeScale;
|
||||
if (_timeOffset != 0.0f)
|
||||
{
|
||||
passedTime += _timeOffset * _animationData->duration;
|
||||
}
|
||||
|
||||
if (playTimes > 0 && (passedTime >= totalTime || passedTime <= -totalTime))
|
||||
{
|
||||
if (playState <= 0 && _animationState->_playheadState == 3)
|
||||
{
|
||||
playState = 1;
|
||||
}
|
||||
|
||||
currentPlayTimes = playTimes;
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
currentTime = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentTime = _duration + 0.000001f; // Precision problem
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playState != 0 && _animationState->_playheadState == 3)
|
||||
{
|
||||
playState = 0;
|
||||
}
|
||||
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
passedTime = -passedTime;
|
||||
currentPlayTimes = (int)(passedTime / _duration);
|
||||
currentTime = _duration - fmod(passedTime, _duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPlayTimes = (int)(passedTime / _duration);
|
||||
currentTime = fmod(passedTime, _duration);
|
||||
}
|
||||
}
|
||||
|
||||
currentTime += _position;
|
||||
}
|
||||
else // Multi frames.
|
||||
{
|
||||
playState = _actionTimeline->playState;
|
||||
currentPlayTimes = _actionTimeline->currentPlayTimes;
|
||||
currentTime = _actionTimeline->currentTime;
|
||||
}
|
||||
|
||||
if (currentPlayTimes == prevPlayTimes && currentTime == prevTime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear frame flag when timeline start or loopComplete.
|
||||
if (
|
||||
(prevState < 0 && playState != prevState) ||
|
||||
(playState <= 0 && currentPlayTimes != prevPlayTimes)
|
||||
)
|
||||
{
|
||||
_frameIndex = -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TimelineState::init(Armature* armature, AnimationState* animationState, TimelineData* timelineData)
|
||||
{
|
||||
_armature = armature;
|
||||
_animationState = animationState;
|
||||
_timelineData = timelineData;
|
||||
_actionTimeline = _animationState->_actionTimeline;
|
||||
|
||||
if (this == _actionTimeline)
|
||||
{
|
||||
_actionTimeline = nullptr; //
|
||||
}
|
||||
|
||||
_animationData = _animationState->_animationData;
|
||||
|
||||
_frameRate = _animationData->parent->frameRate;
|
||||
_frameRateR = 1.0f / _frameRate;
|
||||
_position = _animationState->_position;
|
||||
_duration = _animationState->_duration;
|
||||
_dragonBonesData = _animationData->parent->parent;
|
||||
|
||||
if (_timelineData != nullptr)
|
||||
{
|
||||
_frameIntArray = _dragonBonesData->frameIntArray;
|
||||
_frameFloatArray = _dragonBonesData->frameFloatArray;
|
||||
_frameArray = _dragonBonesData->frameArray;
|
||||
_timelineArray = _dragonBonesData->timelineArray;
|
||||
_frameIndices = &(_dragonBonesData->frameIndices);
|
||||
|
||||
_frameCount = _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineKeyFrameCount];
|
||||
_frameValueOffset = _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineFrameValueOffset];
|
||||
_timeScale = 100.0f / _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineScale];
|
||||
_timeOffset = _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineOffset] * 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineState::update(float passedTime)
|
||||
{
|
||||
if (_setCurrentTime(passedTime))
|
||||
{
|
||||
if (_frameCount > 1)
|
||||
{
|
||||
const auto timelineFrameIndex = (unsigned)(currentTime * _frameRate);
|
||||
const auto frameIndex = (*_frameIndices)[_timelineData->frameIndicesOffset + timelineFrameIndex];
|
||||
if ((unsigned)_frameIndex != frameIndex)
|
||||
{
|
||||
_frameIndex = frameIndex;
|
||||
_frameOffset = _animationData->frameOffset + _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineFrameOffset + _frameIndex];
|
||||
|
||||
_onArriveAtFrame();
|
||||
}
|
||||
}
|
||||
else if (_frameIndex < 0)
|
||||
{
|
||||
_frameIndex = 0;
|
||||
if (_timelineData != nullptr) // May be pose timeline.
|
||||
{
|
||||
_frameOffset = _animationData->frameOffset + _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineFrameOffset];
|
||||
}
|
||||
|
||||
_onArriveAtFrame();
|
||||
}
|
||||
|
||||
if (_tweenState != TweenState::None)
|
||||
{
|
||||
_onUpdateFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TweenTimelineState::_onClear()
|
||||
{
|
||||
TimelineState::_onClear();
|
||||
|
||||
_tweenType = TweenType::None;
|
||||
_curveCount = 0;
|
||||
_framePosition = 0.0f;
|
||||
_frameDurationR = 0.0f;
|
||||
_tweenProgress = 0.0f;
|
||||
_tweenEasing = 0.0f;
|
||||
}
|
||||
|
||||
void TweenTimelineState::_onArriveAtFrame()
|
||||
{
|
||||
if (
|
||||
_frameCount > 1 &&
|
||||
(
|
||||
(unsigned)_frameIndex != _frameCount - 1 ||
|
||||
_animationState->playTimes == 0 ||
|
||||
_animationState->getCurrentPlayTimes() < _animationState->playTimes - 1
|
||||
)
|
||||
)
|
||||
{
|
||||
_tweenType = (TweenType)_frameArray[_frameOffset + (unsigned)BinaryOffset::FrameTweenType]; // TODO recode ture tween type.
|
||||
_tweenState = _tweenType == TweenType::None ? TweenState::Once : TweenState::Always;
|
||||
|
||||
if (_tweenType == TweenType::Curve)
|
||||
{
|
||||
_curveCount = _frameArray[_frameOffset + (unsigned)BinaryOffset::FrameTweenEasingOrCurveSampleCount];
|
||||
}
|
||||
else if (_tweenType != TweenType::None && _tweenType != TweenType::Line)
|
||||
{
|
||||
_tweenEasing = _frameArray[_frameOffset + (unsigned)BinaryOffset::FrameTweenEasingOrCurveSampleCount] * 0.01;
|
||||
}
|
||||
|
||||
_framePosition = _frameArray[_frameOffset] * _frameRateR;
|
||||
|
||||
if ((unsigned)_frameIndex == _frameCount - 1)
|
||||
{
|
||||
_frameDurationR = 1.0f / (_animationData->duration - _framePosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto nextFrameOffset = _animationData->frameOffset + _timelineArray[_timelineData->offset + (unsigned)BinaryOffset::TimelineFrameOffset + _frameIndex + 1];
|
||||
const auto frameDuration = _frameArray[nextFrameOffset] * _frameRateR - _framePosition;
|
||||
|
||||
if (frameDuration > 0.0f) // Fixed animation data bug.
|
||||
{
|
||||
_frameDurationR = 1.0f / frameDuration;
|
||||
}
|
||||
else
|
||||
{
|
||||
_frameDurationR = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tweenState = TweenState::Once;
|
||||
}
|
||||
}
|
||||
|
||||
void TweenTimelineState::_onUpdateFrame()
|
||||
{
|
||||
if (_tweenState == TweenState::Always)
|
||||
{
|
||||
_tweenProgress = (currentTime - _framePosition) * _frameDurationR;
|
||||
|
||||
if (_tweenType == TweenType::Curve)
|
||||
{
|
||||
_tweenProgress = TweenTimelineState::_getEasingCurveValue(_tweenProgress, _frameArray, _curveCount, _frameOffset + (unsigned)BinaryOffset::FrameCurveSamples);
|
||||
}
|
||||
else if (_tweenType != TweenType::Line)
|
||||
{
|
||||
_tweenProgress = TweenTimelineState::_getEasingValue(_tweenType, _tweenProgress, _tweenEasing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tweenProgress = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BoneTimelineState::_onClear()
|
||||
{
|
||||
TweenTimelineState::_onClear();
|
||||
|
||||
bone = nullptr;
|
||||
bonePose = nullptr;
|
||||
}
|
||||
|
||||
void BoneTimelineState::blend(int state)
|
||||
{
|
||||
const auto blendWeight = bone->_blendState.blendWeight;
|
||||
auto& animationPose = bone->animationPose;
|
||||
const auto& result = bonePose->result;
|
||||
|
||||
if (state == 2)
|
||||
{
|
||||
animationPose.x += result.x * blendWeight;
|
||||
animationPose.y += result.y * blendWeight;
|
||||
animationPose.rotation += result.rotation * blendWeight;
|
||||
animationPose.skew += result.skew * blendWeight;
|
||||
animationPose.scaleX += (result.scaleX - 1.0f) * blendWeight;
|
||||
animationPose.scaleY += (result.scaleY - 1.0f) * blendWeight;
|
||||
}
|
||||
else if (blendWeight != 1.0f)
|
||||
{
|
||||
animationPose.x = result.x * blendWeight;
|
||||
animationPose.y = result.y * blendWeight;
|
||||
animationPose.rotation = result.rotation * blendWeight;
|
||||
animationPose.skew = result.skew * blendWeight;
|
||||
animationPose.scaleX = (result.scaleX - 1.0f) * blendWeight + 1.0f;
|
||||
animationPose.scaleY = (result.scaleY - 1.0f) * blendWeight + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationPose.x = result.x;
|
||||
animationPose.y = result.y;
|
||||
animationPose.rotation = result.rotation;
|
||||
animationPose.skew = result.skew;
|
||||
animationPose.scaleX = result.scaleX;
|
||||
animationPose.scaleY = result.scaleY;
|
||||
}
|
||||
|
||||
if (_animationState->_fadeState != 0 || _animationState->_subFadeState != 0)
|
||||
{
|
||||
bone->_transformDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SlotTimelineState::_onClear()
|
||||
{
|
||||
TweenTimelineState::_onClear();
|
||||
|
||||
slot = nullptr;
|
||||
}
|
||||
|
||||
void ConstraintTimelineState::_onClear()
|
||||
{
|
||||
TweenTimelineState::_onClear();
|
||||
|
||||
constraint = nullptr;
|
||||
}
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_BASE_TIMELINE_STATE_H
|
||||
#define DRAGONBONES_BASE_TIMELINE_STATE_H
|
||||
|
||||
#include "../geom/Transform.h"
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class TimelineState : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(TimelineState)
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class TweenState
|
||||
{
|
||||
None = 0,
|
||||
Once = 1,
|
||||
Always = 2
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* -1: start, 0: play, 1: complete;
|
||||
*/
|
||||
int playState;
|
||||
int currentPlayTimes;
|
||||
float currentTime;
|
||||
|
||||
protected:
|
||||
TweenState _tweenState;
|
||||
unsigned _frameRate;
|
||||
unsigned _frameValueOffset;
|
||||
unsigned _frameCount;
|
||||
unsigned _frameOffset;
|
||||
int _frameIndex;
|
||||
float _frameRateR;
|
||||
float _position;
|
||||
float _duration;
|
||||
float _timeScale;
|
||||
float _timeOffset;
|
||||
DragonBonesData* _dragonBonesData;
|
||||
AnimationData* _animationData;
|
||||
TimelineData* _timelineData;
|
||||
Armature* _armature;
|
||||
AnimationState* _animationState;
|
||||
TimelineState* _actionTimeline;
|
||||
const int16_t* _frameArray;
|
||||
const int16_t* _frameIntArray;
|
||||
const float* _frameFloatArray;
|
||||
const uint16_t* _timelineArray;
|
||||
const std::vector<unsigned>* _frameIndices;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
virtual void _onArriveAtFrame() = 0;
|
||||
virtual void _onUpdateFrame() = 0;
|
||||
bool _setCurrentTime(float passedTime);
|
||||
|
||||
public:
|
||||
virtual void init(Armature* armature, AnimationState* animationState, TimelineData* timelineData);
|
||||
virtual void fadeOut() {}
|
||||
virtual void update(float passedTime);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class TweenTimelineState : public TimelineState
|
||||
{
|
||||
ABSTRACT_CLASS(TweenTimelineState)
|
||||
|
||||
private:
|
||||
inline static float _getEasingValue(TweenType tweenType, float progress, float easing)
|
||||
{
|
||||
auto value = progress;
|
||||
switch (tweenType)
|
||||
{
|
||||
case TweenType::QuadIn:
|
||||
value = std::pow(progress, 2.0f);
|
||||
break;
|
||||
|
||||
case TweenType::QuadOut:
|
||||
value = 1.0f - std::pow(1.0f - progress, 2.0f);
|
||||
break;
|
||||
|
||||
case TweenType::QuadInOut:
|
||||
value = 0.5f * (1.0f - std::cos(progress * Transform::PI));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (value - progress) * easing + progress;
|
||||
}
|
||||
|
||||
inline static float _getEasingCurveValue(float progress, const int16_t* samples, unsigned count, unsigned offset)
|
||||
{
|
||||
if (progress <= 0.0f)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
else if (progress >= 1.0f)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const auto segmentCount = count + 1; // + 2 - 1
|
||||
const auto valueIndex = (unsigned)(progress * segmentCount);
|
||||
const auto fromValue = valueIndex == 0 ? 0.0f : samples[offset + valueIndex - 1];
|
||||
const auto toValue = (valueIndex == segmentCount - 1) ? 10000.0f : samples[offset + valueIndex];
|
||||
|
||||
return (fromValue + (toValue - fromValue) * (progress * segmentCount - valueIndex)) * 0.0001f;
|
||||
}
|
||||
|
||||
protected:
|
||||
TweenType _tweenType;
|
||||
unsigned _curveCount;
|
||||
float _framePosition;
|
||||
float _frameDurationR;
|
||||
float _tweenProgress;
|
||||
float _tweenEasing;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoneTimelineState : public TweenTimelineState
|
||||
{
|
||||
ABSTRACT_CLASS(BoneTimelineState)
|
||||
|
||||
public:
|
||||
Bone* bone;
|
||||
BonePose* bonePose;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
void blend(int state);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class SlotTimelineState : public TweenTimelineState
|
||||
{
|
||||
ABSTRACT_CLASS(SlotTimelineState)
|
||||
|
||||
public:
|
||||
Slot* slot;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ConstraintTimelineState : public TweenTimelineState
|
||||
{
|
||||
ABSTRACT_CLASS(ConstraintTimelineState)
|
||||
|
||||
public:
|
||||
Constraint* constraint;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_BASE_TIMELINE_STATE_H
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ANIMATEBLE_H
|
||||
#define DRAGONBONES_ANIMATEBLE_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - Play animation interface. (Both Armature and Wordclock implement the interface)
|
||||
* Any instance that implements the interface can be added to the Worldclock instance and advance time by Worldclock instance uniformly.
|
||||
* @see dragonBones.WorldClock
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放动画接口。 (Armature 和 WordClock 都实现了该接口)
|
||||
* 任何实现了此接口的实例都可以添加到 WorldClock 实例中,由 WorldClock 实例统一更新时间。
|
||||
* @see dragonBones.WorldClock
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class IAnimatable
|
||||
{
|
||||
ABSTRACT_CLASS(IAnimatable)
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Advance time.
|
||||
* @param passedTime - Passed time. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 更新时间。
|
||||
* @param passedTime - 前进的时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void advanceTime(float passedTime) = 0;
|
||||
|
||||
/**
|
||||
* - Render.
|
||||
* @version Cocos creator 2.3
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 渲染。
|
||||
* @version Cocos creator 2.3
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void render() = 0;
|
||||
/**
|
||||
* - The Wordclock instance to which the current belongs.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* armature.clock = factory.clock; // Add armature to clock.
|
||||
* armature.clock = null; // Remove armature from clock.
|
||||
* </pre>
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 当前所属的 WordClock 实例。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* armature.clock = factory.clock; // 将骨架添加到时钟。
|
||||
* armature.clock = null; // 将骨架从时钟移除。
|
||||
* </pre>
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual WorldClock* getClock() const = 0;
|
||||
virtual void setClock(WorldClock* value) = 0;
|
||||
|
||||
/**
|
||||
* - Gets render order.
|
||||
* @version Cocos creator 2.3
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获得渲染顺序。
|
||||
* @version Cocos creator 2.3
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual uint32_t getRenderOrder() const { return 0; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ANIMATEBLE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_TIMELINE_STATE_H
|
||||
#define DRAGONBONES_TIMELINE_STATE_H
|
||||
|
||||
#include "BaseTimelineState.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ActionTimelineState : public TimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(ActionTimelineState);
|
||||
|
||||
void _onCrossFrame(unsigned frameIndex) const;
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override {}
|
||||
virtual void _onUpdateFrame() override {}
|
||||
|
||||
public:
|
||||
void update(float passedTime) override;
|
||||
void setCurrentTime(float value);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ZOrderTimelineState : public TimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(ZOrderTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override {}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoneAllTimelineState : public BoneTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(BoneAllTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
|
||||
public:
|
||||
virtual void fadeOut() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoneTranslateTimelineState : public BoneTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(BoneTranslateTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoneRotateTimelineState : public BoneTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(BoneRotateTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
|
||||
public:
|
||||
virtual void fadeOut() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoneScaleTimelineState : public BoneTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(BoneScaleTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class SlotDislayTimelineState : public SlotTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(SlotDislayTimelineState);
|
||||
|
||||
protected:
|
||||
virtual void _onArriveAtFrame() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class SlotColorTimelineState : public SlotTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_B(SlotColorTimelineState);
|
||||
|
||||
private:
|
||||
bool _dirty;
|
||||
int* _current;
|
||||
int* _delta;
|
||||
float* _result;
|
||||
|
||||
public:
|
||||
SlotColorTimelineState() :
|
||||
_current(new int[8]{ 0 }),
|
||||
_delta(new int[8]{ 0 }),
|
||||
_result(new float[8]{ 0.0f })
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~SlotColorTimelineState()
|
||||
{
|
||||
_onClear();
|
||||
|
||||
delete _current;
|
||||
delete _delta;
|
||||
delete _result;
|
||||
}
|
||||
|
||||
protected:
|
||||
void _onClear() override;
|
||||
void _onArriveAtFrame() override;
|
||||
void _onUpdateFrame() override;
|
||||
|
||||
public:
|
||||
void fadeOut() override;
|
||||
void update(float passedTime) override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class DeformTimelineState : public SlotTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(DeformTimelineState);
|
||||
|
||||
public:
|
||||
unsigned vertexOffset;
|
||||
|
||||
private:
|
||||
bool _dirty;
|
||||
unsigned _frameFloatOffset;
|
||||
unsigned _deformCount;
|
||||
unsigned _valueCount;
|
||||
unsigned _valueOffset;
|
||||
std::vector<float> _current;
|
||||
std::vector<float> _delta;
|
||||
std::vector<float> _result;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
|
||||
public:
|
||||
virtual void init(Armature* armature, AnimationState* animationState, TimelineData* timelineData) override;
|
||||
virtual void fadeOut() override;
|
||||
virtual void update(float passedTime) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class IKConstraintTimelineState : public ConstraintTimelineState
|
||||
{
|
||||
BIND_CLASS_TYPE_A(IKConstraintTimelineState);
|
||||
|
||||
private:
|
||||
float _current;
|
||||
float _delta;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
virtual void _onArriveAtFrame() override;
|
||||
virtual void _onUpdateFrame() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_TIMELINE_STATE_H
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "WorldClock.h"
|
||||
#include <algorithm>
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
WorldClock WorldClock::clock;
|
||||
|
||||
void WorldClock::advanceTime(float passedTime)
|
||||
{
|
||||
if (passedTime < 0.0f || passedTime != passedTime)
|
||||
{
|
||||
passedTime = 0.0f;
|
||||
}
|
||||
|
||||
const auto currentTime = 0.0f;
|
||||
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
passedTime = currentTime - _systemTime;
|
||||
}
|
||||
|
||||
_systemTime = currentTime;
|
||||
|
||||
if (timeScale != 1.0f)
|
||||
{
|
||||
passedTime *= timeScale;
|
||||
}
|
||||
|
||||
if (passedTime == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (passedTime < 0.0f)
|
||||
{
|
||||
time -= passedTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
time += passedTime;
|
||||
}
|
||||
|
||||
std::size_t i = 0, r = 0, l = _animatebles.size();
|
||||
for (; i < l; ++i)
|
||||
{
|
||||
const auto animatable = _animatebles[i];
|
||||
if (animatable != nullptr)
|
||||
{
|
||||
if (r > 0)
|
||||
{
|
||||
_animatebles[i - r] = animatable;
|
||||
_animatebles[i] = nullptr;
|
||||
}
|
||||
|
||||
animatable->advanceTime(passedTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
r++;
|
||||
}
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
{
|
||||
l = _animatebles.size();
|
||||
for (; i < l; ++i)
|
||||
{
|
||||
const auto animateble = _animatebles[i];
|
||||
if (animateble != nullptr)
|
||||
{
|
||||
_animatebles[i - r] = animateble;
|
||||
}
|
||||
else
|
||||
{
|
||||
r++;
|
||||
}
|
||||
}
|
||||
|
||||
_animatebles.resize(l - r);
|
||||
}
|
||||
}
|
||||
|
||||
bool WorldClock::contains(const IAnimatable* value) const
|
||||
{
|
||||
if (value == this) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ancestor = value;
|
||||
while (ancestor != this && ancestor != nullptr)
|
||||
{
|
||||
ancestor = ancestor->getClock();
|
||||
}
|
||||
|
||||
return ancestor == this;
|
||||
}
|
||||
|
||||
void WorldClock::add(IAnimatable* value)
|
||||
{
|
||||
if (std::find(_animatebles.begin(), _animatebles.end(), value) == _animatebles.end())
|
||||
{
|
||||
_animatebles.push_back(value);
|
||||
value->setClock(this);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldClock::remove(IAnimatable* value)
|
||||
{
|
||||
const auto iterator = std::find(_animatebles.begin(), _animatebles.end(), value);
|
||||
if (iterator != _animatebles.end())
|
||||
{
|
||||
*iterator = nullptr;
|
||||
value->setClock(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldClock::render()
|
||||
{
|
||||
auto isOrderDirty = false;
|
||||
uint32_t maxRenderOrder = 0;
|
||||
for (const auto animatable : _animatebles)
|
||||
{
|
||||
if (animatable != nullptr)
|
||||
{
|
||||
animatable->render();
|
||||
auto renderOrder = animatable->getRenderOrder();
|
||||
if (maxRenderOrder > renderOrder)
|
||||
{
|
||||
isOrderDirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxRenderOrder = renderOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isOrderDirty)
|
||||
{
|
||||
std::sort(_animatebles.begin(), _animatebles.end(), [](IAnimatable* it1, IAnimatable* it2)
|
||||
{
|
||||
if (!it1 || !it2) return false;
|
||||
return it1->getRenderOrder() < it2->getRenderOrder();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void WorldClock::clear()
|
||||
{
|
||||
for (const auto animatable : _animatebles)
|
||||
{
|
||||
if (animatable != nullptr)
|
||||
{
|
||||
animatable->setClock(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldClock::setClock(WorldClock* value)
|
||||
{
|
||||
if (_clock == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_clock != nullptr)
|
||||
{
|
||||
_clock->remove(this);
|
||||
}
|
||||
|
||||
_clock = value;
|
||||
|
||||
if (_clock != nullptr)
|
||||
{
|
||||
_clock->add(this);
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_WORLD_CLOCK_H
|
||||
#define DRAGONBONES_WORLD_CLOCK_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
#include "IAnimatable.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - Worldclock provides clock support for animations, advance time for each IAnimatable object added to the instance.
|
||||
* @see dragonBones.IAnimateble
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - WorldClock 对动画提供时钟支持,为每个加入到该实例的 IAnimatable 对象更新时间。
|
||||
* @see dragonBones.IAnimateble
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class WorldClock : public IAnimatable
|
||||
{
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(WorldClock)
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Deprecated, please refer to {@link dragonBones.BaseFactory#clock}.
|
||||
* @deprecated
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 已废弃,请参考 {@link dragonBones.BaseFactory#clock}。
|
||||
* @deprecated
|
||||
* @language zh_CN
|
||||
*/
|
||||
static WorldClock clock;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Current time. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 当前的时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float time;
|
||||
/**
|
||||
* - The play speed, used to control animation speed-shift play.
|
||||
* [0: Stop play, (0~1): Slow play, 1: Normal play, (1~N): Fast play]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放速度,用于控制动画变速播放。
|
||||
* [0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float timeScale;
|
||||
|
||||
private:
|
||||
float _systemTime;
|
||||
std::vector<IAnimatable*> _animatebles;
|
||||
WorldClock* _clock;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Creating a Worldclock instance. Typically, you do not need to create Worldclock instance.
|
||||
* When multiple Worldclock instances are running at different speeds, can achieving some specific animation effects, such as bullet time.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 创建一个 WorldClock 实例。通常并不需要创建 WorldClock 实例。
|
||||
* 当多个 WorldClock 实例使用不同的速度运行时,可以实现一些特殊的动画效果,比如子弹时间等。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
WorldClock(float timeValue = 0.0f) :
|
||||
time(timeValue),
|
||||
timeScale(1.0f),
|
||||
_systemTime(0.0f),
|
||||
_animatebles(),
|
||||
_clock(nullptr)
|
||||
{
|
||||
_systemTime = 0.0f;
|
||||
}
|
||||
virtual ~WorldClock()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
/**
|
||||
* - Advance time for all IAnimatable instances.
|
||||
* @param passedTime - Passed time. [-1: Automatically calculates the time difference between the current frame and the previous frame, [0~N): Passed time] (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 为所有的 IAnimatable 实例更新时间。
|
||||
* @param passedTime - 前进的时间。 [-1: 自动计算当前帧与上一帧的时间差, [0~N): 前进的时间] (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void advanceTime(float passedTime) override;
|
||||
/**
|
||||
* - render all IAnimatable instances.
|
||||
* @version Cocos creator 2.3
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 渲染所有的 IAnimatable 实例。
|
||||
* @version Cocos creator 2.3
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void render() override;
|
||||
|
||||
/**
|
||||
* - Check whether contains a specific instance of IAnimatable.
|
||||
* @param value - The IAnimatable instance.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否包含特定的 IAnimatable 实例。
|
||||
* @param value - IAnimatable 实例。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool contains(const IAnimatable* value) const;
|
||||
/**
|
||||
* - Add IAnimatable instance.
|
||||
* @param value - The IAnimatable instance.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 添加 IAnimatable 实例。
|
||||
* @param value - IAnimatable 实例。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void add(IAnimatable* value);
|
||||
/**
|
||||
* - Removes a specified IAnimatable instance.
|
||||
* @param value - The IAnimatable instance.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 移除特定的 IAnimatable 实例。
|
||||
* @param value - IAnimatable 实例。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void remove(IAnimatable* value);
|
||||
/**
|
||||
* - Clear all IAnimatable instances.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 清除所有的 IAnimatable 实例。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
inline virtual WorldClock* getClock() const override
|
||||
{
|
||||
return _clock;
|
||||
}
|
||||
virtual void setClock(WorldClock* value) override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
static WorldClock* getStaticClock() { return &clock; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_WORLD_CLOCK_H
|
||||
563
cocos2d-x/cocos/editor-support/dragonbones/armature/Armature.cpp
Normal file
563
cocos2d-x/cocos/editor-support/dragonbones/armature/Armature.cpp
Normal file
@@ -0,0 +1,563 @@
|
||||
#include "Armature.h"
|
||||
#include "../model/TextureAtlasData.h"
|
||||
#include "../model/UserData.h"
|
||||
#include "../animation/WorldClock.h"
|
||||
#include "../animation/Animation.h"
|
||||
#include "../event/EventObject.h"
|
||||
#include "IArmatureProxy.h"
|
||||
#include "Bone.h"
|
||||
#include "Slot.h"
|
||||
#include "Constraint.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
bool Armature::_onSortSlots(Slot* a, Slot* b)
|
||||
{
|
||||
return a->_zOrder < b->_zOrder ? true : false;
|
||||
}
|
||||
|
||||
void Armature::_onClear()
|
||||
{
|
||||
if (_clock != nullptr) // Remove clock before slots clear.
|
||||
{
|
||||
_clock->remove(this);
|
||||
}
|
||||
|
||||
for (const auto bone : _bones)
|
||||
{
|
||||
bone->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
slot->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto constraint : _constraints)
|
||||
{
|
||||
constraint->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto action : _actions)
|
||||
{
|
||||
action->returnToPool();
|
||||
}
|
||||
|
||||
if(_animation != nullptr)
|
||||
{
|
||||
_animation->returnToPool();
|
||||
}
|
||||
|
||||
if (_proxy != nullptr)
|
||||
{
|
||||
_proxy->dbClear();
|
||||
}
|
||||
|
||||
if (_replaceTextureAtlasData != nullptr)
|
||||
{
|
||||
_replaceTextureAtlasData->returnToPool();
|
||||
}
|
||||
|
||||
inheritAnimation = true;
|
||||
userData = nullptr;
|
||||
|
||||
_debugDraw = false;
|
||||
_lockUpdate = false;
|
||||
_slotsDirty = false;
|
||||
_zOrderDirty = false;
|
||||
_flipX = false;
|
||||
_flipY = false;
|
||||
_cacheFrameIndex = -1;
|
||||
_bones.clear();
|
||||
_slots.clear();
|
||||
_constraints.clear();
|
||||
_actions.clear();
|
||||
_armatureData = nullptr;
|
||||
_animation = nullptr;
|
||||
_proxy = nullptr;
|
||||
_display = nullptr;
|
||||
_replaceTextureAtlasData = nullptr;
|
||||
_replacedTexture = nullptr;
|
||||
_dragonBones = nullptr;
|
||||
_clock = nullptr;
|
||||
_parent = nullptr;
|
||||
}
|
||||
|
||||
void Armature::_sortZOrder(const int16_t* slotIndices, unsigned offset)
|
||||
{
|
||||
const auto& slotDatas = _armatureData->sortedSlots;
|
||||
const auto isOriginal = slotIndices == nullptr;
|
||||
|
||||
if (_zOrderDirty || !isOriginal)
|
||||
{
|
||||
for (std::size_t i = 0, l = slotDatas.size(); i < l; ++i)
|
||||
{
|
||||
const auto slotIndex = isOriginal ? i : (std::size_t)slotIndices[offset + i];
|
||||
if (slotIndex < 0 || slotIndex >= l)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto slotData = slotDatas[slotIndex];
|
||||
const auto slot = getSlot(slotData->name);
|
||||
if (slot != nullptr)
|
||||
{
|
||||
slot->_setZorder(i);
|
||||
}
|
||||
}
|
||||
|
||||
_slotsDirty = true;
|
||||
_zOrderDirty = !isOriginal;
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::_addBone(Bone* value)
|
||||
{
|
||||
if (std::find(_bones.begin(), _bones.end(), value) == _bones.end())
|
||||
{
|
||||
_bones.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::_addSlot(Slot* value)
|
||||
{
|
||||
if (std::find(_slots.begin(), _slots.end(), value) == _slots.end())
|
||||
{
|
||||
_slots.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::_addConstraint(Constraint* value)
|
||||
{
|
||||
if (std::find(_constraints.cbegin(), _constraints.cend(), value) == _constraints.cend())
|
||||
{
|
||||
_constraints.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::_bufferAction(EventObject* action, bool append)
|
||||
{
|
||||
if (std::find(_actions.cbegin(), _actions.cend(), action) == _actions.cend())
|
||||
{
|
||||
if (append)
|
||||
{
|
||||
_actions.push_back(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
_actions.insert(_actions.begin(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::dispose()
|
||||
{
|
||||
if (_armatureData != nullptr)
|
||||
{
|
||||
_lockUpdate = true;
|
||||
_dragonBones->bufferObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::init(ArmatureData *armatureData, IArmatureProxy* proxy, void* display, DragonBones* dragonBones)
|
||||
{
|
||||
if (_armatureData != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_armatureData = armatureData;
|
||||
_animation = BaseObject::borrowObject<Animation>();
|
||||
_proxy = proxy;
|
||||
_display = display;
|
||||
_dragonBones = dragonBones;
|
||||
|
||||
_proxy->dbInit(this);
|
||||
_animation->init(this);
|
||||
_animation->setAnimations(_armatureData->animations);
|
||||
}
|
||||
|
||||
void Armature::advanceTime(float passedTime)
|
||||
{
|
||||
if (_lockUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_armatureData == nullptr)
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "The armature has been disposed.");
|
||||
return;
|
||||
}
|
||||
else if(_armatureData->parent == nullptr)
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "The armature data has been disposed.\nPlease make sure dispose armature before call factory.clear().");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto prevCacheFrameIndex = _cacheFrameIndex;
|
||||
|
||||
// Update animation.
|
||||
_animation->advanceTime(passedTime);
|
||||
|
||||
// Sort slots.
|
||||
if (_slotsDirty)
|
||||
{
|
||||
_slotsDirty = false;
|
||||
std::sort(_slots.begin(), _slots.end(), Armature::_onSortSlots);
|
||||
}
|
||||
|
||||
// Update bones and slots.
|
||||
if (_cacheFrameIndex < 0 || _cacheFrameIndex != prevCacheFrameIndex)
|
||||
{
|
||||
for (const auto bone : _bones)
|
||||
{
|
||||
bone->update(_cacheFrameIndex);
|
||||
}
|
||||
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
slot->update(_cacheFrameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Do actions.
|
||||
if (!_actions.empty())
|
||||
{
|
||||
_lockUpdate = true;
|
||||
|
||||
for (const auto action : _actions)
|
||||
{
|
||||
const auto actionData = action->actionData;
|
||||
|
||||
if (actionData != nullptr)
|
||||
{
|
||||
if (actionData->type == ActionType::Play)
|
||||
{
|
||||
if (action->slot != nullptr)
|
||||
{
|
||||
const auto childArmature = action->slot->getChildArmature();
|
||||
if (childArmature != nullptr)
|
||||
{
|
||||
childArmature->getAnimation()->fadeIn(actionData->name);
|
||||
}
|
||||
}
|
||||
else if (action->bone != nullptr)
|
||||
{
|
||||
for (const auto slot : getSlots())
|
||||
{
|
||||
if (slot->getParent() == action->bone)
|
||||
{
|
||||
const auto childArmature = slot->getChildArmature();
|
||||
if (childArmature != nullptr)
|
||||
{
|
||||
childArmature->getAnimation()->fadeIn(actionData->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_animation->fadeIn(actionData->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action->returnToPool();
|
||||
}
|
||||
|
||||
_actions.clear();
|
||||
_lockUpdate = false;
|
||||
}
|
||||
|
||||
_proxy->dbUpdate();
|
||||
}
|
||||
|
||||
void Armature::render()
|
||||
{
|
||||
if (_proxy)
|
||||
{
|
||||
_proxy->dbRender();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Armature::getRenderOrder() const
|
||||
{
|
||||
if (_proxy)
|
||||
{
|
||||
return _proxy->getRenderOrder();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Armature::invalidUpdate(const std::string& boneName, bool updateSlot)
|
||||
{
|
||||
if (!boneName.empty())
|
||||
{
|
||||
const auto bone = getBone(boneName);
|
||||
if (bone != nullptr)
|
||||
{
|
||||
bone->invalidUpdate();
|
||||
|
||||
if (updateSlot)
|
||||
{
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
if (slot->getParent() == bone)
|
||||
{
|
||||
slot->invalidUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto bone : _bones)
|
||||
{
|
||||
bone->invalidUpdate();
|
||||
}
|
||||
|
||||
if (updateSlot)
|
||||
{
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
slot->invalidUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Slot* Armature::containsPoint(float x, float y) const
|
||||
{
|
||||
for(const auto slot : _slots)
|
||||
{
|
||||
if(slot->containsPoint(x,y)) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Slot* Armature::intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
) const
|
||||
{
|
||||
const auto isV = xA == xB;
|
||||
auto dMin = 0.0f;
|
||||
auto dMax = 0.0f;
|
||||
auto intXA = 0.0f;
|
||||
auto intYA = 0.0f;
|
||||
auto intXB = 0.0f;
|
||||
auto intYB = 0.0f;
|
||||
auto intAN = 0.0f;
|
||||
auto intBN = 0.0f;
|
||||
Slot* intSlotA = nullptr;
|
||||
Slot* intSlotB = nullptr;
|
||||
|
||||
for (const auto & slot : _slots)
|
||||
{
|
||||
auto intersectionCount = slot->intersectsSegment(xA, yA, xB, yB, intersectionPointA, intersectionPointB, normalRadians);
|
||||
if (intersectionCount > 0)
|
||||
{
|
||||
if (intersectionPointA != nullptr || intersectionPointB != nullptr)
|
||||
{
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
float d = isV ? intersectionPointA->y - yA : intersectionPointA->x - xA;
|
||||
if (d < 0.0f)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
|
||||
if (intSlotA == nullptr || d < dMin)
|
||||
{
|
||||
dMin = d;
|
||||
intXA = intersectionPointA->x;
|
||||
intYA = intersectionPointA->y;
|
||||
intSlotA = slot;
|
||||
|
||||
if (normalRadians) {
|
||||
intAN = normalRadians->x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
float d = intersectionPointB->x - xA;
|
||||
if (d < 0.0f)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
|
||||
if (intSlotB == nullptr || d > dMax)
|
||||
{
|
||||
dMax = d;
|
||||
intXB = intersectionPointB->x;
|
||||
intYB = intersectionPointB->y;
|
||||
intSlotB = slot;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
intBN = normalRadians->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
intSlotA = slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intSlotA != nullptr && intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = intXA;
|
||||
intersectionPointA->y = intYA;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = intAN;
|
||||
}
|
||||
}
|
||||
|
||||
if (intSlotB != nullptr && intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = intXB;
|
||||
intersectionPointB->y = intYB;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->y = intBN;
|
||||
}
|
||||
}
|
||||
|
||||
return intSlotA;
|
||||
}
|
||||
|
||||
Bone* Armature::getBone(const std::string& name) const
|
||||
{
|
||||
for (const auto& bone : _bones)
|
||||
{
|
||||
if (bone->getName() == name)
|
||||
{
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Bone* Armature::getBoneByDisplay(void* display) const
|
||||
{
|
||||
const auto slot = getSlotByDisplay(display);
|
||||
|
||||
return slot != nullptr ? slot->getParent() : nullptr;
|
||||
}
|
||||
|
||||
Slot* Armature::getSlot(const std::string& name) const
|
||||
{
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
if (slot->getName() == name)
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Slot* Armature::getSlotByDisplay(void* display) const
|
||||
{
|
||||
if (display != nullptr)
|
||||
{
|
||||
for (const auto slot : _slots)
|
||||
{
|
||||
if (slot->getDisplay() == display)
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Armature::setCacheFrameRate(unsigned value)
|
||||
{
|
||||
if (_armatureData->cacheFrameRate != value)
|
||||
{
|
||||
_armatureData->cacheFrames(value);
|
||||
|
||||
for (const auto & slot : _slots)
|
||||
{
|
||||
const auto childArmature = slot->getChildArmature();
|
||||
if (childArmature != nullptr && childArmature->getCacheFrameRate() == 0)
|
||||
{
|
||||
childArmature->setCacheFrameRate(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::setClock(WorldClock* value)
|
||||
{
|
||||
if(_clock == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_clock)
|
||||
{
|
||||
_clock->remove(this);
|
||||
}
|
||||
|
||||
_clock = value;
|
||||
|
||||
if(_clock)
|
||||
{
|
||||
_clock->add(this);
|
||||
}
|
||||
|
||||
// Update childArmature clock.
|
||||
for (const auto& slot : _slots)
|
||||
{
|
||||
const auto childArmature = slot->getChildArmature();
|
||||
if (childArmature != nullptr)
|
||||
{
|
||||
childArmature->setClock(_clock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::setReplacedTexture(void* value)
|
||||
{
|
||||
if (_replacedTexture == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_replaceTextureAtlasData != nullptr)
|
||||
{
|
||||
_replaceTextureAtlasData->returnToPool();
|
||||
_replaceTextureAtlasData = nullptr;
|
||||
}
|
||||
|
||||
_replacedTexture = value;
|
||||
|
||||
for (const auto &slot : _slots)
|
||||
{
|
||||
slot->invalidUpdate();
|
||||
slot->update(-1);
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
563
cocos2d-x/cocos/editor-support/dragonbones/armature/Armature.h
Normal file
563
cocos2d-x/cocos/editor-support/dragonbones/armature/Armature.h
Normal file
@@ -0,0 +1,563 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ARMATURE_H
|
||||
#define DRAGONBONES_ARMATURE_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../animation/IAnimatable.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
#include "IArmatureProxy.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - Armature is the core of the skeleton animation system.
|
||||
* @see dragonBones.ArmatureData
|
||||
* @see dragonBones.Bone
|
||||
* @see dragonBones.Slot
|
||||
* @see dragonBones.Animation
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架是骨骼动画系统的核心。
|
||||
* @see dragonBones.ArmatureData
|
||||
* @see dragonBones.Bone
|
||||
* @see dragonBones.Slot
|
||||
* @see dragonBones.Animation
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Armature : public virtual IAnimatable, public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(Armature);
|
||||
|
||||
private:
|
||||
static bool _onSortSlots(Slot* a, Slot* b);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Whether to inherit the animation control of the parent armature.
|
||||
* True to try to have the child armature play an animation with the same name when the parent armature play the animation.
|
||||
* @default true
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否继承父骨架的动画控制。
|
||||
* 如果该值为 true,当父骨架播放动画时,会尝试让子骨架播放同名动画。
|
||||
* @default true
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool inheritAnimation;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void* userData;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
int _cacheFrameIndex;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ArmatureData* _armatureData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
DragonBones* _dragonBones;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
Slot* _parent;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
TextureAtlasData* _replaceTextureAtlasData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
std::vector<Constraint*> _constraints;
|
||||
|
||||
protected:
|
||||
bool _debugDraw;
|
||||
bool _lockUpdate;
|
||||
bool _slotsDirty;
|
||||
bool _zOrderDirty;
|
||||
bool _flipX;
|
||||
bool _flipY;
|
||||
std::vector<Bone*> _bones;
|
||||
std::vector<Slot*> _slots;
|
||||
std::vector<EventObject*> _actions;
|
||||
Animation* _animation;
|
||||
IArmatureProxy* _proxy;
|
||||
void* _display;
|
||||
WorldClock* _clock;
|
||||
void* _replacedTexture;
|
||||
|
||||
public:
|
||||
Armature() :
|
||||
_animation(nullptr),
|
||||
_proxy(nullptr),
|
||||
_clock(nullptr),
|
||||
_replaceTextureAtlasData(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
virtual ~Armature()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
private:
|
||||
void _sortSlots();
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _sortZOrder(const int16_t* slotIndices, unsigned offset);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _addBone(Bone* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _addSlot(Slot* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _addConstraint(Constraint* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _bufferAction(EventObject* action, bool append);
|
||||
/**
|
||||
* - Dispose the armature. (Return to the object pool)
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* removeChild(armature.display);
|
||||
* armature.dispose();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 释放骨架。 (回收到对象池)
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* removeChild(armature.display);
|
||||
* armature.dispose();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void dispose();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void init(ArmatureData *armatureData, IArmatureProxy* proxy, void* display, DragonBones* dragonBones);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void advanceTime(float passedTime) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
void render() override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
uint32_t getRenderOrder() const override;
|
||||
/**
|
||||
* - Forces a specific bone or its owning slot to update the transform or display property in the next frame.
|
||||
* @param boneName - The bone name. (If not set, all bones will be update)
|
||||
* @param updateSlot - Whether to update the bone's slots. (Default: false)
|
||||
* @see dragonBones.Bone#invalidUpdate()
|
||||
* @see dragonBones.Slot#invalidUpdate()
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 强制特定骨骼或其拥有的插槽在下一帧更新变换或显示属性。
|
||||
* @param boneName - 骨骼名称。 (如果未设置,将更新所有骨骼)
|
||||
* @param updateSlot - 是否更新骨骼的插槽。 (默认: false)
|
||||
* @see dragonBones.Bone#invalidUpdate()
|
||||
* @see dragonBones.Slot#invalidUpdate()
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void invalidUpdate(const std::string& boneName = "", bool updateSlot = false);
|
||||
/**
|
||||
* - Check whether a specific point is inside a custom bounding box in a slot.
|
||||
* The coordinate system of the point is the inner coordinate system of the armature.
|
||||
* Custom bounding boxes need to be customized in Dragonbones Pro.
|
||||
* @param x - The horizontal coordinate of the point.
|
||||
* @param y - The vertical coordinate of the point.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查特定点是否在某个插槽的自定义边界框内。
|
||||
* 点的坐标系为骨架内坐标系。
|
||||
* 自定义边界框需要在 DragonBones Pro 中自定义。
|
||||
* @param x - 点的水平坐标。
|
||||
* @param y - 点的垂直坐标。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Slot* containsPoint(float x, float y) const;
|
||||
/**
|
||||
* - Check whether a specific segment intersects a custom bounding box for a slot in the armature.
|
||||
* The coordinate system of the segment and intersection is the inner coordinate system of the armature.
|
||||
* Custom bounding boxes need to be customized in Dragonbones Pro.
|
||||
* @param xA - The horizontal coordinate of the beginning of the segment.
|
||||
* @param yA - The vertical coordinate of the beginning of the segment.
|
||||
* @param xB - The horizontal coordinate of the end point of the segment.
|
||||
* @param yB - The vertical coordinate of the end point of the segment.
|
||||
* @param intersectionPointA - The first intersection at which a line segment intersects the bounding box from the beginning to the end. (If not set, the intersection point will not calculated)
|
||||
* @param intersectionPointB - The first intersection at which a line segment intersects the bounding box from the end to the beginning. (If not set, the intersection point will not calculated)
|
||||
* @param normalRadians - The normal radians of the tangent of the intersection boundary box. [x: Normal radian of the first intersection tangent, y: Normal radian of the second intersection tangent] (If not set, the normal will not calculated)
|
||||
* @returns The slot of the first custom bounding box where the segment intersects from the start point to the end point.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查特定线段是否与骨架的某个插槽的自定义边界框相交。
|
||||
* 线段和交点的坐标系均为骨架内坐标系。
|
||||
* 自定义边界框需要在 DragonBones Pro 中自定义。
|
||||
* @param xA - 线段起点的水平坐标。
|
||||
* @param yA - 线段起点的垂直坐标。
|
||||
* @param xB - 线段终点的水平坐标。
|
||||
* @param yB - 线段终点的垂直坐标。
|
||||
* @param intersectionPointA - 线段从起点到终点与边界框相交的第一个交点。 (如果未设置,则不计算交点)
|
||||
* @param intersectionPointB - 线段从终点到起点与边界框相交的第一个交点。 (如果未设置,则不计算交点)
|
||||
* @param normalRadians - 交点边界框切线的法线弧度。 [x: 第一个交点切线的法线弧度, y: 第二个交点切线的法线弧度] (如果未设置,则不计算法线)
|
||||
* @returns 线段从起点到终点相交的第一个自定义边界框的插槽。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Slot* intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
) const;
|
||||
/**
|
||||
* - Get a specific bone.
|
||||
* @param name - The bone name.
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的骨骼。
|
||||
* @param name - 骨骼名称。
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Bone* getBone(const std::string& name) const;
|
||||
/**
|
||||
* - Get a specific bone by the display.
|
||||
* @param display - The display object.
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 通过显示对象获取特定的骨骼。
|
||||
* @param display - 显示对象。
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Bone* getBoneByDisplay(void* display) const;
|
||||
/**
|
||||
* - Get a specific slot.
|
||||
* @param name - The slot name.
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的插槽。
|
||||
* @param name - 插槽名称。
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Slot* getSlot(const std::string& name) const;
|
||||
/**
|
||||
* - Get a specific slot by the display.
|
||||
* @param display - The display object.
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 通过显示对象获取特定的插槽。
|
||||
* @param display - 显示对象。
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Slot* getSlotByDisplay(void* display) const;
|
||||
/**
|
||||
* - Get all bones.
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取所有的骨骼。
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::vector<Bone*>& getBones() const
|
||||
{
|
||||
return _bones;
|
||||
}
|
||||
/**
|
||||
* - Get all slots.
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取所有的插槽。
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::vector<Slot*>& getSlots() const
|
||||
{
|
||||
return _slots;
|
||||
}
|
||||
/**
|
||||
* - Whether to flip the armature horizontally.
|
||||
* @version DragonBones 5.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否将骨架水平翻转。
|
||||
* @version DragonBones 5.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool getFlipX() const
|
||||
{
|
||||
return _flipX;
|
||||
}
|
||||
void setFlipX(bool value)
|
||||
{
|
||||
_flipX = value;
|
||||
invalidUpdate("");
|
||||
}
|
||||
|
||||
/**
|
||||
* - Whether to flip the armature vertically.
|
||||
* @version DragonBones 5.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 是否将骨架垂直翻转。
|
||||
* @version DragonBones 5.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool getFlipY() const
|
||||
{
|
||||
return _flipY;
|
||||
}
|
||||
void setFlipY(bool value)
|
||||
{
|
||||
_flipY = value;
|
||||
invalidUpdate("");
|
||||
}
|
||||
/**
|
||||
* - The animation cache frame rate, which turns on the animation cache when the set value is greater than 0.
|
||||
* There is a certain amount of memory overhead to improve performance by caching animation data in memory.
|
||||
* The frame rate should not be set too high, usually with the frame rate of the animation is similar and lower than the program running frame rate.
|
||||
* When the animation cache is turned on, some features will fail, such as the offset property of bone.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* armature.cacheFrameRate = 24;
|
||||
* </pre>
|
||||
* @see dragonBones.DragonBonesData#frameRate
|
||||
* @see dragonBones.ArmatureData#frameRate
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画缓存帧率,当设置的值大于 0 的时,将会开启动画缓存。
|
||||
* 通过将动画数据缓存在内存中来提高运行性能,会有一定的内存开销。
|
||||
* 帧率不宜设置的过高,通常跟动画的帧率相当且低于程序运行的帧率。
|
||||
* 开启动画缓存后,某些功能将会失效,比如骨骼的 offset 属性等。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* armature.cacheFrameRate = 24;
|
||||
* </pre>
|
||||
* @see dragonBones.DragonBonesData#frameRate
|
||||
* @see dragonBones.ArmatureData#frameRate
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline unsigned getCacheFrameRate() const
|
||||
{
|
||||
return _armatureData->cacheFrameRate;
|
||||
}
|
||||
void setCacheFrameRate(unsigned value);
|
||||
/**
|
||||
* - The armature name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::string& getName() const
|
||||
{
|
||||
return _armatureData->name;
|
||||
}
|
||||
/**
|
||||
* - The armature data.
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架数据。
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const ArmatureData* getArmatureData() const
|
||||
{
|
||||
return _armatureData;
|
||||
}
|
||||
/**
|
||||
* - The animation player.
|
||||
* @see dragonBones.Animation
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画播放器。
|
||||
* @see dragonBones.Animation
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Animation* getAnimation() const
|
||||
{
|
||||
return _animation;
|
||||
}
|
||||
/**
|
||||
* @pivate
|
||||
*/
|
||||
inline IArmatureProxy* getProxy() const
|
||||
{
|
||||
return _proxy;
|
||||
}
|
||||
/**
|
||||
* - The EventDispatcher instance of the armature.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 该骨架的 EventDispatcher 实例。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline IEventDispatcher* getEventDispatcher() const
|
||||
{
|
||||
return _proxy;
|
||||
}
|
||||
/**
|
||||
* - The display container.
|
||||
* The display of the slot is displayed as the parent.
|
||||
* Depending on the rendering engine, the type will be different, usually the DisplayObjectContainer type.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 显示容器实例。
|
||||
* 插槽的显示对象都会以此显示容器为父级。
|
||||
* 根据渲染引擎的不同,类型会不同,通常是 DisplayObjectContainer 类型。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void* getDisplay() const
|
||||
{
|
||||
return _display;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline void* getReplacedTexture() const
|
||||
{
|
||||
return _replacedTexture;
|
||||
}
|
||||
void setReplacedTexture(void* value);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
inline WorldClock* getClock() const override
|
||||
{
|
||||
return _clock;
|
||||
}
|
||||
void setClock(WorldClock* value) override;
|
||||
/**
|
||||
* - Get the parent slot which the armature belongs to.
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 该骨架所属的父插槽。
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Slot* getParent() const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
IAnimatable* getAnimatable() const { return (IAnimatable*)this; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ARMATURE_H
|
||||
432
cocos2d-x/cocos/editor-support/dragonbones/armature/Bone.cpp
Normal file
432
cocos2d-x/cocos/editor-support/dragonbones/armature/Bone.cpp
Normal file
@@ -0,0 +1,432 @@
|
||||
#include "Bone.h"
|
||||
#include "../geom/Matrix.h"
|
||||
#include "../geom/Transform.h"
|
||||
#include "Armature.h"
|
||||
#include "Slot.h"
|
||||
#include "Constraint.h"
|
||||
#include "../animation/AnimationState.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void Bone::_onClear()
|
||||
{
|
||||
TransformObject::_onClear();
|
||||
|
||||
offsetMode = OffsetMode::Additive;
|
||||
animationPose.identity();
|
||||
|
||||
_transformDirty = false;
|
||||
_childrenTransformDirty = false;
|
||||
_localDirty = true;
|
||||
_hasConstraint = false;
|
||||
_visible = true;
|
||||
_cachedFrameIndex = -1;
|
||||
_blendState.clear();
|
||||
_boneData = nullptr;
|
||||
_parent = nullptr;
|
||||
_cachedFrameIndices = nullptr;
|
||||
}
|
||||
|
||||
void Bone::_updateGlobalTransformMatrix(bool isCache)
|
||||
{
|
||||
const auto flipX = _armature->getFlipX();
|
||||
const auto flipY = _armature->getFlipY() == DragonBones::yDown;
|
||||
auto inherit = _parent != nullptr;
|
||||
auto rotation = 0.0f;
|
||||
|
||||
if (offsetMode == OffsetMode::Additive)
|
||||
{
|
||||
if (origin != nullptr)
|
||||
{
|
||||
// global = *origin; // Copy.
|
||||
// global.add(offset).add(animationPose);
|
||||
global.x = origin->x + offset.x + animationPose.x;
|
||||
global.scaleX = origin->scaleX * offset.scaleX * animationPose.scaleX;
|
||||
global.scaleY = origin->scaleY * offset.scaleY * animationPose.scaleY;
|
||||
if (DragonBones::yDown)
|
||||
{
|
||||
global.y = origin->y + offset.y + animationPose.y;
|
||||
global.skew = origin->skew + offset.skew + animationPose.skew;
|
||||
global.rotation = origin->rotation + offset.rotation + animationPose.rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
global.y = origin->y - offset.y + animationPose.y;
|
||||
global.skew = origin->skew - offset.skew + animationPose.skew;
|
||||
global.rotation = origin->rotation - offset.rotation + animationPose.rotation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
global = offset; // Copy.
|
||||
if (!DragonBones::yDown)
|
||||
{
|
||||
global.y = -global.y;
|
||||
global.skew = -global.skew;
|
||||
global.rotation = -global.rotation;
|
||||
}
|
||||
global.add(animationPose);
|
||||
}
|
||||
}
|
||||
else if (offsetMode == OffsetMode::None)
|
||||
{
|
||||
if (origin != nullptr)
|
||||
{
|
||||
global = *origin;
|
||||
global.add(animationPose);
|
||||
}
|
||||
else
|
||||
{
|
||||
global = animationPose;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inherit = false;
|
||||
global = offset;
|
||||
if (!DragonBones::yDown)
|
||||
{
|
||||
global.y = -global.y;
|
||||
global.skew = -global.skew;
|
||||
global.rotation = -global.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
if (inherit)
|
||||
{
|
||||
const auto& parentMatrix = _parent->globalTransformMatrix;
|
||||
if (_boneData->inheritScale)
|
||||
{
|
||||
if (!_boneData->inheritRotation)
|
||||
{
|
||||
_parent->updateGlobalTransform();
|
||||
|
||||
if (flipX && flipY)
|
||||
{
|
||||
rotation = global.rotation - (_parent->global.rotation + Transform::PI);
|
||||
}
|
||||
else if (flipX)
|
||||
{
|
||||
rotation = global.rotation + _parent->global.rotation + Transform::PI;
|
||||
}
|
||||
else if (flipY)
|
||||
{
|
||||
rotation = global.rotation + _parent->global.rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation = global.rotation - _parent->global.rotation;
|
||||
}
|
||||
|
||||
global.rotation = rotation;
|
||||
}
|
||||
|
||||
global.toMatrix(globalTransformMatrix);
|
||||
globalTransformMatrix.concat(parentMatrix);
|
||||
|
||||
if (_boneData->inheritTranslation)
|
||||
{
|
||||
global.x = globalTransformMatrix.tx;
|
||||
global.y = globalTransformMatrix.ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
globalTransformMatrix.tx = global.x;
|
||||
globalTransformMatrix.ty = global.y;
|
||||
}
|
||||
|
||||
if (isCache)
|
||||
{
|
||||
global.fromMatrix(globalTransformMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
_globalDirty = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_boneData->inheritTranslation)
|
||||
{
|
||||
const auto x = global.x;
|
||||
const auto y = global.y;
|
||||
global.x = parentMatrix.a * x + parentMatrix.c * y + parentMatrix.tx;
|
||||
global.y = parentMatrix.b * x + parentMatrix.d * y + parentMatrix.ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flipX)
|
||||
{
|
||||
global.x = -global.x;
|
||||
}
|
||||
|
||||
if (flipY)
|
||||
{
|
||||
global.y = -global.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (_boneData->inheritRotation)
|
||||
{
|
||||
_parent->updateGlobalTransform();
|
||||
|
||||
if (_parent->global.scaleX < 0.0f)
|
||||
{
|
||||
rotation = global.rotation + _parent->global.rotation + Transform::PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation = global.rotation + _parent->global.rotation;
|
||||
}
|
||||
|
||||
if (parentMatrix.a * parentMatrix.d - parentMatrix.b * parentMatrix.c < 0.0f)
|
||||
{
|
||||
rotation -= global.rotation * 2.0f;
|
||||
|
||||
if (flipX != flipY || _boneData->inheritReflection)
|
||||
{
|
||||
global.skew += Transform::PI;
|
||||
}
|
||||
|
||||
if (!DragonBones::yDown)
|
||||
{
|
||||
global.skew = -global.skew;
|
||||
}
|
||||
}
|
||||
|
||||
global.rotation = rotation;
|
||||
}
|
||||
else if (flipX || flipY)
|
||||
{
|
||||
if (flipX && flipY)
|
||||
{
|
||||
rotation = global.rotation + Transform::PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flipX)
|
||||
{
|
||||
rotation = Transform::PI - global.rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation = -global.rotation;
|
||||
}
|
||||
|
||||
global.skew += Transform::PI;
|
||||
}
|
||||
|
||||
global.rotation = rotation;
|
||||
}
|
||||
|
||||
global.toMatrix(globalTransformMatrix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flipX || flipY)
|
||||
{
|
||||
if (flipX)
|
||||
{
|
||||
global.x = -global.x;
|
||||
}
|
||||
|
||||
if (flipY)
|
||||
{
|
||||
global.y = -global.y;
|
||||
}
|
||||
|
||||
if (flipX && flipY)
|
||||
{
|
||||
rotation = global.rotation + Transform::PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flipX)
|
||||
{
|
||||
rotation = Transform::PI - global.rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation = -global.rotation;
|
||||
}
|
||||
|
||||
global.skew += Transform::PI;
|
||||
}
|
||||
|
||||
global.rotation = rotation;
|
||||
}
|
||||
|
||||
global.toMatrix(globalTransformMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::init(const BoneData* boneData, Armature* armatureValue)
|
||||
{
|
||||
if (_boneData != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_boneData = boneData;
|
||||
_armature = armatureValue;
|
||||
|
||||
if (_boneData->parent != nullptr)
|
||||
{
|
||||
_parent = _armature->getBone(_boneData->parent->name);
|
||||
}
|
||||
|
||||
_armature->_addBone(this);
|
||||
//
|
||||
origin = &(_boneData->transform);
|
||||
}
|
||||
|
||||
void Bone::update(int cacheFrameIndex)
|
||||
{
|
||||
_blendState.dirty = false;
|
||||
|
||||
if (cacheFrameIndex >= 0 && _cachedFrameIndices != nullptr)
|
||||
{
|
||||
const auto cachedFrameIndex = (*_cachedFrameIndices)[cacheFrameIndex];
|
||||
if (cachedFrameIndex >= 0 && _cachedFrameIndex == cachedFrameIndex) // Same cache.
|
||||
{
|
||||
_transformDirty = false;
|
||||
}
|
||||
else if (cachedFrameIndex >= 0) // Has been Cached.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = cachedFrameIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_hasConstraint) // Update constraints.
|
||||
{
|
||||
for (const auto constraint : _armature->_constraints)
|
||||
{
|
||||
if (constraint->_root == this)
|
||||
{
|
||||
constraint->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( _transformDirty || (_parent != nullptr && _parent->_childrenTransformDirty)) // Dirty.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
else if (_cachedFrameIndex >= 0) // Same cache, but not set index yet.
|
||||
{
|
||||
_transformDirty = false;
|
||||
(*_cachedFrameIndices)[cacheFrameIndex] = _cachedFrameIndex;
|
||||
}
|
||||
else // Dirty.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_hasConstraint) // Update constraints.
|
||||
{
|
||||
for (const auto constraint : _armature->_constraints)
|
||||
{
|
||||
if (constraint->_root == this)
|
||||
{
|
||||
constraint->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( _transformDirty || (_parent != nullptr && _parent->_childrenTransformDirty)) // Dirty.
|
||||
{
|
||||
cacheFrameIndex = -1;
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_transformDirty)
|
||||
{
|
||||
_transformDirty = false;
|
||||
_childrenTransformDirty = true;
|
||||
//
|
||||
if (_cachedFrameIndex < 0)
|
||||
{
|
||||
const auto isCache = cacheFrameIndex >= 0;
|
||||
if (_localDirty)
|
||||
{
|
||||
_updateGlobalTransformMatrix(isCache);
|
||||
}
|
||||
|
||||
if (isCache && _cachedFrameIndices != nullptr)
|
||||
{
|
||||
_cachedFrameIndex = (*_cachedFrameIndices)[cacheFrameIndex] = _armature->_armatureData->setCacheFrame(globalTransformMatrix, global);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_armature->_armatureData->getCacheFrame(globalTransformMatrix, global, _cachedFrameIndex);
|
||||
}
|
||||
//
|
||||
}
|
||||
else if (_childrenTransformDirty)
|
||||
{
|
||||
_childrenTransformDirty = false;
|
||||
}
|
||||
|
||||
_localDirty = true;
|
||||
}
|
||||
|
||||
void Bone::updateByConstraint()
|
||||
{
|
||||
if (_localDirty)
|
||||
{
|
||||
_localDirty = false;
|
||||
|
||||
if (_transformDirty || (_parent != nullptr && _parent->_childrenTransformDirty))
|
||||
{
|
||||
_updateGlobalTransformMatrix(true);
|
||||
}
|
||||
|
||||
_transformDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Bone::contains(const Bone* value) const
|
||||
{
|
||||
if (value == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ancestor = value;
|
||||
while (ancestor != this && ancestor != nullptr)
|
||||
{
|
||||
ancestor = ancestor->getParent();
|
||||
}
|
||||
|
||||
return ancestor == this;
|
||||
}
|
||||
|
||||
void Bone::setVisible(bool value)
|
||||
{
|
||||
if (_visible == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_visible = value;
|
||||
|
||||
for (const auto & slot : _armature->getSlots())
|
||||
{
|
||||
if (slot->getParent() == this)
|
||||
{
|
||||
slot->_updateVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
235
cocos2d-x/cocos/editor-support/dragonbones/armature/Bone.h
Normal file
235
cocos2d-x/cocos/editor-support/dragonbones/armature/Bone.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_BONE_H
|
||||
#define DRAGONBONES_BONE_H
|
||||
|
||||
#include "TransformObject.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
#include "../animation/AnimationState.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - Bone is one of the most important logical units in the armature animation system,
|
||||
* and is responsible for the realization of translate, rotation, scaling in the animations.
|
||||
* A armature can contain multiple bones.
|
||||
* @see dragonBones.BoneData
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼在骨骼动画体系中是最重要的逻辑单元之一,负责动画中的平移、旋转、缩放的实现。
|
||||
* 一个骨架中可以包含多个骨骼。
|
||||
* @see dragonBones.BoneData
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Bone final : public TransformObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(Bone);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The offset mode.
|
||||
* @see #offset
|
||||
* @version DragonBones 5.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 偏移模式。
|
||||
* @see #offset
|
||||
* @version DragonBones 5.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
OffsetMode offsetMode;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
Transform animationPose;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _transformDirty;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _childrenTransformDirty;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _hasConstraint;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
BlendState _blendState;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const BoneData* _boneData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
std::vector<int>* _cachedFrameIndices;
|
||||
|
||||
protected:
|
||||
bool _localDirty;
|
||||
bool _visible;
|
||||
int _cachedFrameIndex;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Bone* _parent;
|
||||
|
||||
protected:
|
||||
void _onClear() override;
|
||||
void _updateGlobalTransformMatrix(bool isCache);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void init(const BoneData* boneData, Armature* armatureValue);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void update(int cacheFrameIndex);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void updateByConstraint();
|
||||
/**
|
||||
* - Forces the bone to update the transform in the next frame.
|
||||
* When the bone is not animated or its animation state is finished, the bone will not continue to update,
|
||||
* and when the skeleton must be updated for some reason, the method needs to be called explicitly.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let bone = armature.getBone("arm");
|
||||
* bone.offset.scaleX = 2.0;
|
||||
* bone.invalidUpdate();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 强制骨骼在下一帧更新变换。
|
||||
* 当该骨骼没有动画状态或其动画状态播放完成时,骨骼将不在继续更新,而此时由于某些原因必须更新骨骼时,则需要显式调用该方法。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let bone = armature.getBone("arm");
|
||||
* bone.offset.scaleX = 2.0;
|
||||
* bone.invalidUpdate();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void invalidUpdate()
|
||||
{
|
||||
_transformDirty = true;
|
||||
}
|
||||
/**
|
||||
* - Check whether the bone contains a specific bone.
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查该骨骼是否包含特定的骨骼。
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool contains(const Bone* value) const;
|
||||
/**
|
||||
* - The bone data.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼数据。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const BoneData* getBoneData() const
|
||||
{
|
||||
return _boneData;
|
||||
}
|
||||
/**
|
||||
* - The visible of all slots in the bone.
|
||||
* @default true
|
||||
* @see dragonBones.Slot#visible
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 此骨骼所有插槽的可见。
|
||||
* @default true
|
||||
* @see dragonBones.Slot#visible
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool getVisible() const
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
void setVisible(bool value);
|
||||
/**
|
||||
* - The bone name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::string& getName() const
|
||||
{
|
||||
return _boneData->name;
|
||||
}
|
||||
/**
|
||||
* - The parent bone to which it belongs.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所属的父骨骼。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Bone* getParent() const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
inline int getOffsetMode() const { return (int)offsetMode; }
|
||||
inline void setOffsetMode(int value) { offsetMode = (OffsetMode)value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_BONE_H
|
||||
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Created by liangshuochen on 12/06/2017.
|
||||
//
|
||||
|
||||
#include "Constraint.h"
|
||||
#include "Armature.h"
|
||||
#include "Bone.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
Matrix Constraint::_helpMatrix;
|
||||
Transform Constraint::_helpTransform;
|
||||
Point Constraint::_helpPoint;
|
||||
|
||||
void Constraint::_onClear()
|
||||
{
|
||||
_constraintData = nullptr;
|
||||
_armature = nullptr;
|
||||
_target = nullptr;
|
||||
_root = nullptr;
|
||||
_bone = nullptr;
|
||||
}
|
||||
|
||||
void IKConstraint::_onClear()
|
||||
{
|
||||
Constraint::_onClear();
|
||||
|
||||
_scaleEnabled = false;
|
||||
_bendPositive = false;
|
||||
_weight = 1.0f;
|
||||
}
|
||||
|
||||
void IKConstraint::_computeA()
|
||||
{
|
||||
const auto& ikGlobal = _target->global;
|
||||
auto& global = _root->global;
|
||||
auto& globalTransformMatrix = _root->globalTransformMatrix;
|
||||
|
||||
auto radian = std::atan2(ikGlobal.y - global.y, ikGlobal.x - global.x);
|
||||
if (global.scaleX < 0.0f)
|
||||
{
|
||||
radian += Transform::PI;
|
||||
}
|
||||
|
||||
global.rotation += Transform::normalizeRadian(radian - global.rotation) * _weight;
|
||||
global.toMatrix(globalTransformMatrix);
|
||||
}
|
||||
|
||||
void IKConstraint::_computeB()
|
||||
{
|
||||
const auto boneLength = _bone->_boneData->length;
|
||||
const auto parent = _root;
|
||||
const auto& ikGlobal = _target->global;
|
||||
auto& parentGlobal = parent->global;
|
||||
auto& global = _bone->global;
|
||||
auto& globalTransformMatrix = _bone->globalTransformMatrix;
|
||||
|
||||
const auto x = globalTransformMatrix.a * boneLength;
|
||||
const auto y = globalTransformMatrix.b * boneLength;
|
||||
const auto lLL = x * x + y * y;
|
||||
const auto lL = sqrt(lLL);
|
||||
auto dX = global.x - parentGlobal.x;
|
||||
auto dY = global.y - parentGlobal.y;
|
||||
const auto lPP = dX * dX + dY * dY;
|
||||
const auto lP = sqrt(lPP);
|
||||
const auto rawRadian = global.rotation;
|
||||
const auto rawParentRadian = parentGlobal.rotation;
|
||||
const auto rawRadianA = std::atan2(dY, dX);
|
||||
|
||||
dX = ikGlobal.x - parentGlobal.x;
|
||||
dY = ikGlobal.y - parentGlobal.y;
|
||||
const auto lTT = dX * dX + dY * dY;
|
||||
const auto lT = sqrt(lTT);
|
||||
|
||||
auto radianA = 0.0f;
|
||||
if (lL + lP <= lT || lT + lL <= lP || lT + lP <= lL)
|
||||
{
|
||||
radianA = std::atan2(ikGlobal.y - parentGlobal.y, ikGlobal.x - parentGlobal.x);
|
||||
if (lL + lP <= lT)
|
||||
{
|
||||
}
|
||||
else if (lP < lL)
|
||||
{
|
||||
radianA += Transform::PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto h = (lPP - lLL + lTT) / (2.0f * lTT);
|
||||
const auto r = sqrt(lPP - h * h * lTT) / lT;
|
||||
const auto hX = parentGlobal.x + (dX * h);
|
||||
const auto hY = parentGlobal.y + (dY * h);
|
||||
const auto rX = -dY * r;
|
||||
const auto rY = dX * r;
|
||||
|
||||
auto isPPR = false;
|
||||
const auto parentParent = parent->getParent();
|
||||
if (parentParent != nullptr)
|
||||
{
|
||||
auto parentParentMatrix = parentParent->globalTransformMatrix;
|
||||
isPPR = parentParentMatrix.a * parentParentMatrix.d - parentParentMatrix.b * parentParentMatrix.c < 0.0f;
|
||||
}
|
||||
|
||||
if (isPPR != _bendPositive)
|
||||
{
|
||||
global.x = hX - rX;
|
||||
global.y = hY - rY;
|
||||
}
|
||||
else
|
||||
{
|
||||
global.x = hX + rX;
|
||||
global.y = hY + rY;
|
||||
}
|
||||
|
||||
radianA = std::atan2(global.y - parentGlobal.y, global.x - parentGlobal.x);
|
||||
}
|
||||
|
||||
const auto dR = Transform::normalizeRadian(radianA - rawRadianA);
|
||||
parentGlobal.rotation = rawParentRadian + dR * _weight;
|
||||
parentGlobal.toMatrix(parent->globalTransformMatrix);
|
||||
//
|
||||
const auto currentRadianA = rawRadianA + dR * _weight;
|
||||
global.x = parentGlobal.x + cos(currentRadianA) * lP;
|
||||
global.y = parentGlobal.y + sin(currentRadianA) * lP;
|
||||
//
|
||||
auto radianB = std::atan2(ikGlobal.y - global.y, ikGlobal.x - global.x);
|
||||
if (global.scaleX < 0.0f) {
|
||||
radianB += Transform::PI;
|
||||
}
|
||||
|
||||
global.rotation = parentGlobal.rotation + rawRadian - rawParentRadian + Transform::normalizeRadian(radianB - dR - rawRadian) * _weight;
|
||||
global.toMatrix(globalTransformMatrix);
|
||||
}
|
||||
|
||||
void IKConstraint::init(ConstraintData* constraintData, Armature* armature)
|
||||
{
|
||||
if (_constraintData != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_constraintData = constraintData;
|
||||
_armature = armature;
|
||||
_target = _armature->getBone(_constraintData->target->name);
|
||||
_root = _armature->getBone(_constraintData->root->name);
|
||||
_bone = _constraintData->bone != nullptr ? _armature->getBone(_constraintData->bone->name) : nullptr;
|
||||
|
||||
{
|
||||
const auto ikConstraintData = static_cast<IKConstraintData*>(_constraintData);
|
||||
_bendPositive = ikConstraintData->bendPositive;
|
||||
_scaleEnabled = ikConstraintData->scaleEnabled;
|
||||
_weight = ikConstraintData->weight;
|
||||
}
|
||||
|
||||
_root->_hasConstraint = true;
|
||||
}
|
||||
|
||||
void IKConstraint::update()
|
||||
{
|
||||
_root->updateByConstraint();
|
||||
|
||||
if (_bone != nullptr)
|
||||
{
|
||||
_bone->updateByConstraint();
|
||||
_computeB();
|
||||
}
|
||||
else
|
||||
{
|
||||
_computeA();
|
||||
}
|
||||
}
|
||||
|
||||
void IKConstraint::invalidUpdate()
|
||||
{
|
||||
_root->invalidUpdate();
|
||||
|
||||
if (_bone != nullptr)
|
||||
{
|
||||
_bone->invalidUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
119
cocos2d-x/cocos/editor-support/dragonbones/armature/Constraint.h
Normal file
119
cocos2d-x/cocos/editor-support/dragonbones/armature/Constraint.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
//
|
||||
// Created by liangshuochen on 12/06/2017.
|
||||
//
|
||||
|
||||
#ifndef DRAGONBONESCPP_CONSTRAINTS_H
|
||||
#define DRAGONBONESCPP_CONSTRAINTS_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Matrix.h"
|
||||
#include "../geom/Transform.h"
|
||||
#include "../geom/Point.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
#include "../model/ConstraintData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Constraint : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(Constraint)
|
||||
|
||||
protected:
|
||||
static Matrix _helpMatrix;
|
||||
static Transform _helpTransform;
|
||||
static Point _helpPoint;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - For timeline state.
|
||||
* @internal
|
||||
*/
|
||||
ConstraintData* _constraintData;
|
||||
/**
|
||||
* - For sort bones.
|
||||
* @internal
|
||||
*/
|
||||
Bone* _target;
|
||||
/**
|
||||
* - For sort bones.
|
||||
* @internal
|
||||
*/
|
||||
Bone* _root;
|
||||
|
||||
protected:
|
||||
Armature* _armature;
|
||||
Bone* _bone;
|
||||
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
virtual void init(ConstraintData* constraintData, Armature* armature) = 0;
|
||||
virtual void update() = 0;
|
||||
virtual void invalidUpdate() = 0;
|
||||
|
||||
inline const std::string& getName()
|
||||
{
|
||||
return _constraintData->name;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class IKConstraint : public Constraint
|
||||
{
|
||||
BIND_CLASS_TYPE_A(IKConstraint);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - For timeline state.
|
||||
* @internal
|
||||
*/
|
||||
bool _bendPositive;
|
||||
/**
|
||||
* - For timeline state.
|
||||
* @internal
|
||||
*/
|
||||
float _weight;
|
||||
|
||||
private:
|
||||
bool _scaleEnabled;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
private:
|
||||
void _computeA();
|
||||
void _computeB();
|
||||
|
||||
public:
|
||||
virtual void init(ConstraintData* constraintData, Armature* armature) override;
|
||||
virtual void update() override;
|
||||
virtual void invalidUpdate() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif //DRAGONBONESCPP_CONSTRAINTS_H
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "DeformVertices.h"
|
||||
#include "../model/DragonBonesData.h"
|
||||
#include "../model/DisplayData.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void DeformVertices::_onClear()
|
||||
{
|
||||
verticesDirty = false;
|
||||
vertices.clear();
|
||||
bones.clear();
|
||||
verticesData = nullptr;
|
||||
}
|
||||
|
||||
void DeformVertices::init(const VerticesData* verticesDataValue, Armature* armature)
|
||||
{
|
||||
verticesData = verticesDataValue;
|
||||
|
||||
if (verticesData != nullptr)
|
||||
{
|
||||
unsigned vertexCount = 0;
|
||||
if (verticesData->weight != nullptr)
|
||||
{
|
||||
vertexCount = verticesData->weight->count * 2;
|
||||
}
|
||||
else {
|
||||
vertexCount = verticesData->data->intArray[verticesData->offset + (unsigned)BinaryOffset::MeshVertexCount] * 2;
|
||||
}
|
||||
|
||||
verticesDirty = true;
|
||||
vertices.resize(vertexCount);
|
||||
bones.clear();
|
||||
//
|
||||
for (std::size_t i = 0, l = vertices.size(); i < l; ++i)
|
||||
{
|
||||
vertices[i] = 0.0f;
|
||||
}
|
||||
|
||||
if (verticesData->weight != nullptr)
|
||||
{
|
||||
for (std::size_t i = 0, l = verticesData->weight->bones.size(); i < l; ++i)
|
||||
{
|
||||
const auto bone = armature->getBone(verticesData->weight->bones[i]->name);
|
||||
if (bone != nullptr)
|
||||
{
|
||||
bones.push_back(bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
verticesDirty = false;
|
||||
vertices.clear();
|
||||
bones.clear();
|
||||
verticesData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeformVertices::isBonesUpdate() const
|
||||
{
|
||||
for (const auto bone : bones)
|
||||
{
|
||||
if (bone != nullptr && bone->_childrenTransformDirty)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_DEFORMVERTICES_H
|
||||
#define DRAGONBONES_DEFORMVERTICES_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class DeformVertices : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(DeformVertices);
|
||||
|
||||
public:
|
||||
bool verticesDirty;
|
||||
std::vector<float> vertices;
|
||||
std::vector<Bone*> bones;
|
||||
const VerticesData* verticesData;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
void init(const VerticesData* weightData, Armature* armature);
|
||||
bool isBonesUpdate() const;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_DEFORMVERTICES_H
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_IARMATURE_PROXY_H
|
||||
#define DRAGONBONES_IARMATURE_PROXY_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
#include "../event/IEventDispatcher.h"
|
||||
#include "MiddlewareManager.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The armature proxy interface, the docking engine needs to implement it concretely.
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架代理接口,对接的引擎需要对其进行具体实现。
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class IArmatureProxy : public IEventDispatcher
|
||||
{
|
||||
ABSTRACT_CLASS(IArmatureProxy);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void dbInit(Armature* armature) = 0;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void dbClear() = 0;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void dbUpdate() = 0;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void dbRender() = 0;
|
||||
/**
|
||||
* - Dispose the instance and the Armature instance. (The Armature instance will return to the object pool)
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* removeChild(armatureDisplay);
|
||||
* armatureDisplay.dispose();
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 释放该实例和骨架。 (骨架会回收到对象池)
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* removeChild(armatureDisplay);
|
||||
* armatureDisplay.dispose();
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void dispose(bool disposeProxy) = 0;
|
||||
/**
|
||||
* - The armature.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual Armature* getArmature() const = 0;
|
||||
/**
|
||||
* - The animation player.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画播放器。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual Animation* getAnimation() const = 0;
|
||||
|
||||
/**
|
||||
* - Gets render order
|
||||
* @version Cocos Creator 2.3
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获得渲染顺序。
|
||||
* @version Cocos Creator 2.3
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual uint32_t getRenderOrder() const = 0;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_IARMATURE_PROXY_H
|
||||
919
cocos2d-x/cocos/editor-support/dragonbones/armature/Slot.cpp
Normal file
919
cocos2d-x/cocos/editor-support/dragonbones/armature/Slot.cpp
Normal file
@@ -0,0 +1,919 @@
|
||||
#include "Slot.h"
|
||||
#include "../model/DragonBonesData.h"
|
||||
#include "../model/UserData.h"
|
||||
#include "../model/SkinData.h"
|
||||
#include "../model/DisplayData.h"
|
||||
#include "../model/BoundingBoxData.h"
|
||||
#include "../model/TextureAtlasData.h"
|
||||
#include "Armature.h"
|
||||
#include "Bone.h"
|
||||
#include "DeformVertices.h"
|
||||
#include "../animation/Animation.h"
|
||||
#include "../event/EventObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void Slot::_onClear()
|
||||
{
|
||||
TransformObject::_onClear();
|
||||
|
||||
std::vector<std::pair<void*, DisplayType>> disposeDisplayList;
|
||||
for (const auto& pair : this->_displayList)
|
||||
{
|
||||
if (
|
||||
pair.first != nullptr && pair.first != _rawDisplay && pair.first != _meshDisplay &&
|
||||
std::find(disposeDisplayList.cbegin(), disposeDisplayList.cend(), pair) == disposeDisplayList.cend()
|
||||
)
|
||||
{
|
||||
disposeDisplayList.push_back(pair);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : disposeDisplayList)
|
||||
{
|
||||
if (pair.second == DisplayType::Armature)
|
||||
{
|
||||
static_cast<Armature*>(pair.first)->returnToPool();
|
||||
}
|
||||
else
|
||||
{
|
||||
_disposeDisplay(pair.first, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (_deformVertices != nullptr)
|
||||
{
|
||||
_deformVertices->returnToPool();
|
||||
}
|
||||
|
||||
if (_meshDisplay && _meshDisplay != _rawDisplay)
|
||||
{
|
||||
_disposeDisplay(_meshDisplay, false);
|
||||
}
|
||||
|
||||
if (_rawDisplay) {
|
||||
_disposeDisplay(_rawDisplay, false);
|
||||
}
|
||||
|
||||
displayController = "";
|
||||
|
||||
_displayDirty = false;
|
||||
_zOrderDirty = false;
|
||||
_blendModeDirty = false;
|
||||
_colorDirty = false;
|
||||
_transformDirty = false;
|
||||
_visible = true;
|
||||
_blendMode = BlendMode::Normal;
|
||||
_displayIndex = -1;
|
||||
_animationDisplayIndex = -1;
|
||||
_zOrder = 0;
|
||||
_cachedFrameIndex = -1;
|
||||
_pivotX = 0.0f;
|
||||
_pivotY = 0.0f;
|
||||
_localMatrix.identity();
|
||||
_colorTransform.identity();
|
||||
_displayList.clear();
|
||||
_displayDatas.clear();
|
||||
_slotData = nullptr;
|
||||
_rawDisplayDatas = nullptr; //
|
||||
_displayData = nullptr;
|
||||
_boundingBoxData = nullptr;
|
||||
_textureData = nullptr;
|
||||
_deformVertices = nullptr;
|
||||
_rawDisplay = nullptr;
|
||||
_meshDisplay = nullptr;
|
||||
_display = nullptr;
|
||||
_childArmature = nullptr;
|
||||
_parent = nullptr;
|
||||
_cachedFrameIndices = nullptr;
|
||||
}
|
||||
|
||||
DisplayData* Slot::_getDefaultRawDisplayData(unsigned displayIndex) const
|
||||
{
|
||||
const auto defaultSkin = _armature->_armatureData->defaultSkin;
|
||||
if (defaultSkin != nullptr)
|
||||
{
|
||||
const auto defaultRawDisplayDatas = defaultSkin->getDisplays(_slotData->name);
|
||||
if (defaultRawDisplayDatas != nullptr)
|
||||
{
|
||||
return displayIndex < defaultRawDisplayDatas->size() ? (*defaultRawDisplayDatas)[displayIndex] : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Slot::_updateDisplayData()
|
||||
{
|
||||
const auto prevDisplayData = _displayData;
|
||||
const auto prevVerticesData = _deformVertices != nullptr ? _deformVertices->verticesData : nullptr;
|
||||
const auto prevTextureData = _textureData;
|
||||
|
||||
DisplayData* rawDisplayData = nullptr;
|
||||
VerticesData* currentVerticesData = nullptr;
|
||||
|
||||
_displayData = nullptr;
|
||||
_boundingBoxData = nullptr;
|
||||
_textureData = nullptr;
|
||||
|
||||
if (_displayIndex >= 0)
|
||||
{
|
||||
if (_rawDisplayDatas != nullptr)
|
||||
{
|
||||
rawDisplayData = (unsigned)_displayIndex < _rawDisplayDatas->size() ? (*_rawDisplayDatas)[_displayIndex] : nullptr;
|
||||
}
|
||||
|
||||
if (rawDisplayData == nullptr)
|
||||
{
|
||||
rawDisplayData = _getDefaultRawDisplayData(_displayIndex);
|
||||
}
|
||||
|
||||
if ((unsigned)_displayIndex < _displayDatas.size())
|
||||
{
|
||||
_displayData = _displayDatas[_displayIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Update texture and mesh data.
|
||||
if (_displayData != nullptr)
|
||||
{
|
||||
if (_displayData->type == DisplayType::Mesh)
|
||||
{
|
||||
currentVerticesData = &static_cast<MeshDisplayData*>(_displayData)->vertices;
|
||||
}
|
||||
else if (_displayData->type == DisplayType::Path)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else if (rawDisplayData != nullptr)
|
||||
{
|
||||
if (rawDisplayData->type == DisplayType::Mesh)
|
||||
{
|
||||
currentVerticesData = &static_cast<MeshDisplayData*>(rawDisplayData)->vertices;
|
||||
}
|
||||
else if (rawDisplayData->type == DisplayType::Path)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
if (_displayData->type == DisplayType::BoundingBox)
|
||||
{
|
||||
_boundingBoxData = static_cast<BoundingBoxDisplayData*>(_displayData)->boundingBox;
|
||||
}
|
||||
else if (rawDisplayData != nullptr)
|
||||
{
|
||||
if (rawDisplayData->type == DisplayType::BoundingBox)
|
||||
{
|
||||
_boundingBoxData = static_cast<BoundingBoxDisplayData*>(rawDisplayData)->boundingBox;
|
||||
}
|
||||
}
|
||||
|
||||
if (_displayData->type == DisplayType::Image)
|
||||
{
|
||||
_textureData = static_cast<ImageDisplayData*>(_displayData)->texture;
|
||||
}
|
||||
else if (_displayData->type == DisplayType::Mesh)
|
||||
{
|
||||
_textureData = static_cast<MeshDisplayData*>(_displayData)->texture;
|
||||
}
|
||||
}
|
||||
|
||||
// Update bounding box data.
|
||||
if (_displayData != nullptr && _displayData->type == DisplayType::BoundingBox)
|
||||
{
|
||||
_boundingBoxData = static_cast<BoundingBoxDisplayData*>(_displayData)->boundingBox;
|
||||
}
|
||||
else if (rawDisplayData != nullptr && rawDisplayData->type == DisplayType::BoundingBox)
|
||||
{
|
||||
_boundingBoxData = static_cast<BoundingBoxDisplayData*>(rawDisplayData)->boundingBox;
|
||||
}
|
||||
else
|
||||
{
|
||||
_boundingBoxData = nullptr;
|
||||
}
|
||||
|
||||
if (_displayData != prevDisplayData || currentVerticesData != prevVerticesData || _textureData != prevTextureData)
|
||||
{
|
||||
if (currentVerticesData == nullptr && _textureData != nullptr)
|
||||
{
|
||||
const auto imageDisplayData = static_cast<ImageDisplayData*>(_displayData);
|
||||
const auto scale = _textureData->parent->scale * _armature->_armatureData->scale;
|
||||
const auto frame = _textureData->frame;
|
||||
|
||||
_pivotX = imageDisplayData->pivot.x;
|
||||
_pivotY = imageDisplayData->pivot.y;
|
||||
|
||||
const auto& rect = frame != nullptr ? *frame : _textureData->region;
|
||||
float width = rect.width;
|
||||
float height = rect.height;
|
||||
|
||||
if (_textureData->rotated && frame == nullptr)
|
||||
{
|
||||
width = rect.height;
|
||||
height = rect.width;
|
||||
}
|
||||
|
||||
_pivotX *= width * scale;
|
||||
_pivotY *= height * scale;
|
||||
|
||||
if (frame != nullptr)
|
||||
{
|
||||
_pivotX += frame->x * scale;
|
||||
_pivotY += frame->y * scale;
|
||||
}
|
||||
|
||||
// Update replace pivot.
|
||||
if (_displayData != nullptr && rawDisplayData != nullptr && _displayData != rawDisplayData)
|
||||
{
|
||||
rawDisplayData->transform.toMatrix(_helpMatrix);
|
||||
_helpMatrix.invert();
|
||||
_helpMatrix.transformPoint(0.0f, 0.0f, _helpPoint);
|
||||
_pivotX -= _helpPoint.x;
|
||||
_pivotY -= _helpPoint.y;
|
||||
|
||||
_displayData->transform.toMatrix(_helpMatrix);
|
||||
_helpMatrix.invert();
|
||||
_helpMatrix.transformPoint(0.0f, 0.0f, _helpPoint);
|
||||
_pivotX += _helpPoint.x;
|
||||
_pivotY += _helpPoint.y;
|
||||
}
|
||||
|
||||
if (!DragonBones::yDown)
|
||||
{
|
||||
_pivotY = (_textureData->rotated ? _textureData->region.width : _textureData->region.height) * scale - _pivotY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_pivotX = 0.0f;
|
||||
_pivotY = 0.0f;
|
||||
}
|
||||
|
||||
// Update original transform.
|
||||
if (rawDisplayData != nullptr)
|
||||
{
|
||||
origin = &rawDisplayData->transform;
|
||||
}
|
||||
else if (_displayData != nullptr)
|
||||
{
|
||||
origin = &_displayData->transform;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = nullptr;
|
||||
}
|
||||
|
||||
// Update vertices.
|
||||
if (currentVerticesData != prevVerticesData)
|
||||
{
|
||||
if (_deformVertices == nullptr)
|
||||
{
|
||||
_deformVertices = BaseObject::borrowObject<DeformVertices>();
|
||||
}
|
||||
|
||||
_deformVertices->init(currentVerticesData, _armature);
|
||||
}
|
||||
else if (_deformVertices != nullptr && _textureData != prevTextureData) // Update mesh after update frame.
|
||||
{
|
||||
_deformVertices->verticesDirty = true;
|
||||
}
|
||||
|
||||
_displayDirty = true;
|
||||
_transformDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::_updateDisplay()
|
||||
{
|
||||
const auto prevDisplay = _display != nullptr ? _display : _rawDisplay;
|
||||
const auto prevChildArmature = _childArmature;
|
||||
|
||||
// Update display and child armature.
|
||||
if (_displayIndex >= 0 && (std::size_t)_displayIndex < _displayList.size())
|
||||
{
|
||||
const auto& displayPair = _displayList[_displayIndex];
|
||||
_display = displayPair.first;
|
||||
if (_display != nullptr && displayPair.second == DisplayType::Armature)
|
||||
{
|
||||
_childArmature = static_cast<Armature*>(displayPair.first);
|
||||
_display = _childArmature->getDisplay();
|
||||
}
|
||||
else
|
||||
{
|
||||
_childArmature = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_display = nullptr;
|
||||
_childArmature = nullptr;
|
||||
}
|
||||
|
||||
const auto currentDisplay = _display != nullptr ? _display : _rawDisplay;
|
||||
if (currentDisplay != prevDisplay)
|
||||
{
|
||||
_onUpdateDisplay();
|
||||
_replaceDisplay(prevDisplay, prevChildArmature != nullptr);
|
||||
|
||||
_transformDirty = true;
|
||||
_visibleDirty = true;
|
||||
_blendModeDirty = true;
|
||||
_colorDirty = true;
|
||||
}
|
||||
|
||||
// Update frame.
|
||||
if (currentDisplay == _rawDisplay || currentDisplay == _meshDisplay)
|
||||
{
|
||||
_updateFrame();
|
||||
}
|
||||
|
||||
// Update child armature.
|
||||
if (_childArmature != prevChildArmature)
|
||||
{
|
||||
if (prevChildArmature != nullptr)
|
||||
{
|
||||
prevChildArmature->_parent = nullptr; // Update child armature parent.
|
||||
prevChildArmature->setClock(nullptr);
|
||||
if (prevChildArmature->inheritAnimation)
|
||||
{
|
||||
prevChildArmature->getAnimation()->reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (_childArmature != nullptr)
|
||||
{
|
||||
_childArmature->_parent = this; // Update child armature parent.
|
||||
_childArmature->setClock(_armature->getClock());
|
||||
if (_childArmature->inheritAnimation) // Set child armature cache frameRate.
|
||||
{
|
||||
if (_childArmature->getCacheFrameRate() == 0)
|
||||
{
|
||||
const auto chacheFrameRate = this->_armature->getCacheFrameRate();
|
||||
if (chacheFrameRate != 0)
|
||||
{
|
||||
_childArmature->setCacheFrameRate(chacheFrameRate);
|
||||
}
|
||||
}
|
||||
|
||||
// Child armature action.
|
||||
std::vector<ActionData*>* actions = nullptr;
|
||||
if (_displayData != nullptr && _displayData->type == DisplayType::Armature)
|
||||
{
|
||||
actions = &(static_cast<ArmatureDisplayData*>(_displayData)->actions);
|
||||
}
|
||||
else if(_displayIndex >= 0 && _rawDisplayDatas != nullptr)
|
||||
{
|
||||
auto rawDisplayData = (unsigned)_displayIndex < _rawDisplayDatas->size() ? (*_rawDisplayDatas)[_displayIndex] : nullptr;
|
||||
|
||||
if (rawDisplayData == nullptr)
|
||||
{
|
||||
rawDisplayData = _getDefaultRawDisplayData(_displayIndex);
|
||||
}
|
||||
|
||||
if (rawDisplayData != nullptr && rawDisplayData->type == DisplayType::Armature)
|
||||
{
|
||||
actions = &(static_cast<ArmatureDisplayData*>(rawDisplayData)->actions);
|
||||
}
|
||||
}
|
||||
|
||||
if (actions != nullptr && !actions->empty())
|
||||
{
|
||||
for (const auto action : *actions)
|
||||
{
|
||||
const auto eventObject = BaseObject::borrowObject<EventObject>();
|
||||
EventObject::actionDataToInstance(action, eventObject, _armature);
|
||||
eventObject->slot = this;
|
||||
_armature->_bufferAction(eventObject, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_childArmature->getAnimation()->play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::_updateGlobalTransformMatrix(bool isCache)
|
||||
{
|
||||
const auto& parentMatrix = _parent->globalTransformMatrix;
|
||||
globalTransformMatrix = _localMatrix; // Copy.
|
||||
globalTransformMatrix.concat(parentMatrix);
|
||||
|
||||
if (isCache)
|
||||
{
|
||||
global.fromMatrix(globalTransformMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
_globalDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Slot::_setDisplayIndex(int value, bool isAnimation)
|
||||
{
|
||||
if (isAnimation)
|
||||
{
|
||||
if (_animationDisplayIndex == value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_animationDisplayIndex = value;
|
||||
}
|
||||
|
||||
if (_displayIndex == value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_displayIndex = value;
|
||||
_displayDirty = true;
|
||||
|
||||
_updateDisplayData();
|
||||
|
||||
return _displayDirty;
|
||||
}
|
||||
|
||||
bool Slot::_setZorder(int value)
|
||||
{
|
||||
if (_zOrder == value)
|
||||
{
|
||||
//return false;
|
||||
}
|
||||
|
||||
_zOrder = value;
|
||||
_zOrderDirty = true;
|
||||
|
||||
return _zOrderDirty;
|
||||
}
|
||||
|
||||
bool Slot::_setColor(const ColorTransform& value)
|
||||
{
|
||||
_colorTransform = value; // copy
|
||||
_colorDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Slot::_setDisplayList(const std::vector<std::pair<void*, DisplayType>>& value)
|
||||
{
|
||||
if (!value.empty())
|
||||
{
|
||||
if (_displayList.size() != value.size())
|
||||
{
|
||||
_displayList.resize(value.size());
|
||||
}
|
||||
|
||||
for (std::size_t i = 0, l = value.size(); i < l; ++i)
|
||||
{
|
||||
const auto& eachPair = value[i];
|
||||
if (
|
||||
eachPair.first != nullptr && eachPair.first != _rawDisplay && eachPair.first != _meshDisplay &&
|
||||
eachPair.second != DisplayType::Armature &&
|
||||
std::find(_displayList.cbegin(), _displayList.cend(), eachPair) == _displayList.cend()
|
||||
)
|
||||
{
|
||||
_initDisplay(eachPair.first, true);
|
||||
}
|
||||
|
||||
_displayList[i].first = eachPair.first;
|
||||
_displayList[i].second = eachPair.second;
|
||||
}
|
||||
}
|
||||
else if (!_displayList.empty())
|
||||
{
|
||||
_displayList.clear();
|
||||
}
|
||||
|
||||
if (_displayIndex >= 0 && (std::size_t)_displayIndex < _displayList.size())
|
||||
{
|
||||
_displayDirty = _display != _displayList[_displayIndex].first;
|
||||
}
|
||||
else
|
||||
{
|
||||
_displayDirty = _display != nullptr;
|
||||
}
|
||||
|
||||
_updateDisplayData();
|
||||
|
||||
return _displayDirty;
|
||||
}
|
||||
|
||||
void Slot::init(const SlotData* slotData, Armature* armatureValue, void* rawDisplay, void* meshDisplay)
|
||||
{
|
||||
if (_slotData != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_slotData = slotData;
|
||||
//
|
||||
_visibleDirty = true;
|
||||
_blendModeDirty = true;
|
||||
_colorDirty = true;
|
||||
_blendMode = _slotData->blendMode;
|
||||
_zOrder = _slotData->zOrder;
|
||||
_colorTransform = *(_slotData->color);
|
||||
_rawDisplay = rawDisplay;
|
||||
_meshDisplay = meshDisplay;
|
||||
//
|
||||
_armature = armatureValue;
|
||||
//
|
||||
const auto slotParent = _armature->getBone(_slotData->parent->name);
|
||||
if (slotParent != nullptr)
|
||||
{
|
||||
_parent = slotParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Never;
|
||||
}
|
||||
|
||||
_armature->_addSlot(this);
|
||||
//
|
||||
_initDisplay(_rawDisplay, false);
|
||||
if (_rawDisplay != _meshDisplay)
|
||||
{
|
||||
_initDisplay(_meshDisplay, false);
|
||||
}
|
||||
|
||||
_onUpdateDisplay();
|
||||
_addDisplay();
|
||||
}
|
||||
|
||||
void Slot::update(int cacheFrameIndex)
|
||||
{
|
||||
if (_displayDirty)
|
||||
{
|
||||
_displayDirty = false;
|
||||
_updateDisplay();
|
||||
|
||||
// TODO remove slot offset.
|
||||
if (_transformDirty) // Update local matrix. (Only updated when both display and transform are dirty.)
|
||||
{
|
||||
if (origin != nullptr)
|
||||
{
|
||||
global = *origin; // Copy.
|
||||
global.add(offset).toMatrix(_localMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
global = offset; // Copy.
|
||||
global.toMatrix(_localMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_zOrderDirty)
|
||||
{
|
||||
_zOrderDirty = false;
|
||||
_updateZOrder();
|
||||
}
|
||||
|
||||
if (cacheFrameIndex >= 0 && _cachedFrameIndices != nullptr)
|
||||
{
|
||||
const auto cachedFrameIndex = (*_cachedFrameIndices)[cacheFrameIndex];
|
||||
if (cachedFrameIndex >= 0 && _cachedFrameIndex == cachedFrameIndex) // Same cache.
|
||||
{
|
||||
_transformDirty = false;
|
||||
}
|
||||
else if (cachedFrameIndex >= 0) // Has been Cached.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = cachedFrameIndex;
|
||||
}
|
||||
else if (_transformDirty || _parent->_childrenTransformDirty) // Dirty.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
else if (_cachedFrameIndex >= 0) // Same cache, but not set index yet.
|
||||
{
|
||||
_transformDirty = false;
|
||||
(*_cachedFrameIndices)[cacheFrameIndex] = _cachedFrameIndex;
|
||||
}
|
||||
else // Dirty.
|
||||
{
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
}
|
||||
else if (_transformDirty || this->_parent->_childrenTransformDirty)
|
||||
{
|
||||
cacheFrameIndex = -1;
|
||||
_transformDirty = true;
|
||||
_cachedFrameIndex = -1;
|
||||
}
|
||||
|
||||
if (_display == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_visibleDirty)
|
||||
{
|
||||
_visibleDirty = false;
|
||||
_updateVisible();
|
||||
}
|
||||
|
||||
if (_blendModeDirty)
|
||||
{
|
||||
_blendModeDirty = false;
|
||||
_updateBlendMode();
|
||||
}
|
||||
|
||||
if (_colorDirty)
|
||||
{
|
||||
_colorDirty = false;
|
||||
_updateColor();
|
||||
}
|
||||
|
||||
if (_deformVertices != nullptr && _deformVertices->verticesData != nullptr && _display == _meshDisplay)
|
||||
{
|
||||
const auto isSkinned = _deformVertices->verticesData->weight != nullptr;
|
||||
|
||||
if (
|
||||
_deformVertices->verticesDirty ||
|
||||
(isSkinned && _deformVertices->isBonesUpdate())
|
||||
)
|
||||
{
|
||||
_deformVertices->verticesDirty = false;
|
||||
_updateMesh();
|
||||
}
|
||||
|
||||
if (isSkinned) // Compatible.
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_transformDirty)
|
||||
{
|
||||
_transformDirty = false;
|
||||
|
||||
if (_cachedFrameIndex < 0)
|
||||
{
|
||||
const auto isCache = cacheFrameIndex >= 0;
|
||||
_updateGlobalTransformMatrix(isCache);
|
||||
|
||||
if (isCache && _cachedFrameIndices != nullptr)
|
||||
{
|
||||
_cachedFrameIndex = (*_cachedFrameIndices)[cacheFrameIndex] = _armature->_armatureData->setCacheFrame(globalTransformMatrix, global);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_armature->_armatureData->getCacheFrame(globalTransformMatrix, global, _cachedFrameIndex);
|
||||
}
|
||||
|
||||
_updateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::updateTransformAndMatrix()
|
||||
{
|
||||
if (_transformDirty)
|
||||
{
|
||||
_transformDirty = false;
|
||||
_updateGlobalTransformMatrix(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::replaceDisplayData(DisplayData *displayData, int displayIndex)
|
||||
{
|
||||
if (displayIndex < 0)
|
||||
{
|
||||
if (_displayIndex < 0)
|
||||
{
|
||||
displayIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
displayIndex = _displayIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (_displayDatas.size() <= (unsigned)displayIndex) {
|
||||
_displayDatas.resize(displayIndex + 1, nullptr);
|
||||
}
|
||||
|
||||
_displayDatas[displayIndex] = displayData;
|
||||
}
|
||||
|
||||
bool Slot::containsPoint(float x, float y)
|
||||
{
|
||||
if (_boundingBoxData == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
updateTransformAndMatrix();
|
||||
|
||||
_helpMatrix = globalTransformMatrix; // Copy.
|
||||
_helpMatrix.invert();
|
||||
_helpMatrix.transformPoint(x, y, _helpPoint);
|
||||
|
||||
return _boundingBoxData->containsPoint(_helpPoint.x, _helpPoint.y);
|
||||
}
|
||||
|
||||
int Slot::intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
if (_boundingBoxData == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
updateTransformAndMatrix();
|
||||
_helpMatrix = globalTransformMatrix;
|
||||
_helpMatrix.invert();
|
||||
_helpMatrix.transformPoint(xA, yA, _helpPoint);
|
||||
xA = _helpPoint.x;
|
||||
yA = _helpPoint.y;
|
||||
_helpMatrix.transformPoint(xB, yB, _helpPoint);
|
||||
xB = _helpPoint.x;
|
||||
yB = _helpPoint.y;
|
||||
|
||||
const auto intersectionCount = _boundingBoxData->intersectsSegment(xA, yA, xB, yB, intersectionPointA, intersectionPointB, normalRadians);
|
||||
if (intersectionCount > 0)
|
||||
{
|
||||
if (intersectionCount == 1 || intersectionCount == 2)
|
||||
{
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
globalTransformMatrix.transformPoint(intersectionPointA->x, intersectionPointA->y, *intersectionPointA);
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = intersectionPointA->x;
|
||||
intersectionPointB->y = intersectionPointA->y;
|
||||
}
|
||||
}
|
||||
else if (intersectionPointB != nullptr)
|
||||
{
|
||||
globalTransformMatrix.transformPoint(intersectionPointB->x, intersectionPointB->y, *intersectionPointB);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
globalTransformMatrix.transformPoint(intersectionPointA->x, intersectionPointA->y, *intersectionPointA);
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
globalTransformMatrix.transformPoint(intersectionPointB->x, intersectionPointB->y, *intersectionPointB);
|
||||
}
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
globalTransformMatrix.transformPoint(cos(normalRadians->x), sin(normalRadians->x), _helpPoint, true);
|
||||
normalRadians->x = atan2(_helpPoint.y, _helpPoint.x);
|
||||
|
||||
globalTransformMatrix.transformPoint(cos(normalRadians->y), sin(normalRadians->y), _helpPoint, true);
|
||||
normalRadians->y = atan2(_helpPoint.y, _helpPoint.x);
|
||||
}
|
||||
}
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
void Slot::setVisible(bool value)
|
||||
{
|
||||
if (_visible == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_visible = value;
|
||||
_updateVisible();
|
||||
}
|
||||
|
||||
void Slot::setDisplayIndex(int value)
|
||||
{
|
||||
if (_setDisplayIndex(value))
|
||||
{
|
||||
update(-1);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO lsc check
|
||||
void Slot::setDisplayList(const std::vector<std::pair<void*, DisplayType>>& value)
|
||||
{
|
||||
const auto backupDisplayList = _displayList; // copy
|
||||
auto disposeDisplayList = backupDisplayList; // copy
|
||||
disposeDisplayList.clear();
|
||||
|
||||
if (_setDisplayList(value))
|
||||
{
|
||||
update(-1);
|
||||
}
|
||||
|
||||
for (const auto& pair : backupDisplayList)
|
||||
{
|
||||
if (
|
||||
pair.first != nullptr && pair.first != _rawDisplay && pair.first != _meshDisplay &&
|
||||
std::find(_displayList.cbegin(), _displayList.cend(), pair) == _displayList.cend() &&
|
||||
std::find(disposeDisplayList.cbegin(), disposeDisplayList.cend(), pair) == disposeDisplayList.cend()
|
||||
)
|
||||
{
|
||||
disposeDisplayList.push_back(pair);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : disposeDisplayList)
|
||||
{
|
||||
if (pair.second == DisplayType::Armature)
|
||||
{
|
||||
static_cast<Armature*>(pair.first)->returnToPool();
|
||||
}
|
||||
else
|
||||
{
|
||||
_disposeDisplay(pair.first, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::setRawDisplayDatas(const std::vector<DisplayData*>* value)
|
||||
{
|
||||
if (_rawDisplayDatas == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_displayDirty = true;
|
||||
_rawDisplayDatas = value;
|
||||
|
||||
if (_rawDisplayDatas != nullptr)
|
||||
{
|
||||
_displayDatas.resize(_rawDisplayDatas->size());
|
||||
|
||||
for (std::size_t i = 0, l = _displayDatas.size(); i < l; ++i)
|
||||
{
|
||||
auto rawDisplayData = (*_rawDisplayDatas)[i];
|
||||
|
||||
if (rawDisplayData == nullptr)
|
||||
{
|
||||
rawDisplayData = _getDefaultRawDisplayData(i);
|
||||
}
|
||||
|
||||
_displayDatas[i] = rawDisplayData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_displayDatas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::setDisplay(void* value, DisplayType displayType)
|
||||
{
|
||||
if (_display == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto displayListLength = _displayList.size();
|
||||
if (_displayIndex < 0 && displayListLength == 0) // Emprty
|
||||
{
|
||||
_displayIndex = 0;
|
||||
}
|
||||
|
||||
if (_displayIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto relpaceDisplayList = _displayList; // copy
|
||||
if (displayListLength <= (std::size_t)_displayIndex)
|
||||
{
|
||||
relpaceDisplayList.resize(_displayIndex + 1);
|
||||
}
|
||||
|
||||
relpaceDisplayList[_displayIndex].first = value;
|
||||
relpaceDisplayList[_displayIndex].second = displayType;
|
||||
|
||||
setDisplayList(relpaceDisplayList);
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::setChildArmature(Armature* value)
|
||||
{
|
||||
if (_childArmature == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setDisplay(value, DisplayType::Armature);
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
507
cocos2d-x/cocos/editor-support/dragonbones/armature/Slot.h
Normal file
507
cocos2d-x/cocos/editor-support/dragonbones/armature/Slot.h
Normal file
@@ -0,0 +1,507 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_SLOT_H
|
||||
#define DRAGONBONES_SLOT_H
|
||||
|
||||
#include "TransformObject.h"
|
||||
|
||||
#include "../geom/ColorTransform.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The slot attached to the armature, controls the display status and properties of the display object.
|
||||
* A bone can contain multiple slots.
|
||||
* A slot can contain multiple display objects, displaying only one of the display objects at a time,
|
||||
* but you can toggle the display object into frame animation while the animation is playing.
|
||||
* The display object can be a normal texture, or it can be a display of a child armature, a grid display object,
|
||||
* and a custom other display object.
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.Bone
|
||||
* @see dragonBones.SlotData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽附着在骨骼上,控制显示对象的显示状态和属性。
|
||||
* 一个骨骼上可以包含多个插槽。
|
||||
* 一个插槽中可以包含多个显示对象,同一时间只能显示其中的一个显示对象,但可以在动画播放的过程中切换显示对象实现帧动画。
|
||||
* 显示对象可以是普通的图片纹理,也可以是子骨架的显示容器,网格显示对象,还可以是自定义的其他显示对象。
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.Bone
|
||||
* @see dragonBones.SlotData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Slot : public TransformObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* - Displays the animated state or mixed group name controlled by the object, set to null to be controlled by all animation states.
|
||||
* @default null
|
||||
* @see dragonBones.AnimationState#displayControl
|
||||
* @see dragonBones.AnimationState#name
|
||||
* @see dragonBones.AnimationState#group
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 显示对象受到控制的动画状态或混合组名称,设置为 null 则表示受所有的动画状态控制。
|
||||
* @default null
|
||||
* @see dragonBones.AnimationState#displayControl
|
||||
* @see dragonBones.AnimationState#name
|
||||
* @see dragonBones.AnimationState#group
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string displayController;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _colorDirty;
|
||||
BlendMode _blendMode;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
int _zOrder;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _pivotX;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
float _pivotY;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ColorTransform _colorTransform;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const SlotData* _slotData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
DisplayData* _displayData;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
DeformVertices* _deformVertices;
|
||||
void* _rawDisplay;
|
||||
void* _meshDisplay;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
std::vector<int>* _cachedFrameIndices;
|
||||
|
||||
protected:
|
||||
bool _displayDirty;
|
||||
bool _zOrderDirty;
|
||||
bool _visibleDirty;
|
||||
bool _blendModeDirty;
|
||||
bool _transformDirty;
|
||||
bool _visible;
|
||||
int _displayIndex;
|
||||
int _animationDisplayIndex;
|
||||
int _cachedFrameIndex;
|
||||
Matrix _localMatrix;
|
||||
std::vector<DisplayData*> _displayDatas;
|
||||
std::vector<std::pair<void*, DisplayType>> _displayList;
|
||||
const std::vector<DisplayData*>* _rawDisplayDatas;
|
||||
BoundingBoxData* _boundingBoxData;
|
||||
TextureData* _textureData;
|
||||
void* _display;
|
||||
Armature* _childArmature;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Bone* _parent;
|
||||
|
||||
public:
|
||||
Slot() :
|
||||
_deformVertices(nullptr),
|
||||
_rawDisplay(nullptr),
|
||||
_meshDisplay(nullptr)
|
||||
{}
|
||||
virtual ~Slot() {};
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
virtual void _initDisplay(void* value, bool isRetain) = 0;
|
||||
virtual void _disposeDisplay(void* value, bool isRelease) = 0;
|
||||
virtual void _onUpdateDisplay() = 0;
|
||||
virtual void _addDisplay() = 0;
|
||||
virtual void _replaceDisplay(void* value, bool isArmatureDisplay) = 0;
|
||||
virtual void _removeDisplay() = 0;
|
||||
virtual void _updateZOrder() = 0;
|
||||
virtual void _updateFrame() = 0;
|
||||
virtual void _updateMesh() = 0;
|
||||
virtual void _updateTransform() = 0;
|
||||
virtual void _identityTransform() = 0;
|
||||
/**
|
||||
* - Support default skin data.
|
||||
*/
|
||||
DisplayData* _getDefaultRawDisplayData(unsigned displayIndex) const;
|
||||
void _updateDisplay();
|
||||
void _updateDisplayData();
|
||||
void _updateGlobalTransformMatrix(bool isCache);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void _updateVisible() = 0;
|
||||
virtual void _updateBlendMode() = 0;
|
||||
virtual void _updateColor() = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _setDisplayIndex(int value, bool isAnimation = false);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _setZorder(int value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _setColor(const ColorTransform& value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
bool _setDisplayList(const std::vector<std::pair<void*, DisplayType>>& value);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void init(const SlotData* slotData, Armature* armatureValue, void* rawDisplay, void* meshDisplay);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void update(int cacheFrameIndex);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void updateTransformAndMatrix();
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void replaceDisplayData(DisplayData* displayData, int displayIndex);
|
||||
/**
|
||||
* - Check whether a specific point is inside a custom bounding box in the slot.
|
||||
* The coordinate system of the point is the inner coordinate system of the armature.
|
||||
* Custom bounding boxes need to be customized in Dragonbones Pro.
|
||||
* @param x - The horizontal coordinate of the point.
|
||||
* @param y - The vertical coordinate of the point.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查特定点是否在插槽的自定义边界框内。
|
||||
* 点的坐标系为骨架内坐标系。
|
||||
* 自定义边界框需要在 DragonBones Pro 中自定义。
|
||||
* @param x - 点的水平坐标。
|
||||
* @param y - 点的垂直坐标。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool containsPoint(float x, float y);
|
||||
/**
|
||||
* - Check whether a specific segment intersects a custom bounding box for the slot.
|
||||
* The coordinate system of the segment and intersection is the inner coordinate system of the armature.
|
||||
* Custom bounding boxes need to be customized in Dragonbones Pro.
|
||||
* @param xA - The horizontal coordinate of the beginning of the segment.
|
||||
* @param yA - The vertical coordinate of the beginning of the segment.
|
||||
* @param xB - The horizontal coordinate of the end point of the segment.
|
||||
* @param yB - The vertical coordinate of the end point of the segment.
|
||||
* @param intersectionPointA - The first intersection at which a line segment intersects the bounding box from the beginning to the end. (If not set, the intersection point will not calculated)
|
||||
* @param intersectionPointB - The first intersection at which a line segment intersects the bounding box from the end to the beginning. (If not set, the intersection point will not calculated)
|
||||
* @param normalRadians - The normal radians of the tangent of the intersection boundary box. [x: Normal radian of the first intersection tangent, y: Normal radian of the second intersection tangent] (If not set, the normal will not calculated)
|
||||
* @returns Intersection situation. [1: Disjoint and segments within the bounding box, 0: Disjoint, 1: Intersecting and having a nodal point and ending in the bounding box, 2: Intersecting and having a nodal point and starting at the bounding box, 3: Intersecting and having two intersections, N: Intersecting and having N intersections]
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查特定线段是否与插槽的自定义边界框相交。
|
||||
* 线段和交点的坐标系均为骨架内坐标系。
|
||||
* 自定义边界框需要在 DragonBones Pro 中自定义。
|
||||
* @param xA - 线段起点的水平坐标。
|
||||
* @param yA - 线段起点的垂直坐标。
|
||||
* @param xB - 线段终点的水平坐标。
|
||||
* @param yB - 线段终点的垂直坐标。
|
||||
* @param intersectionPointA - 线段从起点到终点与边界框相交的第一个交点。 (如果未设置,则不计算交点)
|
||||
* @param intersectionPointB - 线段从终点到起点与边界框相交的第一个交点。 (如果未设置,则不计算交点)
|
||||
* @param normalRadians - 交点边界框切线的法线弧度。 [x: 第一个交点切线的法线弧度, y: 第二个交点切线的法线弧度] (如果未设置,则不计算法线)
|
||||
* @returns 相交的情况。 [-1: 不相交且线段在包围盒内, 0: 不相交, 1: 相交且有一个交点且终点在包围盒内, 2: 相交且有一个交点且起点在包围盒内, 3: 相交且有两个交点, N: 相交且有 N 个交点]
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
int intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
);
|
||||
/**
|
||||
* - Forces the slot to update the state of the display object in the next frame.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 强制插槽在下一帧更新显示对象的状态。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void invalidUpdate()
|
||||
{
|
||||
_displayDirty = true;
|
||||
_transformDirty = true;
|
||||
}
|
||||
/**
|
||||
* - The visible of slot's display object.
|
||||
* @default true
|
||||
* @version DragonBones 5.6
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽的显示对象的可见。
|
||||
* @default true
|
||||
* @version DragonBones 5.6
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool getVisible() const
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
void setVisible(bool value);
|
||||
/**
|
||||
* - The index of the display object displayed in the display list.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* slot.displayIndex = 3;
|
||||
* slot.displayController = "none";
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 此时显示的显示对象在显示列表中的索引。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* slot.displayIndex = 3;
|
||||
* slot.displayController = "none";
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline int getDisplayIndex() const
|
||||
{
|
||||
return _displayIndex;
|
||||
}
|
||||
void setDisplayIndex(int value);
|
||||
|
||||
/**
|
||||
* - The slot name.
|
||||
* @see dragonBones.SlotData#name
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽名称。
|
||||
* @see dragonBones.SlotData#name
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline const std::string& getName() const
|
||||
{
|
||||
return _slotData->name;
|
||||
}
|
||||
/**
|
||||
* - Contains a display list of display objects or child armatures.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 包含显示对象或子骨架的显示列表。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline std::vector<std::pair<void*, DisplayType>> getDisplayList() const
|
||||
{
|
||||
return _displayList;
|
||||
}
|
||||
void setDisplayList(const std::vector<std::pair<void*, DisplayType>>& value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline const std::vector<DisplayData*>* getRawDisplayDatas() const
|
||||
{
|
||||
return _rawDisplayDatas;
|
||||
}
|
||||
void setRawDisplayDatas(const std::vector<DisplayData*>* value);
|
||||
/**
|
||||
* - The slot data.
|
||||
* @see dragonBones.SlotData
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽数据。
|
||||
* @see dragonBones.SlotData
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
const SlotData* getSlotData() const
|
||||
{
|
||||
return _slotData;
|
||||
}
|
||||
/**
|
||||
* - The custom bounding box data for the slot at current time.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽此时的自定义包围盒数据。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline BoundingBoxData* getBoundingBoxData() const
|
||||
{
|
||||
return _boundingBoxData;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline void* getRawDisplay() const
|
||||
{
|
||||
return _rawDisplay;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline void* getMeshDisplay() const
|
||||
{
|
||||
return _meshDisplay;
|
||||
}
|
||||
/**
|
||||
* - The display object that the slot displays at this time.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("text");
|
||||
* slot.display = new yourEngine.TextField();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽此时显示的显示对象。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("text");
|
||||
* slot.display = new yourEngine.TextField();
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void* getDisplay() const
|
||||
{
|
||||
return _display;
|
||||
}
|
||||
/**
|
||||
* - Deprecated, please refer to {@link #display}.
|
||||
* @deprecated
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 已废弃,请参考 {@link #display}。
|
||||
* @deprecated
|
||||
* @language zh_CN
|
||||
*/
|
||||
void setDisplay(void* value, DisplayType displayType);
|
||||
/**
|
||||
* - The child armature that the slot displayed at current time.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* let prevChildArmature = slot.childArmature;
|
||||
* if (prevChildArmature) {
|
||||
* prevChildArmature.dispose();
|
||||
* }
|
||||
* slot.childArmature = factory.buildArmature("weapon_blabla", "weapon_blabla_project");
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽此时显示的子骨架。
|
||||
* 注意,被替换的对象或子骨架并不会被回收,根据语言和引擎的不同,需要额外处理。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* let prevChildArmature = slot.childArmature;
|
||||
* if (prevChildArmature) {
|
||||
* prevChildArmature.dispose();
|
||||
* }
|
||||
* slot.childArmature = factory.buildArmature("weapon_blabla", "weapon_blabla_project");
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Armature* getChildArmature() const
|
||||
{
|
||||
return _childArmature;
|
||||
}
|
||||
void setChildArmature(Armature* value);
|
||||
/**
|
||||
* - The parent bone to which it belongs.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所属的父骨骼。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Bone* getParent() const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_SLOT_H
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by liangshuochen on 12/06/2017.
|
||||
//
|
||||
|
||||
#include "TransformObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
Matrix TransformObject::_helpMatrix;
|
||||
Transform TransformObject::_helpTransform;
|
||||
Point TransformObject::_helpPoint;
|
||||
|
||||
void TransformObject::_onClear()
|
||||
{
|
||||
globalTransformMatrix.identity();
|
||||
global.identity();
|
||||
offset.identity();
|
||||
origin = nullptr;
|
||||
userData = nullptr;
|
||||
|
||||
_globalDirty = false;
|
||||
_armature = nullptr;
|
||||
}
|
||||
|
||||
void TransformObject::updateGlobalTransform()
|
||||
{
|
||||
if (_globalDirty)
|
||||
{
|
||||
_globalDirty = false;
|
||||
global.fromMatrix(globalTransformMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_TRANSFORM_OBJECT_H
|
||||
#define DRAGONBONES_TRANSFORM_OBJECT_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Matrix.h"
|
||||
#include "../geom/Transform.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The base class of the transform object.
|
||||
* @see dragonBones.Transform
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 变换对象的基类。
|
||||
* @see dragonBones.Transform
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
class TransformObject : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(TransformObject);
|
||||
|
||||
protected:
|
||||
static Matrix _helpMatrix;
|
||||
static Transform _helpTransform;
|
||||
static Point _helpPoint;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - A matrix relative to the armature coordinate system.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 相对于骨架坐标系的矩阵。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Matrix globalTransformMatrix;
|
||||
/**
|
||||
* - A transform relative to the armature coordinate system.
|
||||
* @see #updateGlobalTransform()
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 相对于骨架坐标系的变换。
|
||||
* @see #updateGlobalTransform()
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Transform global;
|
||||
/**
|
||||
* - The offset transform relative to the armature or the parent bone coordinate system.
|
||||
* @see #dragonBones.Bone#invalidUpdate()
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 相对于骨架或父骨骼坐标系的偏移变换。
|
||||
* @see #dragonBones.Bone#invalidUpdate()
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Transform offset;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
const Transform* origin;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void* userData;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
Armature* _armature;
|
||||
|
||||
protected:
|
||||
bool _globalDirty;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - For performance considerations, rotation or scale in the {@link #global} attribute of the bone or slot is not always properly accessible,
|
||||
* some engines do not rely on these attributes to update rendering, such as Egret.
|
||||
* The use of this method ensures that the access to the {@link #global} property is correctly rotation or scale.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* bone.updateGlobalTransform();
|
||||
* let rotation = bone.global.rotation;
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 出于性能的考虑,骨骼或插槽的 {@link #global} 属性中的旋转或缩放并不总是正确可访问的,有些引擎并不依赖这些属性更新渲染,比如 Egret。
|
||||
* 使用此方法可以保证访问到 {@link #global} 属性中正确的旋转或缩放。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* bone.updateGlobalTransform();
|
||||
* let rotation = bone.global.rotation;
|
||||
* </pre>
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
void updateGlobalTransform();
|
||||
/**
|
||||
* - The armature to which it belongs.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所属的骨架。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline Armature* getArmature() const
|
||||
{
|
||||
return _armature;
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
Matrix* getGlobalTransformMatrix() { return &globalTransformMatrix; }
|
||||
Transform* getGlobal() { return &global; }
|
||||
Transform* getOffset() { return &offset; }
|
||||
const Transform* getOrigin() const { return origin; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_TRANSFORM_OBJECT_H
|
||||
160
cocos2d-x/cocos/editor-support/dragonbones/core/BaseObject.cpp
Normal file
160
cocos2d-x/cocos/editor-support/dragonbones/core/BaseObject.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "BaseObject.h"
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
std::vector<BaseObject*> BaseObject::__allDragonBonesObjects;
|
||||
unsigned BaseObject::_hashCode = 0;
|
||||
unsigned BaseObject::_defaultMaxCount = 3000;
|
||||
std::map<std::size_t, unsigned> BaseObject::_maxCountMap;
|
||||
std::map<std::size_t, std::vector<BaseObject*>> BaseObject::_poolsMap;
|
||||
BaseObject::RecycleOrDestroyCallback BaseObject::_recycleOrDestroyCallback = nullptr;
|
||||
|
||||
void BaseObject::_returnObject(BaseObject* object)
|
||||
{
|
||||
const auto classType = object->getClassTypeIndex();
|
||||
const auto maxCountIterator = _maxCountMap.find(classType);
|
||||
const auto maxCount = maxCountIterator != _maxCountMap.end() ? maxCountIterator->second : _defaultMaxCount;
|
||||
auto& pool = _poolsMap[classType];
|
||||
// If script engine gc,then alway push object into pool,not immediately delete
|
||||
// Because object will be referenced more then one place possibly,if delete it immediately,will
|
||||
// crash.
|
||||
if (!DragonBones::checkInPool || pool.size() < maxCount)
|
||||
{
|
||||
if (!object->_isInPool)
|
||||
{
|
||||
object->_isInPool = true;
|
||||
pool.push_back(object);
|
||||
if (_recycleOrDestroyCallback != nullptr)
|
||||
_recycleOrDestroyCallback(object, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If script engine gc,repeat push into pool will happen.
|
||||
if(DragonBones::checkInPool)
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "The object is already in the pool.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete object;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseObject::setObjectRecycleOrDestroyCallback(const std::function<void(BaseObject*, int)>& cb)
|
||||
{
|
||||
_recycleOrDestroyCallback = cb;
|
||||
}
|
||||
|
||||
void BaseObject::setMaxCount(std::size_t classType, unsigned maxCount)
|
||||
{
|
||||
if (classType > 0)
|
||||
{
|
||||
const auto iterator = _poolsMap.find(classType);
|
||||
if (iterator != _poolsMap.end())
|
||||
{
|
||||
auto& pool = iterator->second;
|
||||
if (pool.size() > (size_t)maxCount)
|
||||
{
|
||||
for (auto i = (size_t)maxCount, l = pool.size(); i < l; ++i)
|
||||
{
|
||||
delete pool[i];
|
||||
}
|
||||
|
||||
pool.resize(maxCount);
|
||||
}
|
||||
}
|
||||
|
||||
_maxCountMap[classType] = maxCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
_defaultMaxCount = maxCount;
|
||||
for (auto& pair : _poolsMap)
|
||||
{
|
||||
auto& pool = pair.second;
|
||||
if (pool.size() > (size_t)maxCount)
|
||||
{
|
||||
for (auto i = (size_t)maxCount, l = pool.size(); i < l; ++i)
|
||||
{
|
||||
delete pool[i];
|
||||
}
|
||||
|
||||
pool.resize(maxCount);
|
||||
}
|
||||
|
||||
if (_maxCountMap.find(pair.first) != _maxCountMap.end())
|
||||
{
|
||||
_maxCountMap[pair.first] = maxCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void BaseObject::clearPool(std::size_t classType)
|
||||
{
|
||||
if (classType > 0)
|
||||
{
|
||||
const auto iterator = _poolsMap.find(classType);
|
||||
if (iterator != _poolsMap.end())
|
||||
{
|
||||
auto& pool = iterator->second;
|
||||
if (!pool.empty())
|
||||
{
|
||||
for (auto object : pool)
|
||||
{
|
||||
delete object;
|
||||
}
|
||||
|
||||
pool.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& pair : _poolsMap)
|
||||
{
|
||||
auto& pool = pair.second;
|
||||
if (!pool.empty())
|
||||
{
|
||||
for (auto object : pool)
|
||||
{
|
||||
delete object;
|
||||
}
|
||||
|
||||
pool.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseObject::BaseObject()
|
||||
:hashCode(BaseObject::_hashCode++)
|
||||
,_isInPool(false)
|
||||
{
|
||||
__allDragonBonesObjects.push_back(this);
|
||||
}
|
||||
|
||||
BaseObject::~BaseObject()
|
||||
{
|
||||
if (_recycleOrDestroyCallback != nullptr)
|
||||
_recycleOrDestroyCallback(this, 1);
|
||||
|
||||
auto iter = std::find(__allDragonBonesObjects.begin(), __allDragonBonesObjects.end(), this);
|
||||
if (iter != __allDragonBonesObjects.end())
|
||||
{
|
||||
__allDragonBonesObjects.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseObject::returnToPool()
|
||||
{
|
||||
_onClear();
|
||||
BaseObject::_returnObject(this);
|
||||
}
|
||||
|
||||
std::vector<BaseObject*>& BaseObject::getAllObjects()
|
||||
{
|
||||
return __allDragonBonesObjects;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
161
cocos2d-x/cocos/editor-support/dragonbones/core/BaseObject.h
Normal file
161
cocos2d-x/cocos/editor-support/dragonbones/core/BaseObject.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_BASE_OBJECT_H
|
||||
#define DRAGONBONES_BASE_OBJECT_H
|
||||
|
||||
#include "DragonBones.h"
|
||||
#include <vector>
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The BaseObject is the base class for all objects in the DragonBones framework.
|
||||
* All BaseObject instances are cached to the object pool to reduce the performance consumption of frequent requests for memory or memory recovery.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 基础对象,通常 DragonBones 的对象都继承自该类。
|
||||
* 所有基础对象的实例都会缓存到对象池,以减少频繁申请内存或内存回收的性能消耗。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
class BaseObject
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(BaseObject*,int)> RecycleOrDestroyCallback;
|
||||
private:
|
||||
static unsigned _hashCode;
|
||||
static unsigned _defaultMaxCount;
|
||||
static std::map<std::size_t, unsigned> _maxCountMap;
|
||||
static std::map<std::size_t, std::vector<BaseObject*>> _poolsMap;
|
||||
static void _returnObject(BaseObject *object);
|
||||
|
||||
static RecycleOrDestroyCallback _recycleOrDestroyCallback;
|
||||
public:
|
||||
static void setObjectRecycleOrDestroyCallback(const RecycleOrDestroyCallback& cb);
|
||||
/**
|
||||
* - Set the maximum cache count of the specify object pool.
|
||||
* @param objectConstructor - The specify class. (Set all object pools max cache count if not set)
|
||||
* @param maxCount - Max count.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 设置特定对象池的最大缓存数量。
|
||||
* @param objectConstructor - 特定的类。 (不设置则设置所有对象池的最大缓存数量)
|
||||
* @param maxCount - 最大缓存数量。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static void setMaxCount(std::size_t classTypeIndex, unsigned maxCount);
|
||||
/**
|
||||
* - Clear the cached instances of a specify object pool.
|
||||
* @param objectConstructor - Specify class. (Clear all cached instances if not set)
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 清除特定对象池的缓存实例。
|
||||
* @param objectConstructor - 特定的类。 (不设置则清除所有缓存的实例)
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static void clearPool(std::size_t classTypeIndex = 0);
|
||||
template<typename T>
|
||||
/**
|
||||
* - Get an instance of the specify class from object pool.
|
||||
* @param objectConstructor - The specify class.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 从对象池中获取特定类的实例。
|
||||
* @param objectConstructor - 特定的类。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static T* borrowObject()
|
||||
{
|
||||
const auto classTypeIndex = T::getTypeIndex();
|
||||
const auto iterator = _poolsMap.find(classTypeIndex);
|
||||
if (iterator != _poolsMap.end())
|
||||
{
|
||||
auto& pool = iterator->second;
|
||||
if (!pool.empty())
|
||||
{
|
||||
const auto object = static_cast<T*>(pool.back());
|
||||
pool.pop_back();
|
||||
object->_isInPool = false;
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
const auto object = new (std::nothrow) T();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static std::vector<dragonBones::BaseObject*>& getAllObjects();
|
||||
public:
|
||||
/**
|
||||
* - A unique identification number assigned to the object.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 分配给此实例的唯一标识号。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
const unsigned hashCode;
|
||||
|
||||
private:
|
||||
static std::vector<dragonBones::BaseObject*> __allDragonBonesObjects;
|
||||
bool _isInPool;
|
||||
|
||||
public:
|
||||
virtual ~BaseObject();
|
||||
|
||||
protected:
|
||||
BaseObject();
|
||||
|
||||
virtual void _onClear() = 0;
|
||||
|
||||
public:
|
||||
virtual std::size_t getClassTypeIndex() const = 0;
|
||||
/**
|
||||
* - Clear the object and return it back to object pool。
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 清除该实例的所有数据并将其返还对象池。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
void returnToPool();
|
||||
inline bool isInPool() const { return _isInPool; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_BASE_OBJECT_H
|
||||
109
cocos2d-x/cocos/editor-support/dragonbones/core/DragonBones.cpp
Normal file
109
cocos2d-x/cocos/editor-support/dragonbones/core/DragonBones.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "DragonBones.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../animation/WorldClock.h"
|
||||
#include "../animation/Animation.h"
|
||||
#include "../event/EventObject.h"
|
||||
#include "../event/IEventDispatcher.h"
|
||||
|
||||
#include "../../dragonbones-creator-support/CCArmatureDisplay.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
const std::string DragonBones::VEISION = "5.6.300";
|
||||
|
||||
bool DragonBones::yDown = false;
|
||||
bool DragonBones::debug = false;
|
||||
bool DragonBones::debugDraw = false;
|
||||
bool DragonBones::webAssembly = false;
|
||||
bool DragonBones::checkInPool = true;
|
||||
|
||||
DragonBones::DragonBones(IEventDispatcher* eventManager) :
|
||||
_events(),
|
||||
_clock(nullptr),
|
||||
_eventManager(eventManager)
|
||||
{
|
||||
_clock = new WorldClock();
|
||||
_eventManager = eventManager;
|
||||
}
|
||||
|
||||
DragonBones::~DragonBones()
|
||||
{
|
||||
if (_clock != nullptr)
|
||||
{
|
||||
delete _clock;
|
||||
}
|
||||
|
||||
_clock = nullptr;
|
||||
|
||||
if (_eventManager) {
|
||||
auto mgr = dynamic_cast<CCArmatureDisplay*>(_eventManager);
|
||||
if (NULL != mgr) {
|
||||
mgr->release();
|
||||
}
|
||||
}
|
||||
|
||||
_eventManager = nullptr;
|
||||
}
|
||||
|
||||
void DragonBones::advanceTime(float passedTime)
|
||||
{
|
||||
if (!_objectsMap.empty())
|
||||
{
|
||||
for (auto it = _objectsMap.begin(); it != _objectsMap.end(); it ++)
|
||||
{
|
||||
auto object = it->first;
|
||||
if (object) {
|
||||
object->returnToPool();
|
||||
}
|
||||
}
|
||||
_objectsMap.clear();
|
||||
}
|
||||
|
||||
if (!_events.empty())
|
||||
{
|
||||
for (std::size_t i = 0; i < _events.size(); ++i)
|
||||
{
|
||||
const auto eventObject = _events[i];
|
||||
const auto armature = eventObject->armature;
|
||||
if (armature->_armatureData != nullptr)
|
||||
{
|
||||
armature->getProxy()->dispatchDBEvent(eventObject->type, eventObject);
|
||||
if (eventObject->type == EventObject::SOUND_EVENT)
|
||||
{
|
||||
_eventManager->dispatchDBEvent(eventObject->type, eventObject);
|
||||
}
|
||||
}
|
||||
|
||||
bufferObject(eventObject);
|
||||
}
|
||||
|
||||
_events.clear();
|
||||
}
|
||||
|
||||
_clock->advanceTime(passedTime);
|
||||
}
|
||||
|
||||
void DragonBones::render()
|
||||
{
|
||||
_clock->render();
|
||||
}
|
||||
|
||||
void DragonBones::bufferEvent(EventObject* value)
|
||||
{
|
||||
_events.push_back(value);
|
||||
}
|
||||
|
||||
void DragonBones::bufferObject(BaseObject* object)
|
||||
{
|
||||
if(object == nullptr || object->isInPool())return;
|
||||
// Just mark object will be put in pool next frame, 'true' is useless.
|
||||
_objectsMap[object] = true;
|
||||
}
|
||||
|
||||
WorldClock* DragonBones::getClock()
|
||||
{
|
||||
return _clock;
|
||||
}
|
||||
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
487
cocos2d-x/cocos/editor-support/dragonbones/core/DragonBones.h
Normal file
487
cocos2d-x/cocos/editor-support/dragonbones/core/DragonBones.h
Normal file
@@ -0,0 +1,487 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_H
|
||||
#define DRAGONBONES_H
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
// dragonBones assert
|
||||
#define DRAGONBONES_ASSERT(cond, msg) \
|
||||
do { \
|
||||
assert(cond); \
|
||||
} while (0)
|
||||
|
||||
// namespace dragonBones {}
|
||||
#define DRAGONBONES_NAMESPACE_BEGIN namespace dragonBones {
|
||||
#define DRAGONBONES_NAMESPACE_END }
|
||||
|
||||
// using dragonBones namespace
|
||||
#define DRAGONBONES_USING_NAME_SPACE using namespace dragonBones
|
||||
|
||||
#define ABSTRACT_CLASS(CLASS) \
|
||||
public:\
|
||||
CLASS(){}\
|
||||
virtual ~CLASS(){};
|
||||
|
||||
#define BIND_CLASS_TYPE(CLASS) \
|
||||
public:\
|
||||
static std::size_t getTypeIndex()\
|
||||
{\
|
||||
static const auto typeIndex = typeid(CLASS).hash_code();\
|
||||
return typeIndex;\
|
||||
}\
|
||||
virtual std::size_t getClassTypeIndex() const override\
|
||||
{\
|
||||
return CLASS::getTypeIndex();\
|
||||
}\
|
||||
|
||||
#define BIND_CLASS_TYPE_A(CLASS) \
|
||||
public:\
|
||||
static std::size_t getTypeIndex()\
|
||||
{\
|
||||
static const auto typeIndex = typeid(CLASS).hash_code();\
|
||||
return typeIndex;\
|
||||
}\
|
||||
virtual std::size_t getClassTypeIndex() const override\
|
||||
{\
|
||||
return CLASS::getTypeIndex();\
|
||||
}\
|
||||
public:\
|
||||
CLASS(){_onClear();}\
|
||||
~CLASS(){_onClear();}\
|
||||
private:\
|
||||
CLASS(const CLASS&);\
|
||||
void operator=(const CLASS&)
|
||||
|
||||
#define BIND_CLASS_TYPE_B(CLASS) \
|
||||
public:\
|
||||
static std::size_t getTypeIndex()\
|
||||
{\
|
||||
static const auto typeIndex = typeid(CLASS).hash_code();\
|
||||
return typeIndex;\
|
||||
}\
|
||||
virtual std::size_t getClassTypeIndex() const override\
|
||||
{\
|
||||
return CLASS::getTypeIndex();\
|
||||
}\
|
||||
private:\
|
||||
CLASS(const CLASS&);\
|
||||
void operator=(const CLASS&)
|
||||
|
||||
#define DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(CLASS) \
|
||||
private:\
|
||||
CLASS(const CLASS&);\
|
||||
void operator=(const CLASS&);
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class BinaryOffset
|
||||
{
|
||||
WeigthBoneCount = 0,
|
||||
WeigthFloatOffset = 1,
|
||||
WeigthBoneIndices = 2,
|
||||
|
||||
MeshVertexCount = 0,
|
||||
MeshTriangleCount = 1,
|
||||
MeshFloatOffset = 2,
|
||||
MeshWeightOffset = 3,
|
||||
MeshVertexIndices = 4,
|
||||
|
||||
TimelineScale = 0,
|
||||
TimelineOffset = 1,
|
||||
TimelineKeyFrameCount = 2,
|
||||
TimelineFrameValueCount = 3,
|
||||
TimelineFrameValueOffset = 4,
|
||||
TimelineFrameOffset = 5,
|
||||
|
||||
FramePosition = 0,
|
||||
FrameTweenType = 1,
|
||||
FrameTweenEasingOrCurveSampleCount = 2,
|
||||
FrameCurveSamples = 3,
|
||||
|
||||
DeformVertexOffset = 0,
|
||||
DeformCount = 1,
|
||||
DeformValueCount = 2,
|
||||
DeformValueOffset = 3,
|
||||
DeformFloatOffset = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class ArmatureType
|
||||
{
|
||||
Armature = 0,
|
||||
MovieClip = 1,
|
||||
Stage = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* - Offset mode.
|
||||
* @version DragonBones 5.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 偏移模式。
|
||||
* @version DragonBones 5.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
enum class OffsetMode {
|
||||
None,
|
||||
Additive,
|
||||
Override
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
enum class DisplayType
|
||||
{
|
||||
Image = 0,
|
||||
Armature = 1,
|
||||
Mesh = 2,
|
||||
BoundingBox = 3,
|
||||
Path = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* - Bounding box type.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 边界框类型。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
enum class BoundingBoxType
|
||||
{
|
||||
Rectangle = 0,
|
||||
Ellipse = 1,
|
||||
Polygon = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class ActionType {
|
||||
Play = 0,
|
||||
Frame = 10,
|
||||
Sound = 11
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class BlendMode
|
||||
{
|
||||
Normal = 0,
|
||||
Add = 1,
|
||||
Alpha = 2,
|
||||
Darken = 3,
|
||||
Difference = 4,
|
||||
Erase = 5,
|
||||
HardLight = 6,
|
||||
Invert = 7,
|
||||
Layer = 8,
|
||||
Lighten = 9,
|
||||
Multiply = 10,
|
||||
Overlay = 11,
|
||||
Screen = 12,
|
||||
Subtract = 13
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class TweenType {
|
||||
None = 0,
|
||||
Line = 1,
|
||||
Curve = 2,
|
||||
QuadIn = 3,
|
||||
QuadOut = 4,
|
||||
QuadInOut = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum class TimelineType {
|
||||
Action = 0,
|
||||
ZOrder = 1,
|
||||
|
||||
BoneAll = 10,
|
||||
|
||||
BoneTranslate = 11,
|
||||
BoneRotate = 12,
|
||||
BoneScale = 13,
|
||||
|
||||
SlotDisplay = 20,
|
||||
SlotColor = 21,
|
||||
SlotDeform = 22,
|
||||
|
||||
IKConstraint = 30,
|
||||
|
||||
AnimationTime = 40,
|
||||
AnimationWeight = 41
|
||||
};
|
||||
|
||||
/**
|
||||
* - Animation fade out mode.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画淡出模式。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
enum class AnimationFadeOutMode {
|
||||
/**
|
||||
* - Do not fade out of any animation states.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 不淡出任何的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
None,
|
||||
/**
|
||||
* - Fade out the animation states of the same layer.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡出同层的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
SameLayer,
|
||||
/**
|
||||
* - Fade out the animation states of the same group.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡出同组的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
SameGroup,
|
||||
/**
|
||||
* - Fade out the animation states of the same layer and group.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡出同层并且同组的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
SameLayerAndGroup,
|
||||
/**
|
||||
* - Fade out of all animation states.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡出所有的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
All,
|
||||
/**
|
||||
* - Does not replace the animation state with the same name.
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 不替换同名的动画状态。
|
||||
* @language zh_CN
|
||||
*/
|
||||
Single
|
||||
};
|
||||
|
||||
enum class TextureFormat
|
||||
{
|
||||
DEFAULT,
|
||||
RGBA8888,
|
||||
BGRA8888,
|
||||
RGBA4444,
|
||||
RGB888,
|
||||
RGB565,
|
||||
RGBA5551
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::string to_string(const T& value)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << value;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline int indexOf(const std::vector<T>& vector, const T& value)
|
||||
{
|
||||
for (std::size_t i = 0, l = vector.size(); i < l; ++i)
|
||||
{
|
||||
if (vector[i] == value)
|
||||
{
|
||||
return (int) i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T* mapFind(const std::map<std::string, T*>& map, const std::string& key)
|
||||
{
|
||||
auto iterator = map.find(key);
|
||||
return (iterator != map.end()) ? iterator->second : nullptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T* mapFindB(std::map<std::string, T>& map, const std::string& key)
|
||||
{
|
||||
auto iterator = map.find(key);
|
||||
return (iterator != map.end()) ? &iterator->second : nullptr;
|
||||
}
|
||||
|
||||
class Matrix;
|
||||
class Transform;
|
||||
class ColorTransform;
|
||||
class Point;
|
||||
class Rectangle;
|
||||
|
||||
class BaseObject;
|
||||
|
||||
class UserData;
|
||||
class ActionData;
|
||||
class DragonBonesData;
|
||||
class ArmatureData;
|
||||
class CanvasData;
|
||||
class BoneData;
|
||||
class SlotData;
|
||||
class SkinData;
|
||||
class ConstraintData;
|
||||
class IKConstraintData;
|
||||
class DisplayData;
|
||||
class ImageDisplayData;
|
||||
class ArmatureDisplayData;
|
||||
class MeshDisplayData;
|
||||
class VerticesData;
|
||||
class WeightData;
|
||||
class BoundingBoxDisplayData;
|
||||
class BoundingBoxData;
|
||||
class RectangleBoundingBoxData;
|
||||
class EllipseBoundingBoxData;
|
||||
class PolygonBoundingBoxData;
|
||||
class AnimationData;
|
||||
class TimelineData;
|
||||
class AnimationConfig;
|
||||
class TextureAtlasData;
|
||||
class TextureData;
|
||||
|
||||
class IArmatureProxy;
|
||||
class Armature;
|
||||
class TransformObject;
|
||||
class Bone;
|
||||
class Slot;
|
||||
class Constraint;
|
||||
class IKConstraint;
|
||||
class DeformVertices;
|
||||
|
||||
class IAnimatable;
|
||||
class WorldClock;
|
||||
class Animation;
|
||||
class AnimationState;
|
||||
class BonePose;
|
||||
class BlendState;
|
||||
class TimelineState;
|
||||
class TweenTimelineState;
|
||||
class BoneTimelineState;
|
||||
class SlotTimelineState;
|
||||
class ConstraintTimelineState;
|
||||
class ActionTimelineState;
|
||||
class ZOrderTimelineState;
|
||||
class BoneAllTimelineState;
|
||||
class SlotDislayTimelineState;
|
||||
class SlotColorTimelineState;
|
||||
class DeformTimelineState;
|
||||
class IKConstraintTimelineState;
|
||||
|
||||
class IEventDispatcher;
|
||||
class EventObject;
|
||||
|
||||
class DataParser;
|
||||
class JSONDataParser;
|
||||
class BinaryDataParser;
|
||||
|
||||
class BaseFactory;
|
||||
class BuildArmaturePackage;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class DragonBones
|
||||
{
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(DragonBones)
|
||||
|
||||
public:
|
||||
static const std::string VEISION;
|
||||
|
||||
static bool yDown;
|
||||
static bool debug;
|
||||
static bool debugDraw;
|
||||
static bool webAssembly;
|
||||
static bool checkInPool;
|
||||
|
||||
private:
|
||||
std::map<BaseObject*,bool> _objectsMap;
|
||||
std::vector<EventObject*> _events;
|
||||
WorldClock* _clock;
|
||||
IEventDispatcher* _eventManager;
|
||||
|
||||
public:
|
||||
DragonBones(IEventDispatcher* eventManager);
|
||||
virtual ~DragonBones();
|
||||
|
||||
void advanceTime(float passedTime);
|
||||
void render();
|
||||
void bufferEvent(EventObject* value);
|
||||
void bufferObject(BaseObject* object);
|
||||
|
||||
WorldClock* getClock();
|
||||
IEventDispatcher* getEventManager() const
|
||||
{
|
||||
return _eventManager;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif // DRAGONBONES_H
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "EventObject.h"
|
||||
#include "../model/UserData.h"
|
||||
#include "../armature/Armature.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
const char* EventObject::START = "start";
|
||||
const char* EventObject::LOOP_COMPLETE = "loopComplete";
|
||||
const char* EventObject::COMPLETE = "complete";
|
||||
const char* EventObject::FADE_IN = "fadeIn";
|
||||
const char* EventObject::FADE_IN_COMPLETE = "fadeInComplete";
|
||||
const char* EventObject::FADE_OUT = "fadeOut";
|
||||
const char* EventObject::FADE_OUT_COMPLETE = "fadeOutComplete";
|
||||
const char* EventObject::FRAME_EVENT = "frameEvent";
|
||||
const char* EventObject::SOUND_EVENT = "soundEvent";
|
||||
|
||||
void EventObject::actionDataToInstance(const ActionData* data, EventObject* instance, Armature* armature)
|
||||
{
|
||||
if (data->type == ActionType::Play)
|
||||
{
|
||||
instance->type = EventObject::FRAME_EVENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->type = data->type == ActionType::Frame ? EventObject::FRAME_EVENT : EventObject::SOUND_EVENT;
|
||||
}
|
||||
|
||||
instance->name = data->name;
|
||||
instance->armature = armature;
|
||||
instance->actionData = data;
|
||||
instance->data = data->data;
|
||||
|
||||
if (data->bone != nullptr)
|
||||
{
|
||||
instance->bone = armature->getBone(data->bone->name);
|
||||
}
|
||||
|
||||
if (data->slot != nullptr)
|
||||
{
|
||||
instance->slot = armature->getSlot(data->slot->name);
|
||||
}
|
||||
}
|
||||
|
||||
void EventObject::_onClear()
|
||||
{
|
||||
time = 0.0f;
|
||||
type = "";
|
||||
name = "";
|
||||
armature = nullptr;
|
||||
bone = nullptr;
|
||||
slot = nullptr;
|
||||
animationState = nullptr;
|
||||
actionData = nullptr;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
267
cocos2d-x/cocos/editor-support/dragonbones/event/EventObject.h
Normal file
267
cocos2d-x/cocos/editor-support/dragonbones/event/EventObject.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_EVENT_OBJECT_H
|
||||
#define DRAGONBONES_EVENT_OBJECT_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The properties of the object carry basic information about an event,
|
||||
* which are passed as parameter or parameter's parameter to event listeners when an event occurs.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 事件对象,包含有关事件的基本信息,当发生事件时,该实例将作为参数或参数的参数传递给事件侦听器。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
class EventObject : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(EventObject);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Animation start play.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画开始播放。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* START;
|
||||
/**
|
||||
* - Animation loop play complete once.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画循环播放完成一次。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* LOOP_COMPLETE;
|
||||
/**
|
||||
* - Animation play complete.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画播放完成。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* COMPLETE;
|
||||
/**
|
||||
* - Animation fade in start.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画淡入开始。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* FADE_IN;
|
||||
/**
|
||||
* - Animation fade in complete.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画淡入完成。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* FADE_IN_COMPLETE;
|
||||
/**
|
||||
* - Animation fade out start.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画淡出开始。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* FADE_OUT;
|
||||
/**
|
||||
* - Animation fade out complete.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画淡出完成。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* FADE_OUT_COMPLETE;
|
||||
/**
|
||||
* - Animation frame event.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画帧事件。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* FRAME_EVENT;
|
||||
/**
|
||||
* - Animation frame sound event.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画帧声音事件。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
static const char* SOUND_EVENT;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static void actionDataToInstance(const ActionData* data, EventObject* instance, Armature* armature);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - If is a frame event, the value is used to describe the time that the event was in the animation timeline. (In seconds)
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 如果是帧事件,此值用来描述该事件在动画时间轴中所处的时间。(以秒为单位)
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
float time;
|
||||
/**
|
||||
* - The event type。
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 事件类型。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string type;
|
||||
/**
|
||||
* - The event name. (The frame event name or the frame sound name)
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 事件名称。 (帧事件的名称或帧声音的名称)
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* - The armature that dispatch the event.
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 发出该事件的骨架。
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
Armature* armature;
|
||||
/**
|
||||
* - The bone that dispatch the event.
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 发出该事件的骨骼。
|
||||
* @see dragonBones.Bone
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
Bone* bone;
|
||||
/**
|
||||
* - The slot that dispatch the event.
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 发出该事件的插槽。
|
||||
* @see dragonBones.Slot
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
Slot* slot;
|
||||
/**
|
||||
* - The animation state that dispatch the event.
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 发出该事件的动画状态。
|
||||
* @see dragonBones.AnimationState
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationState* animationState;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
const ActionData* actionData;
|
||||
/**
|
||||
* - The custom data.
|
||||
* @see dragonBones.CustomData
|
||||
* @private
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 自定义数据。
|
||||
* @see dragonBones.CustomData
|
||||
* @private
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
UserData* data;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
Armature* getArmature() const { return armature; }
|
||||
Bone* getBone() const { return bone; }
|
||||
Slot* getSlot() const { return slot; }
|
||||
AnimationState* getAnimationState() const { return animationState; }
|
||||
UserData* getData() const { return data; }
|
||||
};
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_EVENT_OBJECT_H
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_IEVENT_DISPATCHER_H
|
||||
#define DRAGONBONES_IEVENT_DISPATCHER_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The event dispatcher interface.
|
||||
* Dragonbones event dispatch usually relies on docking engine to implement, which defines the event method to be implemented when docking the engine.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 事件派发接口。
|
||||
* DragonBones 的事件派发通常依赖于对接的引擎来实现,该接口定义了对接引擎时需要实现的事件方法。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
class IEventDispatcher
|
||||
{
|
||||
ABSTRACT_CLASS(IEventDispatcher)
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Checks whether the object has any listeners registered for a specific type of event。
|
||||
* @param type - Event type.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查是否为特定的事件类型注册了任何侦听器。
|
||||
* @param type - 事件类型。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual bool hasDBEventListener(const std::string& type) const = 0;
|
||||
/**
|
||||
* - Dispatches an event into the event flow.
|
||||
* @param type - Event type.
|
||||
* @param eventObject - Event object.
|
||||
* @see dragonBones.EventObject
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 分派特定的事件到事件流中。
|
||||
* @param type - 事件类型。
|
||||
* @param eventObject - 事件数据。
|
||||
* @see dragonBones.EventObject
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void dispatchDBEvent(const std::string& type, EventObject* value) = 0;
|
||||
/**
|
||||
* - Add an event listener object so that the listener receives notification of an event.
|
||||
* @param type - Event type.
|
||||
* @param listener - Event listener.
|
||||
* @param thisObject - The listener function's "this".
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 添加特定事件类型的事件侦听器,以使侦听器能够接收事件通知。
|
||||
* @param type - 事件类型。
|
||||
* @param listener - 事件侦听器。
|
||||
* @param thisObject - 侦听函数绑定的 this 对象。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void addDBEventListener(const std::string& type, const std::function<void(EventObject*)> & listener) = 0;
|
||||
/**
|
||||
* - Removes a listener from the object.
|
||||
* @param type - Event type.
|
||||
* @param listener - Event listener.
|
||||
* @param thisObject - The listener function's "this".
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 删除特定事件类型的侦听器。
|
||||
* @param type - 事件类型。
|
||||
* @param listener - 事件侦听器。
|
||||
* @param thisObject - 侦听函数绑定的 this 对象。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void removeDBEventListener(const std::string& type, const std::function<void(EventObject*)>& listener) = 0;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_IEVENT_DISPATCHER_H
|
||||
@@ -0,0 +1,659 @@
|
||||
#include "BaseFactory.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
JSONDataParser BaseFactory::_jsonParser;
|
||||
BinaryDataParser BaseFactory::_binaryParser;
|
||||
|
||||
TextureData* BaseFactory::_getTextureData(const std::string& textureAtlasName, const std::string& textureName) const
|
||||
{
|
||||
const auto iterator = _textureAtlasDataMap.find(textureAtlasName);
|
||||
if (iterator != _textureAtlasDataMap.end())
|
||||
{
|
||||
for (const auto textureAtlasData : iterator->second)
|
||||
{
|
||||
const auto textureData = textureAtlasData->getTexture(textureName);
|
||||
if (textureData != nullptr)
|
||||
{
|
||||
return textureData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (autoSearch)
|
||||
{
|
||||
for (const auto& pair : _textureAtlasDataMap)
|
||||
{
|
||||
for (const auto textureAtlasData : pair.second)
|
||||
{
|
||||
if (textureAtlasData->autoSearch)
|
||||
{
|
||||
const auto textureData = textureAtlasData->getTexture(textureName);
|
||||
if (textureData != nullptr)
|
||||
{
|
||||
return textureData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BaseFactory::_fillBuildArmaturePackage(
|
||||
BuildArmaturePackage& dataPackage,
|
||||
const std::string& dragonBonesName, const std::string& armatureName, const std::string& skinName, const std::string& textureAtlasName
|
||||
) const
|
||||
{
|
||||
std::string mapName = dragonBonesName;
|
||||
DragonBonesData* dragonBonesData = nullptr;
|
||||
ArmatureData* armatureData = nullptr;
|
||||
|
||||
if (!mapName.empty())
|
||||
{
|
||||
const auto iterator = _dragonBonesDataMap.find(mapName);
|
||||
if (iterator != _dragonBonesDataMap.end())
|
||||
{
|
||||
dragonBonesData = iterator->second;
|
||||
armatureData = dragonBonesData->getArmature(armatureName);
|
||||
}
|
||||
}
|
||||
|
||||
if (armatureData == nullptr && (mapName.empty() || autoSearch))
|
||||
{
|
||||
for (const auto& pair : _dragonBonesDataMap)
|
||||
{
|
||||
dragonBonesData = pair.second;
|
||||
if (mapName.empty() || dragonBonesData->autoSearch)
|
||||
{
|
||||
armatureData = dragonBonesData->getArmature(armatureName);
|
||||
if (armatureData != nullptr)
|
||||
{
|
||||
mapName = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (armatureData != nullptr)
|
||||
{
|
||||
dataPackage.dataName = mapName;
|
||||
dataPackage.textureAtlasName = textureAtlasName;
|
||||
dataPackage.data = dragonBonesData;
|
||||
dataPackage.armature = armatureData;
|
||||
dataPackage.skin = nullptr;
|
||||
|
||||
if (!skinName.empty())
|
||||
{
|
||||
dataPackage.skin = armatureData->getSkin(skinName);
|
||||
if (dataPackage.skin == nullptr && autoSearch)
|
||||
{
|
||||
for (const auto& pair : _dragonBonesDataMap)
|
||||
{
|
||||
const auto skinDragonBonesData = pair.second;
|
||||
const auto skinArmatureData = skinDragonBonesData->getArmature(skinName);
|
||||
if (skinArmatureData != nullptr)
|
||||
{
|
||||
dataPackage.skin = skinArmatureData->defaultSkin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dataPackage.skin == nullptr)
|
||||
{
|
||||
dataPackage.skin = armatureData->defaultSkin;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaseFactory::_buildBones(const BuildArmaturePackage& dataPackage, Armature* armature) const
|
||||
{
|
||||
for (const auto boneData : dataPackage.armature->sortedBones)
|
||||
{
|
||||
const auto bone = BaseObject::borrowObject<Bone>();
|
||||
bone->init(boneData, armature);
|
||||
}
|
||||
|
||||
for (const auto& pair : dataPackage.armature->constraints)
|
||||
{
|
||||
// TODO more constraint type.
|
||||
const auto constraint = BaseObject::borrowObject<IKConstraint>();
|
||||
constraint->init(pair.second, armature);
|
||||
armature->_addConstraint(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseFactory::_buildSlots(const BuildArmaturePackage& dataPackage, Armature* armature) const
|
||||
{
|
||||
const auto currentSkin = dataPackage.skin;
|
||||
const auto defaultSkin = dataPackage.armature->defaultSkin;
|
||||
if (currentSkin == nullptr || defaultSkin == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<DisplayData*>*> skinSlots;
|
||||
for (auto& pair : defaultSkin->displays)
|
||||
{
|
||||
auto& displays = pair.second;
|
||||
skinSlots[pair.first] = &displays;
|
||||
}
|
||||
|
||||
if (currentSkin != defaultSkin)
|
||||
{
|
||||
for (auto& pair : currentSkin->displays)
|
||||
{
|
||||
auto& displays = pair.second;
|
||||
skinSlots[pair.first] = &displays;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto slotData : dataPackage.armature->sortedSlots)
|
||||
{
|
||||
const auto displayDatas = skinSlots[slotData->name];
|
||||
const auto slot = _buildSlot(dataPackage, slotData, armature);
|
||||
slot->setRawDisplayDatas(displayDatas);
|
||||
|
||||
if (displayDatas != nullptr)
|
||||
{
|
||||
std::vector<std::pair<void*, DisplayType>> displayList;
|
||||
|
||||
for (const auto displayData : *displayDatas)
|
||||
{
|
||||
if (displayData != nullptr)
|
||||
{
|
||||
displayList.push_back(_getSlotDisplay(&dataPackage, displayData, nullptr, slot));
|
||||
}
|
||||
else
|
||||
{
|
||||
displayList.push_back(std::make_pair(nullptr, DisplayType::Image));
|
||||
}
|
||||
}
|
||||
|
||||
slot->_setDisplayList(displayList);
|
||||
}
|
||||
|
||||
slot->_setDisplayIndex(slotData->displayIndex, true);
|
||||
}
|
||||
}
|
||||
|
||||
Armature* BaseFactory::_buildChildArmature(const BuildArmaturePackage* dataPackage, Slot* slot, DisplayData* displayData) const
|
||||
{
|
||||
return buildArmature(displayData->path, dataPackage != nullptr ? dataPackage->dataName : "", "", dataPackage != nullptr ? dataPackage->textureAtlasName : "");
|
||||
}
|
||||
|
||||
std::pair<void*, DisplayType> BaseFactory::_getSlotDisplay(const BuildArmaturePackage* dataPackage, DisplayData* displayData, DisplayData* rawDisplayData, Slot* slot) const
|
||||
{
|
||||
std::string dataName = "";
|
||||
|
||||
if (dataPackage != nullptr)
|
||||
{
|
||||
dataName = dataPackage->dataName;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& pair : _dragonBonesDataMap)
|
||||
{
|
||||
if (pair.second == displayData->parent->parent->parent)
|
||||
{
|
||||
dataName = pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
if (dataName.empty())
|
||||
{
|
||||
dataName = displayData->parent->parent->parent->name;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<void*, DisplayType> display(nullptr, DisplayType::Image);
|
||||
switch (displayData->type)
|
||||
{
|
||||
case DisplayType::Image:
|
||||
{
|
||||
auto imageDisplayData = static_cast<ImageDisplayData*>(displayData);
|
||||
|
||||
if (dataPackage != nullptr && !dataPackage->textureAtlasName.empty())
|
||||
{
|
||||
imageDisplayData->texture = _getTextureData(dataPackage->textureAtlasName, displayData->path);
|
||||
}
|
||||
|
||||
if (imageDisplayData->texture == nullptr)
|
||||
{
|
||||
imageDisplayData->texture = _getTextureData(dataName, displayData->path);
|
||||
}
|
||||
|
||||
display.first = slot->_rawDisplay;
|
||||
display.second = DisplayType::Image;
|
||||
break;
|
||||
}
|
||||
|
||||
case DisplayType::Mesh:
|
||||
{
|
||||
auto meshDisplayData = static_cast<MeshDisplayData*>(displayData);
|
||||
|
||||
if (dataPackage != nullptr && !dataPackage->textureAtlasName.empty())
|
||||
{
|
||||
meshDisplayData->texture = _getTextureData(dataPackage->textureAtlasName, meshDisplayData->path);
|
||||
}
|
||||
|
||||
if (meshDisplayData->texture == nullptr)
|
||||
{
|
||||
meshDisplayData->texture = _getTextureData(dataName, meshDisplayData->path);
|
||||
}
|
||||
|
||||
if (_isSupportMesh())
|
||||
{
|
||||
display.first = slot->_meshDisplay;
|
||||
display.second = DisplayType::Mesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
display.first = slot->_rawDisplay;
|
||||
display.second = DisplayType::Image;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DisplayType::Armature:
|
||||
{
|
||||
auto armatureDisplayData = static_cast<ArmatureDisplayData*>(displayData);
|
||||
const auto childArmature = _buildChildArmature(dataPackage, slot, displayData);
|
||||
if (childArmature != nullptr)
|
||||
{
|
||||
childArmature->inheritAnimation = armatureDisplayData->inheritAnimation;
|
||||
if (!childArmature->inheritAnimation)
|
||||
{
|
||||
const auto actions = !armatureDisplayData->actions.empty() ? &(armatureDisplayData->actions) : &(childArmature->_armatureData->defaultActions);
|
||||
if (!actions->empty())
|
||||
{
|
||||
for (const auto action : *actions)
|
||||
{
|
||||
childArmature->getAnimation()->fadeIn(action->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
childArmature->getAnimation()->play();
|
||||
}
|
||||
}
|
||||
|
||||
armatureDisplayData->armature = childArmature->_armatureData; //
|
||||
}
|
||||
|
||||
display.first = childArmature;
|
||||
display.second = DisplayType::Armature;
|
||||
break;
|
||||
}
|
||||
|
||||
case DisplayType::BoundingBox:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
DragonBonesData* BaseFactory::parseDragonBonesData(const char* rawData, const std::string& name, float scale)
|
||||
{
|
||||
DRAGONBONES_ASSERT(rawData != nullptr, "");
|
||||
|
||||
DataParser* dataParser = nullptr;
|
||||
|
||||
if (
|
||||
rawData[0] == 'D' &&
|
||||
rawData[1] == 'B' &&
|
||||
rawData[2] == 'D' &&
|
||||
rawData[3] == 'T'
|
||||
)
|
||||
{
|
||||
dataParser = &_binaryParser;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataParser = _dataParser;
|
||||
}
|
||||
|
||||
const auto dragonBonesData = dataParser->parseDragonBonesData(rawData, scale);
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto textureAtlasData = _buildTextureAtlasData(nullptr, nullptr);
|
||||
if (dataParser->parseTextureAtlasData(nullptr, *textureAtlasData, scale))
|
||||
{
|
||||
addTextureAtlasData(textureAtlasData, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureAtlasData->returnToPool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dragonBonesData != nullptr)
|
||||
{
|
||||
addDragonBonesData(dragonBonesData, name);
|
||||
}
|
||||
|
||||
return dragonBonesData;
|
||||
}
|
||||
|
||||
TextureAtlasData* BaseFactory::parseTextureAtlasData(const char* rawData, void* textureAtlas, const std::string& name, float scale)
|
||||
{
|
||||
const auto textureAtlasData = _buildTextureAtlasData(nullptr, nullptr);
|
||||
_dataParser->parseTextureAtlasData(rawData, *textureAtlasData, scale);
|
||||
_buildTextureAtlasData(textureAtlasData, textureAtlas);
|
||||
addTextureAtlasData(textureAtlasData, name);
|
||||
|
||||
return textureAtlasData;
|
||||
}
|
||||
|
||||
void BaseFactory::addDragonBonesData(DragonBonesData* data, const std::string& name)
|
||||
{
|
||||
const auto& mapName = !name.empty()? name : data->name;
|
||||
if (_dragonBonesDataMap.find(mapName) != _dragonBonesDataMap.cend())
|
||||
{
|
||||
if (_dragonBonesDataMap[name] == data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DRAGONBONES_ASSERT(false, "Can not add same name data: " + name);
|
||||
return;
|
||||
}
|
||||
|
||||
_dragonBonesDataMap[mapName] = data;
|
||||
}
|
||||
|
||||
void BaseFactory::removeDragonBonesData(const std::string& name, bool disposeData)
|
||||
{
|
||||
const auto iterator = _dragonBonesDataMap.find(name);
|
||||
if (iterator != _dragonBonesDataMap.cend())
|
||||
{
|
||||
if (disposeData)
|
||||
{
|
||||
iterator->second->returnToPool();
|
||||
}
|
||||
|
||||
_dragonBonesDataMap.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseFactory::addTextureAtlasData(TextureAtlasData* data, const std::string& name)
|
||||
{
|
||||
const auto& mapName = !name.empty() ? name : data->name;
|
||||
auto& textureAtlasList = _textureAtlasDataMap[mapName];
|
||||
if (std::find(textureAtlasList.cbegin(), textureAtlasList.cend(), data) == textureAtlasList.cend())
|
||||
{
|
||||
textureAtlasList.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseFactory::removeTextureAtlasData(const std::string& name, bool disposeData)
|
||||
{
|
||||
const auto iterator = _textureAtlasDataMap.find(name);
|
||||
if (iterator != _textureAtlasDataMap.end())
|
||||
{
|
||||
if (disposeData)
|
||||
{
|
||||
for (const auto textureAtlasData : iterator->second)
|
||||
{
|
||||
textureAtlasData->returnToPool();
|
||||
}
|
||||
}
|
||||
|
||||
_textureAtlasDataMap.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
ArmatureData* BaseFactory::getArmatureData(const std::string& name, const std::string& dragonBonesName) const
|
||||
{
|
||||
BuildArmaturePackage dataPackage;
|
||||
if (!_fillBuildArmaturePackage(dataPackage, dragonBonesName, name, "", ""))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dataPackage.armature;
|
||||
}
|
||||
|
||||
void BaseFactory::clear(bool disposeData)
|
||||
{
|
||||
if (disposeData)
|
||||
{
|
||||
for (const auto& pair : _dragonBonesDataMap)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : _textureAtlasDataMap)
|
||||
{
|
||||
for (const auto textureAtlasData : pair.second)
|
||||
{
|
||||
textureAtlasData->returnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_dragonBonesDataMap.clear();
|
||||
_textureAtlasDataMap.clear();
|
||||
}
|
||||
|
||||
Armature * BaseFactory::buildArmature(const std::string& armatureName, const std::string& dragonBonesName, const std::string& skinName, const std::string& textureAtlasName) const
|
||||
{
|
||||
BuildArmaturePackage dataPackage;
|
||||
if (!_fillBuildArmaturePackage(dataPackage, dragonBonesName, armatureName, skinName, textureAtlasName))
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "No armature data: " + armatureName + ", " + (!dragonBonesName.empty() ? dragonBonesName : ""));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto armature = _buildArmature(dataPackage);
|
||||
_buildBones(dataPackage, armature);
|
||||
_buildSlots(dataPackage, armature);
|
||||
armature->invalidUpdate("", true);
|
||||
armature->advanceTime(0.0f); // Update armature pose.
|
||||
|
||||
return armature;
|
||||
}
|
||||
|
||||
void BaseFactory::replaceDisplay(Slot* slot, DisplayData* displayData, int displayIndex) const
|
||||
{
|
||||
if (displayIndex < 0)
|
||||
{
|
||||
displayIndex = slot->getDisplayIndex();
|
||||
}
|
||||
|
||||
if (displayIndex < 0)
|
||||
{
|
||||
displayIndex = 0;
|
||||
}
|
||||
|
||||
slot->replaceDisplayData(displayData, displayIndex);
|
||||
|
||||
auto displayList = slot->getDisplayList(); // Copy.
|
||||
if (displayList.size() <= (unsigned)displayIndex)
|
||||
{
|
||||
displayList.resize(displayIndex + 1, std::make_pair(nullptr, DisplayType::Image));
|
||||
}
|
||||
|
||||
if (displayData != nullptr)
|
||||
{
|
||||
const auto rawDisplayDatas = slot->getRawDisplayDatas();
|
||||
displayList[displayIndex] = _getSlotDisplay(
|
||||
nullptr,
|
||||
displayData,
|
||||
rawDisplayDatas != nullptr && (unsigned)displayIndex < rawDisplayDatas->size() ? rawDisplayDatas->at(displayIndex) : nullptr,
|
||||
slot
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayList[displayIndex] = std::make_pair(nullptr, DisplayType::Image);
|
||||
}
|
||||
|
||||
slot->setDisplayList(displayList);
|
||||
}
|
||||
|
||||
bool BaseFactory::replaceSlotDisplay(const std::string& dragonBonesName, const std::string& armatureName, const std::string& slotName, const std::string& displayName, Slot* slot, int displayIndex) const
|
||||
{
|
||||
DRAGONBONES_ASSERT(slot, "Arguments error.");
|
||||
|
||||
const auto armatureData = getArmatureData(armatureName, dragonBonesName);
|
||||
if (!armatureData || !armatureData->defaultSkin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto displayData = armatureData->defaultSkin->getDisplay(slotName, displayName);
|
||||
if (!displayData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
replaceDisplay(slot, displayData, displayIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseFactory::replaceSlotDisplayList(const std::string& dragonBonesName, const std::string& armatureName, const std::string& slotName, Slot* slot) const
|
||||
{
|
||||
DRAGONBONES_ASSERT(slot, "Arguments error.");
|
||||
|
||||
const auto armatureData = getArmatureData(armatureName, dragonBonesName);
|
||||
if (!armatureData || !armatureData->defaultSkin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto displays = armatureData->defaultSkin->getDisplays(slotName);
|
||||
if (!displays)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto displayIndex = 0;
|
||||
for (const auto displayData : *displays)
|
||||
{
|
||||
replaceDisplay(slot, displayData, displayIndex++);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseFactory::replaceSkin(Armature* armature, SkinData* skin, bool isOverride, const std::vector<std::string>& exclude) const
|
||||
{
|
||||
DRAGONBONES_ASSERT(armature && skin, "Arguments error.");
|
||||
|
||||
auto success = false;
|
||||
const auto defaultSkin = skin->parent->defaultSkin;
|
||||
|
||||
for (const auto slot : armature->getSlots())
|
||||
{
|
||||
if (std::find(exclude.cbegin(), exclude.cend(), slot->getName()) != exclude.cend())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto displays = skin->getDisplays(slot->getName());
|
||||
if (displays == nullptr)
|
||||
{
|
||||
if (defaultSkin != nullptr && skin != defaultSkin)
|
||||
{
|
||||
displays = defaultSkin->getDisplays(slot->getName());
|
||||
}
|
||||
|
||||
if (isOverride)
|
||||
{
|
||||
std::vector<std::pair<void*, DisplayType>> displayList;
|
||||
slot->setRawDisplayDatas(nullptr);
|
||||
slot->setDisplayList(displayList);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto displayList = slot->getDisplayList(); // Copy.
|
||||
displayList.resize(displays->size(), std::make_pair(nullptr, DisplayType::Image));
|
||||
for (std::size_t i = 0, l = displays->size(); i < l; ++i)
|
||||
{
|
||||
const auto displayData = displays->at(i);
|
||||
if (displayData != nullptr)
|
||||
{
|
||||
displayList[i] = _getSlotDisplay(nullptr, displayData, nullptr, slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayList[i] = std::make_pair(nullptr, DisplayType::Image);
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
slot->setRawDisplayDatas(displays);
|
||||
slot->setDisplayList(displayList);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool BaseFactory::replaceAnimation(Armature* armature, ArmatureData* armatureData, bool isReplaceAll) const
|
||||
{
|
||||
const auto skinData = armatureData->defaultSkin;
|
||||
if (skinData == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isReplaceAll)
|
||||
{
|
||||
armature->getAnimation()->setAnimations(armatureData->animations);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto animations = armature->getAnimation()->getAnimations(); // Copy.
|
||||
for (const auto& pair : armatureData->animations)
|
||||
{
|
||||
animations[pair.first] = pair.second;
|
||||
}
|
||||
|
||||
armature->getAnimation()->setAnimations(animations);
|
||||
}
|
||||
|
||||
for (const auto slot : armature->getSlots())
|
||||
{
|
||||
unsigned index = 0;
|
||||
for (const auto& pair : slot->getDisplayList())
|
||||
{
|
||||
if (pair.second == DisplayType::Armature)
|
||||
{
|
||||
auto displayDatas = skinData->getDisplays(slot->getName());
|
||||
if (displayDatas != nullptr && index < displayDatas->size())
|
||||
{
|
||||
const auto displayData = (*displayDatas)[index];
|
||||
if (displayData != nullptr && displayData->type == DisplayType::Armature)
|
||||
{
|
||||
const auto childArmatureData = getArmatureData(displayData->path, displayData->parent->parent->parent->name);
|
||||
if (childArmatureData != nullptr)
|
||||
{
|
||||
replaceAnimation((Armature*)pair.first, childArmatureData, isReplaceAll);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
592
cocos2d-x/cocos/editor-support/dragonbones/factory/BaseFactory.h
Normal file
592
cocos2d-x/cocos/editor-support/dragonbones/factory/BaseFactory.h
Normal file
@@ -0,0 +1,592 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_BASE_FACTORY_H
|
||||
#define DRAGONBONES_BASE_FACTORY_H
|
||||
|
||||
#include "../parser/JSONDataParser.h"
|
||||
#include "../parser/BinaryDataParser.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
#include "../armature/Slot.h"
|
||||
#include "../armature/Constraint.h"
|
||||
#include "../animation/Animation.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - Base class for the factory that create the armatures. (Typically only one global factory instance is required)
|
||||
* The factory instance create armatures by parsed and added DragonBonesData instances and TextureAtlasData instances.
|
||||
* Once the data has been parsed, it has been cached in the factory instance and does not need to be parsed again until it is cleared by the factory instance.
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @see dragonBones.ArmatureData
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 创建骨架的工厂基类。 (通常只需要一个全局工厂实例)
|
||||
* 工厂通过解析并添加的 DragonBonesData 实例和 TextureAtlasData 实例来创建骨架。
|
||||
* 当数据被解析过之后,已经添加到工厂中,在没有被工厂清理之前,不需要再次解析。
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @see dragonBones.ArmatureData
|
||||
* @see dragonBones.Armature
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class BaseFactory
|
||||
{
|
||||
protected:
|
||||
static JSONDataParser _jsonParser;
|
||||
static BinaryDataParser _binaryParser;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool autoSearch;
|
||||
|
||||
protected:
|
||||
std::map<std::string, DragonBonesData*> _dragonBonesDataMap;
|
||||
std::map<std::string, std::vector<TextureAtlasData*>> _textureAtlasDataMap;
|
||||
DragonBones* _dragonBones;
|
||||
DataParser* _dataParser;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Create a factory instance. (typically only one global factory instance is required)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 创建一个工厂实例。 (通常只需要一个全局工厂实例)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
BaseFactory(DataParser* dataParser = nullptr) :
|
||||
autoSearch(false),
|
||||
_dragonBonesDataMap(),
|
||||
_textureAtlasDataMap(),
|
||||
_dragonBones(nullptr),
|
||||
_dataParser(nullptr)
|
||||
{
|
||||
_dataParser = dataParser != nullptr ? dataParser : &BaseFactory::_jsonParser;
|
||||
}
|
||||
virtual ~BaseFactory()
|
||||
{
|
||||
clear();
|
||||
|
||||
_dragonBones = nullptr;
|
||||
_dataParser = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual inline bool _isSupportMesh() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual TextureData* _getTextureData(const std::string& textureAtlasName, const std::string& textureName) const;
|
||||
virtual bool _fillBuildArmaturePackage(
|
||||
BuildArmaturePackage& dataPackage,
|
||||
const std::string& dragonBonesName, const std::string& armatureName, const std::string& skinName, const std::string& textureAtlasName
|
||||
) const;
|
||||
virtual void _buildBones(const BuildArmaturePackage& dataPackage, Armature* armature) const;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
virtual void _buildSlots(const BuildArmaturePackage& dataPackage, Armature* armature) const;
|
||||
virtual Armature* _buildChildArmature(const BuildArmaturePackage* dataPackage, Slot* slot, DisplayData* displayData) const;
|
||||
virtual std::pair<void*, DisplayType> _getSlotDisplay(const BuildArmaturePackage* dataPackage, DisplayData* displayData, DisplayData* rawDisplayData, Slot* slot) const;
|
||||
virtual TextureAtlasData* _buildTextureAtlasData(TextureAtlasData* textureAtlasData, void* textureAtlas) const = 0;
|
||||
virtual Armature* _buildArmature(const BuildArmaturePackage& dataPackage) const = 0;
|
||||
virtual Slot* _buildSlot(const BuildArmaturePackage& dataPackage, const SlotData* slotData, Armature* armature) const = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Parse the raw data to a DragonBonesData instance and cache it to the factory.
|
||||
* @param rawData - The raw 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 all armatures. (Default: 1.0)
|
||||
* @returns DragonBonesData instance
|
||||
* @see #getDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将原始数据解析为 DragonBonesData 实例,并缓存到工厂中。
|
||||
* @param rawData - 原始数据。
|
||||
* @param name - 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
|
||||
* @param scale - 为所有的骨架指定一个缩放值。 (默认: 1.0)
|
||||
* @returns DragonBonesData 实例
|
||||
* @see #getDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData, const std::string& name = "", float scale = 1.0f);
|
||||
/**
|
||||
* - Parse the raw texture atlas data and the texture atlas object to a TextureAtlasData instance and cache it to the factory.
|
||||
* @param rawData - The raw texture atlas data.
|
||||
* @param textureAtlas - The texture atlas object.
|
||||
* @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. (Default: 1.0)
|
||||
* @returns TextureAtlasData instance
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将原始贴图集数据和贴图集对象解析为 TextureAtlasData 实例,并缓存到工厂中。
|
||||
* @param rawData - 原始贴图集数据。
|
||||
* @param textureAtlas - 贴图集对象。
|
||||
* @param name - 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
|
||||
* @param scale - 为贴图集指定一个缩放值。 (默认: 1.0)
|
||||
* @returns TextureAtlasData 实例
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual TextureAtlasData* parseTextureAtlasData(const char* rawData, void* textureAtlas, const std::string& name = "", float scale = 1.0f);
|
||||
/**
|
||||
* - Get a specific DragonBonesData instance.
|
||||
* @param name - The DragonBonesData instance cache name.
|
||||
* @returns DragonBonesData instance
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的 DragonBonesData 实例。
|
||||
* @param name - DragonBonesData 实例的缓存名称。
|
||||
* @returns DragonBonesData 实例
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline DragonBonesData* getDragonBonesData(const std::string& name) const
|
||||
{
|
||||
return mapFind(_dragonBonesDataMap, name);
|
||||
}
|
||||
/**
|
||||
* - Cache a DragonBonesData instance to the factory.
|
||||
* @param data - The DragonBonesData instance.
|
||||
* @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)
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #getDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将 DragonBonesData 实例缓存到工厂中。
|
||||
* @param data - DragonBonesData 实例。
|
||||
* @param name - 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #getDragonBonesData()
|
||||
* @see #removeDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void addDragonBonesData(DragonBonesData* data, const std::string& name = "");
|
||||
/**
|
||||
* - Remove a DragonBonesData instance.
|
||||
* @param name - The DragonBonesData instance cache name.
|
||||
* @param disposeData - Whether to dispose data. (Default: true)
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #getDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 移除 DragonBonesData 实例。
|
||||
* @param name - DragonBonesData 实例缓存名称。
|
||||
* @param disposeData - 是否释放数据。 (默认: true)
|
||||
* @see #parseDragonBonesData()
|
||||
* @see #getDragonBonesData()
|
||||
* @see #addDragonBonesData()
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void removeDragonBonesData(const std::string& name, bool disposeData = true);
|
||||
/**
|
||||
* - Get a list of specific TextureAtlasData instances.
|
||||
* @param name - The TextureAtlasData cahce name.
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的 TextureAtlasData 实例列表。
|
||||
* @param name - TextureAtlasData 实例缓存名称。
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline std::vector<TextureAtlasData*>* getTextureAtlasData(const std::string& name)
|
||||
{
|
||||
return mapFindB(_textureAtlasDataMap, name);
|
||||
}
|
||||
/**
|
||||
* - Cache a TextureAtlasData instance to the factory.
|
||||
* @param data - The TextureAtlasData instance.
|
||||
* @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)
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将 TextureAtlasData 实例缓存到工厂中。
|
||||
* @param data - TextureAtlasData 实例。
|
||||
* @param name - 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #removeTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void addTextureAtlasData(TextureAtlasData* data, const std::string& name = "");
|
||||
/**
|
||||
* - Remove a TextureAtlasData instance.
|
||||
* @param name - The TextureAtlasData instance cache name.
|
||||
* @param disposeData - Whether to dispose data.
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 移除 TextureAtlasData 实例。
|
||||
* @param name - TextureAtlasData 实例的缓存名称。
|
||||
* @param disposeData - 是否释放数据。
|
||||
* @see #parseTextureAtlasData()
|
||||
* @see #getTextureAtlasData()
|
||||
* @see #addTextureAtlasData()
|
||||
* @see dragonBones.TextureAtlasData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void removeTextureAtlasData(const std::string& name, bool disposeData = true);
|
||||
/**
|
||||
* - Get a specific armature data.
|
||||
* @param name - The armature data name.
|
||||
* @param dragonBonesName - The cached name for DragonbonesData instance.
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的骨架数据。
|
||||
* @param name - 骨架数据名称。
|
||||
* @param dragonBonesName - DragonBonesData 实例的缓存名称。
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual ArmatureData* getArmatureData(const std::string& name, const std::string& dragonBonesName = "") const;
|
||||
/**
|
||||
* - Clear all cached DragonBonesData instances and TextureAtlasData instances.
|
||||
* @param disposeData - Whether to dispose data.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 清除缓存的所有 DragonBonesData 实例和 TextureAtlasData 实例。
|
||||
* @param disposeData - 是否释放数据。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual void clear(bool disposeData = true);
|
||||
/**
|
||||
* - Create a armature from cached DragonBonesData instances and TextureAtlasData instances.
|
||||
* Note that when the created armature that is no longer in use, you need to explicitly dispose {@link #dragonBones.Armature#dispose()}.
|
||||
* @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.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let armature = factory.buildArmature("armatureName", "dragonBonesName");
|
||||
* armature.clock = factory.clock;
|
||||
* </pre>
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 通过缓存的 DragonBonesData 实例和 TextureAtlasData 实例创建一个骨架。
|
||||
* 注意,创建的骨架不再使用时,需要显式释放 {@link #dragonBones.Armature#dispose()}。
|
||||
* @param armatureName - 骨架数据名称。
|
||||
* @param dragonBonesName - DragonBonesData 实例的缓存名称。 (如果未设置,将检索所有的 DragonBonesData 实例,当多个 DragonBonesData 实例中包含同名的骨架数据时,可能无法准确的创建出特定的骨架)
|
||||
* @param skinName - 皮肤名称,可以设置一个其他骨架数据名称来共享其皮肤数据。(如果未设置,则使用默认的皮肤数据)
|
||||
* @returns 骨架。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let armature = factory.buildArmature("armatureName", "dragonBonesName");
|
||||
* armature.clock = factory.clock;
|
||||
* </pre>
|
||||
* @see dragonBones.DragonBonesData
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual Armature* buildArmature(const std::string& armatureName, const std::string& dragonBonesName = "", const std::string& skinName = "", const std::string & textureAtlasName = "") const;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
virtual void replaceDisplay(Slot* slot, DisplayData* displayData, int displayIndex) const;
|
||||
/**
|
||||
* - Replaces the current display data for a particular slot with a specific display data.
|
||||
* Specify display data with "dragonBonesName/armatureName/slotName/displayName".
|
||||
* @param dragonBonesName - The DragonBonesData instance cache name.
|
||||
* @param armatureName - The armature data name.
|
||||
* @param slotName - The slot data name.
|
||||
* @param displayName - The display data name.
|
||||
* @param slot - The slot.
|
||||
* @param displayIndex - The index of the display data that is replaced. (If it is not set, replaces the current display data)
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* factory.replaceSlotDisplay("dragonBonesName", "armatureName", "slotName", "displayName", slot);
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 用特定的显示对象数据替换特定插槽当前的显示对象数据。
|
||||
* 用 "dragonBonesName/armatureName/slotName/displayName" 指定显示对象数据。
|
||||
* @param dragonBonesName - DragonBonesData 实例的缓存名称。
|
||||
* @param armatureName - 骨架数据名称。
|
||||
* @param slotName - 插槽数据名称。
|
||||
* @param displayName - 显示对象数据名称。
|
||||
* @param slot - 插槽。
|
||||
* @param displayIndex - 被替换的显示对象数据的索引。 (如果未设置,则替换当前的显示对象数据)
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let slot = armature.getSlot("weapon");
|
||||
* factory.replaceSlotDisplay("dragonBonesName", "armatureName", "slotName", "displayName", slot);
|
||||
* </pre>
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual bool replaceSlotDisplay(
|
||||
const std::string& dragonBonesName, const std::string& armatureName, const std::string& slotName, const std::string& displayName,
|
||||
Slot* slot, int displayIndex = -1
|
||||
) const;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
virtual bool replaceSlotDisplayList(
|
||||
const std::string& dragonBonesName, const std::string& armatureName, const std::string& slotName,
|
||||
Slot* slot
|
||||
) const;
|
||||
/**
|
||||
* - Share specific skin data with specific armature.
|
||||
* @param armature - The armature.
|
||||
* @param skin - The skin data.
|
||||
* @param isOverride - Whether it completely override the original skin. (Default: false)
|
||||
* @param exclude - A list of slot names that do not need to be replace.
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let armatureA = factory.buildArmature("armatureA", "dragonBonesA");
|
||||
* let armatureDataB = factory.getArmatureData("armatureB", "dragonBonesB");
|
||||
* if (armatureDataB && armatureDataB.defaultSkin) {
|
||||
* factory.replaceSkin(armatureA, armatureDataB.defaultSkin, false, ["arm_l", "weapon_l"]);
|
||||
* }
|
||||
* </pre>
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.SkinData
|
||||
* @version DragonBones 5.6
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将特定的皮肤数据共享给特定的骨架使用。
|
||||
* @param armature - 骨架。
|
||||
* @param skin - 皮肤数据。
|
||||
* @param isOverride - 是否完全覆盖原来的皮肤。 (默认: false)
|
||||
* @param exclude - 不需要被替换的插槽名称列表。
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let armatureA = factory.buildArmature("armatureA", "dragonBonesA");
|
||||
* let armatureDataB = factory.getArmatureData("armatureB", "dragonBonesB");
|
||||
* if (armatureDataB && armatureDataB.defaultSkin) {
|
||||
* factory.replaceSkin(armatureA, armatureDataB.defaultSkin, false, ["arm_l", "weapon_l"]);
|
||||
* }
|
||||
* </pre>
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.SkinData
|
||||
* @version DragonBones 5.6
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual bool replaceSkin(Armature* armature, SkinData* skin, bool isOverride, const std::vector<std::string>& exclude) const;
|
||||
/**
|
||||
* - Replaces the existing animation data for a specific armature with the animation data for the specific armature data.
|
||||
* This enables you to make a armature template so that other armature without animations can share it's animations.
|
||||
* @param armature - The armtaure.
|
||||
* @param armatureData - The armature data.
|
||||
* @param isOverride - Whether to completely overwrite the original animation. (Default: false)
|
||||
* @example
|
||||
* TypeScript style, for reference only.
|
||||
* <pre>
|
||||
* let armatureA = factory.buildArmature("armatureA", "dragonBonesA");
|
||||
* let armatureDataB = factory.getArmatureData("armatureB", "dragonBonesB");
|
||||
* if (armatureDataB) {
|
||||
* factory.replaceAnimation(armatureA, armatureDataB);
|
||||
* }
|
||||
* </pre>
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 5.6
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 用特定骨架数据的动画数据替换特定骨架现有的动画数据。
|
||||
* 这样就能实现制作一个骨架动画模板,让其他没有制作动画的骨架共享该动画。
|
||||
* @param armature - 骨架。
|
||||
* @param armatureData - 骨架数据。
|
||||
* @param isOverride - 是否完全覆盖原来的动画。(默认: false)
|
||||
* @example
|
||||
* TypeScript 风格,仅供参考。
|
||||
* <pre>
|
||||
* let armatureA = factory.buildArmature("armatureA", "dragonBonesA");
|
||||
* let armatureDataB = factory.getArmatureData("armatureB", "dragonBonesB");
|
||||
* if (armatureDataB) {
|
||||
* factory.replaceAnimation(armatureA, armatureDataB);
|
||||
* }
|
||||
* </pre>
|
||||
* @see dragonBones.Armature
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 5.6
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual bool replaceAnimation(Armature* armature, ArmatureData* armatureData, bool isReplaceAll = true) const;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline const std::map<std::string, std::vector<TextureAtlasData*>>& getAllTextureAtlasData() const
|
||||
{
|
||||
return _textureAtlasDataMap;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline const std::map<std::string, DragonBonesData*>& getAllDragonBonesData() const
|
||||
{
|
||||
return _dragonBonesDataMap;
|
||||
}
|
||||
/**
|
||||
* - An Worldclock instance updated by engine.
|
||||
* @version DragonBones 5.7
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 由引擎驱动的 WorldClock 实例。
|
||||
* @version DragonBones 5.7
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline WorldClock* getClock() const
|
||||
{
|
||||
return _dragonBones->getClock();
|
||||
}
|
||||
|
||||
/**
|
||||
* - Deprecated, please refer to {@link #replaceSkin}.
|
||||
* @deprecated
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 已废弃,请参考 {@link #replaceSkin}。
|
||||
* @deprecated
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline bool changeSkin(Armature* armature, SkinData* skin, const std::vector<std::string>& exclude) const
|
||||
{
|
||||
return replaceSkin(armature, skin, false, exclude);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BuildArmaturePackage
|
||||
{
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(BuildArmaturePackage)
|
||||
|
||||
public:
|
||||
std::string dataName;
|
||||
std::string textureAtlasName;
|
||||
DragonBonesData* data;
|
||||
ArmatureData* armature;
|
||||
SkinData* skin;
|
||||
|
||||
BuildArmaturePackage() :
|
||||
dataName(),
|
||||
textureAtlasName(),
|
||||
data(nullptr),
|
||||
armature(nullptr),
|
||||
skin(nullptr)
|
||||
{}
|
||||
~BuildArmaturePackage() {}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_BASE_FACTORY_H
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_COLOR_TRANSFORM_H
|
||||
#define DRAGONBONES_COLOR_TRANSFORM_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ColorTransform
|
||||
{
|
||||
public:
|
||||
float alphaMultiplier;
|
||||
float redMultiplier;
|
||||
float greenMultiplier;
|
||||
float blueMultiplier;
|
||||
int alphaOffset;
|
||||
int redOffset;
|
||||
int greenOffset;
|
||||
int blueOffset;
|
||||
|
||||
ColorTransform():
|
||||
alphaMultiplier(1.0f),
|
||||
redMultiplier(1.0f),
|
||||
greenMultiplier(1.0f),
|
||||
blueMultiplier(1.0f),
|
||||
alphaOffset(0),
|
||||
redOffset(0),
|
||||
greenOffset(0),
|
||||
blueOffset(0)
|
||||
{}
|
||||
ColorTransform(const ColorTransform &value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
~ColorTransform() {}
|
||||
|
||||
inline void operator=(const ColorTransform &value)
|
||||
{
|
||||
alphaMultiplier = value.alphaMultiplier;
|
||||
redMultiplier = value.redMultiplier;
|
||||
greenMultiplier = value.greenMultiplier;
|
||||
blueMultiplier = value.blueMultiplier;
|
||||
alphaOffset = value.alphaOffset;
|
||||
redOffset = value.redOffset;
|
||||
greenOffset = value.greenOffset;
|
||||
blueOffset = value.blueOffset;
|
||||
}
|
||||
|
||||
inline void identity()
|
||||
{
|
||||
alphaMultiplier = redMultiplier = greenMultiplier = blueMultiplier = 1.0f;
|
||||
alphaOffset = redOffset = greenOffset = blueOffset = 0;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_COLOR_TRANSFORM_H
|
||||
317
cocos2d-x/cocos/editor-support/dragonbones/geom/Matrix.h
Normal file
317
cocos2d-x/cocos/editor-support/dragonbones/geom/Matrix.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_MATRIX_H
|
||||
#define DRAGONBONES_MATRIX_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
#include "Point.h"
|
||||
#include "Rectangle.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - 2D Transform matrix.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 2D 转换矩阵。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Matrix
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* - The value that affects the positioning of pixels along the x axis when scaling or rotating an image.
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 缩放或旋转图像时影响像素沿 x 轴定位的值。
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float a;
|
||||
/**
|
||||
* - The value that affects the positioning of pixels along the y axis when rotating or skewing an image.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 旋转或倾斜图像时影响像素沿 y 轴定位的值。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float b;
|
||||
/**
|
||||
* - The value that affects the positioning of pixels along the x axis when rotating or skewing an image.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 旋转或倾斜图像时影响像素沿 x 轴定位的值。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float c;
|
||||
/**
|
||||
* - The value that affects the positioning of pixels along the y axis when scaling or rotating an image.
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 缩放或旋转图像时影响像素沿 y 轴定位的值。
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float d;
|
||||
/**
|
||||
* - The distance by which to translate each point along the x axis.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 沿 x 轴平移每个点的距离。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float tx;
|
||||
/**
|
||||
* - The distance by which to translate each point along the y axis.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 沿 y 轴平移每个点的距离。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float ty;
|
||||
|
||||
Matrix():
|
||||
a(1.0f),
|
||||
b(0.0f),
|
||||
c(0.0f),
|
||||
d(1.0f),
|
||||
tx(0.0f),
|
||||
ty(0.0f)
|
||||
{}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Matrix(const Matrix& value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
~Matrix() {}
|
||||
|
||||
inline void operator=(const Matrix& value)
|
||||
{
|
||||
a = value.a;
|
||||
b = value.b;
|
||||
c = value.c;
|
||||
d = value.d;
|
||||
tx = value.tx;
|
||||
ty = value.ty;
|
||||
}
|
||||
/**
|
||||
* - Convert to unit matrix.
|
||||
* The resulting matrix has the following properties: a=1, b=0, c=0, d=1, tx=0, ty=0.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 转换为单位矩阵。
|
||||
* 该矩阵具有以下属性:a=1、b=0、c=0、d=1、tx=0、ty=0。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void identity()
|
||||
{
|
||||
a = d = 1.0f;
|
||||
b = c = 0.0f;
|
||||
tx = ty = 0.0f;
|
||||
}
|
||||
/**
|
||||
* - Multiplies the current matrix with another matrix.
|
||||
* @param value - The matrix that needs to be multiplied.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将当前矩阵与另一个矩阵相乘。
|
||||
* @param value - 需要相乘的矩阵。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void concat(const Matrix& value)
|
||||
{
|
||||
const auto aA = a;
|
||||
const auto bA = b;
|
||||
const auto cA = c;
|
||||
const auto dA = d;
|
||||
const auto txA = tx;
|
||||
const auto tyA = ty;
|
||||
const auto aB = value.a;
|
||||
const auto bB = value.b;
|
||||
const auto cB = value.c;
|
||||
const auto dB = value.d;
|
||||
const auto txB = value.tx;
|
||||
const auto tyB = value.ty;
|
||||
|
||||
a = aA * aB + bA * cB;
|
||||
b = aA * bB + bA * dB;
|
||||
c = cA * aB + dA * cB;
|
||||
d = cA * bB + dA * dB;
|
||||
tx = aB * txA + cB * tyA + txB;
|
||||
ty = dB * tyA + bB * txA + tyB;
|
||||
}
|
||||
/**
|
||||
* - Convert to inverse matrix.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 转换为逆矩阵。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void invert()
|
||||
{
|
||||
const auto aA = a;
|
||||
const auto bA = b;
|
||||
const auto cA = c;
|
||||
const auto dA = d;
|
||||
const auto txA = tx;
|
||||
const auto tyA = ty;
|
||||
const auto n = aA * dA - bA * cA;
|
||||
|
||||
a = dA / n;
|
||||
b = -bA / n;
|
||||
c = -cA / n;
|
||||
d = aA / n;
|
||||
tx = (cA * tyA - dA * txA) / n;
|
||||
ty = -(aA * tyA - bA * txA) / n;
|
||||
}
|
||||
/**
|
||||
* - Apply a matrix transformation to a specific point.
|
||||
* @param x - X coordinate.
|
||||
* @param y - Y coordinate.
|
||||
* @param result - The point after the transformation is applied.
|
||||
* @param delta - Whether to ignore tx, ty's conversion to point.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 将矩阵转换应用于特定点。
|
||||
* @param x - 横坐标。
|
||||
* @param y - 纵坐标。
|
||||
* @param result - 应用转换之后的点。
|
||||
* @param delta - 是否忽略 tx,ty 对点的转换。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline void transformPoint(float x, float y, Point& result, bool delta = false) const
|
||||
{
|
||||
result.x = a * x + c * y;
|
||||
result.y = b * x + d * y;
|
||||
|
||||
if (!delta)
|
||||
{
|
||||
result.x += tx;
|
||||
result.y += ty;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline void transformRectangle(Rectangle& rectangle, bool delta = false) const
|
||||
{
|
||||
const auto offsetX = delta ? 0.0f : this->tx;
|
||||
const auto offsetY = delta ? 0.0f : this->ty;
|
||||
|
||||
const auto x = rectangle.x;
|
||||
const auto y = rectangle.y;
|
||||
const auto xMax = x + rectangle.width;
|
||||
const auto yMax = y + rectangle.height;
|
||||
|
||||
auto x0 = a * x + c * y + offsetX;
|
||||
auto y0 = b * x + d * y + offsetY;
|
||||
auto x1 = a * xMax + c * y + offsetX;
|
||||
auto y1 = b * xMax + d * y + offsetY;
|
||||
auto x2 = a * xMax + c * yMax + offsetX;
|
||||
auto y2 = b * xMax + d * yMax + offsetY;
|
||||
auto x3 = a * x + c * yMax + offsetX;
|
||||
auto y3 = b * x + d * yMax + offsetY;
|
||||
auto tmp = 0.0f;
|
||||
|
||||
if (x0 > x1)
|
||||
{
|
||||
tmp = x0;
|
||||
x0 = x1;
|
||||
x1 = tmp;
|
||||
}
|
||||
|
||||
if (x2 > x3)
|
||||
{
|
||||
tmp = x2;
|
||||
x2 = x3;
|
||||
x3 = tmp;
|
||||
}
|
||||
|
||||
rectangle.x = std::floor(x0 < x2 ? x0 : x2);
|
||||
rectangle.width = std::ceil((x1 > x3 ? x1 : x3) - rectangle.x);
|
||||
|
||||
if (y0 > y1)
|
||||
{
|
||||
tmp = y0;
|
||||
y0 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
|
||||
if (y2 > y3)
|
||||
{
|
||||
tmp = y2;
|
||||
y2 = y3;
|
||||
y3 = tmp;
|
||||
}
|
||||
|
||||
rectangle.y = std::floor(y0 < y2 ? y0 : y2);
|
||||
rectangle.height = std::ceil((y1 > y3 ? y1 : y3) - rectangle.y);
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_MATRIX_H
|
||||
10
cocos2d-x/cocos/editor-support/dragonbones/geom/Point.cpp
Normal file
10
cocos2d-x/cocos/editor-support/dragonbones/geom/Point.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "Point.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
Point Point::helpPointA;
|
||||
Point Point::helpPointB;
|
||||
Point Point::helpPointC;
|
||||
Point Point::helpPointD;
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
121
cocos2d-x/cocos/editor-support/dragonbones/geom/Point.h
Normal file
121
cocos2d-x/cocos/editor-support/dragonbones/geom/Point.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_POINT_H
|
||||
#define DRAGONBONES_POINT_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The Point object represents a location in a two-dimensional coordinate system.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - Point 对象表示二维坐标系统中的某个位置。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
static Point helpPointA;
|
||||
static Point helpPointB;
|
||||
static Point helpPointC;
|
||||
static Point helpPointD;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The horizontal coordinate.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 该点的水平坐标。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float x;
|
||||
/**
|
||||
* - The vertical coordinate.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 该点的垂直坐标。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float y;
|
||||
|
||||
Point():
|
||||
x(0.0f),
|
||||
y(0.0f)
|
||||
{}
|
||||
/**
|
||||
* - Creates a new point. If you pass no parameters to this method, a point is created at (0,0).
|
||||
* @param x - The horizontal coordinate.
|
||||
* @param y - The vertical coordinate.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 创建一个 egret.Point 对象.若不传入任何参数,将会创建一个位于(0,0)位置的点。
|
||||
* @param x - 该对象的x属性值,默认为 0.0。
|
||||
* @param y - 该对象的y属性值,默认为 0.0。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
Point(const Point& value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
~Point() {}
|
||||
|
||||
inline void operator=(const Point& value)
|
||||
{
|
||||
x = value.x;
|
||||
y = value.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline void clear()
|
||||
{
|
||||
x = y = 0.0f;
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
static Point* getHelpPointA() { return &helpPointA; }
|
||||
static Point* getHelpPointB() { return &helpPointB; }
|
||||
static Point* getHelpPointC() { return &helpPointC; }
|
||||
static Point* getHelpPointD() { return &helpPointD; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_POINT_H
|
||||
137
cocos2d-x/cocos/editor-support/dragonbones/geom/Rectangle.h
Normal file
137
cocos2d-x/cocos/editor-support/dragonbones/geom/Rectangle.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_RECTANGLE_H
|
||||
#define DRAGONBONES_RECTANGLE_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - A Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its
|
||||
* width and its height.<br/>
|
||||
* The x, y, width, and height properties of the Rectangle class are independent of each other; changing the value of
|
||||
* one property has no effect on the others. However, the right and bottom properties are integrally related to those
|
||||
* four properties. For example, if you change the value of the right property, the value of the width property changes;
|
||||
* if you change the bottom property, the value of the height property changes.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - Rectangle 对象是按其位置(由它左上角的点 (x, y) 确定)以及宽度和高度定义的区域。<br/>
|
||||
* Rectangle 类的 x、y、width 和 height 属性相互独立;更改一个属性的值不会影响其他属性。
|
||||
* 但是,right 和 bottom 属性与这四个属性是整体相关的。例如,如果更改 right 属性的值,则 width
|
||||
* 属性的值将发生变化;如果更改 bottom 属性,则 height 属性的值将发生变化。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Rectangle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* - The x coordinate of the top-left corner of the rectangle.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 矩形左上角的 x 坐标。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float x;
|
||||
/**
|
||||
* - The y coordinate of the top-left corner of the rectangle.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 矩形左上角的 y 坐标。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float y;
|
||||
/**
|
||||
* - The width of the rectangle, in pixels.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 矩形的宽度(以像素为单位)。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float width;
|
||||
/**
|
||||
* - 矩形的高度(以像素为单位)。
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - The height of the rectangle, in pixels.
|
||||
* @default 0.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float height;
|
||||
|
||||
Rectangle():
|
||||
x(0.0f),
|
||||
y(0.0f),
|
||||
width(0.0f),
|
||||
height(0.0f)
|
||||
{}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Rectangle(const Rectangle& value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
~Rectangle() {}
|
||||
|
||||
inline void operator=(const Rectangle& value)
|
||||
{
|
||||
x = value.x;
|
||||
y = value.y;
|
||||
width = value.width;
|
||||
height = value.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
x = y = 0.0f;
|
||||
width = height = 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_RECTANGLE_H
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
#include "Transform.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
const float Transform::PI = 3.14159265358979323846f;
|
||||
const float Transform::PI_D = PI * 2.0f;
|
||||
const float Transform::PI_H = PI * 0.5f;
|
||||
const float Transform::PI_Q = PI * 0.25f;
|
||||
const float Transform::DEG_RAD = PI / 180.f;
|
||||
const float Transform::RAD_DEG = 180.f / PI;
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
289
cocos2d-x/cocos/editor-support/dragonbones/geom/Transform.h
Normal file
289
cocos2d-x/cocos/editor-support/dragonbones/geom/Transform.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_TRANSFORM_H
|
||||
#define DRAGONBONES_TRANSFORM_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - 2D Transform.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 2D 变换。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class Transform final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float PI;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float PI_D;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float PI_H;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float PI_Q;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float DEG_RAD;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static const float RAD_DEG;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static float normalizeRadian(float value)
|
||||
{
|
||||
value = fmod(value + Transform::PI, Transform::PI * 2.0f);
|
||||
value += value > 0.0f ? -Transform::PI : Transform::PI;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Horizontal translate.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 水平位移。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float x;
|
||||
/**
|
||||
* - Vertical translate.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 垂直位移。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float y;
|
||||
/**
|
||||
* - Skew. (In radians)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 倾斜。 (以弧度为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float skew;
|
||||
/**
|
||||
* - rotation. (In radians)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 旋转。 (以弧度为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float rotation;
|
||||
/**
|
||||
* - Horizontal Scaling.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 水平缩放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float scaleX;
|
||||
/**
|
||||
* - Vertical scaling.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 垂直缩放。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float scaleY;
|
||||
|
||||
Transform():
|
||||
x(0.0f),
|
||||
y(0.0f),
|
||||
skew(0.0f),
|
||||
rotation(0.0f),
|
||||
scaleX(1.0f),
|
||||
scaleY(1.0f)
|
||||
{}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Transform(const Transform& value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
~Transform() {}
|
||||
|
||||
inline void operator=(const Transform& value)
|
||||
{
|
||||
x = value.x;
|
||||
y = value.y;
|
||||
skew = value.skew;
|
||||
rotation = value.rotation;
|
||||
scaleX = value.scaleX;
|
||||
scaleY = value.scaleY;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline Transform& identity()
|
||||
{
|
||||
x = y = skew = rotation = 0.0f;
|
||||
scaleX = scaleY = 1.0f;
|
||||
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline Transform& add(const Transform& value)
|
||||
{
|
||||
x += value.x;
|
||||
y += value.y;
|
||||
skew += value.skew;
|
||||
rotation += value.rotation;
|
||||
scaleX *= value.scaleX;
|
||||
scaleY *= value.scaleY;
|
||||
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline Transform& minus(const Transform& value)
|
||||
{
|
||||
x -= value.x;
|
||||
y -= value.y;
|
||||
skew -= value.skew;
|
||||
rotation -= value.rotation;
|
||||
scaleX /= value.scaleX;
|
||||
scaleY /= value.scaleY;
|
||||
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline Transform& fromMatrix(const Matrix& matrix)
|
||||
{
|
||||
const auto backupScaleX = scaleX, backupScaleY = scaleY;
|
||||
|
||||
x = matrix.tx;
|
||||
y = matrix.ty;
|
||||
|
||||
rotation = std::atan(matrix.b / matrix.a);
|
||||
auto skewX = std::atan(-matrix.c / matrix.d);
|
||||
|
||||
scaleX = (rotation > -PI_Q && rotation < PI_Q) ? matrix.a / std::cos(rotation) : matrix.b / std::sin(rotation);
|
||||
scaleY = (skewX > -PI_Q && skewX < PI_Q) ? matrix.d / std::cos(skewX) : -matrix.c / std::sin(skewX);
|
||||
|
||||
if (backupScaleX >= 0.0f && scaleX < 0.0f)
|
||||
{
|
||||
scaleX = -scaleX;
|
||||
rotation = rotation - PI;
|
||||
}
|
||||
|
||||
if (backupScaleY >= 0.0f && scaleY < 0.0f)
|
||||
{
|
||||
scaleY = -scaleY;
|
||||
skewX = skewX - PI;
|
||||
}
|
||||
|
||||
skew = skewX - rotation;
|
||||
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline Transform& toMatrix(Matrix& matrix)
|
||||
{
|
||||
if (rotation == 0.0f)
|
||||
{
|
||||
matrix.a = 1.0f;
|
||||
matrix.b = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix.a = std::cos(rotation);
|
||||
matrix.b = std::sin(rotation);
|
||||
}
|
||||
|
||||
if (skew == 0.0f)
|
||||
{
|
||||
matrix.c = -matrix.b;
|
||||
matrix.d = matrix.a;
|
||||
}
|
||||
else {
|
||||
matrix.c = -std::sin(skew + rotation);
|
||||
matrix.d = std::cos(skew + rotation);
|
||||
}
|
||||
|
||||
if (scaleX != 1.0f)
|
||||
{
|
||||
matrix.a *= scaleX;
|
||||
matrix.b *= scaleX;
|
||||
}
|
||||
|
||||
if (scaleY != 1.0f)
|
||||
{
|
||||
matrix.c *= scaleY;
|
||||
matrix.d *= scaleY;
|
||||
}
|
||||
|
||||
matrix.tx = x;
|
||||
matrix.ty = y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_TRANSFORM_H
|
||||
@@ -0,0 +1,141 @@
|
||||
#include "AnimationConfig.h"
|
||||
#include "../armature/Armature.h"
|
||||
#include "../armature/Bone.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void AnimationConfig::_onClear()
|
||||
{
|
||||
pauseFadeOut = true;
|
||||
fadeOutMode = AnimationFadeOutMode::All;
|
||||
fadeOutTweenType = TweenType::Line;
|
||||
fadeOutTime = -1.0f;
|
||||
|
||||
actionEnabled = true;
|
||||
additiveBlending = false;
|
||||
displayControl = true;
|
||||
pauseFadeIn = true;
|
||||
resetToPose = true;
|
||||
fadeInTweenType = TweenType::Line;
|
||||
playTimes = -1;
|
||||
layer = 0;
|
||||
position = 0.0f;
|
||||
duration = -1.0f;
|
||||
timeScale = -100.0f;
|
||||
weight = 1.0f;
|
||||
fadeInTime = -1.0f;
|
||||
autoFadeOutTime = -1.0f;
|
||||
name = "";
|
||||
animation = "";
|
||||
group = "";
|
||||
boneMask.clear();
|
||||
}
|
||||
|
||||
void AnimationConfig::clear()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
void AnimationConfig::copyFrom(AnimationConfig* value)
|
||||
{
|
||||
pauseFadeOut = value->pauseFadeOut;
|
||||
fadeOutMode = value->fadeOutMode;
|
||||
autoFadeOutTime = value->autoFadeOutTime;
|
||||
fadeOutTweenType = value->fadeOutTweenType;
|
||||
|
||||
actionEnabled = value->actionEnabled;
|
||||
additiveBlending = value->additiveBlending;
|
||||
displayControl = value->displayControl;
|
||||
pauseFadeIn = value->pauseFadeIn;
|
||||
resetToPose = value->resetToPose;
|
||||
playTimes = value->playTimes;
|
||||
layer = value->layer;
|
||||
position = value->position;
|
||||
duration = value->duration;
|
||||
timeScale = value->timeScale;
|
||||
weight = value->weight;
|
||||
fadeInTime = value->fadeInTime;
|
||||
fadeOutTime = value->fadeOutTime;
|
||||
fadeInTweenType = value->fadeInTweenType;
|
||||
name = value->name;
|
||||
animation = value->animation;
|
||||
group = value->group;
|
||||
boneMask = value->boneMask;
|
||||
}
|
||||
|
||||
bool AnimationConfig::containsBoneMask(const std::string& boneName) const
|
||||
{
|
||||
return boneMask.empty() || std::find(boneMask.cbegin(), boneMask.cend(), boneName) != boneMask.cend();
|
||||
}
|
||||
|
||||
void AnimationConfig::addBoneMask(Armature* armature, const std::string& boneName, bool recursive)
|
||||
{
|
||||
const auto currentBone = armature->getBone(boneName);
|
||||
if (currentBone == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::find(boneMask.cbegin(), boneMask.cend(), boneName) == boneMask.cend()) // Add mixing
|
||||
{
|
||||
boneMask.push_back(boneName);
|
||||
}
|
||||
|
||||
if (recursive) // Add recursive mixing.
|
||||
{
|
||||
for (const auto bone : armature->getBones())
|
||||
{
|
||||
if (std::find(boneMask.cbegin(), boneMask.cend(), bone->getName()) == boneMask.cend() && currentBone->contains(bone))
|
||||
{
|
||||
boneMask.push_back(bone->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationConfig::removeBoneMask(Armature* armature, const std::string& boneName, bool recursive)
|
||||
{
|
||||
{
|
||||
auto iterator = std::find(boneMask.begin(), boneMask.end(), boneName);
|
||||
if (iterator != boneMask.end()) // Remove mixing.
|
||||
{
|
||||
boneMask.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
const auto currentBone = armature->getBone(boneName);
|
||||
if (currentBone != nullptr)
|
||||
{
|
||||
if (!boneMask.empty()) // Remove recursive mixing.
|
||||
{
|
||||
for (const auto bone : armature->getBones())
|
||||
{
|
||||
auto iterator = std::find(boneMask.begin(), boneMask.end(), bone->getName());
|
||||
if (iterator != boneMask.end() && currentBone->contains(bone))
|
||||
{
|
||||
boneMask.erase(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Add unrecursive mixing.
|
||||
{
|
||||
for (const auto bone : armature->getBones())
|
||||
{
|
||||
if (bone == currentBone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentBone->contains(bone))
|
||||
{
|
||||
boneMask.push_back(bone->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ANIMATION_CONFIG_H
|
||||
#define DRAGONBONES_ANIMATION_CONFIG_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The animation config is used to describe all the information needed to play an animation state.
|
||||
* The API is still in the experimental phase and may encounter bugs or stability or compatibility issues when used.
|
||||
* @see dragonBones.AnimationState
|
||||
* @beta
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画配置用来描述播放一个动画状态所需要的全部信息。
|
||||
* 该 API 仍在实验阶段,使用时可能遭遇 bug 或稳定性或兼容性问题。
|
||||
* @see dragonBones.AnimationState
|
||||
* @beta
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class AnimationConfig : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(AnimationConfig);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool pauseFadeOut;
|
||||
/**
|
||||
* - Fade out the pattern of other animation states when the animation state is fade in.
|
||||
* This property is typically used to specify the substitution of multiple animation states blend.
|
||||
* @default dragonBones.AnimationFadeOutMode.All
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡入动画状态时淡出其他动画状态的模式。
|
||||
* 该属性通常用来指定多个动画状态混合时的相互替换关系。
|
||||
* @default dragonBones.AnimationFadeOutMode.All
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationFadeOutMode fadeOutMode;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TweenType fadeOutTweenType;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float fadeOutTime;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool actionEnabled;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool additiveBlending;
|
||||
/**
|
||||
* - Whether the animation state has control over the display property of the slots.
|
||||
* Sometimes blend a animation state does not want it to control the display properties of the slots,
|
||||
* especially if other animation state are controlling the display properties of the slots.
|
||||
* @default true
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态是否对插槽的显示对象属性有控制权。
|
||||
* 有时混合一个动画状态并不希望其控制插槽的显示对象属性,
|
||||
* 尤其是其他动画状态正在控制这些插槽的显示对象属性时。
|
||||
* @default true
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool displayControl;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool pauseFadeIn;
|
||||
/**
|
||||
* - Whether to reset the objects without animation to the armature pose when the animation state is start to play.
|
||||
* This property should usually be set to false when blend multiple animation states.
|
||||
* @default true
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 开始播放动画状态时是否将没有动画的对象重置为骨架初始值。
|
||||
* 通常在混合多个动画状态时应该将该属性设置为 false。
|
||||
* @default true
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
bool resetToPose;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TweenType fadeInTweenType;
|
||||
/**
|
||||
* - The play times. [0: Loop play, [1~N]: Play N times]
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放次数。 [0: 无限循环播放, [1~N]: 循环播放 N 次]
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
int playTimes;
|
||||
/**
|
||||
* - The blend layer.
|
||||
* High layer animation state will get the blend weight first.
|
||||
* When the blend weight is assigned more than 1, the remaining animation states will no longer get the weight assigned.
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合图层。
|
||||
* 图层高的动画状态会优先获取混合权重。
|
||||
* 当混合权重分配超过 1 时,剩余的动画状态将不再获得权重分配。
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
int layer;
|
||||
/**
|
||||
* - The start time of play. (In seconds)
|
||||
* @default 0.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放的开始时间。 (以秒为单位)
|
||||
* @default 0.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float position;
|
||||
/**
|
||||
* - The duration of play.
|
||||
* [-1: Use the default value of the animation data, 0: Stop play, (0~N]: The duration] (In seconds)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放的持续时间。
|
||||
* [-1: 使用动画数据默认值, 0: 动画停止, (0~N]: 持续时间] (以秒为单位)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float duration;
|
||||
/**
|
||||
* - The play speed.
|
||||
* The value is an overlay relationship with {@link dragonBones.Animation#timeScale}.
|
||||
* [(-N~0): Reverse play, 0: Stop play, (0~1): Slow play, 1: Normal play, (1~N): Fast play]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 播放速度。
|
||||
* 该值与 {@link dragonBones.Animation#timeScale} 是叠加关系。
|
||||
* [(-N~0): 倒转播放, 0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
|
||||
* @default 1.0
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float timeScale;
|
||||
/**
|
||||
* - The blend weight.
|
||||
* @default 1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合权重。
|
||||
* @default 1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float weight;
|
||||
/**
|
||||
* - The fade in time.
|
||||
* [-1: Use the default value of the animation data, [0~N]: The fade in time] (In seconds)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 淡入时间。
|
||||
* [-1: 使用动画数据默认值, [0~N]: 淡入时间] (以秒为单位)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float fadeInTime;
|
||||
/**
|
||||
* - The auto fade out time when the animation state play completed.
|
||||
* [-1: Do not fade out automatically, [0~N]: The fade out time] (In seconds)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态播放完成后的自动淡出时间。
|
||||
* [-1: 不自动淡出, [0~N]: 淡出时间] (以秒为单位)
|
||||
* @default -1.0
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float autoFadeOutTime;
|
||||
/**
|
||||
* - The name of the animation state. (Can be different from the name of the animation data)
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画状态名称。 (可以不同于动画数据)
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* - The animation data name.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画数据名称。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string animation;
|
||||
/**
|
||||
* - The blend group name of the animation state.
|
||||
* This property is typically used to specify the substitution of multiple animation states blend.
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 混合组名称。
|
||||
* 该属性通常用来指定多个动画状态混合时的相互替换关系。
|
||||
* @readonly
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string group;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<std::string> boneMask;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void copyFrom(AnimationConfig* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool containsBoneMask(const std::string& boneName) const;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void addBoneMask(Armature* armature, const std::string& boneName, bool recursive);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void removeBoneMask(Armature* armature, const std::string& boneName, bool recursive);
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getFadeOutMode() const { return (int)fadeOutMode; }
|
||||
void setFadeOutMode(int value) { fadeOutMode = (AnimationFadeOutMode)value; }
|
||||
|
||||
int getFadeOutTweenType() const { return (int)fadeOutTweenType; }
|
||||
void setFadeOutTweenType(int value) { fadeOutTweenType = (TweenType)value; }
|
||||
|
||||
int getFadeInTweenType() const { return (int)fadeInTweenType; }
|
||||
void setFadeInTweenType(int value) { fadeInTweenType = (TweenType)value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ANIMATION_CONFIG_H
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "AnimationData.h"
|
||||
#include "ArmatureData.h"
|
||||
#include "ConstraintData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void AnimationData::_onClear()
|
||||
{
|
||||
for (const auto& pair : boneTimelines)
|
||||
{
|
||||
for (const auto timeline : pair.second)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : slotTimelines)
|
||||
{
|
||||
for (const auto timeline : pair.second)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : constraintTimelines)
|
||||
{
|
||||
for (const auto timeline : pair.second)
|
||||
{
|
||||
timeline->returnToPool();
|
||||
}
|
||||
}
|
||||
|
||||
if (actionTimeline != nullptr)
|
||||
{
|
||||
actionTimeline->returnToPool();
|
||||
}
|
||||
|
||||
if (zOrderTimeline != nullptr)
|
||||
{
|
||||
zOrderTimeline->returnToPool();
|
||||
}
|
||||
|
||||
frameIntOffset = 0;
|
||||
frameFloatOffset = 0;
|
||||
frameOffset = 0;
|
||||
frameCount = 0;
|
||||
playTimes = 0;
|
||||
duration = 0.0f;
|
||||
scale = 1.0f;
|
||||
fadeInTime = 0.0f;
|
||||
cacheFrameRate = 0.0f;
|
||||
name = "";
|
||||
cachedFrames.clear();
|
||||
boneTimelines.clear();
|
||||
slotTimelines.clear();
|
||||
constraintTimelines.clear();
|
||||
boneCachedFrameIndices.clear();
|
||||
slotCachedFrameIndices.clear();
|
||||
parent = nullptr;
|
||||
actionTimeline = nullptr;
|
||||
zOrderTimeline = nullptr;
|
||||
}
|
||||
|
||||
void AnimationData::cacheFrames(unsigned frameRate)
|
||||
{
|
||||
if (cacheFrameRate > 0.0f) // TODO clear cache.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cacheFrameRate = std::max(std::ceil(frameRate * scale), 1.0f);
|
||||
const auto cacheFrameCount = std::ceil(cacheFrameRate * duration) + 1; // Cache one more frame.
|
||||
|
||||
cachedFrames.resize(cacheFrameCount, false);
|
||||
|
||||
for (const auto bone : parent->sortedBones)
|
||||
{
|
||||
boneCachedFrameIndices[bone->name].resize(cacheFrameCount, -1);
|
||||
}
|
||||
|
||||
for (const auto slot : parent->sortedSlots)
|
||||
{
|
||||
slotCachedFrameIndices[slot->name].resize(cacheFrameCount, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationData::addBoneTimeline(BoneData* bone, TimelineData* value)
|
||||
{
|
||||
auto& timelines = boneTimelines[bone->name];
|
||||
if(std::find(timelines.cbegin(), timelines.cend(), value) == timelines.cend())
|
||||
{
|
||||
timelines.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationData::addSlotTimeline(SlotData* slot, TimelineData* value)
|
||||
{
|
||||
auto& timelines = slotTimelines[slot->name];
|
||||
if (std::find(timelines.cbegin(), timelines.cend(), value) == timelines.cend())
|
||||
{
|
||||
timelines.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationData::addConstraintTimeline(ConstraintData* constraint, TimelineData* value)
|
||||
{
|
||||
auto& timelines = constraintTimelines[constraint->name];
|
||||
if (std::find(timelines.cbegin(), timelines.cend(), value) == timelines.cend())
|
||||
{
|
||||
timelines.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineData::_onClear()
|
||||
{
|
||||
type = TimelineType::BoneAll;
|
||||
offset = 0;
|
||||
frameIndicesOffset = -1;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
256
cocos2d-x/cocos/editor-support/dragonbones/model/AnimationData.h
Normal file
256
cocos2d-x/cocos/editor-support/dragonbones/model/AnimationData.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ANIMATION_DATA_H
|
||||
#define DRAGONBONES_ANIMATION_DATA_H
|
||||
|
||||
#include "ArmatureData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The animation data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class AnimationData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(AnimationData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - FrameIntArray.
|
||||
* @internal
|
||||
*/
|
||||
unsigned frameIntOffset;
|
||||
/**
|
||||
* - FrameFloatArray.
|
||||
* @internal
|
||||
*/
|
||||
unsigned frameFloatOffset;
|
||||
/**
|
||||
* - FrameArray.
|
||||
* @internal
|
||||
*/
|
||||
unsigned frameOffset;
|
||||
/**
|
||||
* - The frame count of the animation.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画的帧数。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned frameCount;
|
||||
/**
|
||||
* - The play times of the animation. [0: Loop play, [1~N]: Play N times]
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画的播放次数。 [0: 无限循环播放, [1~N]: 循环播放 N 次]
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned playTimes;
|
||||
/**
|
||||
* - The duration of the animation. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画的持续时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float duration;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float scale;
|
||||
/**
|
||||
* - The fade in time of the animation. (In seconds)
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画的淡入时间。 (以秒为单位)
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float fadeInTime;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float cacheFrameRate;
|
||||
/**
|
||||
* - The animation name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<bool> cachedFrames;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<TimelineData*>> boneTimelines;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<TimelineData*>> slotTimelines;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<TimelineData*>> constraintTimelines;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<int>> boneCachedFrameIndices;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<int>> slotCachedFrameIndices;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimelineData* actionTimeline;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimelineData* zOrderTimeline;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ArmatureData* parent;
|
||||
AnimationData() :
|
||||
actionTimeline(nullptr),
|
||||
zOrderTimeline(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~AnimationData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void cacheFrames(unsigned frameRate);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void addBoneTimeline(BoneData* bone, TimelineData* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void addSlotTimeline(SlotData* slot, TimelineData* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void addConstraintTimeline(ConstraintData* constraint, TimelineData* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<TimelineData*>* getBoneTimelines(const std::string& timelineName)
|
||||
{
|
||||
return mapFindB(boneTimelines, timelineName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline std::vector<TimelineData*>* getSlotTimelines(const std::string& timelineName)
|
||||
{
|
||||
return mapFindB(slotTimelines, timelineName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline std::vector<TimelineData*>* getConstraintTimelines(const std::string& timelineName)
|
||||
{
|
||||
return mapFindB(constraintTimelines, timelineName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline std::vector<int>* getBoneCachedFrameIndices(const std::string& boneName)
|
||||
{
|
||||
return mapFindB(boneCachedFrameIndices, boneName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline std::vector<int>* getSlotCachedFrameIndices(const std::string& slotName)
|
||||
{
|
||||
return mapFindB(slotCachedFrameIndices, slotName);
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
TimelineData* getActionTimeline() const { return actionTimeline; }
|
||||
void setActionTimeline(TimelineData* pactionTimeline) { actionTimeline = pactionTimeline; }
|
||||
|
||||
TimelineData* getZOrderTimeline() const { return zOrderTimeline; }
|
||||
void setZOrderTimeline(TimelineData* value) { zOrderTimeline = value; }
|
||||
|
||||
ArmatureData* getParent() const { return parent; }
|
||||
void setParent(ArmatureData* value) { parent = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class TimelineData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(TimelineData);
|
||||
|
||||
public:
|
||||
TimelineType type;
|
||||
unsigned offset;
|
||||
int frameIndicesOffset;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getType() const { return (int)type; }
|
||||
void setType(int value) { type = (TimelineType)value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ANIMATION_DATA_H
|
||||
@@ -0,0 +1,320 @@
|
||||
#include "ArmatureData.h"
|
||||
#include "UserData.h"
|
||||
#include "DragonBonesData.h"
|
||||
#include "ConstraintData.h"
|
||||
#include "CanvasData.h"
|
||||
#include "SkinData.h"
|
||||
#include "DisplayData.h"
|
||||
#include "AnimationData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void ArmatureData::_onClear()
|
||||
{
|
||||
for (const auto action : defaultActions)
|
||||
{
|
||||
action->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto action : actions)
|
||||
{
|
||||
action->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : bones)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : slots)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : constraints)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : skins)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
for (const auto& pair : animations)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
if (canvas != nullptr)
|
||||
{
|
||||
canvas->returnToPool();
|
||||
}
|
||||
|
||||
if (userData != nullptr)
|
||||
{
|
||||
userData->returnToPool();
|
||||
}
|
||||
|
||||
type = ArmatureType::Armature;
|
||||
frameRate = 0;
|
||||
cacheFrameRate = 0;
|
||||
scale = 1.0f;
|
||||
name = "";
|
||||
aabb.clear();
|
||||
animationNames.clear();
|
||||
sortedBones.clear();
|
||||
sortedSlots.clear();
|
||||
defaultActions.clear();
|
||||
actions.clear();
|
||||
bones.clear();
|
||||
slots.clear();
|
||||
constraints.clear();
|
||||
skins.clear();
|
||||
animations.clear();
|
||||
parent = nullptr;
|
||||
defaultSkin = nullptr;
|
||||
defaultAnimation = nullptr;
|
||||
canvas = nullptr;
|
||||
userData = nullptr;
|
||||
}
|
||||
|
||||
void ArmatureData::sortBones()
|
||||
{
|
||||
const auto total = sortedBones.size();
|
||||
if (total <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sortHelper = sortedBones; // Copy.
|
||||
unsigned index = 0;
|
||||
unsigned count = 0;
|
||||
sortedBones.clear();
|
||||
while (count < total)
|
||||
{
|
||||
const auto bone = sortHelper[index++];
|
||||
if (index >= total)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (std::find(sortedBones.cbegin(), sortedBones.cend(), bone) != sortedBones.cend())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto flag = false;
|
||||
for(const auto& pair : constraints)
|
||||
{
|
||||
const auto constrait = pair.second;
|
||||
if(constrait->root == bone && std::find(sortedBones.cbegin(), sortedBones.cend(), constrait->target) == sortedBones.cend())
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bone->parent != nullptr && std::find(sortedBones.cbegin(), sortedBones.cend(), bone->parent) == sortedBones.cend())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sortedBones.push_back(bone);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
void ArmatureData::cacheFrames(unsigned value)
|
||||
{
|
||||
if (cacheFrameRate > value) // TODO clear cache.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cacheFrameRate = value;
|
||||
for (const auto& pair : animations)
|
||||
{
|
||||
pair.second->cacheFrames(cacheFrameRate);
|
||||
}
|
||||
}
|
||||
|
||||
int ArmatureData::setCacheFrame(const Matrix& globalTransformMatrix, const Transform& transform)
|
||||
{
|
||||
auto& dataArray = *&parent->cachedFrames;
|
||||
auto arrayOffset = dataArray.size();
|
||||
|
||||
dataArray.resize(arrayOffset + 10);
|
||||
dataArray[arrayOffset] = globalTransformMatrix.a;
|
||||
dataArray[arrayOffset + 1] = globalTransformMatrix.b;
|
||||
dataArray[arrayOffset + 2] = globalTransformMatrix.c;
|
||||
dataArray[arrayOffset + 3] = globalTransformMatrix.d;
|
||||
dataArray[arrayOffset + 4] = globalTransformMatrix.tx;
|
||||
dataArray[arrayOffset + 5] = globalTransformMatrix.ty;
|
||||
dataArray[arrayOffset + 6] = transform.rotation;
|
||||
dataArray[arrayOffset + 7] = transform.skew;
|
||||
dataArray[arrayOffset + 8] = transform.scaleX;
|
||||
dataArray[arrayOffset + 9] = transform.scaleY;
|
||||
|
||||
return arrayOffset;
|
||||
}
|
||||
|
||||
void ArmatureData::getCacheFrame(Matrix& globalTransformMatrix, Transform& transform, unsigned arrayOffset) const
|
||||
{
|
||||
auto& dataArray = *&parent->cachedFrames;
|
||||
globalTransformMatrix.a = dataArray[arrayOffset];
|
||||
globalTransformMatrix.b = dataArray[arrayOffset + 1];
|
||||
globalTransformMatrix.c = dataArray[arrayOffset + 2];
|
||||
globalTransformMatrix.d = dataArray[arrayOffset + 3];
|
||||
globalTransformMatrix.tx = dataArray[arrayOffset + 4];
|
||||
globalTransformMatrix.ty = dataArray[arrayOffset + 5];
|
||||
transform.rotation = dataArray[arrayOffset + 6];
|
||||
transform.skew = dataArray[arrayOffset + 7];
|
||||
transform.scaleX = dataArray[arrayOffset + 8];
|
||||
transform.scaleY = dataArray[arrayOffset + 9];
|
||||
transform.x = globalTransformMatrix.tx;
|
||||
transform.y = globalTransformMatrix.ty;
|
||||
}
|
||||
|
||||
void ArmatureData::addBone(BoneData* value)
|
||||
{
|
||||
if (bones.find(value->name) != bones.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same bone: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
bones[value->name] = value;
|
||||
sortedBones.push_back(value);
|
||||
}
|
||||
|
||||
void ArmatureData::addSlot(SlotData* value)
|
||||
{
|
||||
if (slots.find(value->name) != slots.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same slot: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
slots[value->name] = value;
|
||||
sortedSlots.push_back(value);
|
||||
}
|
||||
|
||||
void ArmatureData::addConstraint(ConstraintData * value)
|
||||
{
|
||||
if (constraints.find(value->name) != constraints.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same constaint: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
constraints[value->name] = value;
|
||||
}
|
||||
|
||||
void ArmatureData::addSkin(SkinData* value)
|
||||
{
|
||||
if (skins.find(value->name) != skins.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same skin: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
value->parent = this;
|
||||
skins[value->name] = value;
|
||||
|
||||
if (defaultSkin == nullptr)
|
||||
{
|
||||
defaultSkin = value;
|
||||
}
|
||||
}
|
||||
|
||||
void ArmatureData::addAnimation(AnimationData* value)
|
||||
{
|
||||
if (animations.find(value->name) != animations.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same animation: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
value->parent = this;
|
||||
animations[value->name] = value;
|
||||
animationNames.push_back(value->name);
|
||||
if (defaultAnimation == nullptr)
|
||||
{
|
||||
defaultAnimation = value;
|
||||
}
|
||||
}
|
||||
|
||||
void ArmatureData::addAction(ActionData* value, bool isDefault)
|
||||
{
|
||||
if (isDefault)
|
||||
{
|
||||
defaultActions.push_back(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
actions.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
MeshDisplayData* ArmatureData::getMesh(const std::string& skinName, const std::string& slotName, const std::string& meshName) const
|
||||
{
|
||||
const auto skin = getSkin(skinName);
|
||||
if (skin == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return static_cast<MeshDisplayData*>(skin->getDisplay(slotName, meshName));
|
||||
}
|
||||
|
||||
void BoneData::_onClear()
|
||||
{
|
||||
if (userData != nullptr)
|
||||
{
|
||||
userData->returnToPool();
|
||||
}
|
||||
|
||||
inheritTranslation = false;
|
||||
inheritRotation = false;
|
||||
inheritScale = false;
|
||||
inheritReflection = false;
|
||||
length = 0.0f;
|
||||
name = "";
|
||||
transform.identity();
|
||||
parent = nullptr;
|
||||
userData = nullptr;
|
||||
}
|
||||
|
||||
ColorTransform SlotData::DEFAULT_COLOR;
|
||||
ColorTransform* SlotData::createColor()
|
||||
{
|
||||
return new ColorTransform();
|
||||
}
|
||||
|
||||
void SlotData::_onClear()
|
||||
{
|
||||
if (userData != nullptr)
|
||||
{
|
||||
userData->returnToPool();
|
||||
}
|
||||
|
||||
if (color != nullptr && color != &DEFAULT_COLOR)
|
||||
{
|
||||
delete color;
|
||||
}
|
||||
|
||||
blendMode = BlendMode::Normal;
|
||||
displayIndex = 0;
|
||||
zOrder = 0;
|
||||
name = "";
|
||||
parent = nullptr;
|
||||
color = nullptr;
|
||||
userData = nullptr;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
513
cocos2d-x/cocos/editor-support/dragonbones/model/ArmatureData.h
Normal file
513
cocos2d-x/cocos/editor-support/dragonbones/model/ArmatureData.h
Normal file
@@ -0,0 +1,513 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_ARMATURE_DATA_H
|
||||
#define DRAGONBONES_ARMATURE_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Matrix.h"
|
||||
#include "../geom/Transform.h"
|
||||
#include "../geom/ColorTransform.h"
|
||||
#include "../geom/Rectangle.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The armature data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class ArmatureData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(ArmatureData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ArmatureType type;
|
||||
/**
|
||||
* - The animation frame rate.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画帧率。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned frameRate;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
unsigned cacheFrameRate;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float scale;
|
||||
/**
|
||||
* - The armature name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨架名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Rectangle aabb;
|
||||
/**
|
||||
* - The names of all the animation data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所有的动画数据名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<std::string> animationNames;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<BoneData*> sortedBones;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<SlotData*> sortedSlots;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<ActionData*> defaultActions;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<ActionData*> actions;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, BoneData*> bones;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, SlotData*> slots;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, ConstraintData*> constraints;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, SkinData*> skins;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, AnimationData*> animations;
|
||||
/**
|
||||
* - The default skin data.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 默认插槽数据。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
SkinData* defaultSkin;
|
||||
/**
|
||||
* - The default animation data.
|
||||
* @version DragonBones 4.5
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 默认动画数据。
|
||||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
AnimationData* defaultAnimation;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
CanvasData* canvas;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
UserData* userData;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
DragonBonesData* parent;
|
||||
ArmatureData() :
|
||||
canvas(nullptr),
|
||||
userData(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~ArmatureData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void sortBones();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void cacheFrames(unsigned frameRate);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
int setCacheFrame(const Matrix& globalTransformMatrix, const Transform& transform);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void getCacheFrame(Matrix& globalTransformMatrix, Transform& transform, unsigned arrayOffset) const;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addBone(BoneData* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addSlot(SlotData* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addConstraint(ConstraintData* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addSkin(SkinData* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addAnimation(AnimationData* value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addAction(ActionData* value, bool isDefault);
|
||||
/**
|
||||
* - Get a specific done data.
|
||||
* @param boneName - The bone name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的骨骼数据。
|
||||
* @param boneName - 骨骼名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline BoneData* getBone(const std::string& boneName) const
|
||||
{
|
||||
return mapFind<BoneData>(bones, boneName);
|
||||
}
|
||||
/**
|
||||
* - Get a specific slot data.
|
||||
* @param slotName - The slot name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的插槽数据。
|
||||
* @param slotName - 插槽名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline SlotData* getSlot(const std::string& slotName) const
|
||||
{
|
||||
return mapFind<SlotData>(slots, slotName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline ConstraintData* getConstraint(const std::string& constraintName) const
|
||||
{
|
||||
return mapFind<ConstraintData>(constraints, constraintName);
|
||||
}
|
||||
/**
|
||||
* - Get a specific skin data.
|
||||
* @param skinName - The skin name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定皮肤数据。
|
||||
* @param skinName - 皮肤名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline SkinData* getSkin(const std::string& skinName) const
|
||||
{
|
||||
return mapFind(skins, skinName);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
MeshDisplayData* getMesh(const std::string& skinName, const std::string& slotName, const std::string& meshName) const;
|
||||
/**
|
||||
* - Get a specific animation data.
|
||||
* @param animationName - The animation animationName.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的动画数据。
|
||||
* @param animationName - 动画名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline AnimationData* getAnimation(const std::string& animationName) const
|
||||
{
|
||||
return mapFind(animations, animationName);
|
||||
}
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getType() const { return (int)type; }
|
||||
void setType(int value) { type = (ArmatureType)value; }
|
||||
|
||||
Rectangle* getAABB() { return &aabb; }
|
||||
const std::vector<std::string>& getAnimationNames() const { return animationNames; }
|
||||
const std::vector<BoneData*>& getSortedBones() const { return sortedBones; }
|
||||
const std::vector<SlotData*>& getSortedSlots() const { return sortedSlots; }
|
||||
const std::vector<ActionData*>& getDefaultActions() const { return defaultActions; }
|
||||
const std::vector<ActionData*>& getActions() const { return actions; }
|
||||
|
||||
SkinData* getDefaultSkin() const { return defaultSkin; }
|
||||
void setDefaultSkin(SkinData* value) { defaultSkin = value; }
|
||||
|
||||
AnimationData* getDefaultAnimation() const { return defaultAnimation; }
|
||||
void setDefaultAnimation(AnimationData* value) { defaultAnimation = value; }
|
||||
|
||||
const UserData* getUserData() const { return userData; }
|
||||
void setUserData(UserData* value) { userData = value; }
|
||||
|
||||
const DragonBonesData* getParent() const { return parent; }
|
||||
void setParent(DragonBonesData* value) { parent = value; }
|
||||
};
|
||||
/**
|
||||
* - The bone data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class BoneData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(BoneData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool inheritTranslation;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool inheritRotation;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool inheritScale;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool inheritReflection;
|
||||
/**
|
||||
* - The bone length.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼长度。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float length;
|
||||
/**
|
||||
* - The bone name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 骨骼名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Transform transform;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
UserData* userData;
|
||||
/**
|
||||
* - The parent bone data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 父骨骼数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
BoneData* parent;
|
||||
BoneData() :
|
||||
userData(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~BoneData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
Transform* getTransfrom() { return &transform; }
|
||||
|
||||
const UserData* getUserData() const { return userData; }
|
||||
void setUserData(UserData* value) { userData = value; }
|
||||
|
||||
const BoneData* getParent() const { return parent; }
|
||||
void setParent(BoneData* value) { parent = value; }
|
||||
};
|
||||
/**
|
||||
* - The slot data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class SlotData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(SlotData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static ColorTransform DEFAULT_COLOR;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static ColorTransform* createColor();
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
BlendMode blendMode;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
int displayIndex;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
int zOrder;
|
||||
/**
|
||||
* - The slot name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 插槽名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ColorTransform* color;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
UserData* userData;
|
||||
/**
|
||||
* - The parent bone data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 父骨骼数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
BoneData* parent;
|
||||
SlotData() :
|
||||
color(nullptr),
|
||||
userData(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~SlotData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
static ColorTransform* getDefaultColor() { return &DEFAULT_COLOR; }
|
||||
|
||||
int getBlendMode() const { return (int)blendMode; }
|
||||
void setBlendMode(int value) { blendMode = (BlendMode)value; }
|
||||
|
||||
ColorTransform* getColor() const { return color; }
|
||||
void setColor(ColorTransform* value) { color = value; }
|
||||
|
||||
const BoneData* getParent() const { return parent; }
|
||||
void setParent(BoneData* value) { parent = value; }
|
||||
|
||||
const UserData* getUserData() const { return userData; }
|
||||
void setUserData(UserData* value) { userData = value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_ARMATURE_DATA_H
|
||||
@@ -0,0 +1,644 @@
|
||||
|
||||
#include "BoundingBoxData.h"
|
||||
#include "DisplayData.h"
|
||||
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void BoundingBoxData::_onClear()
|
||||
{
|
||||
color = 0x000000;
|
||||
width = 0.0f;
|
||||
height = 0.0f;
|
||||
}
|
||||
|
||||
int RectangleBoundingBoxData::_computeOutCode(float x, float y, float xMin, float yMin, float xMax, float yMax)
|
||||
{
|
||||
int code = OutCode::InSide; // initialised as being inside of [[clip window]]
|
||||
|
||||
if (x < xMin) // to the left of clip window
|
||||
{
|
||||
code |= OutCode::Left;
|
||||
}
|
||||
else if (x > xMax) // to the right of clip window
|
||||
{
|
||||
code |= OutCode::Right;
|
||||
}
|
||||
|
||||
if (y < yMin) // below the clip window
|
||||
{
|
||||
code |= OutCode::Top;
|
||||
}
|
||||
else if (y > yMax) // above the clip window
|
||||
{
|
||||
code |= OutCode::Bottom;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int RectangleBoundingBoxData::rectangleIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
float xMin, float yMin, float xMax, float yMax,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
const auto inSideA = xA > xMin && xA < xMax && yA > yMin && yA < yMax;
|
||||
const auto inSideB = xB > xMin && xB < xMax && yB > yMin && yB < yMax;
|
||||
|
||||
if (inSideA && inSideB)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto intersectionCount = 0;
|
||||
auto outcode0 = RectangleBoundingBoxData::_computeOutCode(xA, yA, xMin, yMin, xMax, yMax);
|
||||
auto outcode1 = RectangleBoundingBoxData::_computeOutCode(xB, yB, xMin, yMin, xMax, yMax);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((outcode0 | outcode1) == 0) // Bitwise OR is 0. Trivially accept and get out of loop
|
||||
{
|
||||
intersectionCount = 2;
|
||||
break;
|
||||
}
|
||||
else if ((outcode0 & outcode1) != 0) // Bitwise AND is not 0. Trivially reject and get out of loop
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// failed both tests, so calculate the line segment to clip
|
||||
// from an outside point to an intersection with clip edge
|
||||
auto x = 0.0f;
|
||||
auto y = 0.0f;
|
||||
auto normalRadian = 0.0f;
|
||||
|
||||
// At least one endpoint is outside the clip rectangle; pick it.
|
||||
const auto outcodeOut = outcode0 != 0 ? outcode0 : outcode1;
|
||||
|
||||
// Now find the intersection point;
|
||||
if ((outcodeOut & OutCode::Top) != 0) // point is above the clip rectangle
|
||||
{
|
||||
x = xA + (xB - xA) * (yMin - yA) / (yB - yA);
|
||||
y = yMin;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadian = -Transform::PI * 0.5f;
|
||||
}
|
||||
}
|
||||
else if ((outcodeOut & OutCode::Bottom) != 0) // point is below the clip rectangle
|
||||
{
|
||||
x = xA + (xB - xA) * (yMax - yA) / (yB - yA);
|
||||
y = yMax;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadian = Transform::PI * 0.5;
|
||||
}
|
||||
}
|
||||
else if ((outcodeOut & OutCode::Right) != 0) // point is to the right of clip rectangle
|
||||
{
|
||||
y = yA + (yB - yA) * (xMax - xA) / (xB - xA);
|
||||
x = xMax;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadian = 0;
|
||||
}
|
||||
}
|
||||
else if ((outcodeOut & OutCode::Left) != 0) // point is to the left of clip rectangle
|
||||
{
|
||||
y = yA + (yB - yA) * (xMin - xA) / (xB - xA);
|
||||
x = xMin;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadian = Transform::PI;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we move outside point to intersection point to clip
|
||||
// and get ready for next pass.
|
||||
if (outcodeOut == outcode0)
|
||||
{
|
||||
xA = x;
|
||||
yA = y;
|
||||
outcode0 = RectangleBoundingBoxData::_computeOutCode(xA, yA, xMin, yMin, xMax, yMax);
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = normalRadian;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xB = x;
|
||||
yB = y;
|
||||
outcode1 = RectangleBoundingBoxData::_computeOutCode(xB, yB, xMin, yMin, xMax, yMax);
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->y = normalRadian;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intersectionCount)
|
||||
{
|
||||
if (inSideA)
|
||||
{
|
||||
intersectionCount = 2; // 10
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xB;
|
||||
intersectionPointA->y = yB;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xB;
|
||||
intersectionPointB->y = xB;
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = normalRadians->y + Transform::PI;
|
||||
}
|
||||
}
|
||||
else if (inSideB)
|
||||
{
|
||||
intersectionCount = 1; // 01
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xA;
|
||||
intersectionPointA->y = yA;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xA;
|
||||
intersectionPointB->y = yA;
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->y = normalRadians->x + Transform::PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
intersectionCount = 3; // 11
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xA;
|
||||
intersectionPointA->y = yA;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xB;
|
||||
intersectionPointB->y = yB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
void RectangleBoundingBoxData::_onClear()
|
||||
{
|
||||
BoundingBoxData::_onClear();
|
||||
|
||||
type = BoundingBoxType::Rectangle;
|
||||
}
|
||||
|
||||
bool RectangleBoundingBoxData::containsPoint(float pX, float pY)
|
||||
{
|
||||
const auto widthH = width * 0.5f;
|
||||
if (pX >= -widthH && pX <= widthH)
|
||||
{
|
||||
const auto heightH = height * 0.5f;
|
||||
if (pY >= -heightH && pY <= heightH)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int RectangleBoundingBoxData::intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
const auto widthH = width * 0.5f;
|
||||
const auto heightH = height * 0.5f;
|
||||
const auto intersectionCount = RectangleBoundingBoxData::rectangleIntersectsSegment(
|
||||
xA, yA, xB, yB,
|
||||
-widthH, -heightH, widthH, heightH,
|
||||
intersectionPointA, intersectionPointB, normalRadians
|
||||
);
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
int EllipseBoundingBoxData::ellipseIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
float xC, float yC, float widthH, float heightH,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
const auto d = widthH / heightH;
|
||||
const auto dd = d * d;
|
||||
|
||||
yA *= d;
|
||||
yB *= d;
|
||||
|
||||
const auto dX = xB - xA;
|
||||
const auto dY = yB - yA;
|
||||
const auto lAB = sqrt(dX * dX + dY * dY);
|
||||
const auto xD = dX / lAB;
|
||||
const auto yD = dY / lAB;
|
||||
const auto a = (xC - xA) * xD + (yC - yA) * yD;
|
||||
const auto aa = a * a;
|
||||
const auto ee = xA * xA + yA * yA;
|
||||
const auto rr = widthH * widthH;
|
||||
const auto dR = rr - ee + aa;
|
||||
auto intersectionCount = 0;
|
||||
|
||||
if (dR >= 0.0f)
|
||||
{
|
||||
const auto dT = sqrt(dR);
|
||||
const auto sA = a - dT;
|
||||
const auto sB = a + dT;
|
||||
const auto inSideA = sA < 0.0f ? -1 : (sA <= lAB ? 0 : 1);
|
||||
const auto inSideB = sB < 0.0f ? -1 : (sB <= lAB ? 0 : 1);
|
||||
const auto sideAB = inSideA * inSideB;
|
||||
|
||||
if (sideAB < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (sideAB == 0)
|
||||
{
|
||||
if (inSideA == -1)
|
||||
{
|
||||
intersectionCount = 2; // 10
|
||||
xB = xA + sB * xD;
|
||||
yB = (yA + sB * yD) / d;
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xB;
|
||||
intersectionPointA->y = yB;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xB;
|
||||
intersectionPointB->y = yB;
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(yB / rr * dd, xB / rr);
|
||||
normalRadians->y = normalRadians->x + Transform::PI;
|
||||
}
|
||||
}
|
||||
else if (inSideB == 1)
|
||||
{
|
||||
intersectionCount = 1; // 01
|
||||
xA = xA + sA * xD;
|
||||
yA = (yA + sA * yD) / d;
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xA;
|
||||
intersectionPointA->y = yA;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xA;
|
||||
intersectionPointB->y = yA;
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(yA / rr * dd, xA / rr);
|
||||
normalRadians->y = normalRadians->x + Transform::PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
intersectionCount = 3; // 11
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xA + sA * xD;
|
||||
intersectionPointA->y = (yA + sA * yD) / d;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(intersectionPointA->y / rr * dd, intersectionPointA->x / rr);
|
||||
}
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xA + sB * xD;
|
||||
intersectionPointB->y = (yA + sB * yD) / d;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->y = atan2(intersectionPointB->y / rr * dd, intersectionPointB->x / rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
void EllipseBoundingBoxData::_onClear()
|
||||
|
||||
{
|
||||
BoundingBoxData::_onClear();
|
||||
|
||||
type = BoundingBoxType::Ellipse;
|
||||
}
|
||||
|
||||
bool EllipseBoundingBoxData::containsPoint(float pX, float pY)
|
||||
{
|
||||
const auto widthH = width * 0.5f;
|
||||
if (pX >= -widthH && pX <= widthH)
|
||||
{
|
||||
const auto heightH = height * 0.5f;
|
||||
if (pY >= -heightH && pY <= heightH)
|
||||
{
|
||||
pY *= widthH / heightH;
|
||||
return sqrt(pX * pX + pY * pY) <= widthH;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int EllipseBoundingBoxData::intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
const auto intersectionCount = EllipseBoundingBoxData::ellipseIntersectsSegment(
|
||||
xA, yA, xB, yB,
|
||||
0.0f, 0.0f, width * 0.5f, height * 0.5f,
|
||||
intersectionPointA, intersectionPointB, normalRadians
|
||||
);
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
int PolygonBoundingBoxData::polygonIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
const std::vector<float>& vertices,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians)
|
||||
{
|
||||
if (xA == xB)
|
||||
{
|
||||
xA = xB + 0.000001f;
|
||||
}
|
||||
|
||||
if (yA == yB)
|
||||
{
|
||||
yA = yB + 0.000001f;
|
||||
}
|
||||
|
||||
const auto count = vertices.size();
|
||||
const auto dXAB = xA - xB;
|
||||
const auto dYAB = yA - yB;
|
||||
const auto llAB = xA * yB - yA * xB;
|
||||
auto intersectionCount = 0;
|
||||
auto xC = vertices[count - 2];
|
||||
auto yC = vertices[count - 1];
|
||||
auto dMin = 0.0f;
|
||||
auto dMax = 0.0f;
|
||||
auto xMin = 0.0f;
|
||||
auto yMin = 0.0f;
|
||||
auto xMax = 0.0f;
|
||||
auto yMax = 0.0f;
|
||||
|
||||
for (std::size_t i = 0; i < count; i += 2)
|
||||
{
|
||||
const auto xD = vertices[i];
|
||||
const auto yD = vertices[i + 1];
|
||||
|
||||
if (xC == xD)
|
||||
{
|
||||
xC = xD + 0.000001f;
|
||||
}
|
||||
|
||||
if (yC == yD)
|
||||
{
|
||||
yC = yD + 0.000001f;
|
||||
}
|
||||
|
||||
const auto dXCD = xC - xD;
|
||||
const auto dYCD = yC - yD;
|
||||
const auto llCD = xC * yD - yC * xD;
|
||||
const auto ll = dXAB * dYCD - dYAB * dXCD;
|
||||
const auto x = (llAB * dXCD - dXAB * llCD) / ll;
|
||||
|
||||
if (((x >= xC && x <= xD) || (x >= xD && x <= xC)) && (dXAB == 0.0f || (x >= xA && x <= xB) || (x >= xB && x <= xA)))
|
||||
{
|
||||
const auto y = (llAB * dYCD - dYAB * llCD) / ll;
|
||||
if (((y >= yC && y <= yD) || (y >= yD && y <= yC)) && (dYAB == 0.0f || (y >= yA && y <= yB) || (y >= yB && y <= yA)))
|
||||
{
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
float d = x - xA;
|
||||
if (d < 0.0f)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
|
||||
if (intersectionCount == 0)
|
||||
{
|
||||
dMin = d;
|
||||
dMax = d;
|
||||
xMin = x;
|
||||
yMin = y;
|
||||
xMax = x;
|
||||
yMax = y;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(yD - yC, xD - xC) - Transform::PI * 0.5f;
|
||||
normalRadians->y = normalRadians->x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d < dMin)
|
||||
{
|
||||
dMin = d;
|
||||
xMin = x;
|
||||
yMin = y;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(yD - yC, xD - xC) - Transform::PI * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
if (d > dMax)
|
||||
{
|
||||
dMax = d;
|
||||
xMax = x;
|
||||
yMax = y;
|
||||
|
||||
if (normalRadians != nullptr) {
|
||||
normalRadians->y = atan2(yD - yC, xD - xC) - Transform::PI * 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intersectionCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xMin = x;
|
||||
yMin = y;
|
||||
xMax = x;
|
||||
yMax = y;
|
||||
intersectionCount++;
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->x = atan2(yD - yC, xD - xC) - Transform::PI * 0.5f;
|
||||
normalRadians->y = normalRadians->x;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xC = xD;
|
||||
yC = yD;
|
||||
}
|
||||
|
||||
if (intersectionCount == 1)
|
||||
{
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xMin;
|
||||
intersectionPointA->y = yMin;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xMin;
|
||||
intersectionPointB->y = yMin;
|
||||
}
|
||||
|
||||
if (normalRadians != nullptr)
|
||||
{
|
||||
normalRadians->y = normalRadians->x + Transform::PI;
|
||||
}
|
||||
}
|
||||
else if (intersectionCount > 1)
|
||||
{
|
||||
intersectionCount++;
|
||||
|
||||
if (intersectionPointA != nullptr)
|
||||
{
|
||||
intersectionPointA->x = xMin;
|
||||
intersectionPointA->y = yMin;
|
||||
}
|
||||
|
||||
if (intersectionPointB != nullptr)
|
||||
{
|
||||
intersectionPointB->x = xMax;
|
||||
intersectionPointB->y = yMax;
|
||||
}
|
||||
}
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
void PolygonBoundingBoxData::_onClear()
|
||||
{
|
||||
BoundingBoxData::_onClear();
|
||||
|
||||
if (weight != nullptr)
|
||||
{
|
||||
weight->returnToPool();
|
||||
}
|
||||
|
||||
type = BoundingBoxType::Polygon;
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
vertices.clear();
|
||||
weight = nullptr;
|
||||
}
|
||||
|
||||
bool PolygonBoundingBoxData::containsPoint(float pX, float pY)
|
||||
{
|
||||
auto isInSide = false;
|
||||
if (pX >= x && pX <= width && pY >= y && pY <= height)
|
||||
{
|
||||
for (std::size_t i = 0, l = vertices.size(), iP = l - 2; i < l; i += 2)
|
||||
{
|
||||
const auto yA = vertices[iP + 1];
|
||||
const auto yB = vertices[i + 1];
|
||||
if ((yB < pY && yA >= pY) || (yA < pY && yB >= pY))
|
||||
{
|
||||
const auto xA = vertices[iP];
|
||||
const auto xB = vertices[i];
|
||||
if ((pY - yB) * (xA - xB) / (yA - yB) + xB < pX)
|
||||
{
|
||||
isInSide = !isInSide;
|
||||
}
|
||||
}
|
||||
|
||||
iP = i;
|
||||
}
|
||||
}
|
||||
|
||||
return isInSide;
|
||||
}
|
||||
|
||||
int PolygonBoundingBoxData::intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA,
|
||||
Point* intersectionPointB,
|
||||
Point* normalRadians
|
||||
)
|
||||
{
|
||||
auto intersectionCount = 0;
|
||||
if (RectangleBoundingBoxData::rectangleIntersectsSegment(xA, yA, xB, yB, x, y, x + width, y + height, nullptr, nullptr, nullptr) != 0) {
|
||||
intersectionCount = PolygonBoundingBoxData::polygonIntersectsSegment(
|
||||
xA, yA, xB, yB,
|
||||
vertices,
|
||||
intersectionPointA, intersectionPointB, normalRadians
|
||||
);
|
||||
}
|
||||
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONESCPP_BOUNDINGBOXDATA_H
|
||||
#define DRAGONBONESCPP_BOUNDINGBOXDATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Point.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The base class of bounding box data.
|
||||
* @see dragonBones.RectangleData
|
||||
* @see dragonBones.EllipseData
|
||||
* @see dragonBones.PolygonData
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 边界框数据基类。
|
||||
* @see dragonBones.RectangleData
|
||||
* @see dragonBones.EllipseData
|
||||
* @see dragonBones.PolygonData
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class BoundingBoxData : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(BoundingBoxData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The bounding box type.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 边界框类型。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
BoundingBoxType type;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
unsigned color;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float width;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float height;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* - Check whether the bounding box contains a specific point. (Local coordinate system)
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查边界框是否包含特定点。(本地坐标系)
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual bool containsPoint(float pX, float pY) = 0;
|
||||
/**
|
||||
* - Check whether the bounding box intersects a specific segment. (Local coordinate system)
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 检查边界框是否与特定线段相交。(本地坐标系)
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual int intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
) = 0;
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getType() const { return (int)type; }
|
||||
void setType(int value) { type = (BoundingBoxType)value; }
|
||||
};
|
||||
/**
|
||||
* - The rectangle bounding box data.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 矩形边界框数据。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
class RectangleBoundingBoxData : public BoundingBoxData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(RectangleBoundingBoxData);
|
||||
|
||||
private:
|
||||
enum OutCode {
|
||||
InSide = 0, // 0000
|
||||
Left = 1, // 0001
|
||||
Right = 2, // 0010
|
||||
Top = 4, // 0100
|
||||
Bottom = 8 // 1000
|
||||
};
|
||||
/**
|
||||
* - Compute the bit code for a point (x, y) using the clip rectangle
|
||||
*/
|
||||
static int _computeOutCode(float x, float y, float xMin, float yMin, float xMax, float yMax);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static int rectangleIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
float xMin, float yMin, float xMax, float yMax,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual bool containsPoint(float pX, float pY) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual int intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
) override;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
/**
|
||||
* - The ellipse bounding box data.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 椭圆边界框数据。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
class EllipseBoundingBoxData : public BoundingBoxData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(EllipseBoundingBoxData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static int ellipseIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
float xC, float yC, float widthH, float heightH,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual bool containsPoint(float pX, float pY) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual int intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
) override;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
/**
|
||||
* - The polygon bounding box data.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 多边形边界框数据。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
class PolygonBoundingBoxData : public BoundingBoxData
|
||||
{
|
||||
BIND_CLASS_TYPE_B(PolygonBoundingBoxData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static int polygonIntersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
const std::vector<float>& vertices,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float x;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float y;
|
||||
/**
|
||||
* - The polygon vertices.
|
||||
* @version DragonBones 5.1
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 多边形顶点。
|
||||
* @version DragonBones 5.1
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<float> vertices;
|
||||
WeightData* weight;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual bool containsPoint(float pX, float pY) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual int intersectsSegment(
|
||||
float xA, float yA, float xB, float yB,
|
||||
Point* intersectionPointA = nullptr,
|
||||
Point* intersectionPointB = nullptr,
|
||||
Point* normalRadians = nullptr
|
||||
) override;
|
||||
|
||||
PolygonBoundingBoxData() :
|
||||
weight(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~PolygonBoundingBoxData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
std::vector<float>* getVertices() { return &vertices; }
|
||||
|
||||
/*WeightData* getWeight() const { return weight; }
|
||||
void setWeight(WeightData* value) { weight = value; }
|
||||
*/
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif //DRAGONBONESCPP_BOUNDINGBOXDATA_H
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "CanvasData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void CanvasData::_onClear()
|
||||
{
|
||||
hasBackground = false;
|
||||
color = 0x000000;
|
||||
aabb.clear();
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_CANVAS_DATA_H
|
||||
#define DRAGONBONES_CANVAS_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Rectangle.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class CanvasData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(CanvasData);
|
||||
|
||||
public:
|
||||
bool hasBackground;
|
||||
unsigned color;
|
||||
Rectangle aabb;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_CANVAS_DATA_H
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by liangshuochen on 09/06/2017.
|
||||
//
|
||||
|
||||
#include "ConstraintData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void ConstraintData::_onClear()
|
||||
{
|
||||
order = 0;
|
||||
name = "";
|
||||
target = nullptr;
|
||||
root = nullptr;
|
||||
bone = nullptr;
|
||||
}
|
||||
|
||||
void IKConstraintData::_onClear()
|
||||
{
|
||||
ConstraintData::_onClear();
|
||||
|
||||
scaleEnabled = false;
|
||||
bendPositive = false;
|
||||
weight = 1.0f;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
//
|
||||
// Created by liangshuochen on 09/06/2017.
|
||||
//
|
||||
|
||||
#ifndef DRAGONBONESCPP_CONSTRAINTDATA_H
|
||||
#define DRAGONBONESCPP_CONSTRAINTDATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ConstraintData : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(ConstraintData)
|
||||
|
||||
public:
|
||||
int order;
|
||||
std::string name;
|
||||
const BoneData* target;
|
||||
const BoneData* root;
|
||||
const BoneData* bone;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
const BoneData* getTarget() const { return target; }
|
||||
void setTarget(const BoneData* value) { target = value; }
|
||||
|
||||
const BoneData* getBone() const { return bone; }
|
||||
void setBone(const BoneData* value) { bone = value; }
|
||||
|
||||
const BoneData* getRoot() const { return root; }
|
||||
void setRoot(const BoneData* value) { root = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class IKConstraintData : public ConstraintData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(IKConstraintData);
|
||||
|
||||
public:
|
||||
bool scaleEnabled;
|
||||
bool bendPositive;
|
||||
float weight;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif //DRAGONBONESCPP_CONSTRAINTDATA_H
|
||||
103
cocos2d-x/cocos/editor-support/dragonbones/model/DisplayData.cpp
Normal file
103
cocos2d-x/cocos/editor-support/dragonbones/model/DisplayData.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Created by liangshuochen on 08/06/2017.
|
||||
//
|
||||
|
||||
#include "DisplayData.h"
|
||||
#include "UserData.h"
|
||||
#include "BoundingBoxData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void VerticesData::clear()
|
||||
{
|
||||
if (!isShared && weight != nullptr)
|
||||
{
|
||||
weight->returnToPool();
|
||||
}
|
||||
|
||||
isShared = false;
|
||||
inheritDeform = false;
|
||||
offset = 0;
|
||||
data = nullptr;
|
||||
weight = nullptr;
|
||||
}
|
||||
|
||||
void VerticesData::shareFrom(const VerticesData& value)
|
||||
{
|
||||
isShared = true;
|
||||
offset = value.offset;
|
||||
weight = value.weight;
|
||||
}
|
||||
|
||||
void DisplayData::_onClear()
|
||||
{
|
||||
name = "";
|
||||
path = "";
|
||||
transform.identity();
|
||||
parent = nullptr;
|
||||
}
|
||||
|
||||
void ImageDisplayData::_onClear()
|
||||
{
|
||||
DisplayData::_onClear();
|
||||
|
||||
type = DisplayType::Image;
|
||||
pivot.clear();
|
||||
texture = nullptr;
|
||||
}
|
||||
|
||||
void ArmatureDisplayData::_onClear()
|
||||
{
|
||||
DisplayData::_onClear();
|
||||
|
||||
for(const auto action : actions)
|
||||
{
|
||||
action->returnToPool();
|
||||
}
|
||||
|
||||
type = DisplayType::Armature;
|
||||
inheritAnimation = false;
|
||||
actions.clear();
|
||||
armature = nullptr;
|
||||
}
|
||||
|
||||
void ArmatureDisplayData::addAction(ActionData* value)
|
||||
{
|
||||
actions.push_back(value);
|
||||
}
|
||||
|
||||
void MeshDisplayData::_onClear()
|
||||
{
|
||||
DisplayData::_onClear();
|
||||
|
||||
type = DisplayType::Mesh;
|
||||
vertices.clear();
|
||||
texture = nullptr;
|
||||
}
|
||||
|
||||
void BoundingBoxDisplayData::_onClear()
|
||||
{
|
||||
DisplayData::_onClear();
|
||||
|
||||
if(boundingBox != nullptr)
|
||||
{
|
||||
boundingBox->returnToPool();
|
||||
}
|
||||
|
||||
type = DisplayType::BoundingBox;
|
||||
boundingBox = nullptr;
|
||||
}
|
||||
|
||||
void WeightData::_onClear()
|
||||
{
|
||||
count = 0;
|
||||
offset = 0;
|
||||
bones.clear();
|
||||
}
|
||||
|
||||
void WeightData::addBone(BoneData* value)
|
||||
{
|
||||
bones.push_back(value);
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
192
cocos2d-x/cocos/editor-support/dragonbones/model/DisplayData.h
Normal file
192
cocos2d-x/cocos/editor-support/dragonbones/model/DisplayData.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONESCPP_DISPLAYDATA_H
|
||||
#define DRAGONBONESCPP_DISPLAYDATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Transform.h"
|
||||
#include "BoundingBoxData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class VerticesData
|
||||
{
|
||||
public:
|
||||
bool isShared;
|
||||
bool inheritDeform;
|
||||
unsigned offset;
|
||||
DragonBonesData* data;
|
||||
WeightData* weight;
|
||||
|
||||
VerticesData() :
|
||||
weight(nullptr)
|
||||
{
|
||||
}
|
||||
~VerticesData()
|
||||
{
|
||||
}
|
||||
|
||||
void clear();
|
||||
void shareFrom(const VerticesData& value);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class DisplayData : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(DisplayData)
|
||||
|
||||
public:
|
||||
DisplayType type;
|
||||
std::string name;
|
||||
std::string path;
|
||||
Transform transform;
|
||||
SkinData* parent;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getType() const { return (int)type; }
|
||||
void setType(int value) { type = (DisplayType)value; }
|
||||
|
||||
Transform* getTransform() { return &transform; }
|
||||
|
||||
SkinData* getParent() const { return parent; }
|
||||
void setParent(SkinData* value) { parent = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ImageDisplayData : public DisplayData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(ImageDisplayData);
|
||||
|
||||
public:
|
||||
Point pivot;
|
||||
TextureData* texture;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
Point* getPivot() { return &pivot; }
|
||||
|
||||
TextureData* getTexture() const { return texture; }
|
||||
void setTexture(TextureData* value) { texture = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ArmatureDisplayData : public DisplayData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(ArmatureDisplayData);
|
||||
|
||||
public:
|
||||
bool inheritAnimation;
|
||||
std::vector<ActionData*> actions;
|
||||
ArmatureData* armature;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void addAction(ActionData* value);
|
||||
|
||||
public: // For WebAssembly.
|
||||
const std::vector<ActionData*>& getActions() const { return actions; }
|
||||
|
||||
ArmatureData* getArmature() const { return armature; }
|
||||
void setArmature(ArmatureData* value) { armature = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class MeshDisplayData : public DisplayData
|
||||
{
|
||||
BIND_CLASS_TYPE_A(MeshDisplayData);
|
||||
|
||||
public:
|
||||
VerticesData vertices;
|
||||
TextureData* texture;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BoundingBoxDisplayData : public DisplayData
|
||||
{
|
||||
BIND_CLASS_TYPE_B(BoundingBoxDisplayData);
|
||||
|
||||
public:
|
||||
BoundingBoxData* boundingBox;
|
||||
|
||||
BoundingBoxDisplayData() :
|
||||
boundingBox(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~BoundingBoxDisplayData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
const BoundingBoxData* getBoundingBox() const { return boundingBox; }
|
||||
void setBoundingBox(BoundingBoxData* value) { boundingBox = value; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class WeightData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(WeightData);
|
||||
|
||||
public:
|
||||
unsigned count;
|
||||
unsigned offset;
|
||||
std::vector<BoneData*> bones;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
void addBone(BoneData* value);
|
||||
|
||||
public: // For WebAssembly.
|
||||
const std::vector<BoneData*>& getBones() const { return bones; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
|
||||
#endif //DRAGONBONESCPP_DISPLAYDATA_H
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "DragonBonesData.h"
|
||||
#include "UserData.h"
|
||||
#include "ArmatureData.h"
|
||||
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void DragonBonesData::_onClear()
|
||||
{
|
||||
for (const auto& pair : armatures)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
if (binary != nullptr)
|
||||
{
|
||||
delete binary;
|
||||
}
|
||||
|
||||
if (userData != nullptr)
|
||||
{
|
||||
userData->returnToPool();
|
||||
}
|
||||
|
||||
autoSearch = false;
|
||||
frameRate = 0;
|
||||
version = "";
|
||||
name = "";
|
||||
frameIndices.clear();
|
||||
cachedFrames.clear();
|
||||
armatureNames.clear();
|
||||
armatures.clear();
|
||||
binary = nullptr;
|
||||
intArray = nullptr;
|
||||
floatArray = nullptr;
|
||||
frameIntArray = nullptr;
|
||||
frameFloatArray = nullptr;
|
||||
frameArray = nullptr;
|
||||
timelineArray = nullptr;
|
||||
userData = nullptr;
|
||||
}
|
||||
|
||||
void DragonBonesData::addArmature(ArmatureData* value)
|
||||
{
|
||||
if (armatures.find(value->name) != armatures.end())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same armature: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
value->parent = this;
|
||||
armatures[value->name] = value;
|
||||
armatureNames.push_back(value->name);
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_DRAGONBONES_DATA_H
|
||||
#define DRAGONBONES_DRAGONBONES_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "ArmatureData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The DragonBones data.
|
||||
* A DragonBones data contains multiple armature data.
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 龙骨数据。
|
||||
* 一个龙骨数据包含多个骨架数据。
|
||||
* @see dragonBones.ArmatureData
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class DragonBonesData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(DragonBonesData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool autoSearch;
|
||||
/**
|
||||
* - The animation frame rate.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 动画帧频。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
unsigned frameRate;
|
||||
/**
|
||||
* - The data version.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 数据版本。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string version;
|
||||
/**
|
||||
* - The DragonBones data name.
|
||||
* The name is consistent with the DragonBones project name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 龙骨数据名称。
|
||||
* 该名称与龙骨项目名保持一致。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
std::vector<unsigned> frameIndices;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
std::vector<float> cachedFrames;
|
||||
/**
|
||||
* - All armature data names.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 所有的骨架数据名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<std::string> armatureNames;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, ArmatureData*> armatures;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const char* binary;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const int16_t* intArray;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const float* floatArray;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const int16_t* frameIntArray;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const float* frameFloatArray;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const int16_t* frameArray;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const uint16_t* timelineArray;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
UserData* userData;
|
||||
DragonBonesData() :
|
||||
binary(nullptr),
|
||||
userData(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
~DragonBonesData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addArmature(ArmatureData* value);
|
||||
/**
|
||||
* - Get a specific armature data.
|
||||
* @param armatureName - The armature data name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取特定的骨架数据。
|
||||
* @param armatureName - 骨架数据名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline ArmatureData* getArmature(const std::string& armatureName) const
|
||||
{
|
||||
return mapFind<ArmatureData>(armatures, armatureName);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
std::vector<unsigned>* getFrameIndices() { return &frameIndices; }
|
||||
const std::vector<std::string>& getArmatureNames() const { return armatureNames; }
|
||||
|
||||
#if EGRET_WASM
|
||||
unsigned getBinary() const
|
||||
{
|
||||
return (unsigned)binary;
|
||||
}
|
||||
#endif // EGRET_WASM
|
||||
|
||||
const UserData* getUserData() const { return userData; }
|
||||
void setUserData(UserData* value) { userData = value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_DRAGONBONES_DATA_H
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "SkinData.h"
|
||||
#include "DisplayData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void SkinData::_onClear()
|
||||
{
|
||||
for (const auto& pair : displays)
|
||||
{
|
||||
for (const auto display : pair.second)
|
||||
{
|
||||
if (display != nullptr)
|
||||
{
|
||||
display->returnToPool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name = "";
|
||||
displays.clear();
|
||||
parent = nullptr;
|
||||
}
|
||||
|
||||
void SkinData::addDisplay(const std::string& slotName, DisplayData* value)
|
||||
{
|
||||
if (value != nullptr)
|
||||
{
|
||||
value->parent = this;
|
||||
}
|
||||
|
||||
displays[slotName].push_back(value); // TODO clear prev
|
||||
}
|
||||
|
||||
DisplayData* SkinData::getDisplay(const std::string& slotName, const std::string& displayName)
|
||||
{
|
||||
const auto slotDisplays = getDisplays(slotName);
|
||||
if (slotDisplays != nullptr)
|
||||
{
|
||||
for (const auto display : *slotDisplays)
|
||||
{
|
||||
if (display != nullptr && display->name == displayName)
|
||||
{
|
||||
return display;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
89
cocos2d-x/cocos/editor-support/dragonbones/model/SkinData.h
Normal file
89
cocos2d-x/cocos/editor-support/dragonbones/model/SkinData.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_SKIN_DATA_H
|
||||
#define DRAGONBONES_SKIN_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The skin data, typically a armature data instance contains at least one skinData.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 皮肤数据,通常一个骨架数据至少包含一个皮肤数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class SkinData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(SkinData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The skin name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 皮肤名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, std::vector<DisplayData*>> displays;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ArmatureData* parent;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addDisplay(const std::string& slotName, DisplayData* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
DisplayData* getDisplay(const std::string& slotName, const std::string& displayName);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::vector<DisplayData*>* getDisplays(const std::string& slotName)
|
||||
{
|
||||
return mapFindB(displays, slotName);
|
||||
}
|
||||
|
||||
public: // For WebAssembly. TODO parent
|
||||
const std::map<std::string, std::vector<DisplayData*>>& getSlotDisplays() const { return displays; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_SKIN_DATA_H
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "TextureAtlasData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void TextureAtlasData::_onClear()
|
||||
{
|
||||
for (const auto& pair : textures)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
autoSearch = false;
|
||||
format = TextureFormat::DEFAULT;
|
||||
width = 0;
|
||||
height = 0;
|
||||
scale = 1.0f;
|
||||
name = "";
|
||||
imagePath.clear();
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
void TextureAtlasData::copyFrom(const TextureAtlasData& value)
|
||||
{
|
||||
autoSearch = value.autoSearch;
|
||||
format = value.format;
|
||||
width = value.width;
|
||||
height = value.height;
|
||||
scale = value.scale;
|
||||
name = value.name;
|
||||
imagePath = value.imagePath;
|
||||
|
||||
for (const auto& pair : textures)
|
||||
{
|
||||
pair.second->returnToPool();
|
||||
}
|
||||
|
||||
textures.clear();
|
||||
|
||||
for (const auto& pair : value.textures)
|
||||
{
|
||||
const auto texture = createTexture();
|
||||
texture->copyFrom(*(pair.second));
|
||||
textures[pair.first] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAtlasData::addTexture(TextureData* value)
|
||||
{
|
||||
if (textures.find(value->name) != textures.cend())
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Same texture: " + value->name);
|
||||
return;
|
||||
}
|
||||
|
||||
textures[value->name] = value;
|
||||
value->parent = this;
|
||||
}
|
||||
|
||||
Rectangle* TextureData::createRectangle()
|
||||
{
|
||||
return new Rectangle();
|
||||
}
|
||||
|
||||
TextureData::~TextureData()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureData::_onClear()
|
||||
{
|
||||
if (frame != nullptr)
|
||||
{
|
||||
delete frame;
|
||||
}
|
||||
|
||||
rotated = false;
|
||||
name = "";
|
||||
region.clear();
|
||||
parent = nullptr;
|
||||
frame = nullptr;
|
||||
}
|
||||
|
||||
void TextureData::copyFrom(const TextureData &value)
|
||||
{
|
||||
rotated = value.rotated;
|
||||
name = value.name;
|
||||
region = value.region; // Copy.
|
||||
parent = value.parent;
|
||||
|
||||
if (frame == nullptr && value.frame != nullptr)
|
||||
{
|
||||
frame = TextureData::createRectangle();
|
||||
}
|
||||
else if (frame != nullptr && value.frame == nullptr)
|
||||
{
|
||||
delete frame;
|
||||
frame = nullptr;
|
||||
}
|
||||
|
||||
if (frame != nullptr && value.frame != nullptr)
|
||||
{
|
||||
*frame = *(value.frame); // Copy.
|
||||
}
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_TEXTUREATLAS_DATA_H
|
||||
#define DRAGONBONES_TEXTUREATLAS_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
#include "../geom/Rectangle.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The texture atlas data.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 贴图集数据。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class TextureAtlasData : public BaseObject
|
||||
{
|
||||
ABSTRACT_CLASS(TextureAtlasData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
bool autoSearch;
|
||||
TextureFormat format;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
unsigned width;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
unsigned height;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
float scale;
|
||||
/**
|
||||
* - The texture atlas name.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 贴图集名称。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string name;
|
||||
/**
|
||||
* - The image path of the texture atlas.
|
||||
* @version DragonBones 3.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 贴图集图片路径。
|
||||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string imagePath;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
std::map<std::string, TextureData*> textures;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
void copyFrom(const TextureAtlasData& value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual TextureData* createTexture() const = 0;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual void addTexture(TextureData* value);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
inline TextureData* getTexture(const std::string& textureName) const
|
||||
{
|
||||
return mapFind(textures, textureName);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
const std::map<std::string, TextureData*>& getTextures() const { return textures; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class TextureData : public BaseObject
|
||||
{
|
||||
public:
|
||||
static Rectangle* createRectangle();
|
||||
|
||||
public:
|
||||
bool rotated;
|
||||
std::string name;
|
||||
Rectangle region;
|
||||
Rectangle* frame;
|
||||
TextureAtlasData* parent;
|
||||
|
||||
TextureData() :
|
||||
frame(nullptr)
|
||||
{}
|
||||
virtual ~TextureData() = 0;
|
||||
|
||||
void copyFrom(const TextureData& value);
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
Rectangle* getRegion() { return ®ion; }
|
||||
const Rectangle* getFrame() const { return frame; }
|
||||
void setFrame(Rectangle* value) { frame = value; }
|
||||
const TextureAtlasData* getParent() const { return parent; }
|
||||
void setParent(TextureAtlasData* value) { parent = value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_TEXTUREATLAS_DATA_H
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "UserData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
void UserData::_onClear()
|
||||
{
|
||||
ints.clear();
|
||||
floats.clear();
|
||||
strings.clear();
|
||||
}
|
||||
|
||||
void UserData::addInt(int value)
|
||||
{
|
||||
ints.push_back(value);
|
||||
}
|
||||
|
||||
void UserData::addFloat(float value)
|
||||
{
|
||||
floats.push_back(value);
|
||||
}
|
||||
|
||||
void UserData::addString(std::string value)
|
||||
{
|
||||
strings.push_back(value);
|
||||
}
|
||||
|
||||
int UserData::getInt(unsigned index) const
|
||||
{
|
||||
return index < ints.size() ? ints[index] : 0;
|
||||
}
|
||||
|
||||
float UserData::getFloat(unsigned index) const
|
||||
{
|
||||
return index < floats.size() ? floats[index] : 0;
|
||||
}
|
||||
|
||||
std::string UserData::getString(unsigned index) const
|
||||
{
|
||||
return index < strings.size() ? strings[index] : 0;
|
||||
}
|
||||
|
||||
void ActionData::_onClear()
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
data->returnToPool();
|
||||
}
|
||||
|
||||
type = ActionType::Play;
|
||||
name = "";
|
||||
bone = nullptr;
|
||||
slot = nullptr;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
175
cocos2d-x/cocos/editor-support/dragonbones/model/UserData.h
Normal file
175
cocos2d-x/cocos/editor-support/dragonbones/model/UserData.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_USER_DATA_H
|
||||
#define DRAGONBONES_USER_DATA_H
|
||||
|
||||
#include "../core/BaseObject.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* - The user custom data.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 用户自定义数据。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
class UserData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_A(UserData);
|
||||
|
||||
public:
|
||||
/**
|
||||
* - The custom int numbers.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 自定义整数。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<int> ints;
|
||||
/**
|
||||
* - The custom float numbers.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 自定义浮点数。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<float> floats;
|
||||
/**
|
||||
* - The custom strings.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 自定义字符串。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::vector<std::string> strings;
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addInt(int value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addFloat(float value);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void addString(std::string value);
|
||||
/**
|
||||
* - Get the custom int number.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取自定义整数。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
int getInt(unsigned index) const;
|
||||
/**
|
||||
* - Get the custom float number.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取自定义浮点数。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
float getFloat(unsigned index) const;
|
||||
/**
|
||||
* - Get the custom string.
|
||||
* @version DragonBones 5.0
|
||||
* @language en_US
|
||||
*/
|
||||
/**
|
||||
* - 获取自定义字符串。
|
||||
* @version DragonBones 5.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
std::string getString(unsigned index) const;
|
||||
|
||||
public: // For WebAssembly.
|
||||
const std::vector<int>& getInts() const { return ints; }
|
||||
const std::vector<float>& getFloats() const { return floats; }
|
||||
const std::vector<std::string>& getStrings() const { return strings; }
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ActionData : public BaseObject
|
||||
{
|
||||
BIND_CLASS_TYPE_B(ActionData);
|
||||
|
||||
public:
|
||||
ActionType type;
|
||||
std::string name;
|
||||
const BoneData* bone;
|
||||
const SlotData* slot;
|
||||
UserData* data;
|
||||
|
||||
ActionData() :
|
||||
data(nullptr)
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
virtual ~ActionData()
|
||||
{
|
||||
_onClear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
||||
public: // For WebAssembly.
|
||||
int getType() const { return (int)type; }
|
||||
void setType(int value) { type = (ActionType)value; }
|
||||
|
||||
const BoneData* getBone() const { return bone; }
|
||||
void setBone(const BoneData* value) { bone = value; }
|
||||
|
||||
const SlotData* getSlot() const { return slot; }
|
||||
void setSlot(const SlotData* value) { slot = value; }
|
||||
|
||||
const UserData* getData() const { return data; }
|
||||
void setData(UserData* value) { data = value; }
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_USER_DATA_H
|
||||
@@ -0,0 +1,237 @@
|
||||
#include "BinaryDataParser.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
TimelineData* BinaryDataParser::_parseBinaryTimeline(TimelineType type, unsigned offset, TimelineData* timelineData)
|
||||
{
|
||||
const auto timeline = timelineData != nullptr ? timelineData : BaseObject::borrowObject<TimelineData>();
|
||||
timeline->type = type;
|
||||
timeline->offset = offset;
|
||||
|
||||
_timeline = timeline;
|
||||
|
||||
const auto keyFrameCount = (unsigned)_timelineArray[timeline->offset + (unsigned)BinaryOffset::TimelineKeyFrameCount];
|
||||
if (keyFrameCount == 1)
|
||||
{
|
||||
timeline->frameIndicesOffset = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned frameIndicesOffset = 0;
|
||||
const auto totalFrameCount = _animation->frameCount + 1; // One more frame than animation.
|
||||
auto& frameIndices = _data->frameIndices;
|
||||
|
||||
frameIndicesOffset = frameIndices.size();
|
||||
timeline->frameIndicesOffset = frameIndicesOffset;
|
||||
frameIndices.resize(frameIndicesOffset + totalFrameCount);
|
||||
|
||||
for (
|
||||
std::size_t i = 0, iK = 0, frameStart = 0, frameCount = 0;
|
||||
i < totalFrameCount;
|
||||
++i
|
||||
)
|
||||
{
|
||||
if (frameStart + frameCount <= i && iK < keyFrameCount)
|
||||
{
|
||||
frameStart = _frameArray[_animation->frameOffset + _timelineArray[timeline->offset + (unsigned)BinaryOffset::TimelineFrameOffset + iK]];
|
||||
if (iK == keyFrameCount - 1)
|
||||
{
|
||||
frameCount = _animation->frameCount - frameStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameCount = _frameArray[_animation->frameOffset + _timelineArray[timeline->offset + (unsigned)BinaryOffset::TimelineFrameOffset + iK + 1]] - frameStart;
|
||||
}
|
||||
|
||||
iK++;
|
||||
}
|
||||
|
||||
frameIndices[frameIndicesOffset + i] = iK - 1;
|
||||
}
|
||||
}
|
||||
|
||||
_timeline = nullptr;
|
||||
|
||||
return timeline;
|
||||
}
|
||||
|
||||
void BinaryDataParser::_parseVertices(const rapidjson::Value& rawData, VerticesData& vertices)
|
||||
{
|
||||
vertices.offset = rawData[OFFSET].GetUint();
|
||||
|
||||
const auto weightOffset = _intArray[vertices.offset + (unsigned)BinaryOffset::MeshWeightOffset];
|
||||
if (weightOffset >= 0)
|
||||
{
|
||||
const auto weight = BaseObject::borrowObject<WeightData>();
|
||||
const auto vertexCount = _intArray[vertices.offset + (unsigned)BinaryOffset::MeshVertexCount];
|
||||
const auto boneCount = (unsigned)_intArray[weightOffset + (unsigned)BinaryOffset::WeigthBoneCount];
|
||||
weight->offset = weightOffset;
|
||||
|
||||
for (std::size_t i = 0; i < boneCount; ++i)
|
||||
{
|
||||
const auto boneIndex = _intArray[weightOffset + (unsigned)BinaryOffset::WeigthBoneIndices + i];
|
||||
weight->addBone(_rawBones[boneIndex]);
|
||||
}
|
||||
|
||||
auto boneIndicesOffset = weightOffset + (unsigned)BinaryOffset::WeigthBoneIndices + boneCount;
|
||||
unsigned weightCount = 0;
|
||||
for (std::size_t i = 0, l = vertexCount; i < l; ++i)
|
||||
{
|
||||
const auto vertexBoneCount = (unsigned)_intArray[boneIndicesOffset++];
|
||||
weightCount += vertexBoneCount;
|
||||
boneIndicesOffset += vertexBoneCount;
|
||||
}
|
||||
|
||||
weight->count = weightCount;
|
||||
vertices.weight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryDataParser::_parseMesh(const rapidjson::Value& rawData, MeshDisplayData& mesh)
|
||||
{
|
||||
_parseVertices(rawData, mesh.vertices);
|
||||
}
|
||||
|
||||
AnimationData* BinaryDataParser::_parseAnimation(const rapidjson::Value& rawData)
|
||||
{
|
||||
const auto animation = BaseObject::borrowObject<AnimationData>();
|
||||
animation->frameCount = std::max(_getNumber(rawData, DURATION, 1), 1);
|
||||
animation->playTimes = _getNumber(rawData, PLAY_TIMES, 1);
|
||||
animation->duration = (float)(animation->frameCount) / _armature->frameRate; // float
|
||||
animation->fadeInTime = _getNumber(rawData, FADE_IN_TIME, 0.0f);
|
||||
animation->scale = _getNumber(rawData, SCALE, 1.0f);
|
||||
animation->name = _getString(rawData, NAME, DEFAULT_NAME);
|
||||
if (animation->name.empty())
|
||||
{
|
||||
animation->name = DEFAULT_NAME;
|
||||
}
|
||||
|
||||
// Offsets.
|
||||
const auto& offsets = rawData[OFFSET];
|
||||
animation->frameIntOffset = offsets[0].GetUint();
|
||||
animation->frameFloatOffset = offsets[1].GetUint();
|
||||
animation->frameOffset = offsets[2].GetUint();
|
||||
|
||||
_animation = animation;
|
||||
|
||||
if (rawData.HasMember(ACTION))
|
||||
{
|
||||
animation->actionTimeline = _parseBinaryTimeline(TimelineType::Action, rawData[ACTION].GetUint());
|
||||
}
|
||||
|
||||
if (rawData.HasMember(Z_ORDER))
|
||||
{
|
||||
animation->zOrderTimeline = _parseBinaryTimeline(TimelineType::ZOrder, rawData[Z_ORDER].GetUint());
|
||||
}
|
||||
|
||||
if (rawData.HasMember(BONE))
|
||||
{
|
||||
const auto& rawTimeliness = rawData[BONE];
|
||||
for (auto iterator = rawTimeliness.MemberBegin(); iterator != rawTimeliness.MemberEnd(); ++iterator)
|
||||
{
|
||||
const auto bone = _armature->getBone(iterator->name.GetString());
|
||||
if (bone == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& rawTimelines = *&(iterator->value);
|
||||
for (std::size_t i = 0, l = rawTimelines.Size(); i < l; i += 2)
|
||||
{
|
||||
const auto timelineType = (TimelineType)rawTimelines[i].GetInt();
|
||||
const auto timelineOffset = rawTimelines[i + 1].GetUint();
|
||||
const auto timeline = _parseBinaryTimeline(timelineType, timelineOffset);
|
||||
_animation->addBoneTimeline(bone, timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rawData.HasMember(SLOT))
|
||||
{
|
||||
const auto& rawTimeliness = rawData[SLOT];
|
||||
for (auto iterator = rawTimeliness.MemberBegin(); iterator != rawTimeliness.MemberEnd(); ++iterator)
|
||||
{
|
||||
const auto slot = _armature->getSlot(iterator->name.GetString());
|
||||
if (slot == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& rawTimelines = *&(iterator->value);
|
||||
for (std::size_t i = 0, l = rawTimelines.Size(); i < l; i += 2)
|
||||
{
|
||||
const auto timelineType = (TimelineType)rawTimelines[i].GetInt();
|
||||
const auto timelineOffset = rawTimelines[i + 1].GetUint();
|
||||
const auto timeline = _parseBinaryTimeline(timelineType, timelineOffset);
|
||||
_animation->addSlotTimeline(slot, timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rawData.HasMember(CONSTRAINT))
|
||||
{
|
||||
const auto& rawTimeliness = rawData[CONSTRAINT];
|
||||
for (auto iterator = rawTimeliness.MemberBegin(); iterator != rawTimeliness.MemberEnd(); ++iterator)
|
||||
{
|
||||
const auto constraint = _armature->getConstraint(iterator->name.GetString());
|
||||
if (constraint == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& rawTimelines = *&(iterator->value);
|
||||
for (std::size_t i = 0, l = rawTimelines.Size(); i < l; i += 2)
|
||||
{
|
||||
const auto timelineType = (TimelineType)rawTimelines[i].GetInt();
|
||||
const auto timelineOffset = rawTimelines[i + 1].GetUint();
|
||||
const auto timeline = _parseBinaryTimeline(timelineType, timelineOffset);
|
||||
_animation->addConstraintTimeline(constraint, timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_animation = nullptr;
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
void BinaryDataParser::_parseArray(const rapidjson::Value& rawData)
|
||||
{
|
||||
const auto& offsets = rawData[OFFSET];
|
||||
|
||||
_data->binary = _binary;
|
||||
_data->intArray = _intArray = (int16_t*)(_binary + _binaryOffset + offsets[0].GetUint());
|
||||
_data->floatArray = _floatArray = (float*)(_binary + _binaryOffset + offsets[2].GetUint());
|
||||
_data->frameIntArray = _frameIntArray = (int16_t*)(_binary + _binaryOffset + offsets[4].GetUint());
|
||||
_data->frameFloatArray = _frameFloatArray = (float*)(_binary + _binaryOffset + offsets[6].GetUint());
|
||||
_data->frameArray = _frameArray = (int16_t*)(_binary + _binaryOffset + offsets[8].GetUint());
|
||||
_data->timelineArray = _timelineArray = (uint16_t*)(_binary + _binaryOffset + offsets[10].GetUint());
|
||||
}
|
||||
|
||||
DragonBonesData* BinaryDataParser::parseDragonBonesData(const char* rawData, float scale)
|
||||
{
|
||||
DRAGONBONES_ASSERT(rawData != nullptr, "");
|
||||
|
||||
if (
|
||||
rawData[0] != 'D' ||
|
||||
rawData[1] != 'B' ||
|
||||
rawData[2] != 'D' ||
|
||||
rawData[3] != 'T'
|
||||
)
|
||||
{
|
||||
DRAGONBONES_ASSERT(false, "Nonsupport data.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto headerLength = (std::size_t)(((uint32_t*)(rawData + 8))[0]);
|
||||
const auto headerBytes = rawData + 8 + 4;
|
||||
rapidjson::Document document;
|
||||
document.Parse(headerBytes, headerLength);
|
||||
|
||||
_binaryOffset = 8 + 4 + headerLength;
|
||||
_binary = rawData;
|
||||
|
||||
return JSONDataParser::_parseDragonBonesData(document, scale);
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_BINARY_DATA_PARSER_H
|
||||
#define DRAGONBONES_BINARY_DATA_PARSER_H
|
||||
|
||||
#include "JSONDataParser.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class BinaryDataParser : public JSONDataParser
|
||||
{
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(BinaryDataParser)
|
||||
|
||||
private:
|
||||
unsigned _binaryOffset;
|
||||
const char* _binary;
|
||||
const int16_t* _intArray;
|
||||
const float* _floatArray;
|
||||
const int16_t* _frameIntArray;
|
||||
const float* _frameFloatArray;
|
||||
const int16_t* _frameArray;
|
||||
const uint16_t* _timelineArray;
|
||||
|
||||
TimelineData* _parseBinaryTimeline(TimelineType type, unsigned offset, TimelineData* timelineData = nullptr);
|
||||
void _parseVertices(const rapidjson::Value& rawData, VerticesData& vertices);
|
||||
|
||||
protected:
|
||||
virtual void _parseMesh(const rapidjson::Value& rawData, MeshDisplayData& mesh) override;
|
||||
virtual AnimationData* _parseAnimation(const rapidjson::Value& rawData) override;
|
||||
virtual void _parseArray(const rapidjson::Value& rawData) override;
|
||||
|
||||
public:
|
||||
BinaryDataParser() :
|
||||
_binaryOffset(0),
|
||||
_binary(nullptr),
|
||||
_intArray(nullptr),
|
||||
_floatArray(nullptr),
|
||||
_frameIntArray(nullptr),
|
||||
_frameFloatArray(nullptr),
|
||||
_frameArray(nullptr),
|
||||
_timelineArray(nullptr)
|
||||
{}
|
||||
virtual ~BinaryDataParser() {}
|
||||
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData, float scale = 1.0f) override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_BINARY_DATA_PARSER_H
|
||||
319
cocos2d-x/cocos/editor-support/dragonbones/parser/DataParser.cpp
Normal file
319
cocos2d-x/cocos/editor-support/dragonbones/parser/DataParser.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
#include "DataParser.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
const char* DataParser::DATA_VERSION_2_3 = "2.3";
|
||||
const char* DataParser::DATA_VERSION_3_0 = "3.0";
|
||||
const char* DataParser::DATA_VERSION_4_0 = "4.0";
|
||||
const char* DataParser::DATA_VERSION_4_5 = "4.5";
|
||||
const char* DataParser::DATA_VERSION_5_0 = "5.0";
|
||||
const char* DataParser::DATA_VERSION_5_5 = "5.5";
|
||||
const char* DataParser::DATA_VERSION = DataParser::DATA_VERSION_5_5;
|
||||
|
||||
const std::vector<std::string> DataParser::DATA_VERSIONS
|
||||
{
|
||||
DataParser::DATA_VERSION_4_0,
|
||||
DataParser::DATA_VERSION_4_5,
|
||||
DataParser::DATA_VERSION_5_0,
|
||||
DataParser::DATA_VERSION_5_5
|
||||
};
|
||||
|
||||
const char* DataParser::TEXTURE_ATLAS = "TextureAtlas";
|
||||
const char* DataParser::SUB_TEXTURE = "SubTexture";
|
||||
const char* DataParser::FORMAT = "format";
|
||||
const char* DataParser::IMAGE_PATH = "imagePath";
|
||||
const char* DataParser::WIDTH = "width";
|
||||
const char* DataParser::HEIGHT = "height";
|
||||
const char* DataParser::ROTATED = "rotated";
|
||||
const char* DataParser::FRAME_X = "frameX";
|
||||
const char* DataParser::FRAME_Y = "frameY";
|
||||
const char* DataParser::FRAME_WIDTH = "frameWidth";
|
||||
const char* DataParser::FRAME_HEIGHT = "frameHeight";
|
||||
|
||||
const char* DataParser::DRADON_BONES = "dragonBones";
|
||||
const char* DataParser::USER_DATA = "userData";
|
||||
const char* DataParser::ARMATURE = "armature";
|
||||
const char* DataParser::BONE = "bone";
|
||||
const char* DataParser::SLOT = "slot";
|
||||
const char* DataParser::CONSTRAINT = "constraint";
|
||||
const char* DataParser::IK = "ik";
|
||||
const char* DataParser::SKIN = "skin";
|
||||
const char* DataParser::DISPLAY = "display";
|
||||
const char* DataParser::ANIMATION = "animation";
|
||||
const char* DataParser::Z_ORDER = "zOrder";
|
||||
const char* DataParser::FFD = "ffd";
|
||||
const char* DataParser::FRAME = "frame";
|
||||
const char* DataParser::TRANSLATE_FRAME = "translateFrame";
|
||||
const char* DataParser::ROTATE_FRAME = "rotateFrame";
|
||||
const char* DataParser::SCALE_FRAME = "scaleFrame";
|
||||
const char* DataParser::DISPLAY_FRAME = "displayFrame";
|
||||
const char* DataParser::COLOR_FRAME = "colorFrame";
|
||||
const char* DataParser::DEFAULT_ACTIONS = "defaultActions";
|
||||
const char* DataParser::ACTIONS = "actions";
|
||||
const char* DataParser::EVENTS = "events";
|
||||
const char* DataParser::INTS = "ints";
|
||||
const char* DataParser::FLOATS = "floats";
|
||||
const char* DataParser::STRINGS = "strings";
|
||||
const char* DataParser::CANVAS = "canvas";
|
||||
|
||||
const char* DataParser::TRANSFORM = "transform";
|
||||
const char* DataParser::PIVOT = "pivot";
|
||||
const char* DataParser::AABB = "aabb";
|
||||
const char* DataParser::COLOR = "color";
|
||||
|
||||
const char* DataParser::VERSION = "version";
|
||||
const char* DataParser::COMPATIBLE_VERSION = "compatibleVersion";
|
||||
const char* DataParser::FRAME_RATE = "frameRate";
|
||||
const char* DataParser::TYPE = "type";
|
||||
const char* DataParser::SUB_TYPE = "subType";
|
||||
const char* DataParser::NAME = "name";
|
||||
const char* DataParser::PARENT = "parent";
|
||||
const char* DataParser::TARGET = "target";
|
||||
const char* DataParser::STAGE = "stage";
|
||||
const char* DataParser::SHARE = "share";
|
||||
const char* DataParser::PATH = "path";
|
||||
const char* DataParser::LENGTH = "length";
|
||||
const char* DataParser::DISPLAY_INDEX = "displayIndex";
|
||||
const char* DataParser::BLEND_MODE = "blendMode";
|
||||
const char* DataParser::INHERIT_TRANSLATION = "inheritTranslation";
|
||||
const char* DataParser::INHERIT_ROTATION = "inheritRotation";
|
||||
const char* DataParser::INHERIT_SCALE = "inheritScale";
|
||||
const char* DataParser::INHERIT_REFLECTION = "inheritReflection";
|
||||
const char* DataParser::INHERIT_ANIMATION = "inheritAnimation";
|
||||
const char* DataParser::INHERIT_DEFORM = "inheritDeform";
|
||||
const char* DataParser::BEND_POSITIVE = "bendPositive";
|
||||
const char* DataParser::CHAIN = "chain";
|
||||
const char* DataParser::WEIGHT = "weight";
|
||||
|
||||
const char* DataParser::FADE_IN_TIME = "fadeInTime";
|
||||
const char* DataParser::PLAY_TIMES = "playTimes";
|
||||
const char* DataParser::SCALE = "scale";
|
||||
const char* DataParser::OFFSET = "offset";
|
||||
const char* DataParser::POSITION = "position";
|
||||
const char* DataParser::DURATION = "duration";
|
||||
const char* DataParser::TWEEN_EASING = "tweenEasing";
|
||||
const char* DataParser::TWEEN_ROTATE = "tweenRotate";
|
||||
const char* DataParser::TWEEN_SCALE = "tweenScale";
|
||||
const char* DataParser::CLOCK_WISE = "clockwise";
|
||||
const char* DataParser::CURVE = "curve";
|
||||
const char* DataParser::EVENT = "event";
|
||||
const char* DataParser::SOUND = "sound";
|
||||
const char* DataParser::ACTION = "action";
|
||||
|
||||
const char* DataParser::X = "x";
|
||||
const char* DataParser::Y = "y";
|
||||
const char* DataParser::SKEW_X = "skX";
|
||||
const char* DataParser::SKEW_Y = "skY";
|
||||
const char* DataParser::SCALE_X = "scX";
|
||||
const char* DataParser::SCALE_Y = "scY";
|
||||
const char* DataParser::VALUE = "value";
|
||||
const char* DataParser::ROTATE = "rotate";
|
||||
const char* DataParser::SKEW = "skew";
|
||||
|
||||
const char* DataParser::ALPHA_OFFSET = "aO";
|
||||
const char* DataParser::RED_OFFSET = "rO";
|
||||
const char* DataParser::GREEN_OFFSET = "gO";
|
||||
const char* DataParser::BLUE_OFFSET = "bO";
|
||||
const char* DataParser::ALPHA_MULTIPLIER = "aM";
|
||||
const char* DataParser::RED_MULTIPLIER = "rM";
|
||||
const char* DataParser::GREEN_MULTIPLIER = "gM";
|
||||
const char* DataParser::BLUE_MULTIPLIER = "bM";
|
||||
|
||||
const char* DataParser::UVS = "uvs";
|
||||
const char* DataParser::VERTICES = "vertices";
|
||||
const char* DataParser::TRIANGLES = "triangles";
|
||||
const char* DataParser::WEIGHTS = "weights";
|
||||
const char* DataParser::SLOT_POSE = "slotPose";
|
||||
const char* DataParser::BONE_POSE = "bonePose";
|
||||
|
||||
const char* DataParser::GOTO_AND_PLAY = "gotoAndPlay";
|
||||
|
||||
const char* DataParser::DEFAULT_NAME = "default";
|
||||
|
||||
TextureFormat DataParser::_getTextureFormat(const std::string& value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "rgba8888")
|
||||
{
|
||||
return TextureFormat::RGBA8888;
|
||||
}
|
||||
else if (lower == "bgra8888")
|
||||
{
|
||||
return TextureFormat::BGRA8888;
|
||||
}
|
||||
else if (lower == "rgba4444")
|
||||
{
|
||||
return TextureFormat::RGBA4444;
|
||||
}
|
||||
else if (lower == "rgb888")
|
||||
{
|
||||
return TextureFormat::RGB888;
|
||||
}
|
||||
else if (lower == "rgb565")
|
||||
{
|
||||
return TextureFormat::RGB565;
|
||||
}
|
||||
else if (lower == "rgba5551")
|
||||
{
|
||||
return TextureFormat::RGBA5551;
|
||||
}
|
||||
|
||||
return TextureFormat::DEFAULT;
|
||||
}
|
||||
|
||||
ArmatureType DataParser::_getArmatureType(const std::string& value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "armature")
|
||||
{
|
||||
return ArmatureType::Armature;
|
||||
}
|
||||
else if (lower == "movieClip")
|
||||
{
|
||||
return ArmatureType::MovieClip;
|
||||
}
|
||||
else if (lower == "stage")
|
||||
{
|
||||
return ArmatureType::Stage;
|
||||
}
|
||||
|
||||
return ArmatureType::Armature;
|
||||
}
|
||||
|
||||
DisplayType DataParser::_getDisplayType(const std::string& value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "image")
|
||||
{
|
||||
return DisplayType::Image;
|
||||
}
|
||||
else if (lower == "armature")
|
||||
{
|
||||
return DisplayType::Armature;
|
||||
}
|
||||
else if (lower == "mesh")
|
||||
{
|
||||
return DisplayType::Mesh;
|
||||
}
|
||||
else if (lower == "boundingbox")
|
||||
{
|
||||
return DisplayType::BoundingBox;
|
||||
}
|
||||
|
||||
return DisplayType::Image;
|
||||
}
|
||||
|
||||
BoundingBoxType DataParser::_getBoundingBoxType(const std::string & value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "rectangle")
|
||||
{
|
||||
return BoundingBoxType::Rectangle;
|
||||
}
|
||||
else if (lower == "ellipse")
|
||||
{
|
||||
return BoundingBoxType::Ellipse;
|
||||
}
|
||||
else if (lower == "polygon")
|
||||
{
|
||||
return BoundingBoxType::Polygon;
|
||||
}
|
||||
|
||||
return BoundingBoxType::Rectangle;
|
||||
}
|
||||
|
||||
ActionType DataParser::_getActionType(const std::string& value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "play")
|
||||
{
|
||||
return ActionType::Play;
|
||||
}
|
||||
else if (lower == "frame")
|
||||
{
|
||||
return ActionType::Frame;
|
||||
}
|
||||
else if (lower == "sound")
|
||||
{
|
||||
return ActionType::Sound;
|
||||
}
|
||||
|
||||
return ActionType::Play;
|
||||
}
|
||||
|
||||
BlendMode DataParser::_getBlendMode(const std::string& value)
|
||||
{
|
||||
auto lower = value;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
|
||||
if (lower == "normal")
|
||||
{
|
||||
return BlendMode::Normal;
|
||||
}
|
||||
else if (lower == "add")
|
||||
{
|
||||
return BlendMode::Add;
|
||||
}
|
||||
else if (lower == "alpha")
|
||||
{
|
||||
return BlendMode::Alpha;
|
||||
}
|
||||
else if (lower == "darken")
|
||||
{
|
||||
return BlendMode::Darken;
|
||||
}
|
||||
else if (lower == "difference")
|
||||
{
|
||||
return BlendMode::Difference;
|
||||
}
|
||||
else if (lower == "erase")
|
||||
{
|
||||
return BlendMode::Erase;
|
||||
}
|
||||
else if (lower == "hardlight")
|
||||
{
|
||||
return BlendMode::HardLight;
|
||||
}
|
||||
else if (lower == "invert")
|
||||
{
|
||||
return BlendMode::Invert;
|
||||
}
|
||||
else if (lower == "layer")
|
||||
{
|
||||
return BlendMode::Layer;
|
||||
}
|
||||
else if (lower == "lighten")
|
||||
{
|
||||
return BlendMode::Lighten;
|
||||
}
|
||||
else if (lower == "multiply")
|
||||
{
|
||||
return BlendMode::Multiply;
|
||||
}
|
||||
else if (lower == "overlay")
|
||||
{
|
||||
return BlendMode::Overlay;
|
||||
}
|
||||
else if (lower == "screen")
|
||||
{
|
||||
return BlendMode::Screen;
|
||||
}
|
||||
else if (lower == "subtract")
|
||||
{
|
||||
return BlendMode::Subtract;
|
||||
}
|
||||
|
||||
return BlendMode::Normal;
|
||||
}
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
182
cocos2d-x/cocos/editor-support/dragonbones/parser/DataParser.h
Normal file
182
cocos2d-x/cocos/editor-support/dragonbones/parser/DataParser.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
#ifndef DRAGONBONES_DATA_PARSER_H
|
||||
#define DRAGONBONES_DATA_PARSER_H
|
||||
|
||||
#include "../core/DragonBones.h"
|
||||
#include "../model/UserData.h"
|
||||
#include "../model/DragonBonesData.h"
|
||||
#include "../model/ArmatureData.h"
|
||||
#include "../model/CanvasData.h"
|
||||
#include "../model/ConstraintData.h"
|
||||
#include "../model/SkinData.h"
|
||||
#include "../model/DisplayData.h"
|
||||
#include "../model/BoundingBoxData.h"
|
||||
#include "../model/AnimationData.h"
|
||||
#include "../model/TextureAtlasData.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class DataParser
|
||||
{
|
||||
ABSTRACT_CLASS(DataParser)
|
||||
|
||||
protected:
|
||||
static const char* DATA_VERSION_2_3;
|
||||
static const char* DATA_VERSION_3_0;
|
||||
static const char* DATA_VERSION_4_0;
|
||||
static const char* DATA_VERSION_4_5;
|
||||
static const char* DATA_VERSION_5_0;
|
||||
static const char* DATA_VERSION_5_5;
|
||||
static const char* DATA_VERSION;
|
||||
|
||||
static const std::vector<std::string> DATA_VERSIONS;
|
||||
|
||||
static const char* TEXTURE_ATLAS;
|
||||
static const char* SUB_TEXTURE;
|
||||
static const char* FORMAT;
|
||||
static const char* IMAGE_PATH;
|
||||
static const char* WIDTH;
|
||||
static const char* HEIGHT;
|
||||
static const char* ROTATED;
|
||||
static const char* FRAME_X;
|
||||
static const char* FRAME_Y;
|
||||
static const char* FRAME_WIDTH;
|
||||
static const char* FRAME_HEIGHT;
|
||||
|
||||
static const char* DRADON_BONES;
|
||||
static const char* USER_DATA;
|
||||
static const char* ARMATURE;
|
||||
static const char* BONE;
|
||||
static const char* SLOT;
|
||||
static const char* CONSTRAINT;
|
||||
static const char* IK;
|
||||
static const char* SKIN;
|
||||
static const char* DISPLAY;
|
||||
static const char* ANIMATION;
|
||||
static const char* Z_ORDER;
|
||||
static const char* FFD;
|
||||
static const char* FRAME;
|
||||
static const char* TRANSLATE_FRAME;
|
||||
static const char* ROTATE_FRAME;
|
||||
static const char* SCALE_FRAME;
|
||||
static const char* DISPLAY_FRAME;
|
||||
static const char* COLOR_FRAME;
|
||||
static const char* DEFAULT_ACTIONS;
|
||||
static const char* ACTIONS;
|
||||
static const char* EVENTS;
|
||||
static const char* INTS;
|
||||
static const char* FLOATS;
|
||||
static const char* STRINGS;
|
||||
static const char* CANVAS;
|
||||
|
||||
static const char* PIVOT;
|
||||
static const char* TRANSFORM;
|
||||
static const char* AABB;
|
||||
static const char* COLOR;
|
||||
|
||||
static const char* VERSION;
|
||||
static const char* COMPATIBLE_VERSION;
|
||||
static const char* FRAME_RATE;
|
||||
static const char* TYPE;
|
||||
static const char* SUB_TYPE;
|
||||
static const char* NAME;
|
||||
static const char* PARENT;
|
||||
static const char* TARGET;
|
||||
static const char* STAGE;
|
||||
static const char* SHARE;
|
||||
static const char* PATH;
|
||||
static const char* LENGTH;
|
||||
static const char* DISPLAY_INDEX;
|
||||
static const char* BLEND_MODE;
|
||||
static const char* INHERIT_TRANSLATION;
|
||||
static const char* INHERIT_ROTATION;
|
||||
static const char* INHERIT_SCALE;
|
||||
static const char* INHERIT_REFLECTION;
|
||||
static const char* INHERIT_ANIMATION;
|
||||
static const char* INHERIT_DEFORM;
|
||||
static const char* BEND_POSITIVE;
|
||||
static const char* CHAIN;
|
||||
static const char* WEIGHT;
|
||||
|
||||
static const char* FADE_IN_TIME;
|
||||
static const char* PLAY_TIMES;
|
||||
static const char* SCALE;
|
||||
static const char* OFFSET;
|
||||
static const char* POSITION;
|
||||
static const char* DURATION;
|
||||
static const char* TWEEN_EASING;
|
||||
static const char* TWEEN_ROTATE;
|
||||
static const char* TWEEN_SCALE;
|
||||
static const char* CLOCK_WISE;
|
||||
static const char* CURVE;
|
||||
static const char* EVENT;
|
||||
static const char* SOUND;
|
||||
static const char* ACTION;
|
||||
|
||||
static const char* X;
|
||||
static const char* Y;
|
||||
static const char* SKEW_X;
|
||||
static const char* SKEW_Y;
|
||||
static const char* SCALE_X;
|
||||
static const char* SCALE_Y;
|
||||
static const char* VALUE;
|
||||
static const char* ROTATE;
|
||||
static const char* SKEW;
|
||||
|
||||
static const char* ALPHA_OFFSET;
|
||||
static const char* RED_OFFSET;
|
||||
static const char* GREEN_OFFSET;
|
||||
static const char* BLUE_OFFSET;
|
||||
static const char* ALPHA_MULTIPLIER;
|
||||
static const char* RED_MULTIPLIER;
|
||||
static const char* GREEN_MULTIPLIER;
|
||||
static const char* BLUE_MULTIPLIER;
|
||||
|
||||
static const char* UVS;
|
||||
static const char* VERTICES;
|
||||
static const char* TRIANGLES;
|
||||
static const char* WEIGHTS;
|
||||
static const char* SLOT_POSE;
|
||||
static const char* BONE_POSE;
|
||||
|
||||
static const char* GOTO_AND_PLAY;
|
||||
|
||||
static const char* DEFAULT_NAME;
|
||||
|
||||
static TextureFormat _getTextureFormat(const std::string& value);
|
||||
static ArmatureType _getArmatureType(const std::string& value);
|
||||
static DisplayType _getDisplayType(const std::string& value);
|
||||
static BoundingBoxType _getBoundingBoxType(const std::string& value);
|
||||
static ActionType _getActionType(const std::string& value);
|
||||
static BlendMode _getBlendMode(const std::string& value);
|
||||
|
||||
public:
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData, float scale = 1.0f) = 0;
|
||||
virtual bool parseTextureAtlasData(const char* rawData, TextureAtlasData& textureAtlasData, float scale = 1.0f) = 0;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_DATA_PARSER_H
|
||||
2054
cocos2d-x/cocos/editor-support/dragonbones/parser/JSONDataParser.cpp
Normal file
2054
cocos2d-x/cocos/editor-support/dragonbones/parser/JSONDataParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,270 @@
|
||||
#ifndef DRAGONBONES_JSON_DATA_PARSER_H
|
||||
#define DRAGONBONES_JSON_DATA_PARSER_H
|
||||
|
||||
#include "DataParser.h"
|
||||
#include "json/document.h"
|
||||
|
||||
DRAGONBONES_NAMESPACE_BEGIN
|
||||
|
||||
class ActionFrame
|
||||
{
|
||||
public:
|
||||
unsigned frameStart;
|
||||
std::vector<unsigned> actions;
|
||||
|
||||
bool operator < (const ActionFrame& b) const
|
||||
{
|
||||
return frameStart < b.frameStart;
|
||||
}
|
||||
};
|
||||
|
||||
class JSONDataParser : public DataParser
|
||||
{
|
||||
DRAGONBONES_DISALLOW_COPY_AND_ASSIGN(JSONDataParser)
|
||||
|
||||
protected:
|
||||
inline static bool _getBoolean(const rapidjson::Value& rawData, const char* key, bool defaultValue)
|
||||
{
|
||||
if (rawData.HasMember(key))
|
||||
{
|
||||
const auto& value = rawData[key];
|
||||
if (value.IsBool())
|
||||
{
|
||||
return value.GetBool();
|
||||
}
|
||||
else if (value.IsString())
|
||||
{
|
||||
const std::string stringValue = value.GetString();
|
||||
if (
|
||||
stringValue == "0" ||
|
||||
stringValue == "NaN" ||
|
||||
stringValue == "" ||
|
||||
stringValue == "false" ||
|
||||
stringValue == "null" ||
|
||||
stringValue == "undefined"
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (value.IsNumber())
|
||||
{
|
||||
return value.GetInt() != 0;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static unsigned _getNumber(const rapidjson::Value& rawData, const char* key, unsigned defaultValue)
|
||||
{
|
||||
if (rawData.HasMember(key))
|
||||
{
|
||||
return rawData[key].GetUint();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static int _getNumber(const rapidjson::Value& rawData, const char* key, int defaultValue)
|
||||
{
|
||||
if (rawData.HasMember(key))
|
||||
{
|
||||
return rawData[key].GetInt();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static float _getNumber(const rapidjson::Value& rawData, const char* key, float defaultValue)
|
||||
{
|
||||
if (rawData.HasMember(key) && rawData[key].IsNumber())
|
||||
{
|
||||
return rawData[key].GetDouble(); // cocos can not support GetFloat();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static std::string _getString(const rapidjson::Value& rawData, const char* key, const std::string& defaultValue)
|
||||
{
|
||||
if (rawData.HasMember(key))
|
||||
{
|
||||
if (rawData[key].IsString())
|
||||
{
|
||||
return rawData[key].GetString();
|
||||
}
|
||||
|
||||
return dragonBones::to_string(rawData[key].GetDouble());
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static int _getParameter(const rapidjson::Value& rawData, std::size_t index, int defaultValue)
|
||||
{
|
||||
if (rawData.Size() > index)
|
||||
{
|
||||
return rawData[(int) index].GetInt();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static float _getParameter(const rapidjson::Value& rawData, std::size_t index, float defaultValue)
|
||||
{
|
||||
if (rawData.Size() > index)
|
||||
{
|
||||
return rawData[(int) index].GetDouble();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
inline static std::string _getParameter(const rapidjson::Value& rawData, std::size_t index, const std::string& defaultValue)
|
||||
{
|
||||
if (rawData.Size() > index)
|
||||
{
|
||||
return rawData[(int) index].GetString();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
protected:
|
||||
unsigned _rawTextureAtlasIndex;
|
||||
std::vector<BoneData*> _rawBones;
|
||||
DragonBonesData* _data;
|
||||
ArmatureData* _armature;
|
||||
BoneData* _bone;
|
||||
SlotData* _slot;
|
||||
SkinData* _skin;
|
||||
MeshDisplayData* _mesh;
|
||||
AnimationData* _animation;
|
||||
TimelineData* _timeline;
|
||||
rapidjson::Value* _rawTextureAtlases;
|
||||
|
||||
private:
|
||||
int _defaultColorOffset;
|
||||
int _prevClockwise;
|
||||
float _prevRotation;
|
||||
Matrix _helpMatrixA;
|
||||
Matrix _helpMatrixB;
|
||||
Transform _helpTransform;
|
||||
ColorTransform _helpColorTransform;
|
||||
Point _helpPoint;
|
||||
std::vector<float> _helpArray;
|
||||
std::vector<std::int16_t> _intArray;
|
||||
std::vector<float> _floatArray;
|
||||
std::vector<std::int16_t> _frameIntArray;
|
||||
std::vector<float> _frameFloatArray;
|
||||
std::vector<std::int16_t> _frameArray;
|
||||
std::vector<std::uint16_t> _timelineArray;
|
||||
std::vector<const rapidjson::Value*> _cacheRawMeshes;
|
||||
std::vector<MeshDisplayData*> _cacheMeshes;
|
||||
std::vector<ActionFrame> _actionFrames;
|
||||
std::map<std::string, const rapidjson::Value*> _weightSlotPose;
|
||||
std::map<std::string, const rapidjson::Value*> _weightBonePoses;
|
||||
std::map<std::string, std::vector<BoneData*>> _cacheBones;
|
||||
std::map<std::string, std::vector<ActionData*>> _slotChildActions;
|
||||
|
||||
public:
|
||||
JSONDataParser() :
|
||||
_rawTextureAtlasIndex(0),
|
||||
_rawBones(),
|
||||
_data(nullptr),
|
||||
_armature(nullptr),
|
||||
_bone(nullptr),
|
||||
_slot(nullptr),
|
||||
_skin(nullptr),
|
||||
_mesh(nullptr),
|
||||
_animation(nullptr),
|
||||
_timeline(nullptr),
|
||||
_rawTextureAtlases(nullptr),
|
||||
|
||||
_defaultColorOffset(-1),
|
||||
_prevClockwise(0),
|
||||
_prevRotation(0.0f),
|
||||
_helpMatrixA(),
|
||||
_helpMatrixB(),
|
||||
_helpTransform(),
|
||||
_helpColorTransform(),
|
||||
_helpPoint(),
|
||||
_helpArray(),
|
||||
_intArray(),
|
||||
_floatArray(),
|
||||
_frameIntArray(),
|
||||
_frameFloatArray(),
|
||||
_frameArray(),
|
||||
_timelineArray(),
|
||||
_cacheMeshes(),
|
||||
_cacheRawMeshes(),
|
||||
_actionFrames(),
|
||||
_weightSlotPose(),
|
||||
_weightBonePoses(),
|
||||
_cacheBones(),
|
||||
_slotChildActions()
|
||||
{
|
||||
}
|
||||
virtual ~JSONDataParser()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void _getCurvePoint(
|
||||
float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
|
||||
float t,
|
||||
Point& result
|
||||
);
|
||||
void _samplingEasingCurve(const rapidjson::Value& curve, std::vector<float>& samples);
|
||||
void _parseActionDataInFrame(const rapidjson::Value& rawData, unsigned frameStart, BoneData* bone, SlotData* slot);
|
||||
void _mergeActionFrame(const rapidjson::Value& rawData, unsigned frameStart, ActionType type, BoneData* bone, SlotData* slot);
|
||||
unsigned _parseCacheActionFrame(ActionFrame& frame);
|
||||
|
||||
protected:
|
||||
virtual ArmatureData* _parseArmature(const rapidjson::Value& rawData, float scale);
|
||||
virtual BoneData* _parseBone(const rapidjson::Value& rawData);
|
||||
virtual ConstraintData* _parseIKConstraint(const rapidjson::Value& rawData);
|
||||
virtual SlotData* _parseSlot(const rapidjson::Value& rawData, int zOrder);
|
||||
virtual SkinData* _parseSkin(const rapidjson::Value& rawData);
|
||||
virtual DisplayData* _parseDisplay(const rapidjson::Value& rawData);
|
||||
virtual void _parsePivot(const rapidjson::Value& rawData, ImageDisplayData& display);
|
||||
virtual void _parseMesh(const rapidjson::Value& rawData, MeshDisplayData& mesh);
|
||||
virtual BoundingBoxData* _parseBoundingBox(const rapidjson::Value& rawData);
|
||||
virtual PolygonBoundingBoxData* _parsePolygonBoundingBox(const rapidjson::Value& rawData);
|
||||
virtual AnimationData* _parseAnimation(const rapidjson::Value& rawData);
|
||||
virtual TimelineData* _parseTimeline(
|
||||
const rapidjson::Value& rawData, const char* framesKey, TimelineType type,
|
||||
bool addIntOffset, bool addFloatOffset, unsigned frameValueCount,
|
||||
const std::function<unsigned(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount)>& frameParser
|
||||
);
|
||||
virtual void _parseBoneTimeline(const rapidjson::Value& rawData);
|
||||
virtual void _parseSlotTimeline(const rapidjson::Value& rawData);
|
||||
virtual unsigned _parseFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseTweenFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseActionFrame(const ActionFrame& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseZOrderFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseBoneAllFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseBoneTranslateFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseBoneRotateFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseBoneScaleFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseSlotDisplayFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseSlotColorFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseSlotFFDFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual unsigned _parseIKConstraintFrame(const rapidjson::Value& rawData, unsigned frameStart, unsigned frameCount);
|
||||
virtual const std::vector<ActionData*>& _parseActionData(const rapidjson::Value& rawData, ActionType type, BoneData* bone, SlotData* slot);
|
||||
virtual void _parseTransform(const rapidjson::Value& rawData, Transform& transform, float scale);
|
||||
virtual void _parseColorTransform(const rapidjson::Value& rawData, ColorTransform& color);
|
||||
virtual void _parseArray(const rapidjson::Value& rawData);
|
||||
virtual DragonBonesData* _parseDragonBonesData(const rapidjson::Value& rawData, float scale = 1.0f);
|
||||
virtual void _parseTextureAtlasData(const rapidjson::Value& rawData, TextureAtlasData& textureAtlasData, float scale = 1.0f);
|
||||
|
||||
public:
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData, float scale = 1.0f) override;
|
||||
virtual bool parseTextureAtlasData(const char* rawData, TextureAtlasData& textureAtlasData, float scale = 1.0f) override;
|
||||
};
|
||||
|
||||
DRAGONBONES_NAMESPACE_END
|
||||
#endif // DRAGONBONES_JSON_DATA_PARSER_H
|
||||
Reference in New Issue
Block a user