SelectionBase
射线选择基础类,继承自EventManager,提供3D场景中射线选择的基础功能。支持鼠标和触摸交互,用于拾取和选择3D模型中的对象。
类定义
class SelectionBase extends EventManager构造函数
constructor(sceneManager)
创建射线选择基础类实例,初始化射线选择器,设置相机管理器、渲染DOM、射线投射器等核心组件。
参数:
sceneManager{SceneManager} - 场景管理器,提供相机管理和渲染DOM。详见 SceneManager
示例:
// 创建射线选择器
const selectionBase = new SelectionBase(sceneManager);
// 设置要检测的模型
selectionBase.setModel(model);
// 启用选择功能
selectionBase.enabled = true;属性
cameraManager
相机管理器实例,提供相机控制功能。
类型: {CameraManager} - 详见 CameraManager
只读: true
renderDom
渲染DOM元素,用于计算鼠标坐标。
类型: {HTMLElement}
只读: true
model
被检测的模型类,用于射线检测的3D模型。
类型: {Model|undefined} - 详见 Model
rayCaster
射线投射器,用于执行射线检测。
类型: {Raycaster}
只读: true
enabled
选择功能总开关,控制是否启用射线检测。
类型: {boolean}
默认值: true
rayVisible
射线是否检测物体的可见性,控制是否只检测可见对象。
类型: {boolean}
默认值: true
isMobile
是否为移动端设备,自动检测设备类型。
类型: {boolean}
只读: true
currentMouse
当前鼠标按键,用于控制当前的鼠标按键功能。
类型: {number}
默认值: 0 (LEFT)
camera
相机实例,用于射线检测的相机。
类型: {Camera}
只读: true
isPointerMoved
指针是否移动,检查指针是否从按下位置移动到抬起位置。
类型: {boolean}
只读: true
mouse
鼠标按键代码枚举。
类型: {Object}
只读: true
属性:
LEFT{number} - 左键 (0)MIDDLE{number} - 中键 (1)RIGHT{number} - 右键 (2)
selectionMeshMaterial
拾取3D图元的材质,用于显示选择效果。
类型: {MeshBasicMaterial}
只读: true
selectionLineMaterial
拾取2D图元(线)的材质,用于显示选择效果。
类型: {LineBasicMaterial}
只读: true
方法
setModel(model)
设置要检测的模型,指定射线检测的目标3D模型。
参数:
model{Model} - 要检测的3D模型。详见 Model
示例:
// 设置要检测的模型
selectionBase.setModel(model);setFilter(func)
设置过滤函数,用于自定义筛选射线检测结果。
参数:
func{Function} - 过滤函数,用于筛选射线检测结果
示例:
// 设置过滤函数,只保留距离最近的5个结果
selectionBase.setFilter((intersections) => {
return intersections.slice(0, 5);
});
// 设置过滤函数,过滤掉特定类型的对象
selectionBase.setFilter((intersections) => {
return intersections.filter(intersection =>
intersection.object.userData.type !== 'hidden'
);
});pickObject(pointerEvent)
拾取对象,根据指针事件执行射线检测并返回拾取结果。
参数:
pointerEvent{PointerEvent} - 指针事件对象
返回值:
- {IntersectionResult|null} 拾取结果,如果没有拾取到对象则返回null
示例:
// 拾取对象
const result = selectionBase.pickObject(pointerEvent);
if (result) {
console.log('拾取到对象:', result.object);
console.log('拾取点:', result.point);
console.log('距离:', result.distance);
}screenToStandard(pointerEvent)
转换屏幕坐标到标准坐标系,将屏幕坐标转换为标准化的设备坐标。
参数:
pointerEvent{PointerEvent} - 指针事件对象
返回值:
- {Vector2} 标准化的设备坐标
示例:
// 转换屏幕坐标到标准坐标系
const standardPos = selectionBase.screenToStandard(pointerEvent);
console.log('标准坐标:', standardPos.x, standardPos.y);pointerDownEvent(pointerEvent)
指针按下事件处理,记录指针按下的位置。
参数:
pointerEvent{PointerEvent} - 指针事件对象
返回值:
- {Vector2} 指针按下的位置
示例:
// 重写指针按下事件
pointerDownEvent(pointerEvent){
const startPos = super.pointerDownEvent(pointerEvent);
// 添加自定义逻辑
return startPos;
}pointerUpEvent(pointerEvent)
指针抬起事件处理,记录指针抬起的位置。
参数:
pointerEvent{PointerEvent} - 指针事件对象
返回值:
- {Vector2} 指针抬起的位置
示例:
// 重写指针抬起事件
pointerUpEvent(pointerEvent){
const endPos = super.pointerUpEvent(pointerEvent);
// 添加自定义逻辑
return endPos;
}updateRay(pointerEvent)
更新射线位置,根据指针事件更新射线投射器的位置。
参数:
pointerEvent{PointerEvent} - 指针事件对象
示例:
// 更新射线位置
selectionBase.updateRay(pointerEvent);
// 射线已更新,可以进行检测
const result = selectionBase.pickObject(pointerEvent);getInstance(uniqueId, material, hasEdgeLine)
根据唯一标识符获取对象实例,用于获取3D对象的实例。
参数:
uniqueId{string} - 对象的唯一标识符material{Material} - 材质hasEdgeLine{boolean} - 是否显示边缘线
返回值:
- {Object3D} 对象实例
示例:
// 获取对象实例
const instance = selectionBase.getInstance(uniqueId, material, true);removeFilter()
移除过滤函数,移除当前设置的过滤函数,恢复默认的射线检测行为。
示例:
// 移除过滤函数
selectionBase.removeFilter();pointerMoveEvent(pointerEvent)
指针移动事件处理,处理指针移动事件。这是一个抽象方法,子类应该重写此方法以实现具体的移动逻辑。
参数:
pointerEvent{PointerEvent} - 指针事件对象
示例:
// 重写指针移动事件
pointerMoveEvent(pointerEvent){
// 实现自定义的移动逻辑
console.log('指针移动:', pointerEvent.clientX, pointerEvent.clientY);
}filter(array)
过滤射线选择结果,对射线检测结果进行过滤处理。如果设置了自定义过滤函数,则使用自定义函数;否则直接返回原始结果数组。
参数:
array{Array<IntersectionResult>} - 射线检测结果数组
返回值:
- {Array<IntersectionResult>} 过滤后的结果数组
示例:
// 过滤结果
const filteredResults = selectionBase.filter(intersections);
console.log('过滤后的结果数量:', filteredResults.length);getInstanceByIntersectionResult(intersectionResult, hasEdgeLine)
根据射线检测结果获取实例对象,根据射线检测结果获取对应的3D对象实例,支持材质覆盖和边缘线显示。
参数:
intersectionResult{IntersectionResult} - 射线检测的结果hasEdgeLine{Boolean} [可选] - 是否需要边缘线,可选参数,默认为true
返回值:
- {Object3D|null} 3D对象实例,如果无法获取则返回null
示例:
// 获取实例对象
const instance = selectionBase.getInstanceByIntersectionResult(result);
if (instance) {
console.log('获取到实例:', instance);
}
// 获取带边缘线的实例
const instanceWithEdges = selectionBase.getInstanceByIntersectionResult(result, true);getInstanceHierarchyByIntersectionResult(intersectionResult, hasEdgeLine)
根据射线检测结果获取实例的层级结构,根据射线检测结果获取对应的3D对象实例,并包含该实例的完整层级结构信息。
参数:
intersectionResult{IntersectionResult} - 射线检测的结果hasEdgeLine{Boolean} [可选] - 是否需要边缘线,可选参数,默认为true
返回值:
- {Object|null} 包含实例和层级结构的对象,如果无法获取则返回null
示例:
// 获取实例的层级结构
const hierarchy = selectionBase.getInstanceHierarchyByIntersectionResult(result);
if (hierarchy) {
console.log('实例节点:', hierarchy.node);
console.log('包围球:', hierarchy.boundingSphere);
}getUniqueIdByIntersectionResult(intersectionResult)
根据射线检测结果获取唯一标识符,根据射线检测结果获取对应对象的唯一标识符。
参数:
intersectionResult{IntersectionResult} - 射线检测的结果
返回值:
- {string} 对象的唯一标识符
示例:
// 获取唯一标识符
const uniqueId = selectionBase.getUniqueIdByIntersectionResult(result);
console.log('对象唯一ID:', uniqueId);getNodeIndexByIntersectionResult(intersectionResult)
根据射线检测结果获取节点索引,根据射线检测结果获取对应对象的节点索引信息,包含层级结构数据。
参数:
intersectionResult{IntersectionResult} - 射线检测的结果
返回值:
- {Object} 节点索引信息,包含子节点、数据库ID、Revit ID等
示例:
// 获取节点索引
const nodeIndex = selectionBase.getNodeIndexByIntersectionResult(result);
if (nodeIndex) {
console.log('节点名称:', nodeIndex.name);
console.log('数据库ID:', nodeIndex.databaseId);
console.log('子节点数量:', nodeIndex.children.length);
}getCurrentSelected()
获取当前选中的对象,返回最近一次射线检测选中的对象结果。
返回值:
- {IntersectionResult|null} 当前选中的对象,如果没有选中则返回null
示例:
// 获取当前选中的对象
const selected = selectionBase.getCurrentSelected();
if (selected) {
console.log('当前选中对象:', selected.object);
console.log('选中点:', selected.point);
}setCurrentSelected(result)
设置当前选中的对象,用于内部管理选中状态。
参数:
result{IntersectionResult|null} - 要设置为当前选中的对象结果
示例:
// 设置当前选中的对象
selectionBase.setCurrentSelected(intersectionResult);类型定义
IntersectionResult
射线检测的结果
类型:
属性:
distance{number} - 射线投射原点和相交部分之间的距离point{Vector3} - 相交部分的点(世界坐标)face{Face} - 相交的面faceIndex{number} - 相交的面的索引object{Object3D} - 相交的物体uv{Vector2} - 相交部分的点的UV坐标uv1{Vector2} - 相交点处的第二组UV坐标normal{Vector3} - 交点处的内插法向量instanceId{number} - 当射线与InstancedMesh相交时,相交实例的索引号
使用场景
对象拾取
- 鼠标点击选择3D对象
- 触摸设备上的对象选择
- 射线检测和碰撞检测
交互控制
- 鼠标和触摸事件处理
- 坐标转换和标准化
- 指针移动检测
模型管理
- 设置检测目标模型
- 获取对象实例和节点信息
- 自定义过滤和筛选
可视化反馈
- 选择效果的可视化
- 材质和边缘线显示
- 交互状态的视觉反馈
相关链接
- Selection - 选择类
- SceneManager - 场景管理器
- Model - 模型基类