mirror of https://github.com/axmolengine/axmol.git
308 lines
8.4 KiB
C++
308 lines
8.4 KiB
C++
/**
|
||
* 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
|