Chili3D视图组件:3D渲染容器与交互处理
概述
Chili3D作为一款基于浏览器的3D CAD(计算机辅助设计)应用,其核心视图组件承担着3D模型渲染、用户交互处理、相机控制等关键功能。本文将深入解析Chili3D的视图组件架构,重点介绍ThreeView、ThreeViewHandler和CameraController三大核心模块的实现原理和使用方法。
视图组件架构
Chili3D的视图组件采用分层架构设计,各模块职责明确:
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采用双渲染器架构:
- WebGLRenderer:负责3D几何体的渲染
- 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采用了多种渲染优化策略:
- 按需渲染:通过
_needsUpdate标志控制渲染频率 - 图层管理:根据视图模式启用/禁用不同的渲染图层
- 资源复用:重复使用几何体和材质资源
内存管理
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应用开发的优秀参考实现。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



