import { Box3 } from '@uino/base-thing';
import { Object3D, Utils } from '@uino/thing';
function _calFloorUV2(box, verticesUV2, verticespos, obj) {
for (let i = 0; i < verticespos.length; i += 3) {
let x = (verticespos[i] - (box.center[0] - obj.position[0] - box.halfSize[0])) / (2 * box.halfSize[0]);
let y = (verticespos[i + 2] - (box.center[2] - obj.position[2] - box.halfSize[2])) / (2 * box.halfSize[2]);
verticesUV2.push(x, 1 - y);
}
return verticesUV2;
}
const __ = {
private: Symbol('private'),
}
/**
* @class Floor
* 楼层
* @extends THING.Object3D
* @public
*/
class Floor extends Object3D {
static defaultTagArray = ['Floor'];
constructor(param = {}) {
super(param);
const _private = this[__.private] = {};
// 楼层高度
_private.height = Utils.parseNumber(param['height'], 3);
this._constantShowThings = Utils.parseBoolean(param['constantShowThings'], false);
}
/**
* 显示/隐藏所有屋顶(包括楼层和楼层下方房间的屋顶)
* @param {Boolean} visible true 显示(默认)/ false 隐藏
* @public
*/
showAllRoofs(visible = true) {
const roofs = this.roofs;
if (roofs) {
roofs.forEach(element => {
element.visible = visible;
});
}
}
/**
* 显示/隐藏所有天花板(包括楼层和楼层下方房间的天花板)
* @param {Boolean} visible true 显示(默认)/ false 隐藏
* @public
*/
showAllCeilings(visible = true) {
const ceilings = this.ceilings;
if (ceilings) {
ceilings.forEach(element => {
element.visible = visible;
});
}
}
bake(params) {
var walls = this.walls;
if (!walls.length) {
return;
}
if (params === null) {
if (!this._baked) {
return;
}
this.slabs.forEach(element => {
const ustyle = element.body.style.resource;
ustyle.setImage('AOMap', null)
});
this._baked = false;
}
else {
params = params || {};
const intensity = Utils.parseValue(params['intensity'], 3);
let aoMap = Utils.createObject('RenderTextureResource');
let wallNodes = [];
walls.forEach(wall => {
wallNodes.push(wall.node);
});
const floorBondingBox = this.boundingBox;
let center = [0, 0, 0]
THING.MathUtils.subVector(floorBondingBox.center, this.parent.position, center)
const floorBox = new Box3(floorBondingBox.center, floorBondingBox.halfSize);
const floorBox2 = new Box3(center, floorBondingBox.halfSize);
this.app.view.bakeAOMap(wallNodes, floorBox2, aoMap);
this.slabs.forEach(slab => {
let verticesUV2 = [];
const slabNode = slab.node;
if (slabNode.setUv2) {
slabNode.setUv2(floorBox, slab.position)
} else if (slabNode._geometryResource) {
const verticespos = slabNode._geometryResource.getAttribute('a_Position');
_calFloorUV2(floorBox, verticesUV2, verticespos, slab);
slabNode._geometryResource.setAttribute('a_Uv2', new Float32Array(verticesUV2));
} else {
return;
}
const ustyle = slab.body.style.resource;
ustyle.setAttribute('AOMapIntensity', intensity);
ustyle.setImage('AOMap', aoMap)
});
this._baked = true;
}
}
/**
* Gets the building where the floor is located
* @type {THING.Building}
*/
get building() {
return this.parents.find('tags:or(Building)');
}
get corners() {
return this._corners;
}
/**
* 获取楼层下的墙体对象集合
* @type {THING.Selector<THING.Object3D>}
* @example
* let roofs = floor.roofs;
* console.log(roofs);
* @public
*/
get roofs() {
return this.queryByTags('RoomRoof');
}
/**
* 获取楼层下的房间对象集合
* @type {THING.Selector<THING.Room>}
* @example
* let rooms = floor.rooms;
* console.log(rooms);
* @public
*/
get rooms() {
return this.queryByTags('Room');
}
/**
* 获取楼层下的天花板对象集合
* @type {THING.Selector<THING.Object3D>}
* @example
* let ceilings = floor.ceilings;
* console.log(ceilings);
* @public
*/
get ceilings() {
return this.queryByTags('RoomCeiling');
}
/**
* 获取楼层下的墙体对象集合
* @type {THING.Selector<THING.Object3D>}
* @example
* let walls = floor.walls;
* console.log(walls);
* @public
*/
get walls() {
return this.queryByTags('Wall');
}
/**
* 获取楼层下的门对象集合
* @type {THING.Selector<THING.Door>}
* @example
* let doors = floor.doors;
* console.log(doors);
* @public
*/
get doors() {
return this.queryByTags('Door');
}
/**
* 获取楼层下的板块对象集合
* @type {THING.Selector<THING.Object3D>}
* @example
* let slabs = floor.slabs;
* console.log(slabs);
* @public
*/
get slabs() {
return this.query('tags:or(Slab,RoomFloor)');
}
/**
* 获取其他对象
* @type {THING.Object3D}
* @example
* let misc = floor.misc;
* console.log(misc);
* @public
*/
get misc() {
return this.children.find('tags:or(Misc)');
}
/**
* 获取楼层下的放置对象集合
* @type {THING.Selector<THING.Entity>}
* @example
* let placements = floor.placements;
* console.log(placements);
* @public
*/
get placements() {
let plcs = this.queryByTags('Placement');
return plcs;
}
/**
* 获取楼层编号(从1开始)
* @type {Number}
* @example
* let levelNumber = floor.levelNumber;
* console.log(levelNumber);
* @public
*/
get levelNumber() {
let children = this.parent.children;
let levelNumber = 1;
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (!child.isFloor) {
continue;
}
if (child == this) {
break;
}
++levelNumber;
}
return levelNumber;
}
/**
* Get floor height
* @private
* @type {Number}
*/
get height() {
const _private = this[__.private];
return _private.height;
}
}
export { Floor };