/** * The MIT License (MIT) * * Copyright (c) 2012-2018 DragonBones team and other contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef DRAGONBONES_MATRIX_H #define DRAGONBONES_MATRIX_H #include "../core/DragonBones.h" #include "Point.h" #include "Rectangle.h" DRAGONBONES_NAMESPACE_BEGIN /** * - 2D Transform matrix. * @version DragonBones 3.0 * @language en_US */ /** * - 2D 转换矩阵。 * @version DragonBones 3.0 * @language zh_CN */ class Matrix { public: /** * - The value that affects the positioning of pixels along the x axis when scaling or rotating an image. * @default 1.0 * @version DragonBones 3.0 * @language en_US */ /** * - 缩放或旋转图像时影响像素沿 x 轴定位的值。 * @default 1.0 * @version DragonBones 3.0 * @language zh_CN */ float a; /** * - The value that affects the positioning of pixels along the y axis when rotating or skewing an image. * @default 0.0 * @version DragonBones 3.0 * @language en_US */ /** * - 旋转或倾斜图像时影响像素沿 y 轴定位的值。 * @default 0.0 * @version DragonBones 3.0 * @language zh_CN */ float b; /** * - The value that affects the positioning of pixels along the x axis when rotating or skewing an image. * @default 0.0 * @version DragonBones 3.0 * @language en_US */ /** * - 旋转或倾斜图像时影响像素沿 x 轴定位的值。 * @default 0.0 * @version DragonBones 3.0 * @language zh_CN */ float c; /** * - The value that affects the positioning of pixels along the y axis when scaling or rotating an image. * @default 1.0 * @version DragonBones 3.0 * @language en_US */ /** * - 缩放或旋转图像时影响像素沿 y 轴定位的值。 * @default 1.0 * @version DragonBones 3.0 * @language zh_CN */ float d; /** * - The distance by which to translate each point along the x axis. * @default 0.0 * @version DragonBones 3.0 * @language en_US */ /** * - 沿 x 轴平移每个点的距离。 * @default 0.0 * @version DragonBones 3.0 * @language zh_CN */ float tx; /** * - The distance by which to translate each point along the y axis. * @default 0.0 * @version DragonBones 3.0 * @language en_US */ /** * - 沿 y 轴平移每个点的距离。 * @default 0.0 * @version DragonBones 3.0 * @language zh_CN */ float ty; Matrix() : a(1.0f), b(0.0f), c(0.0f), d(1.0f), tx(0.0f), ty(0.0f) {} /** * @private */ Matrix(const Matrix& value) { operator=(value); } ~Matrix() {} inline void operator=(const Matrix& value) { a = value.a; b = value.b; c = value.c; d = value.d; tx = value.tx; ty = value.ty; } /** * - Convert to unit matrix. * The resulting matrix has the following properties: a=1, b=0, c=0, d=1, tx=0, ty=0. * @version DragonBones 3.0 * @language en_US */ /** * - 转换为单位矩阵。 * 该矩阵具有以下属性:a=1、b=0、c=0、d=1、tx=0、ty=0。 * @version DragonBones 3.0 * @language zh_CN */ inline void identity() { a = d = 1.0f; b = c = 0.0f; tx = ty = 0.0f; } /** * - Multiplies the current matrix with another matrix. * @param value - The matrix that needs to be multiplied. * @version DragonBones 3.0 * @language en_US */ /** * - 将当前矩阵与另一个矩阵相乘。 * @param value - 需要相乘的矩阵。 * @version DragonBones 3.0 * @language zh_CN */ inline void concat(const Matrix& value) { const auto aA = a; const auto bA = b; const auto cA = c; const auto dA = d; const auto txA = tx; const auto tyA = ty; const auto aB = value.a; const auto bB = value.b; const auto cB = value.c; const auto dB = value.d; const auto txB = value.tx; const auto tyB = value.ty; a = aA * aB + bA * cB; b = aA * bB + bA * dB; c = cA * aB + dA * cB; d = cA * bB + dA * dB; tx = aB * txA + cB * tyA + txB; ty = dB * tyA + bB * txA + tyB; } /** * - Convert to inverse matrix. * @version DragonBones 3.0 * @language en_US */ /** * - 转换为逆矩阵。 * @version DragonBones 3.0 * @language zh_CN */ inline void invert() { const auto aA = a; const auto bA = b; const auto cA = c; const auto dA = d; const auto txA = tx; const auto tyA = ty; const auto n = aA * dA - bA * cA; a = dA / n; b = -bA / n; c = -cA / n; d = aA / n; tx = (cA * tyA - dA * txA) / n; ty = -(aA * tyA - bA * txA) / n; } /** * - Apply a matrix transformation to a specific point. * @param x - X coordinate. * @param y - Y coordinate. * @param result - The point after the transformation is applied. * @param delta - Whether to ignore tx, ty's conversion to point. * @version DragonBones 3.0 * @language en_US */ /** * - 将矩阵转换应用于特定点。 * @param x - 横坐标。 * @param y - 纵坐标。 * @param result - 应用转换之后的点。 * @param delta - 是否忽略 tx,ty 对点的转换。 * @version DragonBones 3.0 * @language zh_CN */ inline void transformPoint(float x, float y, Point& result, bool delta = false) const { result.x = a * x + c * y; result.y = b * x + d * y; if (!delta) { result.x += tx; result.y += ty; } } /** * @private */ inline void transformRectangle(Rectangle& rectangle, bool delta = false) const { const auto offsetX = delta ? 0.0f : this->tx; const auto offsetY = delta ? 0.0f : this->ty; const auto x = rectangle.x; const auto y = rectangle.y; const auto xMax = x + rectangle.width; const auto yMax = y + rectangle.height; auto x0 = a * x + c * y + offsetX; auto y0 = b * x + d * y + offsetY; auto x1 = a * xMax + c * y + offsetX; auto y1 = b * xMax + d * y + offsetY; auto x2 = a * xMax + c * yMax + offsetX; auto y2 = b * xMax + d * yMax + offsetY; auto x3 = a * x + c * yMax + offsetX; auto y3 = b * x + d * yMax + offsetY; auto tmp = 0.0f; if (x0 > x1) { tmp = x0; x0 = x1; x1 = tmp; } if (x2 > x3) { tmp = x2; x2 = x3; x3 = tmp; } rectangle.x = std::floor(x0 < x2 ? x0 : x2); rectangle.width = std::ceil((x1 > x3 ? x1 : x3) - rectangle.x); if (y0 > y1) { tmp = y0; y0 = y1; y1 = tmp; } if (y2 > y3) { tmp = y2; y2 = y3; y3 = tmp; } rectangle.y = std::floor(y0 < y2 ? y0 : y2); rectangle.height = std::ceil((y1 > y3 ? y1 : y3) - rectangle.y); } }; DRAGONBONES_NAMESPACE_END #endif // DRAGONBONES_MATRIX_H