Files
esengine/packages/rust/engine/src/math/transform.rs
YHH 155411e743 refactor: reorganize package structure and decouple framework packages (#338)
* refactor: reorganize package structure and decouple framework packages

## Package Structure Reorganization
- Reorganized 55 packages into categorized subdirectories:
  - packages/framework/ - Generic framework (Laya/Cocos compatible)
  - packages/engine/ - ESEngine core modules
  - packages/rendering/ - Rendering modules (WASM dependent)
  - packages/physics/ - Physics modules
  - packages/streaming/ - World streaming
  - packages/network-ext/ - Network extensions
  - packages/editor/ - Editor framework and plugins
  - packages/rust/ - Rust WASM engine
  - packages/tools/ - Build tools and SDK

## Framework Package Decoupling
- Decoupled behavior-tree and blueprint packages from ESEngine dependencies
- Created abstracted interfaces (IBTAssetManager, IBehaviorTreeAssetContent)
- ESEngine-specific code moved to esengine/ subpath exports
- Framework packages now usable with Cocos/Laya without ESEngine

## CI Configuration
- Updated CI to only type-check and lint framework packages
- Added type-check:framework and lint:framework scripts

## Breaking Changes
- Package import paths changed due to directory reorganization
- ESEngine integrations now use subpath imports (e.g., '@esengine/behavior-tree/esengine')

* fix: update es-engine file path after directory reorganization

* docs: update README to focus on framework over engine

* ci: only build framework packages, remove Rust/WASM dependencies

* fix: remove esengine subpath from behavior-tree and blueprint builds

ESEngine integration code will only be available in full engine builds.
Framework packages are now purely engine-agnostic.

* fix: move network-protocols to framework, build both in CI

* fix: update workflow paths from packages/core to packages/framework/core

* fix: exclude esengine folder from type-check in behavior-tree and blueprint

* fix: update network tsconfig references to new paths

* fix: add test:ci:framework to only test framework packages in CI

* fix: only build core and math npm packages in CI

* fix: exclude test files from CodeQL and fix string escaping security issue
2025-12-26 14:50:35 +08:00

178 lines
5.6 KiB
Rust
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.
//! 2D transform implementation.
//! 2D变换实现。
use super::Vec2;
use glam::Mat3;
/// 2D transformation combining position, rotation, and scale.
/// 组合位置、旋转和缩放的2D变换。
///
/// # Examples | 示例
/// ```rust
/// use es_engine::math::{Transform2D, Vec2};
/// let mut transform = Transform2D::new();
/// transform.position = Vec2::new(100.0, 200.0);
/// transform.rotation = std::f32::consts::PI / 4.0; // 45 degrees
/// transform.scale = Vec2::new(2.0, 2.0);
///
/// let matrix = transform.to_matrix();
/// ```
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Transform2D {
/// Position in world space.
/// 世界空间中的位置。
pub position: Vec2,
/// Rotation in radians.
/// 旋转角度(弧度)。
pub rotation: f32,
/// Scale factor.
/// 缩放因子。
pub scale: Vec2,
/// Origin point for rotation and scaling (0-1 range, relative to size).
/// 旋转和缩放的原点0-1范围相对于尺寸
pub origin: Vec2,
}
impl Default for Transform2D {
fn default() -> Self {
Self {
position: Vec2::ZERO,
rotation: 0.0,
scale: Vec2::new(1.0, 1.0),
origin: Vec2::new(0.5, 0.5), // Center by default | 默认居中
}
}
}
impl Transform2D {
/// Create a new transform with default values.
/// 使用默认值创建新变换。
#[inline]
pub fn new() -> Self {
Self::default()
}
/// Create a transform with specified position.
/// 使用指定位置创建变换。
#[inline]
pub fn from_position(x: f32, y: f32) -> Self {
Self {
position: Vec2::new(x, y),
..Default::default()
}
}
/// Create a transform with position, rotation, and scale.
/// 使用位置、旋转和缩放创建变换。
#[inline]
pub fn from_pos_rot_scale(position: Vec2, rotation: f32, scale: Vec2) -> Self {
Self {
position,
rotation,
scale,
..Default::default()
}
}
/// Convert to a 3x3 transformation matrix.
/// 转换为3x3变换矩阵。
///
/// The matrix is constructed as: T * R * S (translate, rotate, scale).
/// 矩阵构造顺序为T * R * S平移、旋转、缩放
///
/// Uses left-hand coordinate system convention:
/// 使用左手坐标系约定:
/// - Positive rotation = clockwise (when viewed from +Z)
/// - 正旋转 = 顺时针(从 +Z 方向观察时)
pub fn to_matrix(&self) -> Mat3 {
let cos = self.rotation.cos();
let sin = self.rotation.sin();
// Construct TRS matrix directly for performance
// 直接构造TRS矩阵以提高性能
// Clockwise rotation: [cos, -sin; sin, cos] (column-major)
// 顺时针旋转矩阵
Mat3::from_cols(
glam::Vec3::new(cos * self.scale.x, -sin * self.scale.x, 0.0),
glam::Vec3::new(sin * self.scale.y, cos * self.scale.y, 0.0),
glam::Vec3::new(self.position.x, self.position.y, 1.0),
)
}
/// Convert to a 3x3 matrix with origin offset applied.
/// 转换为应用原点偏移的3x3矩阵。
///
/// # Arguments | 参数
/// * `width` - Sprite width | 精灵宽度
/// * `height` - Sprite height | 精灵高度
///
/// Uses left-hand coordinate system (clockwise positive rotation).
/// 使用左手坐标系(顺时针正旋转)。
pub fn to_matrix_with_origin(&self, width: f32, height: f32) -> Mat3 {
let ox = -self.origin.x * width * self.scale.x;
let oy = -self.origin.y * height * self.scale.y;
let cos = self.rotation.cos();
let sin = self.rotation.sin();
// Apply origin offset after rotation (clockwise rotation)
// 在旋转后应用原点偏移(顺时针旋转)
let tx = self.position.x + ox * cos + oy * sin;
let ty = self.position.y - ox * sin + oy * cos;
// Clockwise rotation matrix
// 顺时针旋转矩阵
Mat3::from_cols(
glam::Vec3::new(cos * self.scale.x, -sin * self.scale.x, 0.0),
glam::Vec3::new(sin * self.scale.y, cos * self.scale.y, 0.0),
glam::Vec3::new(tx, ty, 1.0),
)
}
/// Transform a local point to world space.
/// 将局部点变换到世界空间。
#[inline]
pub fn transform_point(&self, point: Vec2) -> Vec2 {
let rotated = point.rotate(self.rotation);
Vec2::new(
rotated.x * self.scale.x + self.position.x,
rotated.y * self.scale.y + self.position.y,
)
}
/// Inverse transform a world point to local space.
/// 将世界点反变换到局部空间。
#[inline]
pub fn inverse_transform_point(&self, point: Vec2) -> Vec2 {
let local = Vec2::new(
(point.x - self.position.x) / self.scale.x,
(point.y - self.position.y) / self.scale.y,
);
local.rotate(-self.rotation)
}
/// Translate the transform by a delta.
/// 按增量平移变换。
#[inline]
pub fn translate(&mut self, delta: Vec2) {
self.position = self.position + delta;
}
/// Rotate the transform by an angle (in radians).
/// 按角度旋转变换(弧度)。
#[inline]
pub fn rotate(&mut self, angle: f32) {
self.rotation += angle;
}
/// Scale the transform by a factor.
/// 按因子缩放变换。
#[inline]
pub fn scale_by(&mut self, factor: Vec2) {
self.scale = Vec2::new(self.scale.x * factor.x, self.scale.y * factor.y);
}
}