Skip to content

SelectionBase

射线选择基础类,继承自EventManager,提供3D场景中射线选择的基础功能。支持鼠标和触摸交互,用于拾取和选择3D模型中的对象。

类定义

javascript
class SelectionBase extends EventManager

构造函数

constructor(sceneManager)

创建射线选择基础类实例,初始化射线选择器,设置相机管理器、渲染DOM、射线投射器等核心组件。

参数:

  • sceneManager {SceneManager} - 场景管理器,提供相机管理和渲染DOM。详见 SceneManager

示例:

javascript
// 创建射线选择器
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

示例:

javascript
// 设置要检测的模型
selectionBase.setModel(model);

setFilter(func)

设置过滤函数,用于自定义筛选射线检测结果。

参数:

  • func {Function} - 过滤函数,用于筛选射线检测结果

示例:

javascript
// 设置过滤函数,只保留距离最近的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

示例:

javascript
// 拾取对象
const result = selectionBase.pickObject(pointerEvent);
if (result) {
    console.log('拾取到对象:', result.object);
    console.log('拾取点:', result.point);
    console.log('距离:', result.distance);
}

screenToStandard(pointerEvent)

转换屏幕坐标到标准坐标系,将屏幕坐标转换为标准化的设备坐标。

参数:

  • pointerEvent {PointerEvent} - 指针事件对象

返回值:

  • {Vector2} 标准化的设备坐标

示例:

javascript
// 转换屏幕坐标到标准坐标系
const standardPos = selectionBase.screenToStandard(pointerEvent);
console.log('标准坐标:', standardPos.x, standardPos.y);

pointerDownEvent(pointerEvent)

指针按下事件处理,记录指针按下的位置。

参数:

  • pointerEvent {PointerEvent} - 指针事件对象

返回值:

  • {Vector2} 指针按下的位置

示例:

javascript
// 重写指针按下事件
pointerDownEvent(pointerEvent){
    const startPos = super.pointerDownEvent(pointerEvent);
    // 添加自定义逻辑
    return startPos;
}

pointerUpEvent(pointerEvent)

指针抬起事件处理,记录指针抬起的位置。

参数:

  • pointerEvent {PointerEvent} - 指针事件对象

返回值:

  • {Vector2} 指针抬起的位置

示例:

javascript
// 重写指针抬起事件
pointerUpEvent(pointerEvent){
    const endPos = super.pointerUpEvent(pointerEvent);
    // 添加自定义逻辑
    return endPos;
}

updateRay(pointerEvent)

更新射线位置,根据指针事件更新射线投射器的位置。

参数:

  • pointerEvent {PointerEvent} - 指针事件对象

示例:

javascript
// 更新射线位置
selectionBase.updateRay(pointerEvent);

// 射线已更新,可以进行检测
const result = selectionBase.pickObject(pointerEvent);

getInstance(uniqueId, material, hasEdgeLine)

根据唯一标识符获取对象实例,用于获取3D对象的实例。

参数:

  • uniqueId {string} - 对象的唯一标识符
  • material {Material} - 材质
  • hasEdgeLine {boolean} - 是否显示边缘线

返回值:

  • {Object3D} 对象实例

示例:

javascript
// 获取对象实例
const instance = selectionBase.getInstance(uniqueId, material, true);

removeFilter()

移除过滤函数,移除当前设置的过滤函数,恢复默认的射线检测行为。

示例:

javascript
// 移除过滤函数
selectionBase.removeFilter();

pointerMoveEvent(pointerEvent)

指针移动事件处理,处理指针移动事件。这是一个抽象方法,子类应该重写此方法以实现具体的移动逻辑。

参数:

  • pointerEvent {PointerEvent} - 指针事件对象

示例:

javascript
// 重写指针移动事件
pointerMoveEvent(pointerEvent){
    // 实现自定义的移动逻辑
    console.log('指针移动:', pointerEvent.clientX, pointerEvent.clientY);
}

filter(array)

过滤射线选择结果,对射线检测结果进行过滤处理。如果设置了自定义过滤函数,则使用自定义函数;否则直接返回原始结果数组。

参数:

  • array {Array<IntersectionResult>} - 射线检测结果数组

返回值:

  • {Array<IntersectionResult>} 过滤后的结果数组

示例:

javascript
// 过滤结果
const filteredResults = selectionBase.filter(intersections);
console.log('过滤后的结果数量:', filteredResults.length);

getInstanceByIntersectionResult(intersectionResult, hasEdgeLine)

根据射线检测结果获取实例对象,根据射线检测结果获取对应的3D对象实例,支持材质覆盖和边缘线显示。

参数:

  • intersectionResult {IntersectionResult} - 射线检测的结果
  • hasEdgeLine {Boolean} [可选] - 是否需要边缘线,可选参数,默认为true

返回值:

  • {Object3D|null} 3D对象实例,如果无法获取则返回null

示例:

javascript
// 获取实例对象
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

示例:

javascript
// 获取实例的层级结构
const hierarchy = selectionBase.getInstanceHierarchyByIntersectionResult(result);
if (hierarchy) {
    console.log('实例节点:', hierarchy.node);
    console.log('包围球:', hierarchy.boundingSphere);
}

getUniqueIdByIntersectionResult(intersectionResult)

根据射线检测结果获取唯一标识符,根据射线检测结果获取对应对象的唯一标识符。

参数:

  • intersectionResult {IntersectionResult} - 射线检测的结果

返回值:

  • {string} 对象的唯一标识符

示例:

javascript
// 获取唯一标识符
const uniqueId = selectionBase.getUniqueIdByIntersectionResult(result);
console.log('对象唯一ID:', uniqueId);

getNodeIndexByIntersectionResult(intersectionResult)

根据射线检测结果获取节点索引,根据射线检测结果获取对应对象的节点索引信息,包含层级结构数据。

参数:

  • intersectionResult {IntersectionResult} - 射线检测的结果

返回值:

  • {Object} 节点索引信息,包含子节点、数据库ID、Revit ID等

示例:

javascript
// 获取节点索引
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

示例:

javascript
// 获取当前选中的对象
const selected = selectionBase.getCurrentSelected();
if (selected) {
    console.log('当前选中对象:', selected.object);
    console.log('选中点:', selected.point);
}

setCurrentSelected(result)

设置当前选中的对象,用于内部管理选中状态。

参数:

  • result {IntersectionResult|null} - 要设置为当前选中的对象结果

示例:

javascript
// 设置当前选中的对象
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对象
  • 触摸设备上的对象选择
  • 射线检测和碰撞检测

交互控制

  • 鼠标和触摸事件处理
  • 坐标转换和标准化
  • 指针移动检测

模型管理

  • 设置检测目标模型
  • 获取对象实例和节点信息
  • 自定义过滤和筛选

可视化反馈

  • 选择效果的可视化
  • 材质和边缘线显示
  • 交互状态的视觉反馈

相关链接

文档内容为北京逆维悦动科技有限公司版权所有,禁止未授权转载