|
@@ -1,17 +1,18 @@
|
|
|
|
|
|
import * as THREE from "../../libs/three.js/build/three.module.js";
|
|
|
import {Measure} from "./Measure.js";
|
|
|
-import {Utils} from "../utils.js";
|
|
|
-import {CameraMode} from "../defines.js";
|
|
|
+import {Utils} from "../utils.js";
|
|
|
+import math from "./math.js";
|
|
|
+import {CameraMode,MOUSE} from "../defines.js";
|
|
|
import { EventDispatcher } from "../EventDispatcher.js";
|
|
|
-
|
|
|
+
|
|
|
function updateAzimuth(viewer, measure){
|
|
|
-
|
|
|
+ if(!measure.showAzimuth)return
|
|
|
const azimuth = measure.azimuth;
|
|
|
|
|
|
const isOkay = measure.points.length === 2;
|
|
|
|
|
|
- azimuth.node.visible = isOkay && measure.showAzimuth;
|
|
|
+ azimuth.node.visible = isOkay
|
|
|
|
|
|
if(!azimuth.node.visible){
|
|
|
return;
|
|
@@ -134,26 +135,30 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
});
|
|
|
|
|
|
this.showLabels = true;
|
|
|
- this.scene = new THREE.Scene();
|
|
|
+ this.scene = new THREE.Scene();
|
|
|
this.scene.name = 'scene_measurement';
|
|
|
- this.light = new THREE.PointLight(0xffffff, 1.0);
|
|
|
- this.scene.add(this.light);
|
|
|
-
|
|
|
+ //this.light = new THREE.PointLight(0xffffff, 1.0);
|
|
|
+ //this.scene.add(this.light);
|
|
|
this.viewer.inputHandler.registerInteractiveScene(this.scene);
|
|
|
-
|
|
|
- this.onRemove = (e) => { this.scene.remove(e.measurement);};
|
|
|
+ //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("update", this.update.bind(this));
|
|
|
+ viewer.addEventListener("camera_changed", this.update.bind(this));
|
|
|
+ //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){
|
|
@@ -167,14 +172,11 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
}
|
|
|
|
|
|
startInsertion (args = {}) {
|
|
|
+
|
|
|
+
|
|
|
let domElement = this.viewer.renderer.domElement;
|
|
|
|
|
|
- let measure = new Measure();
|
|
|
-
|
|
|
- this.dispatchEvent({
|
|
|
- type: 'start_inserting_measurement',
|
|
|
- measure: measure
|
|
|
- });
|
|
|
+
|
|
|
|
|
|
const pick = (defaul, alternative) => {
|
|
|
if(defaul != null){
|
|
@@ -184,56 +186,91 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- measure.showDistances = (args.showDistances === null) ? true : args.showDistances;
|
|
|
+ args.showDistances = (args.showDistances === null) ? true : args.showDistances;
|
|
|
+
|
|
|
+ args.showArea = pick(args.showArea, false);
|
|
|
+ args.showAngles = pick(args.showAngles, false);
|
|
|
+ args.showCoordinates = pick(args.showCoordinates, false);
|
|
|
+ args.showHeight = pick(args.showHeight, false);
|
|
|
+ args.showCircle = pick(args.showCircle, false);
|
|
|
+ args.showAzimuth = pick(args.showAzimuth, false);
|
|
|
+ args.showEdges = pick(args.showEdges, true);
|
|
|
+ args.closed = pick(args.closed, false);
|
|
|
+ args.maxMarkers = pick(args.maxMarkers, Infinity);
|
|
|
+ args.direction = args.direction//add
|
|
|
+ args.type = args.type /* || 'Measurement'; */
|
|
|
+ args.showGuideLine = pick(args.showGuideLine, false);
|
|
|
+ args.isRect = pick(args.isRect, false);
|
|
|
+
|
|
|
|
|
|
- measure.showArea = pick(args.showArea, false);
|
|
|
- measure.showAngles = pick(args.showAngles, false);
|
|
|
- measure.showCoordinates = pick(args.showCoordinates, false);
|
|
|
- measure.showHeight = pick(args.showHeight, false);
|
|
|
- measure.showCircle = pick(args.showCircle, false);
|
|
|
- measure.showAzimuth = pick(args.showAzimuth, false);
|
|
|
- measure.showEdges = pick(args.showEdges, true);
|
|
|
- measure.closed = pick(args.closed, false);
|
|
|
- measure.maxMarkers = pick(args.maxMarkers, Infinity);
|
|
|
|
|
|
- measure.name = args.name || 'Measurement';
|
|
|
|
|
|
- this.scene.add(measure);
|
|
|
+ let measure = new Measure(args);
|
|
|
+ /* if(this.editingMeasure){
|
|
|
+ this.editingMeasure.dispatchEvent({type:"endEdit"})
|
|
|
+ }
|
|
|
+ this.editingMeasure = measure */
|
|
|
+
|
|
|
+
|
|
|
+ this.dispatchEvent({
|
|
|
+ type: 'start_inserting_measurement',
|
|
|
+ measure: measure
|
|
|
+ });
|
|
|
|
|
|
- let cancel = {
|
|
|
- //removeLastMarker: measure.maxMarkers > 3,
|
|
|
- callback: null
|
|
|
- };
|
|
|
+
|
|
|
+ this.scene.add(measure);
|
|
|
+
|
|
|
+
|
|
|
|
|
|
let endDragFun = (e) => {
|
|
|
- if (e.button === THREE.MOUSE.LEFT) {
|
|
|
+
|
|
|
+ if (e.drag.mouse == MOUSE.LEFT) {
|
|
|
if (measure.points.length >= measure.maxMarkers) {
|
|
|
- cancel.callback();
|
|
|
+ end({complete:true});
|
|
|
}else{
|
|
|
- this.viewer.inputHandler.startDragging(measure.addMarker(measure.points[measure.points.length - 1].position.clone()),
|
|
|
- {endDragFun}
|
|
|
- );
|
|
|
+ var marker = measure.addMarker(measure.points[measure.points.length - 1].position.clone())
|
|
|
+ if(args.isRect && measure.spheres.length == 3){
|
|
|
+ measure.addMarker(measure.points[0].position.clone())
|
|
|
+ }
|
|
|
+ setTimeout(()=>{//等 drag=null之后
|
|
|
+ this.viewer.inputHandler.startDragging(marker,
|
|
|
+ {endDragFun}
|
|
|
+ );
|
|
|
+ },1)
|
|
|
}
|
|
|
|
|
|
- } else if (e.button === THREE.MOUSE.RIGHT) {
|
|
|
- cancel.callback();
|
|
|
+ } else if (e.drag.mouse === MOUSE.RIGHT) {
|
|
|
+ if(e.pressDistance < 2 )end();//非拖拽的话
|
|
|
+ else setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag
|
|
|
+ this.viewer.inputHandler.startDragging(e.drag.object,
|
|
|
+ {endDragFun}
|
|
|
+ );
|
|
|
+ },1)
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- cancel.callback = e => {
|
|
|
- if(args.minMarkers != void 0 && measure.spheres.length<args.minMarkers){
|
|
|
- this.viewer.scene.removeMeasurement(measure)
|
|
|
- }else if (measure.spheres.length > 3) {
|
|
|
+ let end = (o={}) => {
|
|
|
+ if(args.minMarkers != void 0){
|
|
|
+ if(!o.complete && measure.spheres.length<=args.minMarkers){
|
|
|
+ this.viewer.scene.removeMeasurement(measure)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!o.complete && measure.spheres.length > 3) {
|
|
|
measure.removeMarker(measure.points.length - 1);
|
|
|
}
|
|
|
+
|
|
|
+ //this.editingMeasure = null
|
|
|
//domElement.removeEventListener('mouseup', insertionCallback, false);
|
|
|
- //this.viewer.removeEventListener('cancel_insertions', cancel.callback);
|
|
|
+ this.viewer.removeEventListener('cancel_insertions', end);
|
|
|
};
|
|
|
|
|
|
- if (measure.maxMarkers > 1) {
|
|
|
- //this.viewer.addEventListener('cancel_insertions', cancel.callback);
|
|
|
+ //measure.addEventListener("endEdit", end)
|
|
|
+
|
|
|
+
|
|
|
+ //if (measure.maxMarkers > 1) {
|
|
|
+ this.viewer.addEventListener('cancel_insertions', end);
|
|
|
//domElement.addEventListener('mouseup', insertionCallback, false);
|
|
|
- }
|
|
|
+ //}
|
|
|
|
|
|
/* measure.addMarker(new THREE.Vector3(0, 0, 0));
|
|
|
this.viewer.inputHandler.startDragging(
|
|
@@ -245,13 +282,37 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
endDragFun
|
|
|
});
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
this.viewer.scene.addMeasurement(measure);
|
|
|
-
|
|
|
+
|
|
|
return measure;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ 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)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ setSize(e){
|
|
|
+ if(Measure.lineMats){
|
|
|
+ for(var m in Measure.lineMats){
|
|
|
+ Measure.lineMats[m].resolution.set(e.canvasWidth, e.canvasHeight);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
update(){
|
|
|
let camera = this.viewer.scene.getActiveCamera();
|
|
|
let domElement = this.renderer.domElement;
|
|
@@ -261,159 +322,83 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
let clientWidth = renderAreaSize.width;
|
|
|
let clientHeight = renderAreaSize.height;
|
|
|
|
|
|
- this.light.position.copy(camera.position);
|
|
|
+ //this.light.position.copy(camera.position);
|
|
|
|
|
|
// 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();
|
|
|
+ //measure.update();
|
|
|
|
|
|
updateAzimuth(this.viewer, measure);
|
|
|
|
|
|
// spheres
|
|
|
- for(let sphere of measure.spheres){
|
|
|
- let distance = camera.position.distanceTo(sphere.getWorldPosition(new THREE.Vector3()));
|
|
|
- let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
|
|
|
- let scale = (15 / pr);
|
|
|
- sphere.scale.set(scale, scale, scale);
|
|
|
- }
|
|
|
+
|
|
|
+ for(let sphere of measure.spheres){
|
|
|
+ measure.updateSphereSize(sphere)
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// labels
|
|
|
let labels = measure.edgeLabels.concat(measure.angleLabels);
|
|
|
- for(let label of labels){
|
|
|
- let distance = camera.position.distanceTo(label.getWorldPosition(new THREE.Vector3()));
|
|
|
- let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
|
|
|
- let scale = (70 / pr);
|
|
|
-
|
|
|
- if(Potree.debug.scale){
|
|
|
- scale = (Potree.debug.scale / pr);
|
|
|
- }
|
|
|
-
|
|
|
- label.scale.set(scale, scale, scale);
|
|
|
+ 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];
|
|
|
- let sphere = measure.spheres[j];
|
|
|
-
|
|
|
- let distance = camera.position.distanceTo(sphere.getWorldPosition(new THREE.Vector3()));
|
|
|
-
|
|
|
- let screenPos = sphere.getWorldPosition(new THREE.Vector3()).clone().project(camera);
|
|
|
- screenPos.x = Math.round((screenPos.x + 1) * clientWidth / 2);
|
|
|
- screenPos.y = Math.round((-screenPos.y + 1) * clientHeight / 2);
|
|
|
- screenPos.z = 0;
|
|
|
- screenPos.y -= 30;
|
|
|
-
|
|
|
- let labelPos = new THREE.Vector3(
|
|
|
- (screenPos.x / clientWidth) * 2 - 1,
|
|
|
- -(screenPos.y / clientHeight) * 2 + 1,
|
|
|
- 0.5 );
|
|
|
- labelPos.unproject(camera);
|
|
|
- if(this.viewer.scene.cameraMode == CameraMode.PERSPECTIVE) {
|
|
|
- let direction = labelPos.sub(camera.position).normalize();
|
|
|
- labelPos = new THREE.Vector3().addVectors(
|
|
|
- camera.position, direction.multiplyScalar(distance));
|
|
|
-
|
|
|
- }
|
|
|
- label.position.copy(labelPos);
|
|
|
- let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
|
|
|
- let scale = (70 / pr);
|
|
|
- label.scale.set(scale, scale, scale);
|
|
|
+ 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)
|
|
|
}
|
|
|
|
|
|
- // height label
|
|
|
- if (measure.showHeight) {
|
|
|
- let label = measure.heightLabel;
|
|
|
-
|
|
|
- {
|
|
|
- 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);
|
|
|
- }
|
|
|
-
|
|
|
- { // height edge
|
|
|
- let edge = measure.heightEdge;
|
|
|
-
|
|
|
- let sorted = measure.points.slice().sort((a, b) => a.position.z - b.position.z);
|
|
|
- let lowPoint = sorted[0].position.clone();
|
|
|
- let highPoint = sorted[sorted.length - 1].position.clone();
|
|
|
- let min = lowPoint.z;
|
|
|
- let max = highPoint.z;
|
|
|
-
|
|
|
- let start = new THREE.Vector3(highPoint.x, highPoint.y, min);
|
|
|
- let end = new THREE.Vector3(highPoint.x, highPoint.y, max);
|
|
|
-
|
|
|
- let lowScreen = lowPoint.clone().project(camera);
|
|
|
- let startScreen = start.clone().project(camera);
|
|
|
- let endScreen = end.clone().project(camera);
|
|
|
-
|
|
|
- let toPixelCoordinates = v => {
|
|
|
- let r = v.clone().addScalar(1).divideScalar(2);
|
|
|
- r.x = r.x * clientWidth;
|
|
|
- r.y = r.y * clientHeight;
|
|
|
- r.z = 0;
|
|
|
-
|
|
|
- return r;
|
|
|
- };
|
|
|
-
|
|
|
- let lowEL = toPixelCoordinates(lowScreen);
|
|
|
- let startEL = toPixelCoordinates(startScreen);
|
|
|
- let endEL = toPixelCoordinates(endScreen);
|
|
|
-
|
|
|
- let lToS = lowEL.distanceTo(startEL);
|
|
|
- let sToE = startEL.distanceTo(endEL);
|
|
|
-
|
|
|
- edge.geometry.lineDistances = [0, lToS, lToS, lToS + sToE];
|
|
|
- edge.geometry.lineDistancesNeedUpdate = true;
|
|
|
-
|
|
|
- edge.material.dashSize = 10;
|
|
|
- edge.material.gapSize = 10;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- { // area label
|
|
|
- let label = measure.areaLabel;
|
|
|
- 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);
|
|
|
- }
|
|
|
-
|
|
|
- { // radius 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);
|
|
|
- }
|
|
|
+ } */
|
|
|
|
|
|
{ // edges
|
|
|
- const materials = [
|
|
|
+ /* const materials = [
|
|
|
measure.circleRadiusLine.material,
|
|
|
...measure.edges.map( (e) => e.material),
|
|
|
- measure.heightEdge.material,
|
|
|
+ //measure.heightEdge.material,
|
|
|
+ measure.guideLine.material,
|
|
|
measure.circleLine.material,
|
|
|
- ];
|
|
|
+ ];
|
|
|
|
|
|
for(const material of materials){
|
|
|
material.resolution.set(clientWidth, clientHeight);
|
|
|
- }
|
|
|
+ }*/
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if(!this.showLabels){
|
|
|
|
|
|
const labels = [
|
|
|
- ...measure.sphereLabels,
|
|
|
- ...measure.edgeLabels,
|
|
|
- ...measure.angleLabels,
|
|
|
- ...measure.coordinateLabels,
|
|
|
- measure.heightLabel,
|
|
|
- measure.areaLabel,
|
|
|
+ ...measure.sphereLabels,
|
|
|
+ ...measure.angleLabels,
|
|
|
measure.circleRadiusLabel,
|
|
|
];
|
|
|
|
|
@@ -422,6 +407,8 @@ export class MeasuringTool extends EventDispatcher{
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ this.updateLabelZIndex([{labels:subLabels},{labels:mainLabels}])
|
|
|
+
|
|
|
}
|
|
|
|
|
|
render(o={}){
|