mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 22:45:24 +00:00
初始化
This commit is contained in:
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
|
Reference in New Issue
Block a user