Chili3D视图组件:3D渲染容器与交互处理

Chili3D视图组件:3D渲染容器与交互处理

【免费下载链接】chili3d A 3D CAD application on your browser 【免费下载链接】chili3d 项目地址: https://gitcode.com/GitHub_Trending/ch/chili3d

概述

Chili3D作为一款基于浏览器的3D CAD(计算机辅助设计)应用,其核心视图组件承担着3D模型渲染、用户交互处理、相机控制等关键功能。本文将深入解析Chili3D的视图组件架构,重点介绍ThreeView、ThreeViewHandler和CameraController三大核心模块的实现原理和使用方法。

视图组件架构

Chili3D的视图组件采用分层架构设计,各模块职责明确:

mermaid

ThreeView:核心渲染容器

初始化与配置

ThreeView是Chili3D的核心视图类,继承自Observable并实现IView接口,负责管理整个3D渲染环境:

export class ThreeView extends Observable implements IView {
    private _dom?: HTMLElement;
    private readonly _scene: Scene;
    private readonly _renderer: WebGLRenderer;
    private readonly _cssRenderer: CSS2DRenderer;
    private readonly _workplane: Plane;
    readonly cameraController: CameraController;
}

渲染管线配置

ThreeView采用双渲染器架构:

  1. WebGLRenderer:负责3D几何体的渲染
  2. CSS2DRenderer:处理HTML文本标注和UI元素
