feat: 添加跨平台运行时、资产系统和UI适配功能 (#256)

* feat(platform-common): 添加WASM加载器和环境检测API

* feat(rapier2d): 新增Rapier2D WASM绑定包

* feat(physics-rapier2d): 添加跨平台WASM加载器

* feat(asset-system): 添加运行时资产目录和bundle格式

* feat(asset-system-editor): 新增编辑器资产管理包

* feat(editor-core): 添加构建系统和模块管理

* feat(editor-app): 重构浏览器预览使用import maps

* feat(platform-web): 添加BrowserRuntime和资产读取

* feat(engine): 添加材质系统和着色器管理

* feat(material): 新增材质系统和着色器编辑器

* feat(tilemap): 增强tilemap编辑器和动画系统

* feat(modules): 添加module.json配置

* feat(core): 添加module.json和类型定义更新

* chore: 更新依赖和构建配置

* refactor(plugins): 更新插件模板使用ModuleManifest

* chore: 添加第三方依赖库

* chore: 移除BehaviourTree-ai和ecs-astar子模块

* docs: 更新README和文档主题样式

* fix: 修复Rust文档测试和添加rapier2d WASM绑定

* fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题

* feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea)

* fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖

* fix: 添加缺失的包依赖修复CI构建

* fix: 修复CodeQL检测到的代码问题

* fix: 修复构建错误和缺失依赖

* fix: 修复类型检查错误

* fix(material-system): 修复tsconfig配置支持TypeScript项目引用

* fix(editor-core): 修复Rollup构建配置添加tauri external

* fix: 修复CodeQL检测到的代码问题

* fix: 修复CodeQL检测到的代码问题
This commit is contained in:
YHH
2025-12-03 22:15:22 +08:00
committed by GitHub
parent caf7622aa0
commit 63f006ab62
496 changed files with 77601 additions and 4067 deletions

View File

