Files
esengine/packages/physics-rapier2d/src/PhysicsRuntimeModule.ts
YHH 63f006ab62 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

203 lines
5.6 KiB
TypeScript
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.
/**
* 物理运行时模块
*
* 提供 Rapier2D 物理引擎的 ECS 集成
*/
import type { IScene, ServiceContainer } from '@esengine/ecs-framework';
import { ComponentRegistry } from '@esengine/ecs-framework';
import type { IRuntimeModule, IPlugin, ModuleManifest, SystemContext } from '@esengine/engine-core';
import { WasmLibraryLoaderFactory } from '@esengine/platform-common';
import type * as RAPIER from '@esengine/rapier2d';
import { Rigidbody2DComponent } from './components/Rigidbody2DComponent';
import { BoxCollider2DComponent } from './components/BoxCollider2DComponent';
import { CircleCollider2DComponent } from './components/CircleCollider2DComponent';
import { CapsuleCollider2DComponent } from './components/CapsuleCollider2DComponent';
import { PolygonCollider2DComponent } from './components/PolygonCollider2DComponent';
import { Physics2DSystem } from './systems/Physics2DSystem';
import { Physics2DService } from './services/Physics2DService';
// 注册 Rapier2D 加载器
import './loaders';
/**
* 物理系统上下文扩展
*/
export interface PhysicsSystemContext extends SystemContext {
/**
* 物理系统实例
*/
physicsSystem?: Physics2DSystem;
/**
* 物理世界实例
*/
physics2DWorld?: any;
/**
* 物理配置
*/
physicsConfig?: any;
}
/**
* 物理运行时模块
*
* 负责:
* 1. 加载并初始化 Rapier2D WASM 模块(跨平台)
* 2. 注册物理组件
* 3. 注册物理服务
* 4. 创建物理系统
*
* @example
* ```typescript
* // 作为插件使用
* runtimePluginManager.register(PhysicsPlugin);
* runtimePluginManager.enable('@esengine/physics-rapier2d');
*
* // 插件会自动:
* // 1. 检测平台并选择合适的加载器
* // 2. 安装必要的 polyfills如微信小游戏的 TextDecoder
* // 3. 加载 Rapier2D WASM 模块
* // 4. 注册物理组件和系统
* ```
*/
class PhysicsRuntimeModule implements IRuntimeModule {
private _rapierModule: typeof RAPIER | null = null;
private _physicsSystem: Physics2DSystem | null = null;
/**
* 初始化物理模块
*
* 使用平台适配的加载器加载 Rapier2D
*/
async onInitialize(): Promise<void> {
// 使用工厂创建平台对应的加载器
const loader = WasmLibraryLoaderFactory.createLoader<typeof RAPIER>('rapier2d');
// 获取平台信息
const platformInfo = loader.getPlatformInfo();
console.log(`[Physics] 平台: ${platformInfo.type}`);
console.log(`[Physics] WASM 支持: ${platformInfo.supportsWasm}`);
if (platformInfo.needsPolyfills.length > 0) {
console.log(`[Physics] 需要 Polyfills: ${platformInfo.needsPolyfills.join(', ')}`);
}
// 检查平台支持
if (!loader.isSupported()) {
throw new Error(
`[Physics] 当前平台不支持 Rapier2D: ${platformInfo.type}` +
'请检查 WebAssembly 支持情况。'
);
}
// 加载 Rapier2D
this._rapierModule = await loader.load();
console.log('[Physics] Rapier2D 加载完成');
}
/**
* 注册物理组件
*
* @param registry - 组件注册表
*/
registerComponents(registry: typeof ComponentRegistry): void {
registry.register(Rigidbody2DComponent);
registry.register(BoxCollider2DComponent);
registry.register(CircleCollider2DComponent);
registry.register(CapsuleCollider2DComponent);
registry.register(PolygonCollider2DComponent);
}
/**
* 注册物理服务
*
* @param services - 服务容器
*/
registerServices(services: ServiceContainer): void {
services.registerSingleton(Physics2DService);
}
/**
* 创建物理系统
*
* @param scene - 目标场景
* @param context - 系统上下文
*/
createSystems(scene: IScene, context: SystemContext): void {
const physicsContext = context as PhysicsSystemContext;
const physicsSystem = new Physics2DSystem({
physics: physicsContext.physicsConfig,
updateOrder: -1000
});
scene.addSystem(physicsSystem);
this._physicsSystem = physicsSystem;
if (this._rapierModule) {
physicsSystem.initializeWithRapier(this._rapierModule);
}
physicsContext.physicsSystem = physicsSystem;
physicsContext.physics2DWorld = physicsSystem.world;
}
/**
* 销毁物理模块
*/
onDestroy(): void {
this._physicsSystem = null;
this._rapierModule = null;
}
/**
* 获取 Rapier 模块
*
* @returns Rapier 模块,如果未加载则返回 null
*/
getRapierModule(): typeof RAPIER | null {
return this._rapierModule;
}
/**
* 获取物理系统
*
* @returns 物理系统,如果未创建则返回 null
*/
getPhysicsSystem(): Physics2DSystem | null {
return this._physicsSystem;
}
}
/**
* 模块清单
*/
const manifest: ModuleManifest = {
id: 'physics-rapier2d',
name: '@esengine/physics-rapier2d',
displayName: 'Physics 2D (Rapier)',
version: '1.0.0',
description: '基于 Rapier2D 的确定性 2D 物理引擎(支持跨平台)',
category: 'Physics',
icon: 'Atom',
isCore: false,
defaultEnabled: false,
isEngineModule: true,
dependencies: ['core', 'math'],
exports: { components: ['RigidBody2D'] },
requiresWasm: true
};
/**
* 物理插件
*/
export const PhysicsPlugin: IPlugin = {
manifest,
runtimeModule: new PhysicsRuntimeModule()
};
export { PhysicsRuntimeModule };