* 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
137 lines
3.6 KiB
TypeScript
137 lines
3.6 KiB
TypeScript
import type { IRectangle } from '../utils/MathTypes';
|
|
import type { IRenderCollector, IRenderPrimitive } from './IRenderCollector';
|
|
|
|
/**
|
|
* RenderCollector
|
|
*
|
|
* Collects render primitives from UI hierarchy for batch rendering.
|
|
* Implements IRenderCollector interface with efficient primitive storage.
|
|
*
|
|
* 从 UI 层级收集渲染图元用于批量渲染
|
|
*/
|
|
export class RenderCollector implements IRenderCollector {
|
|
private _primitives: IRenderPrimitive[] = [];
|
|
private _clipStack: IRectangle[] = [];
|
|
private _sortNeeded: boolean = false;
|
|
|
|
/**
|
|
* Add a render primitive
|
|
* 添加渲染图元
|
|
*/
|
|
public addPrimitive(primitive: IRenderPrimitive): void {
|
|
this._primitives.push(primitive);
|
|
this._sortNeeded = true;
|
|
}
|
|
|
|
/**
|
|
* Push a clip rect onto the stack
|
|
* 压入裁剪矩形
|
|
*/
|
|
public pushClipRect(rect: IRectangle): void {
|
|
if (this._clipStack.length > 0) {
|
|
// Intersect with current clip rect
|
|
const current = this._clipStack[this._clipStack.length - 1];
|
|
const intersected = this.intersectRects(current, rect);
|
|
this._clipStack.push(intersected);
|
|
} else {
|
|
this._clipStack.push({ ...rect });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pop the current clip rect
|
|
* 弹出当前裁剪矩形
|
|
*/
|
|
public popClipRect(): void {
|
|
if (this._clipStack.length > 0) {
|
|
this._clipStack.pop();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get current clip rect
|
|
* 获取当前裁剪矩形
|
|
*/
|
|
public getCurrentClipRect(): IRectangle | null {
|
|
if (this._clipStack.length > 0) {
|
|
return this._clipStack[this._clipStack.length - 1];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Clear all primitives
|
|
* 清除所有图元
|
|
*/
|
|
public clear(): void {
|
|
this._primitives.length = 0;
|
|
this._clipStack.length = 0;
|
|
this._sortNeeded = false;
|
|
}
|
|
|
|
/**
|
|
* Get all primitives sorted by sortOrder
|
|
* 获取所有按 sortOrder 排序的图元
|
|
*/
|
|
public getPrimitives(): readonly IRenderPrimitive[] {
|
|
if (this._sortNeeded) {
|
|
this._primitives.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
this._sortNeeded = false;
|
|
}
|
|
return this._primitives;
|
|
}
|
|
|
|
/**
|
|
* Get primitive count
|
|
* 获取图元数量
|
|
*/
|
|
public get primitiveCount(): number {
|
|
return this._primitives.length;
|
|
}
|
|
|
|
/**
|
|
* Get clip stack depth
|
|
* 获取裁剪栈深度
|
|
*/
|
|
public get clipStackDepth(): number {
|
|
return this._clipStack.length;
|
|
}
|
|
|
|
/**
|
|
* Calculate intersection of two rectangles
|
|
* 计算两个矩形的交集
|
|
*/
|
|
private intersectRects(a: IRectangle, b: IRectangle): IRectangle {
|
|
const x = Math.max(a.x, b.x);
|
|
const y = Math.max(a.y, b.y);
|
|
const right = Math.min(a.x + a.width, b.x + b.width);
|
|
const bottom = Math.min(a.y + a.height, b.y + b.height);
|
|
|
|
return {
|
|
x,
|
|
y,
|
|
width: Math.max(0, right - x),
|
|
height: Math.max(0, bottom - y)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Iterate over primitives with callback
|
|
* 遍历图元
|
|
*/
|
|
public forEach(callback: (primitive: IRenderPrimitive, index: number) => void): void {
|
|
const primitives = this.getPrimitives();
|
|
for (let i = 0; i < primitives.length; i++) {
|
|
callback(primitives[i], i);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Filter primitives by type
|
|
* 按类型过滤图元
|
|
*/
|
|
public filterByType(type: string): IRenderPrimitive[] {
|
|
return this._primitives.filter((p) => p.type === type);
|
|
}
|
|
}
|