/****************************************************************************** * Spine Runtimes License Agreement * Last updated January 1, 2020. Replaces all prior versions. * * Copyright (c) 2013-2020, Esoteric Software LLC * * Integration of the Spine Runtimes into software or otherwise creating * derivative works of the Spine Runtimes is permitted under the terms and * conditions of Section 2 of the Spine Editor License Agreement: * http://esotericsoftware.com/spine-editor-license * * Otherwise, it is permitted to integrate the Spine Runtimes into software * or otherwise create derivative works of the Spine Runtimes (collectively, * "Products"), provided that each user of the Products must obtain their own * Spine Editor license and redistribution of the Products in any form must * include this license and copyright notice. * * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ #ifdef SPINE_UE4 #include "SpinePluginPrivatePCH.h" #endif #include #include #include using namespace spine; RTTI_IMPL(RegionAttachment, Attachment) const int RegionAttachment::BLX = 0; const int RegionAttachment::BLY = 1; const int RegionAttachment::ULX = 2; const int RegionAttachment::ULY = 3; const int RegionAttachment::URX = 4; const int RegionAttachment::URY = 5; const int RegionAttachment::BRX = 6; const int RegionAttachment::BRY = 7; RegionAttachment::RegionAttachment(const String &name) : Attachment(name), HasRendererObject(), _x(0), _y(0), _rotation(0), _scaleX(1), _scaleY(1), _width(0), _height(0), _regionOffsetX(0), _regionOffsetY(0), _regionWidth(0), _regionHeight(0), _regionOriginalWidth(0), _regionOriginalHeight(0), _path(), _regionU(0), _regionV(0), _regionU2(0), _regionV2(0), _color(1, 1, 1, 1) { _vertexOffset.setSize(NUM_UVS, 0); _uvs.setSize(NUM_UVS, 0); } void RegionAttachment::updateOffset() { float regionScaleX = _width / _regionOriginalWidth * _scaleX; float regionScaleY = _height / _regionOriginalHeight * _scaleY; float localX = -_width / 2 * _scaleX + _regionOffsetX * regionScaleX; float localY = -_height / 2 * _scaleY + _regionOffsetY * regionScaleY; float localX2 = localX + _regionWidth * regionScaleX; float localY2 = localY + _regionHeight * regionScaleY; float cos = MathUtil::cosDeg(_rotation); float sin = MathUtil::sinDeg(_rotation); float localXCos = localX * cos + _x; float localXSin = localX * sin; float localYCos = localY * cos + _y; float localYSin = localY * sin; float localX2Cos = localX2 * cos + _x; float localX2Sin = localX2 * sin; float localY2Cos = localY2 * cos + _y; float localY2Sin = localY2 * sin; _vertexOffset[BLX] = localXCos - localYSin; _vertexOffset[BLY] = localYCos + localXSin; _vertexOffset[ULX] = localXCos - localY2Sin; _vertexOffset[ULY] = localY2Cos + localXSin; _vertexOffset[URX] = localX2Cos - localY2Sin; _vertexOffset[URY] = localY2Cos + localX2Sin; _vertexOffset[BRX] = localX2Cos - localYSin; _vertexOffset[BRY] = localYCos + localX2Sin; } void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) { if (degrees == 90) { _uvs[URX] = u; _uvs[URY] = v2; _uvs[BRX] = u; _uvs[BRY] = v; _uvs[BLX] = u2; _uvs[BLY] = v; _uvs[ULX] = u2; _uvs[ULY] = v2; } else if (degrees == 270) { _uvs[BLX] = u; _uvs[BLY] = v2; _uvs[ULX] = u; _uvs[ULY] = v; _uvs[URX] = u2; _uvs[URY] = v; _uvs[BRX] = u2; _uvs[BRY] = v2; } else { _uvs[ULX] = u; _uvs[ULY] = v2; _uvs[URX] = u; _uvs[URY] = v; _uvs[BRX] = u2; _uvs[BRY] = v; _uvs[BLX] = u2; _uvs[BLY] = v2; } } void RegionAttachment::computeWorldVertices(Bone &bone, Vector &worldVertices, size_t offset, size_t stride) { assert(worldVertices.size() >= (offset + 8)); computeWorldVertices(bone, worldVertices.buffer(), offset, stride); } void RegionAttachment::computeWorldVertices(Bone &bone, float* worldVertices, size_t offset, size_t stride) { float x = bone.getWorldX(), y = bone.getWorldY(); float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD(); float offsetX, offsetY; offsetX = _vertexOffset[BRX]; offsetY = _vertexOffset[BRY]; worldVertices[offset] = offsetX * a + offsetY * b + x; // br worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; offsetX = _vertexOffset[BLX]; offsetY = _vertexOffset[BLY]; worldVertices[offset] = offsetX * a + offsetY * b + x; // bl worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; offsetX = _vertexOffset[ULX]; offsetY = _vertexOffset[ULY]; worldVertices[offset] = offsetX * a + offsetY * b + x; // ul worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; offsetX = _vertexOffset[URX]; offsetY = _vertexOffset[URY]; worldVertices[offset] = offsetX * a + offsetY * b + x; // ur worldVertices[offset + 1] = offsetX * c + offsetY * d + y; } float RegionAttachment::getX() { return _x; } void RegionAttachment::setX(float inValue) { _x = inValue; } float RegionAttachment::getY() { return _y; } void RegionAttachment::setY(float inValue) { _y = inValue; } float RegionAttachment::getRotation() { return _rotation; } void RegionAttachment::setRotation(float inValue) { _rotation = inValue; } float RegionAttachment::getScaleX() { return _scaleX; } void RegionAttachment::setScaleX(float inValue) { _scaleX = inValue; } float RegionAttachment::getScaleY() { return _scaleY; } void RegionAttachment::setScaleY(float inValue) { _scaleY = inValue; } float RegionAttachment::getWidth() { return _width; } void RegionAttachment::setWidth(float inValue) { _width = inValue; } float RegionAttachment::getHeight() { return _height; } void RegionAttachment::setHeight(float inValue) { _height = inValue; } const String &RegionAttachment::getPath() { return _path; } void RegionAttachment::setPath(const String &inValue) { _path = inValue; } float RegionAttachment::getRegionDegrees() { return _regionDegrees; } void RegionAttachment::setRegionDegrees(float inValue) { _regionDegrees = inValue; } float RegionAttachment::getRegionOffsetX() { return _regionOffsetX; } void RegionAttachment::setRegionOffsetX(float inValue) { _regionOffsetX = inValue; } float RegionAttachment::getRegionOffsetY() { return _regionOffsetY; } void RegionAttachment::setRegionOffsetY(float inValue) { _regionOffsetY = inValue; } float RegionAttachment::getRegionX() { return _regionX; } void RegionAttachment::setRegionX(float inValue) { _regionX = inValue; } float RegionAttachment::getRegionY() { return _regionY; } void RegionAttachment::setRegionY(float inValue) { _regionY = inValue; } float RegionAttachment::getRegionWidth() { return _regionWidth; } void RegionAttachment::setRegionWidth(float inValue) { _regionWidth = inValue; } float RegionAttachment::getRegionHeight() { return _regionHeight; } void RegionAttachment::setRegionHeight(float inValue) { _regionHeight = inValue; } float RegionAttachment::getRegionOriginalWidth() { return _regionOriginalWidth; } void RegionAttachment::setRegionOriginalWidth(float inValue) { _regionOriginalWidth = inValue; } float RegionAttachment::getRegionOriginalHeight() { return _regionOriginalHeight; } void RegionAttachment::setRegionOriginalHeight(float inValue) { _regionOriginalHeight = inValue; } Vector &RegionAttachment::getOffset() { return _vertexOffset; } Vector &RegionAttachment::getUVs() { return _uvs; } spine::Color &RegionAttachment::getColor() { return _color; } Attachment* RegionAttachment::copy() { RegionAttachment* copy = new (__FILE__, __LINE__) RegionAttachment(getName()); copy->_regionWidth = _regionWidth; copy->_regionHeight = _regionHeight; copy->_regionOffsetX = _regionOffsetX; copy->_regionOffsetY = _regionOffsetY; copy->_regionOriginalWidth = _regionOriginalWidth; copy->_regionOriginalHeight = _regionOriginalHeight; copy->setRendererObject(getRendererObject()); copy->_path = _path; copy->_x = _x; copy->_y = _y; copy->_scaleX = _scaleX; copy->_scaleY = _scaleY; copy->_rotation = _rotation; copy->_width = _width; copy->_height = _height; copy->_uvs.clearAndAddAll(_uvs); copy->_vertexOffset.clearAndAddAll(_vertexOffset); copy->_color.set(_color); return copy; }