|
@@ -223,17 +223,21 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
viewer.addTimeMark('pick','start')
|
|
|
|
|
|
let getVal = (a, b) => a != void 0 ? a : b;
|
|
|
-
|
|
|
-
|
|
|
- let r0 = this.nodeMaxLevel > 0 ? this.maxLevel/this.nodeMaxLevel : 0.5
|
|
|
- let pickWindowSize_ = THREE.Math.clamp( Math.round((1.1-r0)*80), 5, 100)
|
|
|
- let pickWindowSize = getVal(params.pickWindowSize, pickWindowSize_ ); /* 65 */ //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关//突然发现pickWindowSize在一百以内的变化对pick费时影响甚微,1和100差1毫秒不到,但400时会多4毫秒
|
|
|
-
|
|
|
+ let pickWindowSize = params.pickWindowSize; //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关//突然发现pickWindowSize在一百以内的变化对pick费时影响甚微,1和100差1毫秒不到,但400时会多4毫秒
|
|
|
+ if(pickWindowSize == void 0){
|
|
|
+ if(Potree.settings.displayMode == 'showPanos'){
|
|
|
+ pickWindowSize = 50
|
|
|
+ }else{
|
|
|
+ let r0 = this.nodeMaxLevel > 0 ? this.maxLevel/this.nodeMaxLevel : 0.5
|
|
|
+ pickWindowSize = THREE.Math.clamp( Math.round((1.1-r0)*80), 15, 100)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if(camera.type == 'OrthographicCamera'){
|
|
|
var cameraDir = new THREE.Vector3(0,0,-1).applyQuaternion(camera.quaternion)
|
|
|
pickWindowSize *= 4 //pointsize比较大时截取太小会没多少点可以选
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
let pickOutsideClipRegion = getVal(params.pickOutsideClipRegion, false);
|
|
|
|
|
@@ -246,7 +250,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
if(window.testScreen){
|
|
|
let dataUrl = Potree.Utils.renderTargetToDataUrl(pickState.renderTarget, width, height, renderer)
|
|
|
|
|
|
- Common.downloadFile(dataUrl, 'screenshot.jpg') //为什么图片上不是只有pickWindowSize区域有颜色??
|
|
|
+ Potree.Common.downloadFile(dataUrl, 'screenshot.png')
|
|
|
window.testScreen = 0
|
|
|
}
|
|
|
}
|
|
@@ -296,7 +300,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
pickMaterial.uniforms.uFilterGPSTimeClipRange.value = this.material.uniforms.uFilterGPSTimeClipRange.value;
|
|
|
pickMaterial.uniforms.uFilterPointSourceIDClipRange.value = this.material.uniforms.uFilterPointSourceIDClipRange.value;
|
|
|
|
|
|
- pickMaterial.activeAttributeName = "indices";
|
|
|
+ pickMaterial.activeAttributeName = "indices";//indices
|
|
|
|
|
|
pickMaterial.size = pointSize;
|
|
|
pickMaterial.uniforms.minSize.value = this.material.uniforms.minSize.value;
|
|
@@ -314,14 +318,18 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
pickState.renderTarget.setSize(width, height); //仅绘制屏幕大小的,而不乘以devicePixelRatio
|
|
|
|
|
|
let pixelPos = new THREE.Vector2(params.x, params.y);
|
|
|
-
|
|
|
+
|
|
|
let gl = renderer.getContext();
|
|
|
+ //规定渲染范围,只渲染一小块
|
|
|
+ /* renderer.setScissorTest(true);
|
|
|
gl.enable(gl.SCISSOR_TEST);
|
|
|
- gl.scissor( //规定渲染范围,只渲染一小块
|
|
|
+ gl.scissor(
|
|
|
parseInt(pixelPos.x - (pickWindowSize - 1) / 2),
|
|
|
parseInt(pixelPos.y - (pickWindowSize - 1) / 2),
|
|
|
parseInt(pickWindowSize), parseInt(pickWindowSize));
|
|
|
-
|
|
|
+ */ //---这段没用
|
|
|
+ pickState.renderTarget.scissor.set(parseInt(pixelPos.x - (pickWindowSize - 1) / 2), parseInt(pixelPos.y - (pickWindowSize - 1) / 2),parseInt(pickWindowSize), parseInt(pickWindowSize));
|
|
|
+ pickState.renderTarget.scissorTest = true
|
|
|
|
|
|
renderer.state.buffers.depth.setTest(pickMaterial.depthTest);
|
|
|
renderer.state.buffers.depth.setMask(pickMaterial.depthWrite);
|
|
@@ -331,14 +339,14 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
{ // RENDER
|
|
|
renderer.setRenderTarget(pickState.renderTarget);
|
|
|
gl.clearColor(0, 0, 0, 0);
|
|
|
- renderer.clear(true, true, true);
|
|
|
+ //renderer.clear(true, true, true);
|
|
|
|
|
|
let tmp = this.material;
|
|
|
this.material = pickMaterial;
|
|
|
|
|
|
pRenderer.renderOctree(this, nodes, camera, pickState.renderTarget);
|
|
|
screenshot();
|
|
|
-
|
|
|
+
|
|
|
|
|
|
this.material = tmp;
|
|
|
}
|
|
@@ -355,12 +363,16 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
//w<pickWindowSize会报错
|
|
|
|
|
|
gl.readPixels(x, y, pickWindowSize, pickWindowSize, gl.RGBA, gl.UNSIGNED_BYTE, buffer); //这句花费最多时间 pc:2-4, 即使只有1*1像素
|
|
|
-
|
|
|
+ renderer.clear(true, true, true); //绘制完就clear否则download的图会有上次的轨迹
|
|
|
+
|
|
|
+
|
|
|
renderer.setRenderTarget(null);
|
|
|
renderer.state.reset();
|
|
|
renderer.setScissorTest(false);
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
let pixels = buffer;
|
|
|
let ibuffer = new Uint32Array(buffer.buffer); //四个数整合成一个
|
|
|
|
|
@@ -407,7 +419,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(!params.all){
|
|
|
+ if(!params.all && Potree.settings.pickFrontPointRatio){
|
|
|
if(hits2.length){//add
|
|
|
hits = hits2
|
|
|
}
|
|
@@ -462,7 +474,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
point[attributeName] = position;
|
|
|
|
|
|
//add
|
|
|
- if(!params.all){
|
|
|
+ if(!params.all && Potree.settings.pickFrontPointRatio ){
|
|
|
if(camera.type == 'OrthographicCamera'){
|
|
|
let vec = new THREE.Vector3().subVectors(position, camera.position)
|
|
|
hit.disSquare = vec.projectOnVector( cameraDir ).length(); //只考虑到相机的垂直距离
|
|
@@ -509,16 +521,21 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
|
|
|
if(hits.length === 0){
|
|
|
return null;
|
|
|
}else{
|
|
|
+
|
|
|
+ if(Potree.settings.pickFrontPointRatio == 0){//如果不需要选偏离镜头近的,就要离中心近的即可
|
|
|
+ //console.log(hits[0], hits2, pixelPos)
|
|
|
+ return hits[0].point;
|
|
|
+ }
|
|
|
+
|
|
|
//为了防止透过点云缝隙,选到后排的点云,将选取的位置离相机的距离考虑进去。倾向选择离相机近、且离鼠标位置近的点。(否则按照原方案只选离鼠标位置最近的,可能从高楼不小心走到下层,导航选点也是)
|
|
|
let sorted1 = hits.sort( (a, b) => a.disSquare - b.disSquare ).slice();
|
|
|
|
|
|
let nearest = sorted1[0] //return nearest.point; //直接用最近点 在点云稀疏时不太跟手,如地面上,最近点往往在鼠标下方
|
|
|
- let r = 10
|
|
|
-
|
|
|
+
|
|
|
hits.forEach( hit=>{
|
|
|
let disDiff = hit.disSquare - nearest.disSquare //和最近点的偏差
|
|
|
hit.disDiff = disDiff
|
|
|
- hit.score = -hit.distanceToCenter - disDiff * r
|
|
|
+ hit.score = -hit.distanceToCenter - disDiff * Potree.settings.pickFrontPointRatio
|
|
|
})
|
|
|
|
|
|
let sorted2 = hits.sort( (a, b) => b.score - a.score );
|