Merge remote master
This commit is contained in:
@@ -24,15 +24,7 @@ cd esengine
|
|||||||
pnpm install
|
pnpm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Clone Physics Dependencies (Optional)
|
### 2. Build Dependencies
|
||||||
|
|
||||||
If you need physics support, clone the rapier.js dependency:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/esengine/rapier.js.git packages/thirdparty/rapier.js
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Build Dependencies
|
|
||||||
|
|
||||||
From the project root:
|
From the project root:
|
||||||
|
|
||||||
@@ -40,7 +32,7 @@ From the project root:
|
|||||||
pnpm build:editor
|
pnpm build:editor
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Run Editor
|
### 3. Run Editor
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd packages/editor/editor-app
|
cd packages/editor/editor-app
|
||||||
|
|||||||
@@ -24,15 +24,7 @@ cd esengine
|
|||||||
pnpm install
|
pnpm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 克隆物理依赖(可选)
|
### 2. 构建依赖
|
||||||
|
|
||||||
如果需要物理引擎支持,需要克隆 rapier.js 依赖:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/esengine/rapier.js.git packages/thirdparty/rapier.js
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 构建依赖
|
|
||||||
|
|
||||||
在项目根目录执行:
|
在项目根目录执行:
|
||||||
|
|
||||||
@@ -40,7 +32,7 @@ git clone https://github.com/esengine/rapier.js.git packages/thirdparty/rapier.j
|
|||||||
pnpm build:editor
|
pnpm build:editor
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 启动编辑器
|
### 3. 启动编辑器
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd packages/editor/editor-app
|
cd packages/editor/editor-app
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@esengine/ecs-framework": "workspace:*",
|
"@esengine/ecs-framework": "workspace:*",
|
||||||
"@esengine/engine-core": "workspace:*",
|
"@esengine/engine-core": "workspace:*",
|
||||||
|
"@esengine/asset-system": "workspace:*",
|
||||||
"@esengine/editor-core": "workspace:*",
|
"@esengine/editor-core": "workspace:*",
|
||||||
"@esengine/editor-runtime": "workspace:*",
|
"@esengine/editor-runtime": "workspace:*",
|
||||||
"@esengine/node-editor": "workspace:*",
|
"@esengine/node-editor": "workspace:*",
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* @zh ESEngine 行为树运行时模块
|
||||||
|
* @en ESEngine Behavior Tree Runtime Module
|
||||||
|
*
|
||||||
|
* @zh 纯运行时模块,不依赖 asset-system。资产加载由编辑器在 install 时注册。
|
||||||
|
* @en Pure runtime module, no asset-system dependency. Asset loading is registered by editor during install.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { IScene, ServiceContainer, IComponentRegistry } from '@esengine/ecs-framework';
|
||||||
|
import type { IRuntimeModule, SystemContext } from '@esengine/engine-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BehaviorTreeRuntimeComponent,
|
||||||
|
BehaviorTreeExecutionSystem,
|
||||||
|
BehaviorTreeAssetManager,
|
||||||
|
GlobalBlackboardService,
|
||||||
|
BehaviorTreeSystemToken
|
||||||
|
} from '@esengine/behavior-tree';
|
||||||
|
|
||||||
|
export class BehaviorTreeRuntimeModule implements IRuntimeModule {
|
||||||
|
registerComponents(registry: IComponentRegistry): void {
|
||||||
|
registry.register(BehaviorTreeRuntimeComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerServices(services: ServiceContainer): void {
|
||||||
|
if (!services.isRegistered(GlobalBlackboardService)) {
|
||||||
|
services.registerSingleton(GlobalBlackboardService);
|
||||||
|
}
|
||||||
|
if (!services.isRegistered(BehaviorTreeAssetManager)) {
|
||||||
|
services.registerSingleton(BehaviorTreeAssetManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createSystems(scene: IScene, context: SystemContext): void {
|
||||||
|
const ecsServices = (context as { ecsServices?: ServiceContainer }).ecsServices;
|
||||||
|
const behaviorTreeSystem = new BehaviorTreeExecutionSystem(ecsServices);
|
||||||
|
|
||||||
|
if (context.isEditor) {
|
||||||
|
behaviorTreeSystem.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene.addSystem(behaviorTreeSystem);
|
||||||
|
context.services.register(BehaviorTreeSystemToken, behaviorTreeSystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,8 +30,11 @@ import {
|
|||||||
LocaleService,
|
LocaleService,
|
||||||
} from '@esengine/editor-runtime';
|
} from '@esengine/editor-runtime';
|
||||||
|
|
||||||
// Runtime imports from @esengine/behavior-tree package
|
// Runtime imports
|
||||||
import { BehaviorTreeRuntimeComponent, BehaviorTreeRuntimeModule } from '@esengine/behavior-tree';
|
import { BehaviorTreeRuntimeComponent, BehaviorTreeAssetType } from '@esengine/behavior-tree';
|
||||||
|
import { AssetManagerToken } from '@esengine/asset-system';
|
||||||
|
import { BehaviorTreeRuntimeModule } from './BehaviorTreeRuntimeModule';
|
||||||
|
import { BehaviorTreeLoader } from './runtime/BehaviorTreeLoader';
|
||||||
|
|
||||||
// Editor components and services
|
// Editor components and services
|
||||||
import { BehaviorTreeService } from './services/BehaviorTreeService';
|
import { BehaviorTreeService } from './services/BehaviorTreeService';
|
||||||
@@ -71,6 +74,10 @@ export class BehaviorTreeEditorModule implements IEditorModuleLoader {
|
|||||||
// 设置插件上下文
|
// 设置插件上下文
|
||||||
PluginContext.setServices(services);
|
PluginContext.setServices(services);
|
||||||
|
|
||||||
|
// 注册行为树资产加载器到 AssetManager
|
||||||
|
// Register behavior tree asset loader to AssetManager
|
||||||
|
this.registerAssetLoader();
|
||||||
|
|
||||||
// 注册服务
|
// 注册服务
|
||||||
this.registerServices(services);
|
this.registerServices(services);
|
||||||
|
|
||||||
@@ -92,6 +99,22 @@ export class BehaviorTreeEditorModule implements IEditorModuleLoader {
|
|||||||
logger.info('BehaviorTree editor module installed');
|
logger.info('BehaviorTree editor module installed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册行为树资产加载器
|
||||||
|
* Register behavior tree asset loader
|
||||||
|
*/
|
||||||
|
private registerAssetLoader(): void {
|
||||||
|
try {
|
||||||
|
const assetManager = PluginAPI.resolve(AssetManagerToken);
|
||||||
|
if (assetManager) {
|
||||||
|
assetManager.registerLoader(BehaviorTreeAssetType, new BehaviorTreeLoader());
|
||||||
|
logger.info('BehaviorTree asset loader registered');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn('Failed to register asset loader:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private registerAssetCreationMappings(services: ServiceContainer): void {
|
private registerAssetCreationMappings(services: ServiceContainer): void {
|
||||||
try {
|
try {
|
||||||
const fileActionRegistry = services.resolve<FileActionRegistry>(IFileActionRegistry);
|
const fileActionRegistry = services.resolve<FileActionRegistry>(IFileActionRegistry);
|
||||||
@@ -376,7 +399,7 @@ export const BehaviorTreePlugin: IEditorPlugin = {
|
|||||||
editorModule: new BehaviorTreeEditorModule(),
|
editorModule: new BehaviorTreeEditorModule(),
|
||||||
};
|
};
|
||||||
|
|
||||||
export { BehaviorTreeRuntimeModule };
|
// BehaviorTreeRuntimeModule is internal, not re-exported
|
||||||
|
|
||||||
// Re-exports for editor functionality
|
// Re-exports for editor functionality
|
||||||
export { PluginContext } from './PluginContext';
|
export { PluginContext } from './PluginContext';
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* @zh ESEngine 资产加载器
|
||||||
|
* @en ESEngine asset loader
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Core } from '@esengine/ecs-framework';
|
||||||
|
import {
|
||||||
|
BehaviorTreeAssetManager,
|
||||||
|
EditorToBehaviorTreeDataConverter,
|
||||||
|
BehaviorTreeAssetType,
|
||||||
|
type BehaviorTreeData
|
||||||
|
} from '@esengine/behavior-tree';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 行为树资产接口
|
||||||
|
* @en Behavior tree asset interface
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface IBehaviorTreeAsset {
|
||||||
|
data: BehaviorTreeData;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 行为树加载器
|
||||||
|
* @en Behavior tree loader implementing IAssetLoader interface
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export class BehaviorTreeLoader {
|
||||||
|
readonly supportedType = BehaviorTreeAssetType;
|
||||||
|
readonly supportedExtensions = ['.btree'];
|
||||||
|
readonly contentType = 'text' as const;
|
||||||
|
|
||||||
|
async parse(content: { text?: string }, context: { metadata: { path: string } }): Promise<IBehaviorTreeAsset> {
|
||||||
|
if (!content.text) {
|
||||||
|
throw new Error('Behavior tree content is empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
const treeData = EditorToBehaviorTreeDataConverter.fromEditorJSON(content.text);
|
||||||
|
const assetPath = context.metadata.path;
|
||||||
|
treeData.id = assetPath;
|
||||||
|
|
||||||
|
const btAssetManager = Core.services.tryResolve(BehaviorTreeAssetManager);
|
||||||
|
if (btAssetManager) {
|
||||||
|
btAssetManager.loadAsset(treeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: treeData,
|
||||||
|
path: assetPath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(asset: IBehaviorTreeAsset): void {
|
||||||
|
const btAssetManager = Core.services.tryResolve(BehaviorTreeAssetManager);
|
||||||
|
if (btAssetManager && asset.data) {
|
||||||
|
btAssetManager.unloadAsset(asset.data.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +1,15 @@
|
|||||||
{
|
{
|
||||||
|
"extends": "../../../../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"composite": false,
|
||||||
"module": "ES2020",
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"lib": ["ES2020", "DOM"],
|
|
||||||
"outDir": "./dist",
|
|
||||||
"rootDir": "./src",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"resolveJsonModule": true,
|
"skipLibCheck": true,
|
||||||
"experimentalDecorators": true,
|
"moduleResolution": "bundler"
|
||||||
"emitDecoratorMetadata": true
|
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*"],
|
||||||
"exclude": ["node_modules", "dist"]
|
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { defineConfig } from 'tsup';
|
|||||||
import { editorOnlyPreset } from '../../../tools/build-config/src/presets/plugin-tsup';
|
import { editorOnlyPreset } from '../../../tools/build-config/src/presets/plugin-tsup';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
...editorOnlyPreset(),
|
...editorOnlyPreset({
|
||||||
|
external: ['@esengine/asset-system']
|
||||||
|
}),
|
||||||
tsconfig: 'tsconfig.build.json'
|
tsconfig: 'tsconfig.build.json'
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": false,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"jsx": "react-jsx"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../build-config/tsconfig.json",
|
"extends": "../../../../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export default defineConfig({
|
|||||||
format: ['esm'],
|
format: ['esm'],
|
||||||
dts: true,
|
dts: true,
|
||||||
clean: true,
|
clean: true,
|
||||||
|
tsconfig: 'tsconfig.build.json',
|
||||||
external: [
|
external: [
|
||||||
'react',
|
'react',
|
||||||
'react-dom',
|
'react-dom',
|
||||||
|
|||||||
@@ -121,9 +121,9 @@ export class WeChatRapier2DLoader implements IWasmLibraryLoader<RapierModule> {
|
|||||||
// 导入 Rapier2D 标准版
|
// 导入 Rapier2D 标准版
|
||||||
const RAPIER = await import('@esengine/rapier2d');
|
const RAPIER = await import('@esengine/rapier2d');
|
||||||
|
|
||||||
// 初始化 WASM - 标准版需要提供 WASM 路径
|
// 初始化 WASM - WASM 已经作为 base64 嵌入到包中
|
||||||
const wasmPath = this._config.minigame?.wasmPath || 'wasm/rapier_wasm2d_bg.wasm';
|
// Initialize WASM - WASM is embedded as base64 in the package
|
||||||
await RAPIER.init(wasmPath);
|
await RAPIER.init();
|
||||||
|
|
||||||
return RAPIER;
|
return RAPIER;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -53,10 +53,9 @@ export class WebRapier2DLoader implements IWasmLibraryLoader<RapierModule> {
|
|||||||
// 动态导入标准版
|
// 动态导入标准版
|
||||||
const RAPIER = await import('@esengine/rapier2d');
|
const RAPIER = await import('@esengine/rapier2d');
|
||||||
|
|
||||||
// 初始化 WASM - 标准版需要提供 WASM 路径
|
// 初始化 WASM - WASM 已经作为 base64 嵌入到包中
|
||||||
// 构建时 WASM 文件会被复制到 wasm/ 目录
|
// Initialize WASM - WASM is embedded as base64 in the package
|
||||||
const wasmPath = this._config.web?.wasmPath || 'wasm/rapier_wasm2d_bg.wasm';
|
await RAPIER.init();
|
||||||
await RAPIER.init(wasmPath);
|
|
||||||
|
|
||||||
console.log(`[${this._config.name}] 加载完成`);
|
console.log(`[${this._config.name}] 加载完成`);
|
||||||
return RAPIER;
|
return RAPIER;
|
||||||
|
|||||||
@@ -19,11 +19,13 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"gen:src": "node scripts/gen-src.mjs",
|
"gen:src": "node scripts/gen-src.mjs",
|
||||||
"build": "pnpm gen:src && tsup",
|
"build": "tsup",
|
||||||
"clean": "rimraf dist src"
|
"build:regen": "pnpm gen:src && tsup",
|
||||||
|
"clean": "rimraf dist"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"base64-js": "^1.5.1",
|
||||||
"rimraf": "^5.0.0",
|
"rimraf": "^5.0.0",
|
||||||
"tsup": "^8.0.0",
|
"tsup": "^8.0.0",
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
|
|||||||
@@ -91,9 +91,8 @@ export class KinematicCharacterController {
|
|||||||
*/
|
*/
|
||||||
public setUp(vector: Vector) {
|
public setUp(vector: Vector) {
|
||||||
let rawVect = VectorOps.intoRaw(vector);
|
let rawVect = VectorOps.intoRaw(vector);
|
||||||
const result = this.raw.setUp(rawVect);
|
return this.raw.setUp(rawVect);
|
||||||
rawVect.free();
|
rawVect.free();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyImpulsesToDynamicBodies(): boolean {
|
public applyImpulsesToDynamicBodies(): boolean {
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ export class DynamicRayCastVehicleController {
|
|||||||
bodies: RigidBodySet,
|
bodies: RigidBodySet,
|
||||||
colliders: ColliderSet,
|
colliders: ColliderSet,
|
||||||
) {
|
) {
|
||||||
if (typeof RawDynamicRayCastVehicleController === 'undefined') {
|
|
||||||
throw new Error('DynamicRayCastVehicleController is not available in 2D mode');
|
|
||||||
}
|
|
||||||
this.raw = new RawDynamicRayCastVehicleController(chassis.handle);
|
this.raw = new RawDynamicRayCastVehicleController(chassis.handle);
|
||||||
this.broadPhase = broadPhase;
|
this.broadPhase = broadPhase;
|
||||||
this.narrowPhase = narrowPhase;
|
this.narrowPhase = narrowPhase;
|
||||||
|
|||||||
@@ -1,60 +1,12 @@
|
|||||||
/**
|
// @ts-ignore
|
||||||
* RAPIER initialization module with dynamic WASM loading support.
|
import wasmBase64 from "../pkg/rapier_wasm2d_bg.wasm";
|
||||||
* RAPIER 初始化模块,支持动态 WASM 加载。
|
|
||||||
*/
|
|
||||||
|
|
||||||
import wasmInit from "../pkg/rapier_wasm2d";
|
import wasmInit from "../pkg/rapier_wasm2d";
|
||||||
|
import base64 from "base64-js";
|
||||||
/**
|
|
||||||
* Input types for WASM initialization.
|
|
||||||
* WASM 初始化的输入类型。
|
|
||||||
*/
|
|
||||||
export type InitInput =
|
|
||||||
| RequestInfo // URL string or Request object
|
|
||||||
| URL // URL object
|
|
||||||
| Response // Fetch Response object
|
|
||||||
| BufferSource // ArrayBuffer or TypedArray
|
|
||||||
| WebAssembly.Module; // Pre-compiled module
|
|
||||||
|
|
||||||
let initialized = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes RAPIER.
|
* Initializes RAPIER.
|
||||||
* Has to be called and awaited before using any library methods.
|
* Has to be called and awaited before using any library methods.
|
||||||
*
|
|
||||||
* 初始化 RAPIER。
|
|
||||||
* 必须在使用任何库方法之前调用并等待。
|
|
||||||
*
|
|
||||||
* @param input - WASM source (required). Can be URL, Response, ArrayBuffer, etc.
|
|
||||||
* WASM 源(必需)。可以是 URL、Response、ArrayBuffer 等。
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // Load from URL | 从 URL 加载
|
|
||||||
* await RAPIER.init('wasm/rapier_wasm2d_bg.wasm');
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // Load from fetch response | 从 fetch 响应加载
|
|
||||||
* const response = await fetch('wasm/rapier_wasm2d_bg.wasm');
|
|
||||||
* await RAPIER.init(response);
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // Load from ArrayBuffer | 从 ArrayBuffer 加载
|
|
||||||
* const buffer = await fetch('wasm/rapier_wasm2d_bg.wasm').then(r => r.arrayBuffer());
|
|
||||||
* await RAPIER.init(buffer);
|
|
||||||
*/
|
*/
|
||||||
export async function init(input?: InitInput): Promise<void> {
|
export async function init() {
|
||||||
if (initialized) {
|
await wasmInit(base64.toByteArray(wasmBase64 as unknown as string).buffer);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await wasmInit(input);
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if RAPIER is already initialized.
|
|
||||||
* 检查 RAPIER 是否已初始化。
|
|
||||||
*/
|
|
||||||
export function isInitialized(): boolean {
|
|
||||||
return initialized;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class VectorOps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: type ram: RawVector?
|
// FIXME: type ram: RawVector?
|
||||||
public static fromRaw(raw: RawVector): Vector | null {
|
public static fromRaw(raw: RawVector): Vector {
|
||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
|
|
||||||
let res = VectorOps.new(raw.x, raw.y);
|
let res = VectorOps.new(raw.x, raw.y);
|
||||||
@@ -56,7 +56,7 @@ export class RotationOps {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromRaw(raw: RawRotation): Rotation | null {
|
public static fromRaw(raw: RawRotation): Rotation {
|
||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
|
|
||||||
let res = raw.angle;
|
let res = raw.angle;
|
||||||
|
|||||||
@@ -7,4 +7,7 @@ export default defineConfig({
|
|||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
clean: true,
|
clean: true,
|
||||||
external: ["../pkg/rapier_wasm2d.js"],
|
external: ["../pkg/rapier_wasm2d.js"],
|
||||||
|
loader: {
|
||||||
|
".wasm": "base64",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Generated
+6
@@ -569,6 +569,9 @@ importers:
|
|||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../../framework/behavior-tree
|
version: link:../../../framework/behavior-tree
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@esengine/asset-system':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../../engine/asset-system
|
||||||
'@esengine/build-config':
|
'@esengine/build-config':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../../tools/build-config
|
version: link:../../../tools/build-config
|
||||||
@@ -1861,6 +1864,9 @@ importers:
|
|||||||
|
|
||||||
packages/physics/rapier2d:
|
packages/physics/rapier2d:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
base64-js:
|
||||||
|
specifier: ^1.5.1
|
||||||
|
version: 1.5.1
|
||||||
rimraf:
|
rimraf:
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.0.10
|
version: 5.0.10
|
||||||
|
|||||||
Reference in New Issue
Block a user