You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.0 KiB
100 lines
3.0 KiB
我想用 JS 开发一个浏览器 3D 场景下的物品查询工具 ItemFindManager, 借助 octree 算法结构来实现
|
|
物品数超过 100,000 个, 基于物品的 OBB 包围盒进行各种查询操作, 并可能存在频繁且少量的点位更新/删除操作
|
|
查询方法包括:
|
|
1.根据位置,获取命中到物品OBB包围盒的所有物品ID集合
|
|
2.根据位置和距离,获取给定范围内,OBB包围盒碰到的所有物品ID集合
|
|
3.给定一个矩形区域 (x1,z1)->(x2,z2),获取物品OBB包围盒与矩形有交集的所有物品ID集合
|
|
|
|
不要创建 Mesh 不要创建 Group
|
|
物品不用管渲染(不用去到 Scene / 不用管纹理和材质),但期望他最大程度的使用 BufferGeometry 用显卡来运算
|
|
OBB 不用刻意追求,可以先用 AABB 进行检索,再通过 OBB 进行进一步筛选达到目的
|
|
|
|
物品的结构是
|
|
|
|
export interface ItemMetrix {
|
|
/**
|
|
* 物体ID, 唯一标识
|
|
*/
|
|
id: string
|
|
|
|
/**
|
|
* 变换矩阵, 3x3矩阵, X轴正增长向右, Y轴正增长向屏幕外, Z轴正增长向下。右手坐标系
|
|
*/
|
|
tf: [
|
|
/**
|
|
* 平移向量 position, 三维坐标
|
|
* [0]=x轴向右, [1]=y轴高度向屏幕外, [2]=z轴向下
|
|
*/
|
|
[number, number, number],
|
|
|
|
/**
|
|
* 旋转向量 rotation, 单位为度
|
|
* [0]=X轴逆向旋转角度, [1]=Y轴逆向旋转角度, [2]=Z轴逆向旋转角度
|
|
* 对应 three.js 应进行"角度"转"弧度"的换算
|
|
*/
|
|
[number, number, number],
|
|
|
|
/**
|
|
* 缩放向量 scale, 三维缩放比例, [0]=X宽度, [1]=Y高度, [2]=Z长度
|
|
*/
|
|
[number, number, number],
|
|
]
|
|
}
|
|
|
|
参考:
|
|
|
|
import * as THREE from 'three'
|
|
|
|
/**
|
|
* 物品 OBB 包围盒管理器
|
|
* 物品数超过 100,000 个, 基于物品的 OBB 包围盒进行各种查询操作
|
|
* 并可能存在频繁且少量的点位更新/删除操作
|
|
*/
|
|
export default class ItemObbManager {
|
|
/**
|
|
* 添加或更新物品 (根据ID)
|
|
*/
|
|
addOrUpdate(...items: ItemMetrix[]): void {
|
|
}
|
|
|
|
/**
|
|
* 根据 ID 移除物品
|
|
*/
|
|
remove(...ids: string[]): void {
|
|
}
|
|
|
|
/**
|
|
* 根据位置,获取命中到物品OBB包围盒的所有物品ID集合
|
|
* @param x 位置X坐标
|
|
* @param z 位置Z坐标
|
|
*/
|
|
getItemsByPosition(x: number, z: number): string[] {
|
|
return []
|
|
}
|
|
|
|
/**
|
|
* 根据位置和距离,获取给定范围内,OBB包围盒碰到的所有物品ID集合
|
|
* @param x 位置X坐标
|
|
* @param z 位置Z坐标
|
|
* @param distance 范围距离
|
|
*/
|
|
getItemsByDistance(x: number, z: number, distance: number): string[] {
|
|
// Implementation for getting items by distance
|
|
return []
|
|
}
|
|
|
|
/**
|
|
* 给定一个矩形区域 (x1,z1)->(x2,z2),获取物品OBB包围盒与矩形有交集的所有物品ID集合
|
|
*/
|
|
getItemsByRect(x1: number, z1: number, x2: number, z2: number): string[] {
|
|
return []
|
|
}
|
|
|
|
/**
|
|
* 给定一个矩形区域 (x1,z1)->(x2,z2),获取物品OBB包围盒完全在矩形内的物品ID集合
|
|
*/
|
|
getItemsByRectInclude(): string[] {
|
|
return []
|
|
}
|
|
}
|
|
|
|
|