|
|
@@ -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)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ */
|