You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

130 lines
2.6 KiB

import _ from 'lodash'
import Example1 from './example1'
import { markRaw, reactive } from 'vue'
import { Scene } from 'three'
import type Viewport from '@/designer/Viewport.ts'
import * as THREE from 'three'
/**
* 世界模型
*/
export default class WorldModel {
data: any = null
allLevels: any = null
sceneMap = new Map<string, Scene>()
viewPorts: Viewport[] = []
constructor() {
this.init()
this.open()
}
init() {
window['worldModel'] = this
}
open() {
if (this.sceneMap.size > 0) {
// 释放旧场景
this.sceneMap.forEach((scene: Scene) => {
this.sceneDispose(scene)
})
}
if (this.viewPorts.length > 0) {
// 注销视口
this.viewPorts.forEach((viewport: Viewport) => {
this.unregisterViewport(viewport)
})
}
system.msg('打开世界地图完成')
this.data = markRaw(Example1)
this.allLevels = reactive(this.data.allLevels)
}
/**
* 获取当前楼层的场景, 如果没有则创建一个新的场景
* @param floor
*/
getSceneByFloor(floor: string) {
if (this.sceneMap.has(floor)) {
return this.sceneMap.get(floor)
} else {
const scene = this.createScene(floor)
this.sceneMap.set(floor, scene)
return scene
}
}
/**
* 创建一个新的场景
*/
createScene(floor: string) {
const scene = new Scene()
scene.background = new THREE.Color(0xeeeeee)
return scene
}
/**
* 注册视口
*/
registerViewport(viewport: Viewport) {
this.viewPorts = this.viewPorts || []
this.viewPorts.push(viewport)
}
/**
* 注销视口
*/
unregisterViewport(viewport: Viewport) {
const index = this.viewPorts.indexOf(viewport)
if (index > -1) {
this.viewPorts.splice(index, 1)
}
}
/**
* 销毁场景, 释放全部 WebGL 资源
*/
sceneDispose(scene: Scene = null) {
// 移除旧模型
if (!scene) {
return
}
scene.traverse((obj: any) => {
// 释放几何体
if (obj.geometry) {
obj.geometry.dispose()
}
// 释放材质
if (obj.material) {
if (Array.isArray(obj.material)) {
obj.material.forEach(m => m.dispose())
} else {
obj.material.dispose()
}
}
// 释放纹理
if (obj.texture) {
obj.texture.dispose()
}
// 释放渲染目标
if (obj.renderTarget) {
obj.renderTarget.dispose()
}
// 移除事件监听(如 OrbitControls)
if (obj.dispose) {
obj.dispose()
}
})
// 清空场景
scene.children = []
}
}