* 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检测到的代码问题
203 lines
5.6 KiB
TypeScript
203 lines
5.6 KiB
TypeScript
/**
|
||
* 物理运行时模块
|
||
*
|
||
* 提供 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 };
|