123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- import * as THREE from "../../../../libs/three.js/build/three.module.js";
- import {ctrlPolygon} from '../../objects/tool/ctrlPolygon.js'
- import {LineDraw, MeshDraw } from "../../utils/DrawUtil.js";
- import math from "../../utils/math.js";
- import Sprite from '../../objects/Sprite.js'
- /* import {config} from '../settings' */
- import searchRings from "../../utils/searchRings.js";
- import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
- let texLoader = new THREE.TextureLoader()
-
- let markerMats
- let markerSizeInfo = {width2d:35}
- let color = new THREE.Color('#FFF')
- let faceMats
- let getFaceMat = (name)=>{
- if(!faceMats){ //navvis材质可以搜gridTexture
- let gridTex = texLoader.load( Potree.resourcePath+'/textures/gridmap.png' )
- gridTex.wrapS = gridTex.wrapT = THREE.RepeatWrapping
- //gridTex.repeat.set(0.5,0.5)//放大一些
- faceMats = {
- dataset: new THREE.MeshStandardMaterial({
- color:812922,
- side:THREE.DoubleSide,
- opacity:0.2,
- transparent:true,
- depthTest:false,
- wireframe:true
- }),
- building: new THREE.MeshStandardMaterial({
- color:812922, metalness: 0.2, roughness:0.8,
- side:THREE.DoubleSide,
- opacity:0.1,
- transparent:true,
- depthTest:true
- }),
- buildingSelect: new THREE.MeshStandardMaterial({
- color:36582, metalness: 0, roughness:1,
- side:THREE.DoubleSide,
- opacity:0.1,
- transparent:true,
- depthTest:true
- }),
- floor: new THREE.MeshStandardMaterial({
- color:11708469, metalness: 0.1, roughness:1,
- side:THREE.DoubleSide,//BackSide,
- opacity:0.05,
- transparent:true,
- depthTest:true,
- }),
-
- floorSelect: new DepthBasicMaterial({
- map: gridTex,
- color:16707151,
- side:THREE.DoubleSide,//BackSide,
- opacity:1,
- transparent:true,
- useDepth : true,
- clipDistance : 1, occlusionDistance:1, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */
- maxClipFactor:0.9, backColor:'#efe' //backColor:"#669988" ,
- }),
-
- room: new THREE.MeshStandardMaterial({
- color:"#ff44ee", metalness: 0, roughness:1,
- side:THREE.DoubleSide,//BackSide,
- opacity:0.08,
- transparent:true,
- depthTest:false,
- }),
-
- roomSelect: new DepthBasicMaterial({
- map: gridTex,
- color:"#ff44ee",
- side:THREE.DoubleSide,//BackSide,
- opacity:1,
- transparent:true,
- useDepth : true,
- clipDistance : 1, occlusionDistance:0.5, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */
- maxClipFactor:0.8, backColor:'#ff88dd'//"#cc99c2" ,
-
- })
- }
- }
- return faceMats[name]
- }
-
- export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, floor, room
- constructor(prop) {
- prop.dimension = '3d'
- //prop.name = Potree.config.siteModel.names[prop.buildType] +
-
- super('siteModel_'+prop.buildType, prop);
-
-
-
- this.midMarkers = []
- this.buildChildren = []//子实体
- this.holes = [] //在这创建的hole
- this.parentHoles = [];//floor从building那得到的当层holes
- this.mats = {} //材质
-
- this.panos = this.panos || [];
- this.center //中心点
-
- if(this.buildType=='floor'){
-
- this.points = prop.points = this.buildParent.points;//完全等于建筑的点
- this.buildParent.holes.forEach(hole=>{//从building获取holes
- let floorHole = new BuildingBox({
- buildType : 'hole',
- buildParent:this,
- originHole : hole, //整栋大楼在当层的hole
- ifDraw: this.ifDraw || Potree.settings.drawEntityData
- });
- this.parentHoles.push(floorHole)
- this.add(floorHole)
-
- floorHole.points = hole.points//完全等于建筑的点
- })
- }
- if(this.buildType == 'room' || this.buildType == 'hole'){
- this.restrictArea = this.buildParent //不能超出的区域
- }
- if(this.buildParent)this.dontDragFloorHeight = this.buildParent.dontDragFloorHeight
-
-
- if(this.buildType != 'hole'){
- this.box = this.createBox() //无论是否edit都绘制的原因:为了将在外的点移到在内,需要用mesh来获取intersect
- this.add(this.box)
- this.box.visible = !!this.ifDraw
- }
-
- if(this.ifDraw){ //只存储空间模型信息,不绘制
-
- {
- this.createPrismLines(color)
- this.lineMesh.visible = false
- Potree.Utils.setObjectLayers(this.lineMesh, 'bothMapAndScene' )
- }
-
-
- this.addEventListener('dragChange',(e)=>{ //修改中点
- this.updateTwoMidMarker(e.index)
- })
-
- }
-
- this.initData(prop)
-
-
- }
-
-
- initData(prop){
- if(prop.ifDraw){
- super.initData(prop)
- }else{
- if(prop.points){
- this.points = prop.points
- }
- }
- }
-
- intersectPointcloudVolume(pointcloud){//和pointcloud的重叠体积
- return this.intersectPointcloudArea(pointcloud) * this.coverPointcloudHeight(pointcloud)
- }
-
-
- coverPointcloudHeight(pointcloud, getPercent){
- let bound2 = pointcloud.bound;
- let {zMin , zMax} = this.getRealZ()
- let min = Math.min(zMin, bound2.min.z);
- let max = Math.max(zMax, bound2.max.z);
- let height1 = zMax - zMin
- let height2 = bound2.max.z-bound2.min.z
- let coverHeight = height1 + height2 - (max-min)//重叠高度 <=0是没重叠
- if(getPercent){
- return coverHeight / height1
- }
- return coverHeight
- }
-
- intersectPointcloudArea(pointcloud, getPercent){//和pointcloud的重叠面积
- var bound = this.getBound()
- let bound2 = pointcloud.bound;
- if(!bound.intersectsBox(bound2)) return 0;
-
- let boxPoints = pointcloud.getUnrotBoundPoint() //获取tightBound的四个点。 如果是有旋转角度的点云,这个和pointcloud.bound的四个点是不一致的,覆盖面积小于pointcloud.bound
-
- let areaWhole = 0
- let area1 = this.getArea()
- let area2 = Math.abs(math.getArea(boxPoints))
-
- {//计算points与点云总面积 (但是把hole也加入了面积)(并集,重叠部分只算一次)
- let rings = math.getPolygonsMixedRings([this.points, boxPoints] )
-
- rings.forEach(e=>{
- areaWhole+=e.area
- })
- }
-
- let coverHoleArea = 0 //holes与数据集重叠的部分
- let holes = this.holes.concat(this.parentHoles)
- let holesArea = 0 //所有holes面积相加
- let areaHoleWithPointcloud = 0 //hole和点云的面积并集
-
- if(holes.length>0){//还要再扣除holes与数据集重叠的部分。其中holes为mix轮廓
- let outHoles = []//没有重合的holes的外轮廓
- /* if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
-
- let holes_ = holes.map(e=>e.points)
-
- outHoles = math.getPolygonsMixedRings(holes_, true )
- outHoles.forEach(e=>{
- holesArea+=e.area
- })
- outHoles = outHoles.map(e=>e.points)
-
-
- }else{
- outHoles = holes.map(e=>e.points)
- outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))
- } */
- holesArea = this.getHolesArea()
-
- //holes与数据集重叠的部分
-
- {
- let polygons = outHoles.concat([boxPoints])
- let rings = math.getPolygonsMixedRings(polygons)
- rings.forEach(e=>{
- areaHoleWithPointcloud+=e.area
- })
- coverHoleArea = holesArea + area2 - areaHoleWithPointcloud//hole和点云的交集
- }
-
- }
-
- let coverArea = area1 + area2 - areaWhole - coverHoleArea; //重叠面积
-
- if(getPercent){
- return {
- toEntity:coverArea / this.getArea(true), //占entity
- toPointcloud:coverArea / area2 //占点云
- }
- }
- return coverArea
- }
-
- addHole(points=[]){
- let prop = {
- buildType : 'hole',
- zMin : this.zMin,
- zMax : this.zMax,
- points,
- buildParent:this,
- ifDraw: this.ifDraw || Potree.settings.drawEntityData
- }
- //hole的zMin zMax跟随buildParent
- var hole = new BuildingBox(prop);
- this.holes.push(hole)
-
- if(this.buildType == 'building'){//为每一层添加对应的hole
- this.buildChildren.forEach(floor=>{
- let floorHole = new BuildingBox({
- buildType : 'hole',
- zMin : this.zMin,
- zMax : this.zMax,
- buildParent:floor,
- originHole : hole, //整栋大楼在当层的hole
- ifDraw: this.ifDraw || Potree.settings.drawEntityData
- });
- floor.parentHoles.push(floorHole)
- floor.add(floorHole)
- floorHole.points = hole.points//完全等于建筑的点
- })
-
- }
-
- this.add(hole);//直接加在这,不加meshGroup了
- this.update() //update box mesh
- return hole
-
- //hole不创建box,只有它的buildParent需要更新box。 但有线条和marker. hole不在buildChildren里,但有buildParent
-
- }
-
-
- removeHole(hole){// 这个hole不会是parentHoles里的。
- hole.dispose()
-
- if(this.buildType == 'building'){ //若是整栋大楼的hole,在每层去除它的对应hole
- this.buildChildren.forEach(floor=>{
- let holeAtFloor = floor.parentHoles.find(e=>e.originHole == this )
- let index = floor.parentHoles.indexOf(holeAtFloor)
- index > -1 && floor.parentHoles.splice(index, 1)
- holeAtFloor.dispose()
- })
- }
-
- let index = this.holes.indexOf(hole)
- if(index>-1){
- this.holes.splice(index, 1)
- }
- this.remove(hole)
- this.update()
- }
-
-
-
-
- createBox(){
- var geometry = new THREE.Geometry();
-
-
-
- this.mats.boxDefault = getFaceMat(this.buildType)
- this.mats.boxSelected = getFaceMat(this.buildType+'Select')
-
-
- var mesh = new THREE.Mesh(geometry, this.mats.boxDefault)
- mesh.name = 'buildingBox';
-
-
-
- if(this.buildType == 'floor'){
- Potree.Utils.setObjectLayers(mesh, 'mapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
- //mesh.renderOrder = 1
- }else{
- /* if(this.buildType == 'room'){
- mesh.renderOrder = 2
- } */
- Potree.Utils.setObjectLayers(mesh, 'bothMapAndScene' )
-
- }
-
-
-
- //mesh.frustumCulled = false;
- return mesh
- }
-
-
-
- addMarker(o={} ){
- if(this.buildType=='floor')return; //楼层不需要marker
-
- let marker = new Sprite({mat:this.getMarkerMaterial('default'), renderOrder : 3, sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_marker"} )
-
-
- Potree.Utils.setObjectLayers(marker, 'onlyMapVisi' )
-
- o.marker = marker
- super.addMarker(o)
-
- if(!this.selected)Potree.Utils.updateVisible(marker,'select',false)
-
- let addClickEvent = (e)=>{
- let click = (e) => {
- this.dispatchEvent({type:'clickMarker', marker } ) //由entity发送给sitemodel统一处理
- };
- marker.addEventListener('click', click);
- marker.addEventListener('clickSelect', (e)=>{
- this.setMarkerSelected(marker, e.state ? 'select' : 'unselect' );
- });
- marker.removeEventListener('addHoverEvent',addClickEvent)
- }
- marker.addEventListener('addHoverEvent',addClickEvent)//当非isNew时才添加事件
- if(!this.isNew){
- marker.dispatchEvent('addHoverEvent')
- }
-
- return marker
- }
-
- removeMarker(index){
- super.removeMarker(index);
- if(!this.isNew){
- //重新添加midMarkers
- this.midMarkers.forEach(e=>this.remove(e));
- this.midMarkers = []
- this.addMidMarkers()
- }
-
- this.update();
- if(this.points.length == 2 && this.box){//清除原先length>=3时候的
- this.box.geometry = new THREE.Geometry();
- }
-
-
- }
-
- addMidMarker(index, point){
- if(this.buildType=='floor')return; //楼层不需要marker
- let marker = new Sprite({mat:this.getMarkerMaterial('midPrepare'), sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_midMarker"} )
- this.midMarkers = [...this.midMarkers.slice(0,index), marker, ...this.midMarkers.slice(index,this.midMarkers.length)]
-
- marker.renderOrder = 3
-
- Potree.Utils.setObjectLayers(marker, 'onlyMapVisi' )
- { // Event Listeners
- let mouseover = (e) => {
- this.setMarkerSelected(e.object, 'hover', 'single');
- viewer.dispatchEvent({
- type : "CursorChange", action : "add", name:"markerMove"
- })
- };
- let mouseleave = (e) => {
- this.setMarkerSelected(e.object, 'unhover', 'single');
- viewer.dispatchEvent({
- type : "CursorChange", action : "remove", name:"markerMove"
- })
- }
- let drag = (e) => {
- this.dispatchEvent('startDragging')
- let index = this.midMarkers.indexOf(marker)
- let newMarker = this.addMarker({index:(index+1), point:marker.position.clone() })
- this.addMidMarker(index+1, new THREE.Vector3 )
- this.updateTwoMidMarker(index+1)
- this.setMarkerSelected(marker, 'unhover')
- viewer.inputHandler.startDragging(newMarker , {/* dragViewport:viewer.mapViewer.viewports[0], */ } ); //notPressMouse代表不是通过按下鼠标来拖拽. dragViewport指定了只能在地图上拖拽
- }
- marker.addEventListener('drag', drag );
- marker.addEventListener('mouseover', mouseover);
- marker.addEventListener('mouseleave', mouseleave);
- }
- this.add(marker)
- this.updateMarker(marker, point)
- if(!this.selected)Potree.Utils.updateVisible(marker,'select',false)
- return marker
- }
-
-
-
-
-
- addMidMarkers(){//第一次画好所有marker后,一次性为线段增加中点marker
- let length = this.points.length
- this.points.forEach((point,index)=>{
- let nextPoint = this.points[(index+1)%length]
- let midPoint = new THREE.Vector3().addVectors(point, nextPoint).multiplyScalar(0.5)
- this.addMidMarker(index, midPoint )
- })
- }
-
- updateTwoMidMarker(index){//更新第index个marker两边的midMarker
- if(!this.midMarkers.length)return
- let length = this.points.length
- let last = this.points[(index-1+length)%length] //它之前的marker位置
- let next = this.points[(index+1)%length];//它之后的marker位置
- let current = this.points[index]//当前位置
- let lastMid = new THREE.Vector3().addVectors(last, current).multiplyScalar(0.5)//上一个中点
- let nextMid = new THREE.Vector3().addVectors(next, current).multiplyScalar(0.5)//下一个中点
- let lastMidMarker = this.midMarkers[(index-1+length)%length];
- let nextMidMarker = this.midMarkers[index]
- this.updateMarker(lastMidMarker, lastMid)
- this.updateMarker(nextMidMarker, nextMid)
- }
-
-
-
-
-
- dispose(){//销毁geo、remove from parent
- super.dispose()
- this.box && this.box.geometry.dispose();
- this.lineMesh && this.lineMesh.geometry.dispose();
- this.holes.forEach(e=>e.dispose())
- this.parentHoles.forEach(e=>e.dispose())
- //this.buildChildren.forEach(e=>e.dispose())
- this.dispatchEvent('dispose')
- }
-
-
-
- updateBox(){
- if(!this.box)return
- this.box.geometry.dispose()
- var shrink = this.buildType == 'room' ? 0.11 : this.buildType == 'floor' ? 0.082 : 0.2 ;//防止mesh重叠冲突(给一个不寻常的数字) 但离远了还是会有点闪烁
- if(this.points.length >= 3){
- let holes = this.holes.concat(this.parentHoles)
- let holesPoints = holes.filter(e=>e.points.length>2).map(e=>e.points)
- this.box.geometry = MeshDraw.getExtrudeGeo(this.points, holesPoints, {
- depth:this.zMax-this.zMin-shrink,
- UVGenerator: new MetricUVGenerator()
- })
- if(this.buildType == 'building' ){
- this.box.position.z = this.zMin - shrink / 2
- }else{
- this.box.position.z = this.zMin + shrink / 2
- }
-
- }
- }
-
-
-
- update(options={}){
- super.update(this.buildType != 'floor' && options.ifUpdateMarkers)
- let length = this.points.length
-
-
-
- {//确保一下一样
- if(this.originHole){
- this.points = this.originHole.points //完全等于building的hole
- }
- if(this.buildType == 'hole'){
- this.zMin = this.buildParent.zMin;
- this.zMax = this.buildParent.zMax;
- }
- }
-
-
-
- if(!options.dontUpdateBox){
- let boxOwner
- if(this.buildType == 'hole'){
- if(this.buildParent.buildType == 'building'){ //若是整栋大楼的hole,在每层都要更新下它的对应hole
- this.buildParent.buildChildren.forEach(floor=>{
- let holeAtFloor = floor.parentHoles.find(e=>e.originHole == this )
- holeAtFloor && holeAtFloor.update() //刚开始创建时还没创建对应的 holeAtFloor会为null
- })
- }
- boxOwner = this.buildParent
- }else{
- boxOwner = this
- }
- boxOwner.updateBox()
- }
-
-
- this.updatePrismLines()//update lines
-
- if(!options.dontUpdateChildren){
- if(this.buildType == 'building' ){
- this.buildChildren.forEach(floor=>{
- floor.points = this.points
- floor.update()
- })
-
- }
-
- {
- let holes = this.holes.concat(this.parentHoles)
- holes.forEach(hole=> {
-
- hole.update({dontUpdateBox:true})//父级更新了box,hole就不需要更新box了
- })
-
- }
-
- }
- }
-
-
-
-
-
-
- getHolesArea(){
- let holes = this.holes.concat(this.parentHoles)
- let outHoles, holesArea = 0
- if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
-
- let holes_ = holes.map(e=>e.points)
-
- outHoles = math.getPolygonsMixedRings(holes_, true )
- outHoles.forEach(e=>{
- holesArea+=e.area
- })
- outHoles = outHoles.map(e=>e.points)
-
-
- }else{
- outHoles = holes.map(e=>e.points)
- outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))
- }
- return holesArea
-
- }
-
- getArea(ifRidOfHoles){//面积
- //不排除hole
- return Math.abs(math.getArea(this.points)) - (ifRidOfHoles ? this.getHolesArea() : 0)
- }
-
- getVolume(ifRidOfHoles){//体积
- let {zMin , zMax} = this.getRealZ()
- let height = zMax - zMin;
- if(isNaN(height))height = 0
- return this.getArea(ifRidOfHoles) * height
-
- }
-
- getRealZ(){//求真实高度时用到的
- let zMin , zMax
- if (this.buildType == 'building') {
- //因为building只有一个地基平面 所以自身的zMin == 自身的zMax 所以要算
- let top = this.buildChildren[this.buildChildren.length - 1]
- let btm = this.buildChildren[0]
- zMin = btm ? btm.zMin : 0 //建好的建筑不加楼的话是0。
- zMax = top ? top.zMax : 0
- }else if(this.buildType == 'hole'){
- return this.buildParent.getRealZ()
- }else{
- zMin = this.zMin, zMax = this.zMax
- }
- return {zMin,zMax}
- }
- //架站式多楼层SG-t-ihjV2cDVFlE 有初始的z, 但是总高度范围小于数据集。 不允许修改高度。
-
- /* getDrawZ(){ //画线和box时用到的z
- let zMin , zMax
- if(this.buildType == 'hole'){
- if(this.buildParent.buildType == 'building' && atFloor){
- zMin = atFloor.zMin, zMax = atFloor.zMax
- }else{
- zMin = this.buildParent.zMin, zMax = this.buildParent.zMax
- }
- }else{
- zMin = this.zMin, zMax = this.zMax
- }
-
- return {zMin, zMax}
-
- } */
-
-
-
- getBound(){
- let bound = new THREE.Box3
-
- let {zMin , zMax} = this.getRealZ()
-
- let points = this.buildType == 'floor' ? this.buildParent.points : this.points
- points.forEach(p=>{
- bound.expandByPoint(p.clone().setZ(zMin))
- bound.expandByPoint(p.clone().setZ(zMax))
- })
- return bound
- }
-
-
- getMarkerMaterial(type) {
- if(!markerMats){
- markerMats = {
- default: new THREE.MeshBasicMaterial({
- transparent: !0,
- color,
- opacity: 0.8,
- map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),
- depthTest:false,
-
- }),
- midPrepare: new THREE.MeshBasicMaterial({ //线中心的半透明点
- transparent: !0,
- color,
- opacity: 0.4,
- map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),
- depthTest:false,
- }),
- hover: new THREE.MeshBasicMaterial({
- transparent: !0,
- color,
- opacity: 1,
- map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),
- depthTest:false,
-
- }),
- select: new THREE.MeshBasicMaterial({
- transparent: !0,
- color:new THREE.Color('#00C8AF'),
- opacity: 1,
- map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),
- depthTest:false,
-
- }),
- }
-
- }
- return markerMats[type]
-
- }
-
-
- setMarkerSelected(marker, state, hoverObject){
- //console.warn(marker.id , state, hoverObject)
-
-
- if(state == 'select'){
- marker.selected = true
- marker.material = this.getMarkerMaterial('select')
- }else if(state == 'unselect'){
- marker.selected = false
- marker.material = this.getMarkerMaterial('default')
- }else{
- if(marker.selected)return //选中时不允许修改为除了'unselect'以外的状态
-
- if(state == 'hover'){
- marker.material = this.getMarkerMaterial('hover')
- }else if(state == 'unhover'){
- if(marker.name.includes('mid')){
- marker.material = this.getMarkerMaterial('midPrepare')
- }else{
- marker.material = this.getMarkerMaterial('default')
- }
- }
- }
- }
-
-
- select(){
- //最多再显示一层子级的线,如building不会显示room中的hole的线
- //box是一直显示的,但会切换材质
-
- /*
- 选中 box 线
-
- building 自己(底盘)选中 自己, floor不带hole
-
- floor 自己选中 自己, room不带hole
-
- room 自己选中 自己
-
- */ //注:自己的就代表定包括hole,如果有parentHoles的也(building上的hole的对应)
-
-
- //console.log('select '+this.name, this.selected)
-
- if(this.selected)return
-
- if(this.box){
- this.box.material = this.mats.boxSelected;
- }
-
- if(this.buildType == 'building'|| this.buildType == 'floor'){
- this.buildChildren.forEach(e=>{
- e.lineMesh.visible = true
- })
-
- if(this.buildType == 'floor'){
- Potree.Utils.setObjectLayers(this.box, 'bothMapAndScene' )
- Potree.Utils.setObjectLayers(this.buildParent.box, 'mapUnvisi' ) //当选中floor或room时,building在地图不可见
- }
- }else if(this.buildType == 'room'){
- Potree.Utils.setObjectLayers(this.buildParent.box, 'bothMapAndScene' )
- Potree.Utils.setObjectLayers(this.buildParent.buildParent.box, 'mapUnvisi' )
- }
-
-
-
-
-
- this.lineMesh.visible = true
- this.markers && this.markers.forEach(e=>Potree.Utils.updateVisible(e,'select',true) )
- this.midMarkers && this.midMarkers.forEach(e=>Potree.Utils.updateVisible(e,'select',true) )
-
- let holes = this.holes.concat(this.parentHoles)
- holes.forEach(e=>e.select())
-
- this.selected = true
- this.dispatchEvent({type:'select'})
- }
-
-
- unselect(){
- if(!this.selected)return
- //console.log('unselect '+this.name )
- if(this.box){
- this.box.material = this.mats.boxDefault;
- }
-
- if(this.buildType == 'building' || this.buildType == 'floor'){
- this.buildChildren.forEach(e=>{ //(这里要保证选中前要先取消选中,否则如选中房间后取消了楼层,房间线就隐藏了)
- e.lineMesh.visible = false
- })
-
- if(this.buildType == 'floor'){
- Potree.Utils.setObjectLayers(this.box, 'mapUnvisi' )
- Potree.Utils.setObjectLayers(this.buildParent.box, 'bothMapAndScene' )
- }
-
- }else if(this.buildType == 'room'){
- Potree.Utils.setObjectLayers(this.buildParent.box, 'mapUnvisi' )
- Potree.Utils.setObjectLayers(this.buildParent.buildParent.box, 'bothMapAndScene' )
- }
-
- this.lineMesh.visible = false
- this.markers && this.markers.forEach(e=>Potree.Utils.updateVisible(e,'select',false) )
- this.midMarkers && this.midMarkers.forEach(e=>Potree.Utils.updateVisible(e,'select',false) )
-
- let holes = this.holes.concat(this.parentHoles)
- holes.forEach(e=>e.unselect())
-
- this.selected = false
- this.dispatchEvent({type:'unselect'})
- }
-
-
-
-
- ifContainsPoint(position){//看它所定义的空间是否包含某个坐标(要排除hole)
-
- let {zMin , zMax} = this.getRealZ()
- if(position.z < zMin || position.z > zMax ) return
-
- let holes = this.holes.concat(this.parentHoles)
- let holesPoints = holes.filter(e=>e!=this && e.points.length>2).map(e=>e.points)
- let inShape = math.isPointInArea(this.points, holesPoints, position)
-
-
- return !!inShape
- }
-
- }
- class MetricUVGenerator{
- constructor(){
- this.a = new THREE.Vector3,
- this.b = new THREE.Vector3,
- this.c = new THREE.Vector3,
- this.d = new THREE.Vector3
- }
- generateTopUV(t, e, n, r, o) {
- return [new THREE.Vector2(e[3 * n],e[3 * n + 1]), new THREE.Vector2(e[3 * r],e[3 * r + 1]), new THREE.Vector2(e[3 * o],e[3 * o + 1])]
- }
-
- generateSideWallUV(t, e, n, r, o, a) {
- var s = e;
- this.a.set(s[3 * n], s[3 * n + 1], s[3 * n + 2]),
- this.b.set(s[3 * r], s[3 * r + 1], s[3 * r + 2]),
- this.c.set(s[3 * o], s[3 * o + 1], s[3 * o + 2]),
- this.d.set(s[3 * a], s[3 * a + 1], s[3 * a + 2]);
- var c = this.a.x !== this.b.x
- , l = c ? this.b : this.d
- , u = this.a.distanceTo(l)
- , d = l.distanceTo(this.c);
- return [new THREE.Vector2(this.a.x,0), c ? new THREE.Vector2(this.a.x + u,0) : new THREE.Vector2(this.a.x,d), new THREE.Vector2(this.a.x + u,d), c ? new THREE.Vector2(this.a.x,d) : new THREE.Vector2(this.a.x + u,0)]
- }
- }
-
|