axmol/extensions/dragonbones/geom/Matrix.h

318 lines
8.2 KiB
C
Raw Normal View History

2019-11-24 23:15:56 +08:00
/**
* 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 ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><EFBFBD><EFBFBD>תͼ<EFBFBD><EFBFBD>ʱӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD>λ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD>бͼ<EFBFBD><EFBFBD>ʱӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD>λ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD>бͼ<EFBFBD><EFBFBD>ʱӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD>λ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><EFBFBD><EFBFBD>תͼ<EFBFBD><EFBFBD>ʱӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD>λ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD> x <EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD> y <EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD>
* @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
*/
/**
* - ת<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD>þ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>a=1<EFBFBD><EFBFBD>b=0<EFBFBD><EFBFBD>c=0<EFBFBD><EFBFBD>d=1<EFBFBD><EFBFBD>tx=0<EFBFBD><EFBFBD>ty=0<EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD>
* @param value - <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>˵ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @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
*/
/**
* - ת<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @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
*/
/**
* - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD>
* @param x - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param y - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param result - Ӧ<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD>ĵ
* @param delta - <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tx<EFBFBD><EFBFBD>ty <EFBFBD>Ե<EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @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