123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- import * as THREE from "../../../../libs/three.js/build/three.module.js";
- import {Measure} from "./Measure.js";
- import History from "../../utils/History.js"
- import {Utils} from "../../../utils.js";
- import math from "../../utils/math.js";
- import {CameraMode} from "../../../defines.js";
- import {TextSprite} from '../TextSprite.js'
-
- import {Prism} from "../../modules/volumeCompute/Prism.js";
-
-
- export class MeasuringTool extends THREE.EventDispatcher{
- constructor (viewer) {
- super();
- this.viewer = viewer;
- this.renderer = viewer.renderer;
- this.viewer.addEventListener('start_inserting_measurement', e => {
- this.viewer.dispatchEvent({
- type: 'cancel_insertions'
- });
- });
- this.showLabels = true;
- this.scene = new THREE.Scene();
- this.scene.name = 'scene_measurement';
- //this.light = new THREE.PointLight(0xffffff, 1.0);
- //this.scene.add(this.light);
- this.viewer.inputHandler.registerInteractiveScene(this.scene);
-
- this.history = new History({
- applyData: (data)=>{
- if(data.measure.parent && data.measure.visible){
-
- data = Potree.Common.CloneObject(data) //避免使用后更改数据又被使用
- data.measure.reDraw()
- data.measure.initData(data)
- data.measure.isNew = data.isNew
- data.measure.dispatchEvent('changeByHistory')
- /* if(data.measure.isPrism){
- data.measure.needsCompute = data.needsCompute
- } */
- data.measure.facePlane = data.facePlane && data.facePlane.clone()
- data.measure.cannotConfirmNormal = data.cannotConfirmNormal
- return true
- }
- },
- getData:(measure)=>{
- let data = {
- measure,
- points: measure.points.map(e=>e.clone()),
- dataset_points: measure.dataset_points ? measure.dataset_points.map(e=>e&&e.clone()) : null,
- points_datasets: measure.points_datasets.slice(),
- datasetId: measure.datasetId,
- isNew: measure.isNew,
- facePlane: measure.facePlane && measure.facePlane.clone(),
- cannotConfirmNormal: measure.cannotConfirmNormal
- }
- /* if(measure.isPrism){ //没用
- data.volumeInfo = measure.volumeInfo
- data.needsCompute = measure.needsCompute
- //但不记录其他信息
- } */
- return data
- }
- }),
- //this.scene = viewer.overlay//
-
-
- this.onRemove = (e) => { e.measurement.dispose()/* this.scene.remove(e.measurement); */};
- this.onAdd = e => {this.scene.add(e.measurement);};
- for(let measurement of viewer.scene.measurements){
- this.onAdd({measurement: measurement});
- }
-
-
- viewer.addEventListener('camera_changed', this.update.bind(this),{importance:10})//优先级高于sprite
-
-
- if(Potree.config.measure.mulLabelHideFaraway ){
-
-
- viewer.addEventListener("raycaster", this.beforeDraw.bind(this),{importance:10}) //before render
- viewer.addEventListener("render.begin", this.beforeDraw.bind(this),{importance:10}) //before render
- viewer.addEventListener("render.begin2", this.beforeDraw.bind(this),{importance:10})
-
- }
-
- //viewer.addEventListener("update", this.update.bind(this));
- viewer.addEventListener("render.pass.perspective_overlay", this.render.bind(this));
- viewer.addEventListener("scene_changed", this.onSceneChange.bind(this));
- viewer.scene.addEventListener('measurement_added', this.onAdd);
- viewer.scene.addEventListener('measurement_removed', this.onRemove);
-
- viewer.addEventListener('resize',this.setSize.bind(this))
-
- }
- onSceneChange(e){
- if(e.oldScene){
- e.oldScene.removeEventListener('measurement_added', this.onAdd);
- e.oldScene.removeEventListener('measurement_removed', this.onRemove);
- }
- e.scene.addEventListener('measurement_added', this.onAdd);
- e.scene.addEventListener('measurement_removed', this.onRemove);
- }
-
-
- createMeasureFromData(data){//add
-
- const measure = data.measureType == 'MulDistance Ring' ? new Prism(data) : new Measure(data);
- if(measure.failBuilded){
- return
- }
- viewer.scene.addMeasurement(measure);
-
- if(measure.guideLine)measure.guideLine.visible = false
- return measure
- }
-
-
- beforeDraw(e){
- if(e.viewport.name == 'mapViewport' && !viewer.mapViewer.attachedToViewer)return //no measures
-
- viewer.scene.measurements.forEach(measure=>{
- if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
- let lastIndex = measure.points.length - 1;
- for (let index = 0; index <= lastIndex; index++) {
- if(!measure.closed && index == lastIndex)continue
- let edgeLabel = measure.edgeLabels[index];
- let v = edgeLabel.visiMap.get(e.viewport.camera)
-
- if(v == void 0){
- return measure.getEdgeLabelVisi(e.viewport)
- }
-
- Potree.Utils.updateVisible(edgeLabel, 'tooFar', v === false ? false : true)
- }
- })
-
- }
-
- update(e){
-
-
-
- /* viewer.scene.measurements.forEach(measure=>{
- if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
-
-
- }) */
-
-
-
- if(viewer.inputHandler.measuring && Potree.settings.adsorption){
- viewer.scene.measurements.forEach(measure=>{
- measure.getPointsPos2d(e.viewport, true)
- })
-
- }
-
-
-
- if(Potree.config.measure.mulLabelHideFaraway){
-
- if(e.changeInfo.projectionChanged || e.viewport.camera.type == 'PerspectiveCamera' && e.changeInfo.positionChanged){//for MulDistance
-
-
- viewer.scene.measurements.forEach(measure=>{
- if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
- measure.getEdgeLabelVisi(e.viewport)
- return
-
- let lastIndex = measure.points.length - 1;
- for (let index = 0; index <= lastIndex; index++) {
- if(!measure.closed && index == lastIndex)continue
-
- let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
- let previousIndex = (index === 0) ? lastIndex : index - 1;
-
- let point = measure.points[index];
- let nextPoint = measure.points[nextIndex];
- let previousPoint = measure.points[previousIndex];
- let point2d = new THREE.Vector2().copy(pos2ds[index]);
- let nextPoint2d = new THREE.Vector2().copy(pos2ds[nextIndex]);
- if(measure.showDistances || measure.labelText){ // edge labels
- let edgeLabel = measure.edgeLabels[index];
-
- if(edgeLabel.visible){
- measure.setEdgeLabelPos(edgeLabel, point, nextPoint )
- }
- }
- }
- })
-
- }
- }
-
-
- return;
-
-
-
-
- let camera = this.viewer.scene.getActiveCamera();
- let domElement = this.renderer.domElement;
- let measurements = this.viewer.scene.measurements;
-
- // make size independant of distance
- let mainLabels = [], subLabels = [];
-
-
-
- for (let measure of measurements) {
- measure.lengthUnit = this.viewer.lengthUnit;
- measure.lengthUnitDisplay = this.viewer.lengthUnitDisplay;
- //measure.update();
- updateAzimuth(this.viewer, measure);
-
- /* [...measure.markers, ...measure.edgeLabels, measure.areaLabel].forEach(e=>{
- e && e.update()
- }); */
-
- // labels
- /* let labels = measure.edgeLabels.concat(measure.angleLabels);
- for(let label of labels){
- label.update()
- if(label.elem.hasClass('sub')){
- subLabels.push(label)
- }else{
- mainLabels.push(label)
- }
- }
- // coordinate labels
- for (let j = 0; j < measure.coordinateLabels.length; j++) {
- let label = measure.coordinateLabels[j];
- label.update()
- mainLabels.push(label)
- }
-
- if(measure.showArea){ // area label
- let label = measure.areaLabel;
- label.update()
- mainLabels.push(label)
- } */
-
-
- /* if(measure.showCircle){ // radius label
- let label = measure.circleRadiusLabel;
- let distance = label.position.distanceTo(camera.position);
- let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
- let scale = (70 / pr);
- label.scale.set(scale, scale, scale);
- } */
- if(!this.showLabels){
- const labels = [
- ...measure.sphereLabels,
- ...measure.angleLabels,
- measure.circleRadiusLabel,
- ];
- for(const label of labels){
- label.visible = false;
- }
- }
- }
- //this.updateLabelZIndex([{labels:subLabels},{labels:mainLabels}])
-
- }
- setSize(e){ //e.resolution
- /* if(Measure.lineMats){
- for(var m in Measure.lineMats){
- Measure.lineMats[m].resolution.set(e.canvasWidth, e.canvasHeight);
- }
- }
- if(Measure.sphereMats){
- for(var s in Measure.sphereMats){
- Measure.sphereMats[s].uniforms.resolution.value.set(e.canvasWidth, e.canvasHeight);
- }
- }
- for (let measure of this.viewer.scene.measurements) {
- measure.edgeLabels.concat(measure.areaLabel).forEach(label=>{
- label.sprite.material.uniforms.resolution.value.set(e.canvasWidth, e.canvasHeight);
- })
- } */
- }
-
- updateLabelZIndex(group){//[{labels:[]},{}] 顺序按照z-index低到高
-
- group.forEach((e,i)=>{
- e.base = group[i-1] ? group[i-1].base + group[i-1].labels.length : 0
-
- var labels = e.labels.sort((a,b)=>{
- return b.pos2d.z - a.pos2d.z
- })
- labels.forEach((label,index)=>{
- $(label.elem).css('z-index', e.base+index)
- })
- })
-
- }
-
-
- changeEditMode(mode){
- viewer.dispatchEvent({type : "CursorChange", action : "remove", name:"addPoint"})
- viewer.dispatchEvent({type : "CursorChange", action : "remove", name:"delPoint"})
- if(mode){
- if(mode == 'addPoint'){
- viewer.dispatchEvent({type : "CursorChange", action : "add", name:"addPoint"})
- }else{
- viewer.dispatchEvent({type : "CursorChange", action : "add", name:"delPoint"})
- }
-
- }
- this.editMode = mode
- }
-
- editStateChange(e){
- //console.log("editStateChange" , e.state)
- let state = e.state
- if(!state){
- state = viewer.scene.measurements.some(e=>e.isEditing)
- }
-
- if(state){
- viewer.dispatchEvent({type:"measureMovePoint"})//重新激活reticule状态
- }else{
- viewer.dispatchEvent({type:"endMeasureMove"})
- }
-
-
- //this.editing =
- }
-
-
-
- startInsertion (args = {}, callback, cancelFun) {
-
-
- let domElement = this.viewer.renderer.domElement;
-
-
- let measure = args.measureType == 'MulDistance Ring' ? new Prism(args) : new Measure(args);
- this.scene.add(measure);
- measure.isNew = true
-
- this.viewer.dispatchEvent({
- type: 'start_inserting_measurement',
- measure: measure
- });
-
- measure.addEventListener('editStateChange', this.editStateChange.bind(this))
- measure.editStateChange(true)
-
- let timer;
- this.isAdding = true
-
- let endDragFun = (e) => {
- let length = measure.points.length
- if (e.button == THREE.MOUSE.LEFT || e.isTouch) {
- if (length >= measure.maxMarkers) {
- end({finish:true});
- }else{
-
- this.history.beforeChange(measure)
-
- let marker = measure.cloneMarker(length - 1, length)
-
- if(args.isRect && measure.markers.length == 3){//marker全可见
- measure.cloneMarker(0, 3)
- }else{
- measure.markers[length].visible = false
- measure.edges[length].visible = false
- }
- measure.edges[length-1].visible = true
-
- measure.markers[length-1].visible = true;
-
- marker.isDragging = true
-
- this.history.afterChange(measure)
-
- measure.continueDrag(marker, e)
- }
-
- } else if (e.button === THREE.MOUSE.RIGHT ) { //触屏怎么取消?
- if(e.pressDistance < Potree.config.clickMaxDragDis){//非拖拽的话
- var isIntersectSelf = measure.atPlane && measure.closed && !measure.isRect && measure.point2dInfo && measure.intersectSelf(measure.point2dInfo.points2d.slice(0,measure.point2dInfo.points2d.length-1))//检测除了最后一个点的相交情况
- if(!isIntersectSelf)end(e);
- else measure.continueDrag(null, e)
- }else measure.continueDrag(null, e)
-
- }
- };
- let end = (e={}) => {//确定、结束
- if(!measure.isNew )return
-
- if(args.minMarkers != void 0 ){
-
- if(!e.finish && measure.markers.length<=args.minMarkers ){//右键 当个数不够时取消
- //this.viewer.scene.removeMeasurement(measure)
-
- //重新开始画
- if(measure.markers.length>0){
- measure.markers[0].removeEventListener('mousedown',end)
- measure.reDraw()
- this.viewer.addEventListener('global_click', click, {importance:10})
- measure.editStateChange(true)
- }
- return
-
- /* if(!Potree.settings.isOfficial) this.viewer.scene.removeMeasurement(measure)
- else if(e.drag){ //正式版本不允许右键退出, 继续
- continueDrag(e.drag.object)
- measure.editStateChange(true)
- return
- } */
- }
- }
-
-
- let lastMarker = measure.markers[measure.markers.length-1]
-
- if (/* !e.finish&& */ measure.markers.length > args.minMarkers) {
- measure.removeMarker(measure.points.length - 1);
- measure.markers[0].removeEventListener('mouseover', mouseover);
- measure.markers[0].removeEventListener('mouseleave', mouseleave);
- measure.markers[0].removeEventListener('click'/* 'mousedown' */,Exit)
-
- if(e.byClickMarker && measure.markers.length > args.minMarkers ){//通过点击第一个marker而结束的话,会多一个marker。但点击marker后可能会因为和它坐标一致而没有添加成功,就不删,根据添加的时间来判断。
- let delta = Date.now() - lastMarker.createTime
- //console.log('delta',delta)
- if(delta < 10){//刚生成的,说明点击后新增了一个marker
- measure.removeMarker(measure.points.length - 1);
- }
- }
- }
- measure.isNew = false
- let length = measure.points.length
- if(length){
- measure.markers[length-1].visible = true;
- measure.edges[length-1].visible = !!measure.closed
-
- measure.markers.forEach(marker=>{marker.dispatchEvent('addHoverEvent') })
- measure.edges.forEach(edge=>{edge.dispatchEvent('addHoverEvent') })
- measure.update();//update last edgeLabel
- }
-
-
-
-
- clearTimeout(timer)
- this.viewer.removeEventListener('cancel_insertions', Exit);
- //pressExit && this.viewer.inputHandler.removeEventListener('keydown', pressExit);
- this.viewer.removeEventListener('global_click', click)
- this.viewer.removeEventListener('global_mousemove', ifAtWrongPlace)
- viewer.dispatchEvent({
- type : "CursorChange", action : "remove", name:"polygon_AtWrongPlace"
- });
-
- viewer.inputHandler.dispatchEvent({type:'measuring', v:false, cause:'stopInsertion', situation:'adding', object:measure} )
-
-
- //var isIntersectSelf = measure.atPlane && measure.closed && !measure.isRect && measure.point2dInfo && measure.intersectSelf(measure.point2dInfo.points2d.slice(0,measure.point2dInfo.points2d.length-1))//检测除了最后一个点的相交情况
- var isIntersectSelf = measure.atPlane && measure.closed && !measure.isRect && measure.point2dInfo && measure.intersectSelf(measure.point2dInfo.points2d)
- if(isIntersectSelf) return cancelFun && cancelFun() //请求删除,不重建
-
-
-
- e.remove || callback && callback()
- /* this.viewer.dispatchEvent({
- type: 'finish_inserting_measurement',
- measure: measure
- }); */
-
- this.isAdding = false
-
- measure.dispatchEvent('createDone')
- };
- measure.addEventListener('finish', end) //完成
-
-
- let Exit = (e)=>{//强制退出
-
- if(e.measure && e.measure != measure || !viewer.scene.measurements.includes(measure) || !measure.isNew){
- return;//若指定了退出的measure但和该measure不一致,就返回
- }
- if(e.remove || e.type == 'cancel_insertions'){
- viewer.scene.removeMeasurement(measure)
- }
-
-
- measure.editStateChange(false)
- measure.cannotConfirmNormal = false //一些dropMarker中的句子
- measure.guideLine && (measure.guideLine.visible = false)
- /*
- if(this.viewer.inputHandler.drag && !e.remove ){//还未触发drop的话
- this.viewer.inputHandler.drag.object.dispatchEvent({ //这句会导致又增一个marker
- type: 'drop',
- drag: this.viewer.inputHandler.drag,
- viewer: this.viewer,
- pressDistance:0,
- button : THREE.MOUSE.RIGHT
- });
-
- } else {*///未结束时添加新的measure时会触发
- end({finish:true, remove:e.remove, byClickMarker: e.type == 'click'})
- //}
- this.viewer.inputHandler.drag && (this.viewer.inputHandler.drag.object = null)
-
- }
-
-
-
- this.viewer.addEventListener('cancel_insertions', Exit);
-
- /*let pressExit
- if(!Potree.settings.isOfficial){
- pressExit = (e)=>{
- if(e.keyCode == 27){//Esc
- //Exit()
- //怎么模拟右键???//现由前端发出
- }
- }
- this.viewer.inputHandler.addEventListener('keydown', pressExit)
- } */
- let mouseover = (e) => {
- measure.setMarkerSelected(e.object, 'hover', 'single');
-
- };
- let mouseleave = (e) => {
- measure.setMarkerSelected(e.object, 'unhover', 'single');
- }
-
-
- let click = (e)=>{//一旦点击就立刻增加两marker
-
- if(ifAtWrongPlace(e))return
- if(e.clickElement)return //如点击label时focusOnObject
-
-
- if(e.button === THREE.MOUSE.RIGHT)return
-
- //console.log('measure clicked33', !!e.intersectPoint)
-
- //var I = e.intersectPoint && (e.intersectPoint.orthoIntersect || e.intersectPoint.location)
- var I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
- if(!I){
- return measure.dispatchEvent('intersectNoPointcloud')
- }
- var atMap = e.drag.dragViewport.name == 'mapViewport'
- //在地图上测量的首个点按楼层高度(暂时先只按mainViewport相机高度吧,但navvis是按楼层,画在楼层的地面上,可能因为平面图显示的是楼层近地面),
-
- if(atMap){
- I = I.clone().setZ(viewer.mainViewport.camera.position.z )
- }
-
- var marker = measure.addMarker({point:I})
- marker.isDragging = true
- this.viewer.inputHandler.startDragging(marker , {endDragFun, notPressMouse:true} ); //notPressMouse代表不是通过按下鼠标来拖拽
- e.drag = this.viewer.inputHandler.drag
- /* e.drag.endDragFun = endDragFun
- e.drag.notPressMouse = true */
-
- //if(!measure.dragMarker(e) || !measure.dropMarker(e))return
-
- measure.dragMarker(e)
- measure.dropMarker(e)
-
- if(measure.maxMarkers > 1 ){
- measure.markers[1].visible = false
- measure.edges[1].visible = false
- }
- if(measure.closed && !measure.isRect){
- measure.markers[0].addEventListener('mouseover', mouseover);
- measure.markers[0].addEventListener('mouseleave', mouseleave);
- measure.markers[0].addEventListener('click'/* 'mousedown' */,Exit) //点击到第一个marker就结束
- }
-
-
- this.viewer.removeEventListener('global_click', click)///* global_drop */
-
-
-
- //console.log('measure clicked')
- e.consume && e.consume()
-
- return {stopContinue:true}//防止继续执行别的侦听,如flytopano
- }
-
- //点击第n下拥有n+1个marker, n>0
-
- viewer.inputHandler.dispatchEvent({type: 'measuring', v: true, cause:'startInsertion', situation:'adding', object:measure})
-
- this.viewer.addEventListener('global_click', click, {importance:10})//add importance
-
- let ifAtWrongPlace = (e)=>{
- if(measure.unableDragAtMap && e.hoverViewport.name == 'mapViewport' ){
- if(e.isTouch){
- viewer.dispatchEvent({type:'reticule_forbit', v:true})
- }else{
- viewer.dispatchEvent({
- type : "CursorChange", action : "add", name:"polygon_AtWrongPlace"
- });
- }
- return true
- }else{
- if(e.isTouch){
- viewer.dispatchEvent({type:'reticule_forbit',v:false})
- }else{
- viewer.dispatchEvent({
- type : "CursorChange", action : "remove", name:"polygon_AtWrongPlace"
- });
- }
- }
- }
-
-
-
- if(measure.unableDragAtMap){
- this.viewer.addEventListener('global_mousemove', ifAtWrongPlace)
- }
-
-
- let changeByHistory = (e)=>{
- if(!measure.isNew)return
-
- let marker = measure.markers[measure.points.length-1]
- this.viewer.inputHandler.startDragging(marker , {endDragFun, notPressMouse:true} );
-
-
- var I = viewer.inputHandler.intersect && (viewer.inputHandler.intersect.orthoIntersect || viewer.inputHandler.intersect.location)
- if(I){
- measure.dragChange(I.clone(), measure.points.length-1 ) //使最后一个点在鼠标处
- }
- /* if(measure.markers.length == 1){
- Common.updateVisible(marker, ,false)
- } */
- args.isRect || ( measure.edges[measure.points.length-1].visible = false)
-
-
-
- //measure.continueDrag(measure.markers[measure.points.length-1], o )
- }
- measure.addEventListener('changeByHistory',changeByHistory)
-
-
- this.viewer.scene.addMeasurement(measure);
-
- return measure;
- }
-
-
- render(o={}){
- if(this.scene.children.filter(e=>e.visible).length == 0)return
- let renderer = o.renderer || this.viewer.renderer
- Potree.Utils.setCameraLayers(o.camera, ['measure'])
-
- /* if(o.screenshot && this.viewer.fxaaPass.enabled){ //抗锯齿
- this.viewer.ssaaRenderPass.sampleLevel = 4
- this.viewer.composer.render(this.scene, o.camera );
- }else{ */
-
- viewer.dispatchEvent({type: "render.begin2" , name:'measure', viewport:o.viewport, renderer:o.renderer })
- renderer.render(this.scene, o.camera );
- //}
- }
-
-
-
- };
- function updateAzimuth(viewer, measure){
- if(!measure.showAzimuth)return
- const azimuth = measure.azimuth;
- const isOkay = measure.points.length === 2;
- azimuth.node.visible = isOkay
- if(!azimuth.node.visible){
- return;
- }
- const camera = viewer.scene.getActiveCamera();
- const renderAreaSize = viewer.renderer.getSize(new THREE.Vector2());
- const width = renderAreaSize.width;
- const height = renderAreaSize.height;
-
- const [p0, p1] = measure.points;
- const r = p0.position.distanceTo(p1.position);
- const northVec = Utils.getNorthVec(p0.position, r, viewer.getProjection());
- const northPos = p0.position.clone().add(northVec);
- azimuth.center.position.copy(p0.position);
- azimuth.center.scale.set(2, 2, 2);
-
- azimuth.center.visible = false;
- // azimuth.target.visible = false;
- { // north
- azimuth.north.position.copy(northPos);
- azimuth.north.scale.set(2, 2, 2);
- let distance = azimuth.north.position.distanceTo(camera.position);
- let pr = Utils.projectedRadius(1, camera, distance, width, height);
- let scale = (5 / pr);
- azimuth.north.scale.set(scale, scale, scale);
- }
- { // target
- azimuth.target.position.copy(p1.position);
- azimuth.target.position.z = azimuth.north.position.z;
- let distance = azimuth.target.position.distanceTo(camera.position);
- let pr = Utils.projectedRadius(1, camera, distance, width, height);
- let scale = (5 / pr);
- azimuth.target.scale.set(scale, scale, scale);
- }
-
- azimuth.circle.position.copy(p0.position);
- azimuth.circle.scale.set(r, r, r);
- azimuth.circle.material.resolution.set(width, height);
- // to target
- azimuth.centerToTarget.geometry.setPositions([
- 0, 0, 0,
- ...p1.position.clone().sub(p0.position).toArray(),
- ]);
- azimuth.centerToTarget.position.copy(p0.position);
- azimuth.centerToTarget.geometry.verticesNeedUpdate = true;
- azimuth.centerToTarget.geometry.computeBoundingSphere();
- azimuth.centerToTarget.computeLineDistances();
- azimuth.centerToTarget.material.resolution.set(width, height);
- // to target ground
- azimuth.centerToTargetground.geometry.setPositions([
- 0, 0, 0,
- p1.position.x - p0.position.x,
- p1.position.y - p0.position.y,
- 0,
- ]);
- azimuth.centerToTargetground.position.copy(p0.position);
- azimuth.centerToTargetground.geometry.verticesNeedUpdate = true;
- azimuth.centerToTargetground.geometry.computeBoundingSphere();
- azimuth.centerToTargetground.computeLineDistances();
- azimuth.centerToTargetground.material.resolution.set(width, height);
- // to north
- azimuth.centerToNorth.geometry.setPositions([
- 0, 0, 0,
- northPos.x - p0.position.x,
- northPos.y - p0.position.y,
- 0,
- ]);
- azimuth.centerToNorth.position.copy(p0.position);
- azimuth.centerToNorth.geometry.verticesNeedUpdate = true;
- azimuth.centerToNorth.geometry.computeBoundingSphere();
- azimuth.centerToNorth.computeLineDistances();
- azimuth.centerToNorth.material.resolution.set(width, height);
- // label
- const radians = Utils.computeAzimuth(p0.position, p1.position, viewer.getProjection());
- let degrees = THREE.Math.radToDeg(radians);
- if(degrees < 0){
- degrees = 360 + degrees;
- }
- const txtDegrees = `${degrees.toFixed(2)}°`;
- const labelDir = northPos.clone().add(p1.position).multiplyScalar(0.5).sub(p0.position);
- if(labelDir.length() > 0){
- labelDir.z = 0;
- labelDir.normalize();
- const labelVec = labelDir.clone().multiplyScalar(r);
- const labelPos = p0.position.clone().add(labelVec);
- azimuth.label.position.copy(labelPos);
- }
- azimuth.label.setText(txtDegrees);
- let distance = azimuth.label.position.distanceTo(camera.position);
- let pr = Utils.projectedRadius(1, camera, distance, width, height);
- let scale = (70 / pr);
- azimuth.label.scale.set(scale, scale, scale);
- }
|