Files
esengine/packages/sprite/src/SpriteComponent.ts

478 lines
14 KiB
TypeScript
Raw Normal View History

import type { AssetReference } from '@esengine/asset-system';
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检测到的代码问题
2025-12-03 22:15:22 +08:00
import { Component, ECSComponent, Property, Serializable, Serialize } from '@esengine/ecs-framework';
/**
* Material property override value.
*
*
* Used to override specific uniform parameters on a per-instance basis
* without creating a new material instance.
* uniform
*/
export interface MaterialPropertyOverride {
/** Uniform type. | Uniform 类型。 */
type: 'float' | 'vec2' | 'vec3' | 'vec4' | 'color' | 'int';
/** Uniform value. | Uniform 值。 */
value: number | number[];
}
/**
* Material property overrides map.
*
*/
export type MaterialOverrides = Record<string, MaterialPropertyOverride>;
/**
* - 2D图像渲染
* Sprite component - manages 2D image rendering
*/
@ECSComponent('Sprite')
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检测到的代码问题
2025-12-03 22:15:22 +08:00
@Serializable({ version: 3, typeId: 'Sprite' })
export class SpriteComponent extends Component {
/** 纹理路径或资源ID | Texture path or asset ID */
@Serialize()
@Property({ type: 'asset', label: 'Texture', assetType: 'texture' })
public texture: string = '';
/**
* GUID
* Asset GUID for new asset system
*/
@Serialize()
public assetGuid?: string;
/**
* ID使
* Texture ID for runtime rendering
*/
public textureId: number = 0;
/**
*
* Asset reference (runtime only, not serialized)
*/
private _assetReference?: AssetReference<HTMLImageElement>;
/**
*
* Sprite width in pixels
*/
@Serialize()
@Property({
type: 'number',
label: 'Width',
min: 0,
actions: [{
id: 'nativeSize',
label: 'Native',
tooltip: 'Set to texture native size',
icon: 'Maximize2'
}]
})
public width: number = 64;
/**
*
* Sprite height in pixels
*/
@Serialize()
@Property({
type: 'number',
label: 'Height',
min: 0,
actions: [{
id: 'nativeSize',
label: 'Native',
tooltip: 'Set to texture native size',
icon: 'Maximize2'
}]
})
public height: number = 64;
/**
* UV坐标 [u0, v0, u1, v1]
* UV coordinates [u0, v0, u1, v1]
* [0, 0, 1, 1]
* Default is full texture [0, 0, 1, 1]
*/
@Serialize()
public uv: [number, number, number, number] = [0, 0, 1, 1];
/** 颜色(十六进制)| Color (hex string) */
@Serialize()
@Property({ type: 'color', label: 'Color' })
public color: string = '#ffffff';
/** 透明度 (0-1) | Alpha (0-1) */
@Serialize()
@Property({ type: 'number', label: 'Alpha', min: 0, max: 1, step: 0.01 })
public alpha: number = 1;
/**
* X (0-1, 0.5)
* Origin point X (0-1, where 0.5 is center)
*/
@Serialize()
@Property({ type: 'number', label: 'Origin X', min: 0, max: 1, step: 0.01 })
public originX: number = 0.5;
/**
* Y (0-1, 0.5)
* Origin point Y (0-1, where 0.5 is center)
*/
@Serialize()
@Property({ type: 'number', label: 'Origin Y', min: 0, max: 1, step: 0.01 })
public originY: number = 0.5;
/**
*
* Whether sprite is visible
*/
@Serialize()
@Property({ type: 'boolean', label: 'Visible' })
public visible: boolean = true;
/** 是否水平翻转 | Flip sprite horizontally */
@Serialize()
@Property({ type: 'boolean', label: 'Flip X' })
public flipX: boolean = false;
/** 是否垂直翻转 | Flip sprite vertically */
@Serialize()
@Property({ type: 'boolean', label: 'Flip Y' })
public flipY: boolean = false;
/**
* /
* Render layer/order (higher = rendered on top)
*/
@Serialize()
@Property({ type: 'integer', label: 'Sorting Order' })
public sortingOrder: number = 0;
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检测到的代码问题
2025-12-03 22:15:22 +08:00
/**
*
* Material asset path (shared material)
*
* Multiple sprites can reference the same material file.
*
*/
@Serialize()
@Property({ type: 'asset', label: 'Material', extensions: ['.mat'] })
public material: string = '';
/**
*
* Material property overrides (instance level)
*
* Override specific uniform parameters without creating a new material.
* uniform
*/
@Serialize()
public materialOverrides: MaterialOverrides = {};
/**
* 使
* Whether to use an independent material instance
*
* When true, a copy of the shared material is created for this sprite.
* Changes to this material won't affect other sprites using the same source.
* true
* 使
*/
@Serialize()
@Property({ type: 'boolean', label: 'Use Instance Material' })
public useInstanceMaterial: boolean = false;
/**
* ID
* Runtime material ID (cached)
*
* Cached material ID for rendering. Updated when material path changes.
* ID
*/
private _materialId: number = 0;
/**
* useInstanceMaterial true
* Independent material instance (if useInstanceMaterial is true)
*/
private _instanceMaterial: unknown = null;
/** 锚点X (0-1) - 别名为originX | Anchor X (0-1) - alias for originX */
get anchorX(): number {
return this.originX;
}
set anchorX(value: number) {
this.originX = value;
}
/** 锚点Y (0-1) - 别名为originY | Anchor Y (0-1) - alias for originY */
get anchorY(): number {
return this.originY;
}
set anchorY(value: number) {
this.originY = value;
}
constructor(texture: string = '') {
super();
this.texture = texture;
}
/**
* UV
* Set UV from a sprite atlas region
*
* @param x - X| Region X in pixels
* @param y - Y| Region Y in pixels
* @param w - | Region width in pixels
* @param h - | Region height in pixels
* @param atlasWidth - | Atlas total width
* @param atlasHeight - | Atlas total height
*/
setAtlasRegion(
x: number,
y: number,
w: number,
h: number,
atlasWidth: number,
atlasHeight: number
): void {
this.uv = [
x / atlasWidth,
y / atlasHeight,
(x + w) / atlasWidth,
(y + h) / atlasHeight
];
this.width = w;
this.height = h;
}
/**
*
* Set asset reference
*/
setAssetReference(reference: AssetReference<HTMLImageElement>): void {
// 释放旧引用 / Release old reference
if (this._assetReference) {
this._assetReference.release();
}
this._assetReference = reference;
if (reference) {
this.assetGuid = reference.guid;
}
}
/**
*
* Get asset reference
*/
getAssetReference(): AssetReference<HTMLImageElement> | undefined {
return this._assetReference;
}
/**
*
* Load texture asynchronously
*/
async loadTextureAsync(): Promise<void> {
if (this._assetReference) {
try {
const textureAsset = await this._assetReference.loadAsync();
// 如果纹理资产有 textureId 属性,使用它
// If texture asset has textureId property, use it
if (textureAsset && typeof textureAsset === 'object' && 'textureId' in textureAsset) {
this.textureId = (textureAsset as any).textureId;
}
} catch (error) {
console.error('Failed to load texture:', error);
}
}
}
/**
*
* Get effective texture source
*/
getTextureSource(): string {
return this.assetGuid || this.texture;
}
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检测到的代码问题
2025-12-03 22:15:22 +08:00
// ============= Material Override Methods =============
// ============= 材质覆盖方法 =============
/**
* ID
* Get material ID
*
* # Returns |
* The cached material ID for rendering.
* ID
*/
getMaterialId(): number {
return this._materialId;
}
/**
* ID
* Set material ID
*
* # Arguments |
* * `id` - Material ID from MaterialManager. | MaterialManager ID
*/
setMaterialId(id: number): void {
this._materialId = id;
}
/**
*
* Set float override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `value` - Float value. |
*/
setOverrideFloat(name: string, value: number): this {
this.materialOverrides[name] = { type: 'float', value };
return this;
}
/**
* vec2
* Set vec2 override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `x` - X component. | X
* * `y` - Y component. | Y
*/
setOverrideVec2(name: string, x: number, y: number): this {
this.materialOverrides[name] = { type: 'vec2', value: [x, y] };
return this;
}
/**
* vec3
* Set vec3 override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `x` - X component. | X
* * `y` - Y component. | Y
* * `z` - Z component. | Z
*/
setOverrideVec3(name: string, x: number, y: number, z: number): this {
this.materialOverrides[name] = { type: 'vec3', value: [x, y, z] };
return this;
}
/**
* vec4
* Set vec4 override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `x` - X component. | X
* * `y` - Y component. | Y
* * `z` - Z component. | Z
* * `w` - W component. | W
*/
setOverrideVec4(name: string, x: number, y: number, z: number, w: number): this {
this.materialOverrides[name] = { type: 'vec4', value: [x, y, z, w] };
return this;
}
/**
*
* Set color override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `r` - Red component (0-1). | (0-1)
* * `g` - Green component (0-1). | 绿 (0-1)
* * `b` - Blue component (0-1). | (0-1)
* * `a` - Alpha component (0-1). | (0-1)
*/
setOverrideColor(name: string, r: number, g: number, b: number, a: number = 1.0): this {
this.materialOverrides[name] = { type: 'color', value: [r, g, b, a] };
return this;
}
/**
*
* Set integer override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
* * `value` - Integer value. |
*/
setOverrideInt(name: string, value: number): this {
this.materialOverrides[name] = { type: 'int', value: Math.floor(value) };
return this;
}
/**
*
* Get override value
*
* # Arguments |
* * `name` - Uniform name. | Uniform
*
* # Returns |
* Override value or undefined if not set.
* undefined
*/
getOverride(name: string): MaterialPropertyOverride | undefined {
return this.materialOverrides[name];
}
/**
*
* Remove override value
*
* # Arguments |
* * `name` - Uniform name to remove. | Uniform
*/
removeOverride(name: string): this {
delete this.materialOverrides[name];
return this;
}
/**
*
* Clear all override values
*/
clearOverrides(): this {
this.materialOverrides = {};
return this;
}
/**
*
* Check if there are any overrides
*
* # Returns |
* True if there are any material overrides.
* true
*/
hasOverrides(): boolean {
return Object.keys(this.materialOverrides).length > 0;
}
/**
*
* Called when component is destroyed
*/
onDestroy(): void {
// 释放资产引用 / Release asset reference
if (this._assetReference) {
this._assetReference.release();
this._assetReference = undefined;
}
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检测到的代码问题
2025-12-03 22:15:22 +08:00
// 清理材质覆盖 / Clear material overrides
this.materialOverrides = {};
this._instanceMaterial = null;
}
}