You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
736 lines
23 KiB
736 lines
23 KiB
#include "Slot.h"
|
|
#include "../animation/Animation.h"
|
|
#include "../event/EventObject.h"
|
|
#include "../model/BoundingBoxData.h"
|
|
#include "../model/DisplayData.h"
|
|
#include "../model/DragonBonesData.h"
|
|
#include "../model/SkinData.h"
|
|
#include "../model/TextureAtlasData.h"
|
|
#include "../model/UserData.h"
|
|
#include "Armature.h"
|
|
#include "Bone.h"
|
|
#include "DeformVertices.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
|
|
|