protected initRenderer() {
    let renderer = new WebGLRenderer({
        antialias: false,
        alpha: true,
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    return renderer;
}

private initCssRenderer() {
    let renderer = new CSS2DRenderer();
    return renderer;
}

视图模式管理

Chili3D支持多种视图渲染模式:

模式类型描述适用场景
solidAndWireframe实体+线框默认编辑模式
solid仅实体查看最终效果
wireframe仅线框检查模型结构
get mode(): ViewMode {
    return this.getPrivateValue("mode", ViewMode.solidAndWireframe);
}
set mode(value: ViewMode) {
    this.setProperty("mode", value, () => {
        this.cameraController.setCameraLayer(this.camera, this.mode);
    });
}

交互检测系统

射线检测机制

ThreeView实现了精确的几何体检测系统,支持多种检测模式:

detectVisual(x: number, y: number, nodeFilter?: INodeFilter): IVisualObject[] {
    let visual: IVisualObject[] = [];
    let detecteds = this.findIntersectedNodes(x, y);
    // 过滤和处理检测结果
    return visual;
}

选择框检测

支持矩形区域选择,用于批量操作:

detectVisualRect(
    mx1: number, my1: number,
    mx2: number, my2: number,
    nodeFilter?: INodeFilter
): IVisualObject[] {
    const selectionBox = this.initSelectionBox(mx1, my1, mx2, my2);
    let visual = new Set<IVisualObject>();
    // 处理选择框内的对象
    return Array.from(visual);
}

ThreeViewHandler:事件处理中枢

鼠标事件处理

ThreeViewHandler实现了完整的鼠标交互逻辑,支持中键旋转、滚轮缩放等操作:

mouseWheel(view: IView, event: WheelEvent): void {
    const currentNav3D = Config.instance.navigation3DIndex;
    if (currentNav3D === Navigation3D.Nav3DType.Solidworks) {
        view.cameraController.zoom(event.offsetX, event.offsetY, -event.deltaY);
    } else {
        view.cameraController.zoom(event.offsetX, event.offsetY, event.deltaY);
    }
    view.update();
}

多指触控支持

支持移动端的多指触控操作,包括旋转、平移和缩放:

private handleTouchMove(view: IView, event: PointerEvent) {
    if (this.currentPointerEventMap.size === 3) {
        // 三指旋转
        const offset = this.getPrimaryTouchOffset();
        if (offset) view.cameraController.rotate(offset.dx, offset.dy);
    } else if (this.currentPointerEventMap.size === 2) {
        // 双指平移和缩放
        const last = this.getCenterAndDistance(this.lastPointerEventMap);
        const current = this.getCenterAndDistance(this.currentPointerEventMap);
        // 判断操作类型并执行
    }
}

CameraController:相机控制系统

相机类型管理

支持多种相机模式:

get cameraType(): CameraType {
    return this.getPrivateValue("cameraType", "perspective");
}
set cameraType(value: CameraType) {
    if (this.setProperty("cameraType", value)) {
        this._camera = this.createCamera(this._camera.near, this._camera.far);
        this.updateCameraPosionTarget();
    }
}

视角控制操作

CameraController实现了完整的相机控制功能:

平移操作
pan(dx: number, dy: number): void {
    const ratio = PAN_SPEED_FACTOR * this._target.distanceTo(this._position);
    const direction = this._target.clone().sub(this._position).normalize();
    const hor = direction.clone().cross(this.camera.up).normalize();
    const ver = hor.clone().cross(direction).normalize();
    const vector = hor.multiplyScalar(-dx).add(ver.multiplyScalar(dy)).multiplyScalar(ratio);
    this._target.add(vector);
    this._position.add(vector);
    this.updateCameraPosionTarget();
}
旋转操作
rotate(dx: number, dy: number): void {
    const newRotation = this.getRotation(dx * ROTATE_SPEED_FACTOR, dy * ROTATE_SPEED_FACTOR);
    this._camera.up.copy(new Vector3(0, 1, 0).applyQuaternion(newRotation));
    // 计算新的相机位置
    this.updateCameraPosionTarget();
}
智能缩放
zoom(x: number, y: number, delta: number): void {
    const vector = this._target.clone().sub(this._position);
    let zoomFactor = this.caclueZoomFactor(x, y, vector);
    const scale = delta > 0 ? zoomFactor : -zoomFactor;
    // 基于鼠标位置的智能缩放
    this.updateCameraPosionTarget();
}

自动视图适配

支持一键适配视图到选中内容或整个场景:

fitContent(): void {
    const context = this.view.document.visual.context as ThreeVisualContext;
    const sphere = this.getBoundingSphere(context);
    // 计算最佳视角距离
    const distance = Math.abs(sphere.radius / Math.sin(fieldOfView * DEG_TO_RAD));
    this.updateCameraPosionTarget();
}

坐标转换系统

ThreeView提供了完整的坐标转换功能,支持屏幕坐标到世界坐标的相互转换:

屏幕到世界坐标

screenToWorld(mx: number, my: number): XYZ {
    let vec = this.mouseToWorld(mx, my);
    return ThreeHelper.toXYZ(vec);
}

世界到屏幕坐标

worldToScreen(point: XYZ): XY {
    let cx = this.width / 2;
    let cy = this.height / 2;
    let vec = new Vector3(point.x, point.y, point.z).project(this.camera);
    return new XY(Math.round(cx * vec.x + cx), Math.round(-cy * vec.y + cy));
}

射线生成

rayAt(mx: number, my: number): Ray {
    const { x, y } = this.screenToCameraRect(mx, my);
    const origin = new Vector3();
    const direction = new Vector3(x, y, 0.5);
    // 根据不同相机类型计算射线
    return new Ray(ThreeHelper.toXYZ(origin), ThreeHelper.toXYZ(direction));
}

性能优化策略

渲染优化

ThreeView采用了多种渲染优化策略:

  1. 按需渲染:通过_needsUpdate标志控制渲染频率
  2. 图层管理:根据视图模式启用/禁用不同的渲染图层
  3. 资源复用:重复使用几何体和材质资源

内存管理

override disposeInternal(): void {
    super.disposeInternal();
    this._resizeObserver.disconnect();
    // 释放所有相关资源
}

扩展与定制

自定义视图模式

开发者可以通过继承ThreeView类来实现自定义的视图模式:

class CustomView extends ThreeView {
    // 重写检测方法
    detectVisual(x: number, y: number): IVisualObject[] {
        // 自定义检测逻辑
    }
    
    // 添加新的渲染效果
    customRenderEffect(): void {
        // 特殊渲染处理
    }
}

事件处理扩展

可以通过实现IEventHandler接口来添加自定义的交互行为:

class CustomEventHandler implements IEventHandler {
    mouseWheel(view: IView, event: WheelEvent): void {
        // 自定义滚轮行为
    }
    
    pointerMove(view: IView, event: PointerEvent): void {
        // 自定义指针移动行为
    }
}

最佳实践

视图初始化流程

// 1. 创建视图实例
const view = new ThreeView(document, "Main View", workplane, highlighter, content);

// 2. 设置DOM容器
view.setDom(containerElement);

// 3. 配置事件处理器
const handler = new ThreeViewHandler();
document.addEventListener("wheel", (e) => handler.mouseWheel(view, e));

相机控制示例

// 切换到正交视图
view.cameraController.cameraType = "orthographic";

// 设置特定视角
view.cameraController.lookAt(
    { x: 1000, y: 1000, z: 1000 },
    { x: 0, y: 0, z: 0 },
    { x: 0, y: 0, z: 1 }
);

// 适配视图到内容
view.cameraController.fitContent();

总结

Chili3D的视图组件提供了一个强大而灵活的3D渲染和交互解决方案。通过ThreeView、ThreeViewHandler和CameraController的协同工作,实现了高性能的3D模型显示、精确的交互检测和流畅的相机控制。开发者可以基于这套架构快速构建专业的3D CAD应用,或者根据特定需求进行扩展和定制。

这套视图系统的设计充分考虑了Web环境的特点,在保证功能完整性的同时,也注重性能和用户体验,是Web端3D应用开发的优秀参考实现。

【免费下载链接】chili3d A 3D CAD application on your browser 【免费下载链接】chili3d 项目地址: https://gitcode.com/GitHub_Trending/ch/chili3d

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值