@@ -0,0 +1,198 @@
/**
* Viewport Overlay Interface
* 视口覆盖层接口
*
* Defines the interface for rendering overlays on viewports (grid, selection, gizmos, etc.)
* 定义在视口上渲染覆盖层的接口(网格、选区、辅助线等)
*/
import type { ViewportCameraConfig } from '../Services/IViewportService';
/**
* Context passed to overlay renderers
* 传递给覆盖层渲染器的上下文
*/
export interface OverlayRenderContext {
/** Current camera state | 当前相机状态 */
camera: ViewportCameraConfig;
/** Viewport dimensions | 视口尺寸 */
viewport: { width: number; height: number };
/** Device pixel ratio | 设备像素比 */
dpr: number;
/** Selected entity IDs (if applicable) | 选中的实体 ID如果适用 */
selectedEntityIds?: number[];
/** Delta time since last frame | 距上一帧的时间差 */
deltaTime: number;
/** Add a line gizmo | 添加线条辅助线 */
addLine(x1: number, y1: number, x2: number, y2: number, color: number, thickness?: number): void;
/** Add a rectangle gizmo (outline) | 添加矩形辅助线(轮廓) */
addRect(x: number, y: number, width: number, height: number, color: number, thickness?: number): void;
/** Add a filled rectangle gizmo | 添加填充矩形辅助线 */
addFilledRect(x: number, y: number, width: number, height: number, color: number): void;
/** Add a circle gizmo (outline) | 添加圆形辅助线(轮廓) */
addCircle(x: number, y: number, radius: number, color: number, thickness?: number): void;
/** Add a filled circle gizmo | 添加填充圆形辅助线 */
addFilledCircle(x: number, y: number, radius: number, color: number): void;
/** Add text | 添加文本 */
addText?(text: string, x: number, y: number, color: number, fontSize?: number): void;
}
/**
* Interface for viewport overlays (grid, selection, etc.)
* 视口覆盖层接口(网格、选区等)
*/
export interface IViewportOverlay {
/** Unique overlay identifier | 唯一覆盖层标识符 */
readonly id: string;
/** Priority (higher = rendered later/on top) | 优先级(越高越晚渲染/在上层) */
priority: number;
/** Whether overlay is visible | 覆盖层是否可见 */
visible: boolean;
/**
* Render the overlay
* 渲染覆盖层
* @param context - Render context with camera, viewport info, and gizmo APIs
*/
render(context: OverlayRenderContext): void;
/**
* Update the overlay (optional, called each frame before render)
* 更新覆盖层(可选,每帧在渲染前调用)
* @param deltaTime - Time since last update
*/
update?(deltaTime: number): void;
/**
* Dispose the overlay resources
* 释放覆盖层资源
*/
dispose?(): void;
}
/**
* Base class for viewport overlays
* 视口覆盖层基类
*/
export abstract class ViewportOverlayBase implements IViewportOverlay {
abstract readonly id: string;
priority = 0;
visible = true;
abstract render(context: OverlayRenderContext): void;
update?(deltaTime: number): void;
dispose?(): void;
}
/**
* Grid overlay for viewports
* 视口网格覆盖层
*/
export class GridOverlay extends ViewportOverlayBase {
override readonly id = 'grid';
override priority = 0;
/** Grid cell size in world units | 网格单元格大小(世界单位) */
cellSize = 32;
/** Grid line color (ARGB packed) | 网格线颜色ARGB 打包) */
lineColor = 0x40FFFFFF;
/** Major grid line interval | 主网格线间隔 */
majorLineInterval = 10;
/** Major grid line color (ARGB packed) | 主网格线颜色ARGB 打包) */
majorLineColor = 0x60FFFFFF;
/** Show axis lines | 显示轴线 */
showAxisLines = true;
/** X axis color | X 轴颜色 */
xAxisColor = 0xFFFF5555;
/** Y axis color | Y 轴颜色 */
yAxisColor = 0xFF55FF55;
render(context: OverlayRenderContext): void {
const { camera, viewport } = context;
const halfWidth = (viewport.width / 2) / camera.zoom;
const halfHeight = (viewport.height / 2) / camera.zoom;
// Calculate visible grid range
const left = camera.x - halfWidth;
const right = camera.x + halfWidth;
const bottom = camera.y - halfHeight;
const top = camera.y + halfHeight;
// Round to grid lines
const startX = Math.floor(left / this.cellSize) * this.cellSize;
const endX = Math.ceil(right / this.cellSize) * this.cellSize;
const startY = Math.floor(bottom / this.cellSize) * this.cellSize;
const endY = Math.ceil(top / this.cellSize) * this.cellSize;
// Draw vertical lines
for (let x = startX; x <= endX; x += this.cellSize) {
const isMajor = x % (this.cellSize * this.majorLineInterval) === 0;
const color = isMajor ? this.majorLineColor : this.lineColor;
context.addLine(x, startY, x, endY, color, isMajor ? 1.5 : 1);
}
// Draw horizontal lines
for (let y = startY; y <= endY; y += this.cellSize) {
const isMajor = y % (this.cellSize * this.majorLineInterval) === 0;
const color = isMajor ? this.majorLineColor : this.lineColor;
context.addLine(startX, y, endX, y, color, isMajor ? 1.5 : 1);
}
// Draw axis lines
if (this.showAxisLines) {
// X axis (red)
if (bottom <= 0 && top >= 0) {
context.addLine(startX, 0, endX, 0, this.xAxisColor, 2);
}
// Y axis (green)
if (left <= 0 && right >= 0) {
context.addLine(0, startY, 0, endY, this.yAxisColor, 2);
}
}
}
}
/**
* Selection highlight overlay
* 选区高亮覆盖层
*/
export class SelectionOverlay extends ViewportOverlayBase {
override readonly id = 'selection';
override priority = 100;
/** Selection highlight color (ARGB packed) | 选区高亮颜色ARGB 打包) */
highlightColor = 0x404488FF;
/** Selection border color (ARGB packed) | 选区边框颜色ARGB 打包) */
borderColor = 0xFF4488FF;
/** Border thickness | 边框厚度 */
borderThickness = 2;
private _selections: Array<{ x: number; y: number; width: number; height: number }> = [];
/**
* Set selection rectangles
* 设置选区矩形
*/
setSelections(selections: Array<{ x: number; y: number; width: number; height: number }>): void {
this._selections = selections;
}
/**
* Clear all selections
* 清除所有选区
*/
clearSelections(): void {
this._selections = [];
}
render(context: OverlayRenderContext): void {
for (const sel of this._selections) {
// Draw filled rectangle
context.addFilledRect(sel.x, sel.y, sel.width, sel.height, this.highlightColor);
// Draw border
context.addRect(sel.x, sel.y, sel.width, sel.height, this.borderColor, this.borderThickness);
}
}
}

View File

@@ -0,0 +1,6 @@
/**
* Rendering module exports
* 渲染模块导出
*/
export * from './IViewportOverlay';