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.
498 lines
18 KiB
498 lines
18 KiB
3 years ago
|
|
||
|
import { DataManager } from "../../controller/data-manager";
|
||
|
import { InfoManager } from "../../controller/info-manager";
|
||
|
import { SceneManager } from "../../controller/scene-manager";
|
||
|
import { ServeManager } from "../../controller/serve-manager";
|
||
|
import { BuildingStatus } from "../../controller/status/building-status";
|
||
|
import { StatusManager } from "../../controller/status/status-manager";
|
||
|
import { BuildingData_Normal, BuildingData_Environment, BuildingData_ChemicalPlant, BuildingType, BuildingData } from "../../model/data/institution/building/building-data";
|
||
|
import { BuildingPosType, ModelType } from "../../model/data/model-data/model-data";
|
||
|
import { FacilityType } from "../../model/data/model-data/model-data-facility";
|
||
|
import { ModelEditData } from "../../model/data/model-data/model-edit-data";
|
||
|
import { BuildingInfo } from "../../model/info/building/building-info";
|
||
|
import { BuildingInfo_ChemicalPlant } from "../../model/info/building/building-info-chemicalplant";
|
||
|
import { BuildingInfo_Environment } from "../../model/info/building/building-info-environment";
|
||
|
import { BuildingInfo_Normal } from "../../model/info/building/building-info-normal";
|
||
|
import { ModelInfo_building } from "../../model/info/model/model-info-building";
|
||
|
import { TsTool } from "../../tool/ts-tool";
|
||
|
import { UIBase } from "../window-base/ui-base";
|
||
|
import { BuildingUIItem } from "./building-ui-item";
|
||
|
|
||
|
//建筑界面
|
||
|
export class BuildingWindow extends UIBase {
|
||
|
buldingStatus: BuildingStatus;
|
||
|
|
||
|
buildingUIItems: BuildingUIItem[] = [];//所有建筑UI
|
||
|
|
||
|
currentBuidngItem: BuildingUIItem; //当前正在操作的建筑
|
||
|
|
||
|
// three: ThreeDimensionalHomeComponent;//前端组件
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//#region 与前端对接部分
|
||
|
|
||
|
/**
|
||
|
* UI上添加一个建筑item
|
||
|
* @param buildingData 建筑data数据
|
||
|
* @param index 序号
|
||
|
* @param onSuccess 成功的回调
|
||
|
*/
|
||
|
createOneBuildingItem(buildingData: BuildingData_Normal | BuildingData_Environment | BuildingData_ChemicalPlant, index: number, onSuccess?: (buildingUIItem: BuildingUIItem, index: number) => void) {
|
||
|
let buildingInfo: BuildingInfo_Normal | BuildingInfo_Environment | BuildingInfo_ChemicalPlant;
|
||
|
switch (buildingData.buildingType) {
|
||
|
case BuildingType.Normal:
|
||
|
buildingInfo = new BuildingInfo_Normal(buildingData as BuildingData_Normal, null);
|
||
|
break;
|
||
|
case BuildingType.Environment:
|
||
|
buildingInfo = new BuildingInfo_Environment(buildingData, null);
|
||
|
break;
|
||
|
case BuildingType.ChemicalPlant:
|
||
|
buildingInfo = new BuildingInfo_ChemicalPlant(buildingData, null);
|
||
|
break;
|
||
|
}
|
||
|
// console.log("初始化建筑info");
|
||
|
// console.log(buildingInfo.buildingData);
|
||
|
let uiItem = this.addBuildingItem(buildingInfo);
|
||
|
|
||
|
if (buildingData.outdoorData != null && buildingData.outdoorData.modelData != null && buildingData.outdoorData.modelData.resName != null) {
|
||
|
this.updateBuildingModel(buildingInfo, false, () => {
|
||
|
buildingInfo.initFacility();
|
||
|
BuildingStatus.enterSuccessObservable.notifyObservers(uiItem);
|
||
|
if (onSuccess) {
|
||
|
onSuccess(uiItem, index);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//删除建筑
|
||
|
deleteBuilding(buidlingUIItem: BuildingUIItem) {
|
||
|
// console.log("删除建筑" + buidlingUIItem.buildingInfo.buildingData.normalData.key);
|
||
|
DataManager.deleteOneBuildingData(buidlingUIItem.buildingInfo.buildingData.buildingType, buidlingUIItem.buildingInfo.buildingData.normalData.key);
|
||
|
for (let i = 0; i < this.buildingUIItems.length; i++) {
|
||
|
if (this.buildingUIItems[i] == buidlingUIItem) {
|
||
|
buidlingUIItem.dispose();
|
||
|
TsTool.arrayRemove(this.buildingUIItems, buidlingUIItem);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 改变模型
|
||
|
* @param file
|
||
|
*/
|
||
|
changeModel(file: File[], buildingData: BuildingData) {
|
||
|
if (file == null || file.length == 0) {
|
||
|
return;
|
||
|
}
|
||
|
console.log("修改模型");
|
||
|
|
||
|
buildingData.outdoorData.modelData.key = buildingData.normalData.key;
|
||
|
buildingData.outdoorData.modelData.name = buildingData.normalData.key;
|
||
|
|
||
|
let normalData = buildingData.normalData;
|
||
|
let resPath_out = DataManager.getResPath_building(
|
||
|
DataManager.institutionData.normalData.key.toLowerCase(),
|
||
|
normalData.key.toLocaleLowerCase(),
|
||
|
buildingData.normalData.key
|
||
|
);
|
||
|
// console.log("新资源路径" + resPath_out);
|
||
|
let buildingWindow = this;
|
||
|
|
||
|
let manifestFile: File = null;
|
||
|
if (buildingData.outdoorData.modelData.resName != null) {
|
||
|
|
||
|
manifestFile = DataManager.createManifestFile(buildingData.outdoorData.modelData);
|
||
|
file.push(manifestFile); //临时关闭缓存文件
|
||
|
}
|
||
|
|
||
|
|
||
|
ServeManager.instance.uploadFile(0, file, resPath_out, (name: string, path: string, currentfile) => {
|
||
|
if (TsTool.stringContain(name, ".gltf")) {
|
||
|
if (TsTool.stringContain(name, ".gltf.manifest")) {
|
||
|
//缓存文件,提取版本号
|
||
|
DataManager.readFile_manifest(currentfile, (version: number) => {
|
||
|
buildingData.outdoorData.modelData.version = version;
|
||
|
// console.log("设置version" + version);
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
buildingData.outdoorData.modelData.resName = name;
|
||
|
buildingData.outdoorData.modelData.resPath = path;
|
||
|
if (manifestFile == null) {
|
||
|
manifestFile = DataManager.createManifestFile(buildingData.outdoorData.modelData);
|
||
|
file.push(manifestFile);
|
||
|
}//临时关闭缓存文件
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
, () => {
|
||
|
let buildingInfo = buildingWindow.getBuildingInfo(buildingData.normalData.key);
|
||
|
buildingWindow.updateBuildingModel(buildingInfo, true);
|
||
|
// buildingWindow.three = ThreeDimensionalHomeComponent.instance;
|
||
|
// buildingWindow.three.maskLayerService.sendMessage(false) //关闭遮罩层
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取目标建筑中,室内的某类设备数目
|
||
|
*/
|
||
|
getNormalBuildingIndoorFacilitys(buildingUIItem: BuildingUIItem, facilityType: FacilityType) {
|
||
|
let result = 0;
|
||
|
|
||
|
if (buildingUIItem.buildingInfo.buildingData.buildingType != BuildingType.Normal) {
|
||
|
//不是普通建筑,没有室内
|
||
|
}
|
||
|
else {
|
||
|
let indoorData: ModelEditData[] = (buildingUIItem.buildingInfo.buildingData as BuildingData_Normal).indoorsData;
|
||
|
if (indoorData != null) {
|
||
|
for (let i = 0; i < indoorData.length; i++) {
|
||
|
let facilitiesByType = indoorData[i].getFacilitiesByType(facilityType);
|
||
|
if (facilitiesByType != null) {
|
||
|
result += facilitiesByType.length;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 进入第一个具有本设备的室内楼层
|
||
|
*/
|
||
|
changeToFirstIndoorByFacility(buildingUIItem: BuildingUIItem, facilityType: FacilityType) {
|
||
|
|
||
|
let result = false;//是否成功找到并进入某室内层
|
||
|
let num = 0;
|
||
|
|
||
|
if (buildingUIItem.buildingInfo.buildingData.buildingType != BuildingType.Normal) {
|
||
|
//不是普通建筑,没有室内
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
let indoorData: ModelEditData[] = (buildingUIItem.buildingInfo.buildingData as BuildingData_Normal).indoorsData;
|
||
|
for (let i = 0; i < indoorData.length; i++) {
|
||
|
let facilitiesByType = indoorData[i].getFacilitiesByType(facilityType);
|
||
|
if (facilitiesByType != null) {
|
||
|
num += facilitiesByType.length;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (num > 0) {
|
||
|
result = true;
|
||
|
buildingUIItem.enterIndoor(indoorData[i].modelData.key, true);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
//#endregion
|
||
|
|
||
|
|
||
|
//#region 生命周期
|
||
|
onInit() {
|
||
|
super.onInit();
|
||
|
|
||
|
this.buldingStatus = StatusManager.getStatus<BuildingStatus>(BuildingStatus);
|
||
|
|
||
|
|
||
|
this.initBuildings();//创建每一个建筑buildingItem
|
||
|
|
||
|
|
||
|
|
||
|
// this.three = ThreeDimensionalHomeComponent.instance;
|
||
|
// this.three.getAllBuilding(this);
|
||
|
|
||
|
}
|
||
|
|
||
|
onShow() {
|
||
|
this.showModel(true);
|
||
|
|
||
|
super.onShow();
|
||
|
}
|
||
|
onHide() {
|
||
|
this.showModel(false);
|
||
|
super.onHide();
|
||
|
}
|
||
|
|
||
|
//#endregion
|
||
|
|
||
|
|
||
|
//#region 外部公有
|
||
|
|
||
|
/**
|
||
|
* 清空建筑上的设备实例
|
||
|
* @param buildingInfo
|
||
|
*/
|
||
|
clearFacilityInfos(buildingInfo: BuildingInfo) {
|
||
|
|
||
|
if (buildingInfo.ModelInfo != null) {
|
||
|
for (let i = 0; i < buildingInfo.ModelInfo.facilityInfos.length; i++) {
|
||
|
buildingInfo.ModelInfo.facilityInfos[i].dispose();
|
||
|
}
|
||
|
buildingInfo.ModelInfo.facilityInfos = [];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 显示或隐藏建筑上的设备icon
|
||
|
* @param buildingInfo
|
||
|
* @param show
|
||
|
*/
|
||
|
showFacilityInfosIcon(buildingInfo: BuildingInfo, show: boolean) {
|
||
|
if (buildingInfo.ModelInfo != null) {
|
||
|
buildingInfo.ModelInfo.showFacilityUI(show);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 根据buildingInfo找到item,然后模拟选中
|
||
|
* @param buildingInfo 建筑信息
|
||
|
*/
|
||
|
changeCurrentBuildingInfo(modelInfo: ModelInfo_building) {
|
||
|
|
||
|
let item: BuildingUIItem = null;
|
||
|
for (let i = 0; i < this.buildingUIItems.length; i++) {
|
||
|
if (this.buildingUIItems[i].buildingInfo.ModelInfo == modelInfo) {
|
||
|
item = this.buildingUIItems[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//this.onChangeCurrentBuildingItem(item);
|
||
|
|
||
|
// this.three.selectLeftBuilding(item);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 改变当前操作建筑目标
|
||
|
* @param buidlingUIItem 新选中的目标
|
||
|
*/
|
||
|
onChangeCurrentBuildingItem(buidlingUIItem: BuildingUIItem, animMove = true) {
|
||
|
if (this.currentBuidngItem != null && this.currentBuidngItem != buidlingUIItem) {
|
||
|
this.currentBuidngItem.onSelect(false);
|
||
|
}
|
||
|
|
||
|
this.currentBuidngItem = buidlingUIItem;
|
||
|
this.currentBuidngItem.onSelect(true, animMove);
|
||
|
|
||
|
this.buldingStatus.changeCurrentBuilding(buidlingUIItem.buildingInfo);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 查询buildingKey
|
||
|
* @param key
|
||
|
*/
|
||
|
public getBuildingInfo(key: string): BuildingInfo {
|
||
|
for (let i = 0; i < this.buildingUIItems.length; i++) {
|
||
|
if (this.buildingUIItems[i].buildingInfo.buildingData.normalData.key == key) {
|
||
|
return this.buildingUIItems[i].buildingInfo;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 查询UIItem
|
||
|
* @param key
|
||
|
*/
|
||
|
public getBuildingUIItem(key: string) {
|
||
|
for (let i = 0; i < this.buildingUIItems.length; i++) {
|
||
|
if (this.buildingUIItems[i].buildingInfo.buildingData.normalData.key == key) {
|
||
|
return this.buildingUIItems[i];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 更新建筑模型
|
||
|
* @param buildingInfo
|
||
|
* @param updateFacility
|
||
|
* @param onSuccess
|
||
|
*/
|
||
|
public updateBuildingModel(buildingInfo: BuildingInfo, updateFacility: boolean, onSuccess?: () => void) {
|
||
|
if (buildingInfo == null) {
|
||
|
return;
|
||
|
}
|
||
|
if (buildingInfo.ModelInfo != null) {
|
||
|
buildingInfo.ModelInfo.dispose();
|
||
|
}
|
||
|
|
||
|
|
||
|
SceneManager.createModel(ModelType.Building, buildingInfo.buildingData.outdoorData.modelData, true, true, "Building", (newMesh, box, modelInfo) => {
|
||
|
buildingInfo.ModelInfo = modelInfo as ModelInfo_building;
|
||
|
buildingInfo.ModelInfo.updateName(buildingInfo.buildingData.normalData.name);
|
||
|
if (updateFacility) {
|
||
|
InfoManager.createFacilityInfos(buildingInfo.buildingData.outdoorData, buildingInfo);
|
||
|
}
|
||
|
if (buildingInfo instanceof BuildingInfo_Environment) {
|
||
|
buildingInfo.updateFuGaiCeng();
|
||
|
}
|
||
|
|
||
|
if (onSuccess) {
|
||
|
onSuccess();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
//#endregion
|
||
|
|
||
|
|
||
|
//#region 内部私有
|
||
|
|
||
|
|
||
|
//填充建筑列表
|
||
|
private initBuildings() {
|
||
|
|
||
|
|
||
|
//因为babylon内对indexDB的封装使用有问题,在用户第一次使用时触发了创建数据库操作,导致我们同时调用多个加载方法时报错
|
||
|
//解决策略是:如果发现有多个模型要加载,则先加载第一个模型,保证indexDB数据库正常建立, 第一个加载完成后,在加载剩余模型
|
||
|
|
||
|
BuildingStatus.startEnterObservable.notifyObservers(null);
|
||
|
|
||
|
let instance = this;
|
||
|
let firstItem; //第一个要加载的模型
|
||
|
let firstType: BuildingType;
|
||
|
|
||
|
let allModelNumber = 0;
|
||
|
|
||
|
|
||
|
let buildingDatas_Environment = DataManager.getBuildingDataListByType(BuildingType.Environment);
|
||
|
if (buildingDatas_Environment != null) {
|
||
|
allModelNumber += buildingDatas_Environment.length;
|
||
|
if (buildingDatas_Environment.length > 0) {
|
||
|
firstItem = buildingDatas_Environment[0];
|
||
|
firstType = BuildingType.Environment;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let buildingDatas_mormal = DataManager.getBuildingDataListByType(BuildingType.Normal);
|
||
|
if (buildingDatas_mormal != null) {
|
||
|
allModelNumber += buildingDatas_mormal.length;
|
||
|
if (buildingDatas_mormal.length > 0) {
|
||
|
firstItem = buildingDatas_mormal[0];
|
||
|
firstType = BuildingType.Normal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (allModelNumber > 1) {
|
||
|
|
||
|
if (firstType == BuildingType.Environment) {
|
||
|
instance.createOneBuildingItem(firstItem, 0, (uiItem, index) => {
|
||
|
instance.onChangeCurrentBuildingItem(uiItem, false);
|
||
|
uiItem.lookAt(false);
|
||
|
if (buildingDatas_Environment.length > 1) {
|
||
|
instance.addBuildings(BuildingType.Environment, 1);
|
||
|
}
|
||
|
|
||
|
instance.addBuildings(BuildingType.Normal, 0);
|
||
|
|
||
|
});
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
instance.createOneBuildingItem(firstItem, 0, (uiItem, index) => {
|
||
|
instance.onChangeCurrentBuildingItem(uiItem, false);
|
||
|
uiItem.lookAt(false);
|
||
|
if (buildingDatas_mormal.length > 1) {
|
||
|
instance.addBuildings(BuildingType.Normal, 1);
|
||
|
}
|
||
|
instance.addBuildings(BuildingType.Environment, 0);
|
||
|
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
instance.addBuildings(BuildingType.Normal, 0, (uiItem, index) => {
|
||
|
if (index == 0 && uiItem.buildingInfo.isEnable) {
|
||
|
instance.onChangeCurrentBuildingItem(uiItem, false);
|
||
|
uiItem.lookAt(false);
|
||
|
// console.log("默认选中" + uiItem.buildingInfo.buildingData.normalData.key);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
instance.addBuildings(BuildingType.Environment, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//初始化建筑显示(根据类别)
|
||
|
private addBuildings(buildingType: BuildingType, startIndex: number, onSuccess?: (buildingUIItem: BuildingUIItem, index: number) => void) {
|
||
|
let index = startIndex;
|
||
|
|
||
|
let buildingDatas = DataManager.getBuildingDataListByType(buildingType);
|
||
|
// console.log(buildingDatas);
|
||
|
while (buildingDatas != null && index < buildingDatas.length) {
|
||
|
let l_index = index;
|
||
|
let buildingData = buildingDatas[l_index];
|
||
|
this.createOneBuildingItem(buildingData, l_index, onSuccess);
|
||
|
|
||
|
index++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//添加一个item到界面中
|
||
|
private addBuildingItem(buildingInfo: BuildingInfo): BuildingUIItem {
|
||
|
let buildingItem = new BuildingUIItem(buildingInfo, this);
|
||
|
this.buildingUIItems.push(buildingItem);
|
||
|
|
||
|
return buildingItem;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* 隐藏或展示模型
|
||
|
* @param show true-表示展示
|
||
|
*/
|
||
|
private showModel(show: boolean) {
|
||
|
for (let i = 0; i < this.buildingUIItems.length; i++) {
|
||
|
|
||
|
//周围环境,不隐藏(也就不用再显示)
|
||
|
if (this.buildingUIItems[i].buildingInfo.ModelInfo.buildingType == BuildingType.Environment) {
|
||
|
(this.buildingUIItems[i].buildingInfo as BuildingInfo_Environment).updateFuGaiCeng();
|
||
|
if (show) { //切换到室外时,根据选中状态恢复设备UI
|
||
|
if (this.currentBuidngItem == this.buildingUIItems[i]) {
|
||
|
this.buildingUIItems[i].buildingInfo.ModelInfo.showFacilityUI(show);
|
||
|
}
|
||
|
else {
|
||
|
this.buildingUIItems[i].buildingInfo.ModelInfo.showFacilityUI(false);
|
||
|
}
|
||
|
this.buildingUIItems[i].buildingInfo.ModelInfo.showFollowUI(true);//环境的名称UI 不显示
|
||
|
}
|
||
|
else { //切换到室内时,显示环境的设备UI
|
||
|
this.buildingUIItems[i].buildingInfo.ModelInfo.showFacilityUI(false);//(感觉太乱,暂时取消)
|
||
|
this.buildingUIItems[i].buildingInfo.ModelInfo.showFollowUI(false);//环境的名称UI 不显示
|
||
|
}
|
||
|
}
|
||
|
else { // 建筑,正常显隐
|
||
|
this.buildingUIItems[i].setModelEnable(show);
|
||
|
}
|
||
|
// if (this.buildingUIItems[i].buildingInfo != null) {
|
||
|
// this.buildingUIItems[i].buildingInfo.setEnable(show);
|
||
|
// }
|
||
|
}
|
||
|
}
|
||
|
//#endregion
|
||
|
|
||
|
|
||
|
}
|