xzw 1 month ago
parent
commit
fcf920bebf
1 changed files with 117 additions and 1 deletions
  1. 117 1
      src/ExtendPointCloudOctree.js

+ 117 - 1
src/ExtendPointCloudOctree.js

@@ -3,7 +3,7 @@ import * as THREE from "../libs/three.js/build/three.module.js";
  
 import {ExtendPointCloudMaterial} from "./materials/ExtendPointCloudMaterial.js";
  
-import {PointCloudOctree} from './PointCloudOctree.js'
+import {PointCloudOctree,  PointCloudOctreeNode} from './PointCloudOctree.js'
 import {PointSizeType } from "./defines.js";
 import math from './custom/utils/math.js'
 
@@ -784,5 +784,121 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
     }
     
     
+    deepestNodeAt(position){ //改
+		let startTime = performance.now()
+		const toObjectSpace = this.matrixWorld.clone().invert();
+
+		const objPos = position.clone().applyMatrix4(toObjectSpace);
+
+		let current = this.root;
+		while(true){
+
+			let containingChild = null;
+            
+			for(const child of current.children){ 
+				if(child !== undefined && !containingChild){//
+					if(child.getBoundingBox().containsPoint(objPos)){
+						containingChild = child;
+					}
+				}
+			}
+
+			if(containingChild !== null && containingChild instanceof PointCloudOctreeNode){//如果是PointCloudOctreeGeometryNode可能geometry还没加载
+				current = containingChild;
+			}else{
+				break;
+			}
+		}
+
+		const deepest = current;
+        console.log('deepestNodeAt',  performance.now() - startTime  )
+		return deepest;
+	}
+    
+    
+    getNearestPoint(position, onlySearchLeaves){//add 输入一个世界坐标,查找该点云中和它最近的点
+        let startTime = performance.now()
+        let inNode = this.deepestNodeAt(position)
+        
+        const toObjectSpace = this.matrixWorld.clone().invert();
+		const objPos = position.clone().applyMatrix4(toObjectSpace);    //该值记录一下,以后不改两点云相对位置直接用      
+        let firstNode = inNode || this.root  //第一个搜寻点的node为所在node,初步找出最近点
+        
+        let nearest = firstNode.searchNearestPoint(position, {point:null, disSquare:Infinity})
+        nearest.inNode = inNode?.name
+        
+        //重新回到根结点向下找邻近node 
+        let traverse = (current)=>{
+            if(current == firstNode || current.getBoundingBox().distanceToPoint(objPos) < nearest.dis){ 
+                onlySearchLeaves || current.searchNearestPoint(position, nearest) //搜寻当前节点
+                let children = current.children.filter(e=>e && e instanceof PointCloudOctreeNode)
+                if(children.length){
+                    for(const child of children){ 
+                        if(child != firstNode){  
+                            traverse(child)
+                        } 
+                    }
+                }else{
+                    onlySearchLeaves && current.searchNearestPoint(position, nearest) //搜寻叶子节点
+                }
+            }
+            
+        }
+        traverse(this.root) 
+        console.log('getNearestPoint',  nearest,   performance.now() - startTime  )
+    }
+    
+    
+    
     
 }
+
+
+ 
+PointCloudOctreeNode.prototype.searchNearestPoint = function(pos, nearest = {point:null,disSquare:Infinity}){
+    let positions = this.geometryNode.geometry.attributes.position
+    let tempPos = new THREE.Vector3
+    
+    const toObjectSpace = this.sceneNode.matrixWorld.clone().invert();
+    const objPos = pos.clone().applyMatrix4(toObjectSpace); 
+    let startTime = performance.now(), finded
+   
+    for(let i=0;i<positions.count;i++){
+        tempPos.fromArray(positions.array.slice(i*3,i*3+3))
+        
+        //let diff = new THREE.Vector3().subVectors(tempPos,objPos)
+        if(nearest.dis != void 0 && !Potree.math.closeTo(tempPos,objPos, nearest.dis)){//先筛除在xyz方向上的距离
+            continue;
+        }
+        let d = tempPos.distanceToSquared(objPos)
+        if(d<nearest.disSquare){
+            finded = true, nearest.point = tempPos, nearest.disSquare=d
+            nearest.dis == void 0 && (nearest.dis = Math.sqrt(nearest.disSquare)) //update
+        }
+    }
+    if(finded){
+        nearest.dis = Math.sqrt(nearest.disSquare) //update
+        nearest.point = tempPos.applyMatrix4(this.sceneNode.matrixWorld) //global pos
+        nearest.nodeName = this.name
+    }
+    console.log('node searchNearestPoint',  this.name,  performance.now() - startTime )
+    //onlySearchLeaves开启后减少了10倍时间,但小概率不准,误差:    点云上的坐标 0.05m , 非点云上的0.1m
+    return nearest 
+}
+
+/* 
+
+
+搜索方A pointLoaded
+    let tempPos = new THREE.Vector3
+    let newAttri = ...
+    for(let i=0;i<positions.count;i++){
+        tempPos.set(positions[i*3], positions[i*3+1],positions[i*3+2]) 
+        tempPos.applyMatrix4(this.matrixWorld)
+        cloudB.getNearestPoint(tempPos)
+    }
+
+
+
+
+ */