axmol/extensions/DragonBones/geom/Matrix.h

318 lines
8.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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 - 是否忽略 txty 对点的转换。
* @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