88 lines
2.4 KiB
C
88 lines
2.4 KiB
C
|
|
#pragma once
|
|||
|
|
|
|||
|
|
#include <core/vec2.h>
|
|||
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|||
|
|
#include <glm/mat4x4.hpp>
|
|||
|
|
|
|||
|
|
namespace extra2d {
|
|||
|
|
|
|||
|
|
// ---------------------------------------------------------------------------
|
|||
|
|
// 2D 变换矩阵(基于 glm::mat4,兼容 OpenGL)
|
|||
|
|
// ---------------------------------------------------------------------------
|
|||
|
|
struct Transform2D {
|
|||
|
|
glm::mat4 matrix{1.0f}; // 单位矩阵
|
|||
|
|
|
|||
|
|
Transform2D() = default;
|
|||
|
|
explicit Transform2D(const glm::mat4 &m) : matrix(m) {}
|
|||
|
|
|
|||
|
|
static Transform2D identity() { return Transform2D{}; }
|
|||
|
|
|
|||
|
|
static Transform2D translation(float x, float y) {
|
|||
|
|
Transform2D t;
|
|||
|
|
t.matrix = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Transform2D translation(const Vec2 &v) {
|
|||
|
|
return translation(v.x, v.y);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Transform2D rotation(float degrees) {
|
|||
|
|
Transform2D t;
|
|||
|
|
t.matrix = glm::rotate(glm::mat4(1.0f), degrees * DEG_TO_RAD,
|
|||
|
|
glm::vec3(0.0f, 0.0f, 1.0f));
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Transform2D scaling(float sx, float sy) {
|
|||
|
|
Transform2D t;
|
|||
|
|
t.matrix = glm::scale(glm::mat4(1.0f), glm::vec3(sx, sy, 1.0f));
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static Transform2D scaling(float s) { return scaling(s, s); }
|
|||
|
|
|
|||
|
|
static Transform2D skewing(float skewX, float skewY) {
|
|||
|
|
Transform2D t;
|
|||
|
|
t.matrix = glm::mat4(1.0f);
|
|||
|
|
t.matrix[1][0] = std::tan(skewX * DEG_TO_RAD);
|
|||
|
|
t.matrix[0][1] = std::tan(skewY * DEG_TO_RAD);
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transform2D operator*(const Transform2D &other) const {
|
|||
|
|
return Transform2D(matrix * other.matrix);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transform2D &operator*=(const Transform2D &other) {
|
|||
|
|
matrix *= other.matrix;
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Vec2 transformPoint(const Vec2 &p) const {
|
|||
|
|
glm::vec4 result = matrix * glm::vec4(p.x, p.y, 0.0f, 1.0f);
|
|||
|
|
return {result.x, result.y};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transform2D inverse() const { return Transform2D(glm::inverse(matrix)); }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ---------------------------------------------------------------------------
|
|||
|
|
// 数学工具函数
|
|||
|
|
// ---------------------------------------------------------------------------
|
|||
|
|
namespace math {
|
|||
|
|
|
|||
|
|
inline float clamp(float value, float minVal, float maxVal) {
|
|||
|
|
return value < minVal ? minVal : (value > maxVal ? maxVal : value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline float lerp(float a, float b, float t) { return a + (b - a) * t; }
|
|||
|
|
|
|||
|
|
inline float degrees(float radians) { return radians * RAD_TO_DEG; }
|
|||
|
|
|
|||
|
|
inline float radians(float degrees) { return degrees * DEG_TO_RAD; }
|
|||
|
|
|
|||
|
|
} // namespace math
|
|||
|
|
|
|||
|
|
} // namespace extra2d
|