init
This commit is contained in:
119
src/babylonjs/AppModel.ts
Normal file
119
src/babylonjs/AppModel.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { ImportMeshAsync } from '@babylonjs/core/Loading/sceneLoader';
|
||||
import '@babylonjs/loaders/glTF';
|
||||
import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
|
||||
import { Scene } from '@babylonjs/core/scene';
|
||||
import { Monobehiver } from '../base/Monobehiver';
|
||||
import { Dictionary } from '../utils/Dictionary';
|
||||
import { AppConfig } from './AppConfig';
|
||||
|
||||
type LoadResult = {
|
||||
success: boolean;
|
||||
meshes?: AbstractMesh[];
|
||||
skeletons?: unknown[];
|
||||
error?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 模型管理类- 负责加载、缓存和管理3D模型
|
||||
*/
|
||||
export class AppModel extends Monobehiver {
|
||||
private modelDic: Dictionary<AbstractMesh[]>;
|
||||
private loadedMeshes: AbstractMesh[];
|
||||
private skeletonManager: any;
|
||||
private outfitManager: any;
|
||||
private isLoading: boolean;
|
||||
private skeletonMerged: boolean;
|
||||
|
||||
constructor(mainApp: any) {
|
||||
super(mainApp);
|
||||
this.modelDic = new Dictionary<AbstractMesh[]>();
|
||||
this.loadedMeshes = [];
|
||||
this.skeletonManager = null;
|
||||
this.outfitManager = null;
|
||||
this.isLoading = false;
|
||||
this.skeletonMerged = false;
|
||||
}
|
||||
|
||||
/** 初始化子管理器(占位:实际实现已移除) */
|
||||
initManagers(): void {
|
||||
// 这里原本会初始化 SkeletonManager 和 OutfitManager,已留空以避免恢复已删除的实现
|
||||
}
|
||||
|
||||
/** 加载配置中的所有模型 */
|
||||
async loadModel(): Promise<void> {
|
||||
if (!AppConfig.modelUrlList?.length || this.isLoading) return;
|
||||
this.isLoading = true;
|
||||
try {
|
||||
for (const url of AppConfig.modelUrlList) {
|
||||
await this.loadSingleModel(url);
|
||||
}
|
||||
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载单个模型
|
||||
* @param modelUrl 模型URL
|
||||
*/
|
||||
async loadSingleModel(modelUrl: string): Promise<LoadResult> {
|
||||
try {
|
||||
const cached = this.getCachedMeshes(modelUrl);
|
||||
if (cached) return { success: true, meshes: cached };
|
||||
|
||||
const scene: Scene | null = this.mainApp.appScene.object;
|
||||
if (!scene) return { success: false, error: '场景未初始化' };
|
||||
|
||||
// ImportMeshAsync的签名与当前调用不完全一致,使用any规避编译报错
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const result: any = await (ImportMeshAsync as any)(modelUrl, scene);
|
||||
if (!result?.meshes?.length) return { success: false, error: '未找到网格' };
|
||||
|
||||
this.modelDic.Set(modelUrl, result.meshes);
|
||||
this.loadedMeshes.push(...result.meshes);
|
||||
|
||||
this.setupShadows(result.meshes as AbstractMesh[]);
|
||||
|
||||
return { success: true, meshes: result.meshes, skeletons: result.skeletons };
|
||||
} catch (e: any) {
|
||||
console.error(`模型加载失败: ${modelUrl}`, e);
|
||||
return { success: false, error: e?.message };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** 为网格设置阴影(投射和接收) */
|
||||
setupShadows(meshes: AbstractMesh[]): void {
|
||||
const appLight = this.mainApp.appLight;
|
||||
if (!appLight) return;
|
||||
|
||||
meshes.forEach(mesh => {
|
||||
if (mesh.getTotalVertices() > 0) {
|
||||
appLight.addShadowCaster(mesh);
|
||||
mesh.receiveShadows = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取缓存的网格 */
|
||||
getCachedMeshes(url: string): AbstractMesh[] | undefined {
|
||||
return this.modelDic.Get(url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** 清理所有资源 */
|
||||
clean(): void {
|
||||
this.modelDic.Clear();
|
||||
this.loadedMeshes.forEach(m => m?.dispose());
|
||||
this.loadedMeshes = [];
|
||||
this.skeletonManager?.clean();
|
||||
this.outfitManager?.clean();
|
||||
this.isLoading = false;
|
||||
this.skeletonMerged = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user