123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932 |
- import * as THREE from "../../../libs/three.js/build/three.module.js";
- import SplitScreen from "../../utils/SplitScreen"
- import {BuildingBox} from "./BuildingBox"
- import Common from "../../utils/Common.js";
- import {Images360} from '../Images360/Images360'
- const minFloorHeight = 0.5
- const ifDrawDatasetBound = true //显示一下数据集的tightBound线框
- var SiteModel = {
-
- entities:[], //所有实体
- buildings:[], //所有建筑父集
- meshGroup: new THREE.Object3D,
-
-
- init: function(){
-
-
- viewer.scene.scene.add(this.meshGroup)
- this.meshGroup.name = 'siteModel'
- this.SplitScreen = SplitScreen
-
- this.createHeightPull();
-
-
- if(Potree.settings.isTest && ifDrawDatasetBound){
- viewer.on('allLoaded',()=>{
- viewer.scene.pointclouds.forEach(pointcloud=>{
- let boxPoints = pointcloud.getUnrotBoundPoint();
-
- let boundingBox = new BuildingBox({
- name: '数据集tightBound_'+pointcloud.dataset_id,
- points: boxPoints,
- buildType : 'dataset',
- zMax: pointcloud.bound.max.z,
- zMin: pointcloud.bound.min.z,
- ifDraw:true
- })
-
- this.meshGroup.add(boundingBox)
- //boundingBox.markers.forEach(e=>e.visible = false)
- })
- })
- }
- if(Potree.settings.isOfficial){
- let lastPos = new THREE.Vector3
- let lastEntity
- viewer.addEventListener('camera_changed', e => {
- if(!this.entities.length || this.editing) return
- Common.intervalTool.isWaiting('sitemodelCameraInterval', ()=>{ //延时update,防止卡顿
- let currPos = viewer.scene.getActiveCamera().position
-
- if(!currPos.equals(lastPos)){
- lastPos.copy(currPos)
- let entity;
- if(Potree.settings.displayMode == 'showPanos'){
- entity = this.entities.find(e=>e.panos.includes(viewer.images360.currentPano))
- if(!entity)console.log('没找到entity')
- }
- if(!entity){
- entity = this.pointInWhichEntity(currPos, 'room');
- }
-
- if(lastEntity != entity ){
- console.log('buildingChange', entity)
- entity && Potree.sdk.scene.emit('buildingChange', entity.polygon)
- lastEntity = entity
- }
- return true
- }
- }, 1000)
- })
- }
-
- },
-
- enter:function(){
-
- Potree.Log('sitemodel enter')
- this.clear() //确保全部清空
- this.editing = true
-
-
- let mapViewport = viewer.mapViewer.viewports[0]
- SplitScreen.splitScreen4Views({siteModel:true/* , viewports:[{name:'Top',viewport : mapViewport }] */})
-
-
- viewer.viewports.forEach(e=>{
- if(e.name != 'mapViewport'){
- e.layersAdd('siteModelMapUnvisi')
- }
- if(e.name == 'Right' || e.name == 'Back'){
- e.layersAdd('siteModeSideVisi')
- }
- })
-
-
- viewer.images360.panos.forEach(pano=>{
- viewer.setObjectLayers(pano.marker, 'siteModelMapUnvisi' )
- })
- mapViewport.layersAdd('siteModeOnlyMapVisi') //只有mapViewport能看到marker
-
-
-
-
- },
-
-
-
- leave:function(){
-
- Potree.Log('sitemodel leave')
-
- let mapViewport = viewer.mapViewer.viewports[0]
- SplitScreen.recoverFrom4Views()
-
- viewer.images360.panos.forEach(pano=>{
- viewer.setObjectLayers(pano.marker, 'mapObjects' )
- })
-
- mapViewport.layersRemove('siteModeOnlyMapVisi')
- this.clear()
- this.editing = false
-
- }
-
- ,
-
- /* startSetSiteModel:function(pos, type){//开始创建空间模型(非编辑状态的,不绘制)
- if(this.editing)return //编辑中不允许重新创建
- this.clear()
- }, */
-
- addFloor:function(parent, dirType, sid, name){//dirType:'top'|'bottom'在上方建还是下方。如果建筑中没有楼层,默认在基底建一个
- let buildType = 'floor'
- let zMin, zMax
- if(parent.buildChildren.length == 0){
- zMin = parent.zMin
- zMax = zMin + Potree.config.siteModel.floorHeightDefault
- }else{
- if(dirType == 'bottom'){
- //var btm = Common.find(parent.buildChildren,null,[e=>e.zMin])
- var btm = parent.buildChildren[0]
- zMax = btm.zMin
- zMin = zMax - Potree.config.siteModel.floorHeightDefault
- }else{
- //var top = Common.find(parent.buildChildren,null,[e=>e.zMax])
- var top = parent.buildChildren[parent.buildChildren.length - 1]
- zMin = top.zMax
- zMax = zMin + Potree.config.siteModel.floorHeightDefault
- }
-
- }
-
-
- let prop = {
- buildType,
- //name : Potree.config.siteModel.names[buildType],
- zMin,
- zMax,
- buildParent:parent,
- sid, name,
- ifDraw:true
- }
- var floor = new BuildingBox(prop);
- /* parent.buildChildren.push(floor)
- this.meshGroup.add(floor);
- this.entities.push(floor) */
- floor.update()
- this.addEntity(floor,parent)
- this.selectEntity(floor)
-
- this.updateBuildingZ(parent)
-
- return floor
- },
-
-
-
- startInsertion:function(buildType, parent, sid, name, callback, cancelFun){
-
- let zMin, zMax
-
- if(buildType == 'hole' || buildType == 'room'){
- zMin = parent.zMin
- zMax = parent.zMax
- }else if(buildType == 'building'){
- parent = null
- zMin = viewer.bound.boundingBox.min.z
- zMax = viewer.bound.boundingBox.min.z
- }
- let minMarkers = 3
- let mapViewport = viewer.mapViewer.viewports[0]
-
- let entity
- if(buildType == 'hole'){
- entity = parent.addHole()
- this.selectEntity(parent)
- entity.select()
- console.log('挖洞 ',entity.uuid)
- }else{
-
- let prop = {
- buildType,
- //name : Potree.config.siteModel.names[buildType],//'building',
- zMin,
- zMax,
- buildParent:parent,
- sid, name,
- ifDraw:true
- }
-
- entity = new BuildingBox(prop);
- this.selectEntity(entity)
- }
-
-
- entity.isNew = true
-
-
-
- let timer;
-
-
- let endDragFun = (e) => {
- if (e.button == THREE.MOUSE.LEFT ) {
- var marker = entity.addMarker({point:entity.points[entity.points.length - 1].clone()})
-
- //entity.editStateChange(true) //重新激活reticule状态
- entity.continueDrag(marker, e)
- } else if (e.button === THREE.MOUSE.RIGHT ) {
- if(e.pressDistance < Potree.config.clickMaxDragDis )end(e);//非拖拽的话
- else entity.continueDrag(null, e/* .drag.object */)
-
- }
- };
- let end = (e={}) => {//确定、结束
-
- if(!e.finish && entity.markers.length<=minMarkers){//右键 当个数不够时取消
-
- //重新开始画
- entity.reDraw(1)
-
- viewer.updateVisible(entity.markers[0],'unMove',false);
- var f = ()=>{
- viewer.updateVisible(entity.markers[0],'unMove',true);
- entity.removeEventListener('dragChange',f)
- }
- entity.addEventListener('dragChange',f)
-
- console.log('waitcontinue')
- entity.continueDrag(entity.markers[0], e)
- return
-
-
- }
- viewer.removeEventListener('cancel_insertions', Exit);
- //entity.removeEventListener('unselect', Exit);
- clearTimeout(timer)
- entity.editStateChange(false)
-
-
- if (!e.finish && entity.markers.length > 3) {
- entity.removeMarker(entity.points.length - 1);
- entity.addHoverEvent()
- if(buildType == 'room'){
- this.fitPullBox()
- }
- entity.isNew = false
- entity.addMidMarkers()
-
-
- pressExit && viewer.inputHandler.removeEventListener('keydown', pressExit);
- callback && callback(entity)
- }else{
- this.removeEntity(entity) //直接删除没画好的,比较简单。这样就不用担心旧的continueDrag仍旧触发了
-
- }
-
- return entity
- };
-
- let Exit = (e)=>{
- //entity.removeEventListener('unselect', Exit);
-
- if(viewer.inputHandler.drag){//还未触发drop的话
- viewer.inputHandler.drag.object.dispatchEvent({
- type: 'drop',
- drag: viewer.inputHandler.drag,
- viewer: viewer,
- pressDistance:0,
- button : THREE.MOUSE.RIGHT
- });
- viewer.inputHandler.drag = null
- }else{
- end({finish:true, remove:e.remove}) //未结束时添加新的polygon时会触发
- }
- viewer.inputHandler.drag = null
-
-
- }
-
- viewer.dispatchEvent({
- type: 'cancel_insertions' //取消之前的
- });
- viewer.addEventListener('cancel_insertions', Exit);
- //entity.addEventListener('unselect', Exit); //这个太难了,创建时也会被取消选中的
-
- let pressExit
- if(!Potree.settings.isOfficial){
- pressExit = (e)=>{
- if(e.keyCode == 27){//Esc
- Exit()
- }
- }
- viewer.inputHandler.addEventListener('keydown', pressExit)
- }
-
-
- var marker = entity.addMarker({point:new THREE.Vector3(0, 0, 0)})
- viewer.inputHandler.startDragging(marker , {dragViewport:mapViewport, endDragFun, notPressMouse:true} ); //notPressMouse代表不是通过按下鼠标来拖拽. dragViewport指定了只能在地图上拖拽
- viewer.updateVisible(marker,'unMove',false);//这时候的位置是假的(0,0,0)所以先不可见
-
- var f = ()=>{
- viewer.updateVisible(marker,'unMove',true);
- entity.removeEventListener('dragChange',f)
- }
- entity.addEventListener('dragChange',f)
-
-
- if(buildType!='hole'){
- this.addEntity(entity, parent)
- }
-
-
-
- return entity;
-
-
-
-
- },
-
-
- createFromData:function( buildType, parent ,sid, name, points=[], holes=[], zMin, zMax, initial,panos,flagPano){
- if(buildType != 'building' && buildType != 'floor' && buildType != 'room' ) return
-
- {
- if(initial){//初始数据错的,要自己建(只有一个building和floor) 原posIsLonlat
- var bound = viewer.bound.boundingBox
- points = [
- new THREE.Vector3(bound.min.x, bound.min.y,0),
- new THREE.Vector3(bound.max.x, bound.min.y,0),
- new THREE.Vector3(bound.max.x, bound.max.y,0),
- new THREE.Vector3(bound.min.x, bound.max.y,0),
- ]
- zMin = bound.min.z
- zMax = bound.max.z
- /* points = points.map(e=>{
- return viewer.transform.lonlatToLocal.forward(e)
- }) */
- }else{//相对于初始数据集的模型内坐标
- points = points.map(e=> this.transform(e, 'fromDataset'))
-
- }
- }
-
-
- if(buildType == 'building' ){
- zMax = zMin //强制变得一样,作为基底。如果有必要,保存时再算真实的zMax。目前zMin没有保存所以数据是错的,会直接根据floor计算
- }
-
-
-
-
- {
-
- let getPano = (id)=>{
- return viewer.images360.panos.find(pano=>pano.id == id)
- }
-
- panos = panos ? panos.map(e=>getPano(e)) : [];
- flagPano = flagPano != void 0 ? getPano(flagPano) : null ; //最中心的pano 或者 最靠近该实体的pano(当panos为空时)
-
- if(!this.editing && buildType == 'floor' && !flagPano){//没有的话可能是自动添加的floor,直接用parent的吧
- panos = parent.panos;
- flagPano = parent.flagPano;
- }
- }
-
-
-
-
-
- let prop = {
- buildType,
- points,
- name,
- sid,
- zMin,
- zMax,
- buildParent:parent,
- ifDraw:this.editing || Potree.settings.drawEntityData,
- panos,flagPano
- }
-
- let entity = new BuildingBox(prop)
- SiteModel.addEntity(entity, parent )
- if(this.editing){
- if(buildType == 'building'|| buildType == 'room'){
- entity.addMidMarkers()
- }
- }
-
-
- holes.forEach(points =>{
- let ps = points.map(e=> this.transform(e, 'fromDataset'))
- let hole = entity.addHole(ps)
- this.editing && hole.addMidMarkers()
- })
-
-
- if(buildType == 'floor'){
- this.updateBuildingZ(parent)
- }
-
-
- return entity
- },
-
- transform:function(pos, type){
- if(type == 'toDataset'){
- let point = Potree.Utils.datasetPosTransform({ toDataset: true, position: pos.clone(), datasetId: Potree.datasetData[0].id })
- return new THREE.Vector2().copy(point)
-
- }else{
- let position = new THREE.Vector3().copy(pos).setZ(0)
- return Potree.Utils.datasetPosTransform({ fromDataset: true, position, datasetId: Potree.datasetData[0].id })
-
- }
- },
-
-
-
-
-
- addEntity:function(entity, parent){
- this.meshGroup.add(entity);
- this.entities.push(entity)
- if(entity.buildType == 'building'){
- this.buildings.push(entity)
- }else{
- parent.buildChildren.push(entity)
-
- }
-
-
- if(entity.buildType == 'room'){
- entity.addEventListener('marker_dropped',()=>{
- this.fitPullBox()
- })
- }else if(entity.buildType == 'floor'){
- parent.dispatchEvent({type:'addFloor'})
- }
-
- console.log('添加实体:', entity.buildType, entity.sid, entity.uuid)
-
- },
-
- removeEntity : function(entity){
- if(!this.entities.includes(entity))return
-
-
-
- if(this.selected == entity){
- this.height_pull_box.visible = false
- this.selectEntity(null)
- }
-
-
- if(entity.buildType == 'building'){
- var index = this.buildings.indexOf(entity);
- if(index>-1){
- this.buildings.splice(index,1)
- }
- }else{
- var index = entity.buildParent.buildChildren.indexOf(entity);
- if(index>-1){
- entity.buildParent.buildChildren.splice(index,1)
- }
- }
-
- var index = this.entities.indexOf(entity);
- if(index>-1){
- this.entities.splice(index,1)
- }
-
-
- entity.dispose()
- entity.dispatchEvent({type:'delete'})
-
- console.log('删除实体:', entity.buildType, entity.sid)
-
- },
-
-
- updateBuildingZ:function(building){
-
- building.buildChildren = building.buildChildren.sort((e,a)=>e.zMin-a.zMin)//从低到高排序
- building.zMin = building.zMax = building.buildChildren[0].zMin //基底高度
- //building.zMax = building.buildChildren[building.buildChildren.length-1].zMax
- if(this.editing) building.update({dontUpdateChildren:true})
- },
-
-
-
- selectEntity : function(entity){
- if(this.selected == entity || entity && entity.buildType == 'hole')return
- //this.buildings.forEach(e=>e.unselect())
- this.selected && this.selected.unselect()
- this.height_pull_box.visible = false
-
-
- if(entity){
- entity.select()
-
- }
-
-
- this.selected = entity
-
-
- if(entity && (entity.buildType == 'floor' || entity.buildType == 'room' )){
- this.height_pull_box.visible = true
- this.fitPullBox()
- }
-
-
- },
-
-
- /* selectFloor:function(floor){
- this.buildings.forEach(e=>e.unselect())
- floor.select()
- this.selected = floor
- this.height_pull_box.visible = true
-
- this.fitPullBox()
- },
- selectBuilding:function(building){
- this.buildings.forEach(e=>e.unselect())
- building.select()
- }
- selectRoom:function(room){
- this.buildings.forEach(e=>e.unselect())
- room.select()
- }
- */
-
-
-
-
- fitPullBox: function(){ //自适应拖拽楼层的pullMesh
- let bound = new THREE.Box3();
- bound.expandByObject(this.selected.box)
- let center = bound.getCenter(new THREE.Vector3() )
- let size = bound.getSize(new THREE.Vector3() )
- this.height_pull_box.scale.copy(size)
- this.height_pull_box.position.copy(center)
- },
-
-
-
-
-
- changeZ:function(entity, dirType, value){ // floor or room 修改zMin or zMax
- let max, min //limit
-
- if(entity.buildType == 'floor'){//楼层
- let index = entity.buildParent.buildChildren.indexOf(this.selected)
- if(dirType == 'zMax'){
- let upper = entity.buildParent.buildChildren[index+1];
- entity.zMax = value
- min = entity.zMin + minFloorHeight
- if(entity.zMax < min){
- entity.zMax = min
- }else{
- if(upper){
- max = upper.zMax - minFloorHeight;
- if(entity.zMax > max){
- entity.zMax = max
- }
- }
- }
- if(upper){
- upper.zMin = entity.zMax
- upper.update()
- upper.dispatchEvent({type:'changeHeight'})
- }
- }else{
- let lower = entity.buildParent.buildChildren[index-1];
-
- entity.zMin = value
- max = entity.zMax - minFloorHeight
- if(entity.zMin > max){
- entity.zMin = max
- }else{
- if(lower){
- min = lower.zMin + minFloorHeight;
- if(entity.zMin < min){
- entity.zMin = min
- }
- }
- }
- if(lower){
- lower.zMax = entity.zMin
- lower.update()
- lower.dispatchEvent({type:'changeHeight'})
- }
- if(index == 0)this.updateBuildingZ(this.selected.buildParent)
- }
- }else if(entity.buildType == 'room'){//房间
- //按照navvis的是不一定限制在当前楼层,只要高度不超过当前楼层即可。
- let maxHeight = entity.buildParent.zMax - entity.buildParent.zMin
-
-
- if(dirType == 'zMax'){
- min = entity.zMin + minFloorHeight
- max = entity.zMin + maxHeight
- entity.zMax = THREE.Math.clamp(value, min, max);
- }else{
- min = entity.zMax - maxHeight
- max = entity.zMax - minFloorHeight
- entity.zMin = THREE.Math.clamp(value, min, max);
- }
- }
- entity.update()
- entity.dispatchEvent({type:'changeHeight'})
- //this.selected.emit('update')
- this.fitPullBox()
- },
-
-
-
- createHeightPull:function(){ //拖拽楼层的bounding box
- let boxGeo = new THREE.BoxBufferGeometry( 1, 1, 1/4 )
- let boxMat = new THREE.MeshBasicMaterial({
- color:"#F00",
- opacity:0 ,
- transparent:true,
- depthTest:false
- })
-
- let height_pull_box_up = new THREE.Mesh(boxGeo,boxMat)
- let height_pull_box_down = new THREE.Mesh(boxGeo,boxMat)
- height_pull_box_up.name = 'height_pull_box_up';
- height_pull_box_down.name = 'height_pull_box_down';
- this.height_pull_box = new THREE.Object3D();
- this.height_pull_box.name = 'height_pull_box'
- this.height_pull_box.add(height_pull_box_up)
- this.height_pull_box.add(height_pull_box_down)
- this.height_pull_box.visible = false
- this.meshGroup.add(this.height_pull_box)
- height_pull_box_up.position.set(0,0,3/8)
- height_pull_box_down.position.set(0,0,-3/8)
- viewer.setObjectLayers(this.height_pull_box, 'siteModeSideVisi' )
-
-
-
- let mouseover = (e)=>{
- viewer.dispatchEvent({
- type : "CursorChange", action : "add", name:"siteModelFloorDrag"
- })
- }
- let mouseleave = (e)=>{
- viewer.dispatchEvent({
- type : "CursorChange", action : "remove", name:"siteModelFloorDrag"
- })
- }
-
-
- let firstZ, firstIntersect;
- let drag = (e)=>{
- var intersectPoint = e.intersectPoint.orthoIntersect //不要点云的intersect,只要orthocamera算出的平面intersect
-
- if(firstIntersect != void 0){
-
- let moveZ = intersectPoint.z - firstIntersect
- if(this.selected.buildType == 'floor'){//楼层
- //限制高度不能超过上下
- if(e.target == height_pull_box_up){
- if(firstZ == void 0)firstZ = this.selected.zMax
- this.changeZ(this.selected, 'zMax', firstZ + moveZ)
- }else{
- if(firstZ == void 0)firstZ = this.selected.zMin
- this.changeZ(this.selected, 'zMin', firstZ + moveZ)
- }
- }else if(this.selected.buildType == 'room'){//房屋
- if(e.target == height_pull_box_up){
- if(firstZ == void 0)firstZ = this.selected.zMax
- this.changeZ(this.selected, 'zMax', firstZ + moveZ)
- }else{
- if(firstZ == void 0)firstZ = this.selected.zMin
- this.changeZ(this.selected, 'zMin', firstZ + moveZ)
- }
- }
- }else{
- firstIntersect = intersectPoint.z
- }
- }
-
-
- let drop = (e)=>{
- firstZ = firstIntersect = null
- }
-
- height_pull_box_up.addEventListener('mousemove',mouseover)
- height_pull_box_down.addEventListener('mousemove',mouseover)
- height_pull_box_up.addEventListener('mouseleave',mouseleave)
- height_pull_box_down.addEventListener('mouseleave',mouseleave)
- height_pull_box_up.addEventListener('drag',drag)
- height_pull_box_down.addEventListener('drag',drag)
- height_pull_box_up.addEventListener('drop',drop)
- height_pull_box_down.addEventListener('drop',drop)
- },
-
-
- pointInWhichEntity(position, buildType, ifIgnoreHole){//返回第一个符合标准的实体,buildType是要找的建筑类型
-
- //由于房间可能在building外,所以房间要另外单独识别。
-
- let lastResult; //最接近的上一层结果,如果没有result返回这个
- let result
-
-
- let traverse = (parent)=>{
- if(parent.ifContainsPoint(position)){
- lastResult = parent
- if(parent.buildType == buildType){
- return parent
- }else{
- for(let i=0,len=parent.buildChildren.length; i<len; i++){
- if(traverse(parent.buildChildren[i])){
- return parent.buildChildren[i]
- }
- }
- }
- }
-
- }
-
-
- for(let i=0,len=this.buildings.length; i<len; i++){
- result = traverse(this.buildings[i])
-
- if(result){break}
- }
-
-
-
- /* if(!result && buildType == 'room'){//如果要找的是room, 且按刚才的顺序找不到的话,就单独从所有rooms中找一遍。因为room可能不在floor和building内。
- let rooms = this.entities.filter(e=>e.buildType == 'room');
- result = rooms.find(e=>e.ifContainsPoint(position))
- }*/
- //虽然房间可以画到上级之外,但是为了方便起见,假定房间绝对在楼层之内。找不到的话要调整空间模型了。
-
-
- return result || lastResult
-
- }
- ,
-
-
- findPanos: function(){
-
- viewer.images360.panos.forEach(pano=>{
- let result = this.pointInWhichEntity(pano.position, 'room');
-
- {//get panos for every entities
- let entity = result
- while(entity){
- entity.panos.push(pano);
- entity = entity.buildParent
- }
- }
- })
-
- {//search center pano
- this.entities.forEach(entity=>{
- let bound = entity.getBound();
- let center = bound.getCenter(new THREE.Vector3)
- let request = []
- let rank = [
- Images360.scoreFunctions.distanceSquared({position: center})
- ]
- let panos = entity.panos && entity.panos.length ? entity.panos : viewer.images360.panos
- let r = Common.sortByScore(panos, request, rank);//entity没有panos的话,就扩大到所有panos
- if(r && r.length){
- entity.flagPano = r[0].item
- }else{
- console.error('no flagPano??')
- }
-
-
- })
-
- }
-
- }
- ,
- findEntityForDataset:function(){
- var entities = this.entities.filter(e=>e.buildType == 'room' || e.buildType == 'floor' && e.buildChildren.length == 0)
- entities.length && viewer.scene.pointclouds.forEach(pointcloud=>{
-
- let volumes = []
- entities.forEach(entity=>{
- let volume = entity.intersectPointcloudVolume(pointcloud)
- volumes.push({entity, volume})
- })
- volumes.sort((a,b)=>{ return b.volume-a.volume })
- console.log(volumes)
- pointcloud.belongToEntity = volumes[0].entity; //如果约等于0怎么办???
- })
-
- /*
- 只需要考虑 floor 和 room, 因为building的只有一个基底没高度
- floor 和 room 在空间中没有完全的从属关系,因为room可以超出floor之外。所以直接混在一起来查找,但要排除有房间的楼层。
- 直接计算实体和点云的重叠体积 ,重叠体积大的最小实体将会拥有该点云。
-
-
-
-
- */
- }
-
-
-
- ,
- clear:function(){//清空
-
- /* entities:[], //所有实体
- buildings:[], //所有建筑父集
- meshGroup: new THREE.Object3D, */
- this.selectEntity(null)
-
- let length = this.buildings.length;
- for(let i=0;i<length;i++){
- this.buildings[i].dispose()
- }
-
- this.entities = []
- this.buildings = []
-
-
-
- }
- ,
- gotoEntity(id, isNearBy) {
- var entity = this.entities.find(e => e.sid == id)
- let aimPano
- if (!entity) {
- return console.error('没找到entity ')
- }
- if (isNearBy && entity.panos.length) {
- let position = viewer.scene.getActiveCamera().position
- let request = []
- let rank = [Images360.scoreFunctions.distanceSquared({ position })]
- let r = Common.sortByScore(entity.panos, request, rank)
- aimPano = r[0].item
- } else {
- if (!entity.flagPano) {
- return console.error('没找到flagPano')
- }
- aimPano = entity.flagPano
- }
- viewer.images360.flyToPano(aimPano)
- },
-
- }
- /*
- 规则
- 层级:
- type 中文名 改动范围 其他
-
- BUILDING 建筑 xy mesh由自己的基底以及所有floor的组成。如果删除所有floor,就剩一个平面。故而zMin == zMax
- FLOOR 楼层 z(xy未解锁) 点击楼层时房间也会显示,而建筑的其他楼层不显示线框,会显示面. 拖拽高度实际是拖拽楼层间的分界线,楼层之间不会有缝隙
- ROOM 房间 xyz(xy可加锁) 可能超出楼层外,因为楼层拖拽时房间没变。所以建筑不一定包容房间。
- CUSTOM 自定义(现作房间) xyz
- ( xy范绘制时不能超出父级外轮廓,但父级编辑时可以进入子级轮廓。只要能解锁轮廓的都能切洞)
- floor输入高度数值的限制和拖拽是一样的,相当于调节其zMax, 且不能超出其上层的zMax。
- navvis弊端:
- 空间模型不会随着数据集移动而移动 (可以做成跟随,但是如果一个建筑对应多个数据集,那只能跟序号在前的数据集走)
- 建筑点修改后,房间可能飘出建筑外的。 楼层高度修改后也是。
- 调整高度时,看不到相邻的楼层界限,导致拖不动时像bug。
- 调整高度时,侧面看有的重叠的部分比较高亮,感觉是冗余信息?有点乱
-
- 问题:
- 磨砂材质
- 没有阴影,可directionallight 加了呀
-
-
- 暂定一个数据集只属于一个实体(从最小的找起)
-
-
- https://testlaser.4dkankan.com/indoor/t-8KbK1JjubE/api/site_model
- 删点全删光了要删实体吗
- */
- export {SiteModel}
|