第03章-核心架构与技术栈
第三章:核心架构与技术栈
3.1 架构概述
Astral3D采用现代化的前端架构设计,将整个系统分为SDK核心层和编辑器应用层两大部分。这种分层设计既保证了核心功能的复用性,又提供了灵活的扩展能力。
3.1.1 整体架构图
┌────────────────────────────────────────────────────────────────────┐
│ Astral3D Editor │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 用户界面层 (UI Layer) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │ │
│ │ │ 工具栏 │ │ 侧边栏 │ │ 属性面板│ │ 视口区域│ │ 状态栏 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 状态管理层 (State Layer) │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Pinia Store │ │ 场景状态管理 │ │ 编辑器配置 │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────────┤
│ @astral3d/engine (SDK) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 核心层 (Core Layer) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Viewer │ │ Scene │ │ Camera │ │ │
│ │ │ 主视图 │ │ 场景管理 │ │ 相机控制 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 功能层 (Feature Layer) │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌──────┐ │ │
│ │ │Loader │ │Effect │ │Particle│ │Weather│ │Control│ │Plugin│ │ │
│ │ │加载器 │ │特效 │ │粒子系统│ │天气 │ │控制器 │ │插件 │ │ │
│ │ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └──────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 事件系统 (Signals System) │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ Signal | Dispatch | Subscribe | Unsubscribe │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 渲染引擎 (Render Engine) │ │
│ │ ┌───────────────────┐ ┌───────────────────────────────────┐ │ │
│ │ │ Three.js │ │ Cesium │ │ │
│ │ │ 3D场景渲染 │ │ 地理信息渲染 │ │ │
│ │ └───────────────────┘ └───────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
3.1.2 分层职责
| 层级 | 职责 | 主要技术 |
|---|---|---|
| 用户界面层 | 提供用户交互界面 | Vue3 + Naive UI |
| 状态管理层 | 管理应用状态和数据流 | Pinia |
| 核心层 | 3D场景的核心管理 | TypeScript |
| 功能层 | 各种功能模块实现 | TypeScript + Three.js |
| 事件系统 | 模块间通信和解耦 | Signals |
| 渲染引擎 | 底层3D渲染 | Three.js + Cesium |
3.2 Viewer核心类
Viewer是Astral3D SDK的核心入口类,负责管理整个3D渲染管线和场景。
3.2.1 Viewer类结构
// Viewer类的核心结构
class Viewer {
// 核心组件
scene: THREE.Scene; // Three.js场景
camera: THREE.Camera; // 相机
renderer: THREE.WebGLRenderer; // 渲染器
controls: OrbitControls; // 轨道控制器
// 功能模块
loader: Loader; // 模型加载器
particleSystem: ParticleSystem; // 粒子系统
weatherSystem: WeatherSystem; // 天气系统
effectManager: EffectManager; // 特效管理器
// 配置选项
options: IViewerSettings; // 配置选项
// 生命周期
constructor(options: IViewerSettings);
init(): void;
render(): void;
dispose(): void;
}
3.2.2 初始化配置
// IViewerSettings 配置接口
interface IViewerSettings {
// 容器配置
container: HTMLElement | string; // 渲染容器
width?: number; // 宽度
height?: number; // 高度
// 渲染器配置
antialias?: boolean; // 抗锯齿
alpha?: boolean; // 透明背景
shadowMap?: boolean; // 阴影映射
toneMapping?: THREE.ToneMapping; // 色调映射
outputEncoding?: THREE.TextureEncoding; // 输出编码
// 相机配置
cameraType?: 'perspective' | 'orthographic'; // 相机类型
fov?: number; // 视场角
near?: number; // 近裁面
far?: number; // 远裁面
// 控制器配置
enableControls?: boolean; // 启用控制器
controlsType?: string; // 控制器类型
// 功能开关
enableStats?: boolean; // 性能统计
enableHelper?: boolean; // 辅助器
enableSelection?: boolean; // 选择功能
}
3.2.3 基本使用示例
import { Viewer } from '@astral3d/engine';
// 创建Viewer实例
const viewer = new Viewer({
container: '#viewer-container',
antialias: true,
alpha: false,
shadowMap: true,
cameraType: 'perspective',
fov: 60,
enableControls: true,
enableStats: true
});
// 初始化
viewer.init();
// 加载模型
viewer.loader.load('model.gltf').then(model => {
viewer.scene.add(model);
});
// 开始渲染循环
viewer.render();
3.2.4 生命周期管理
// Viewer生命周期钩子
viewer.on('beforeInit', () => {
console.log('初始化前');
});
viewer.on('afterInit', () => {
console.log('初始化后');
});
viewer.on('beforeRender', (delta) => {
console.log('渲染前', delta);
});
viewer.on('afterRender', (delta) => {
console.log('渲染后', delta);
});
viewer.on('dispose', () => {
console.log('销毁');
});
3.3 事件系统(Signals)
Astral3D采用Signals事件系统进行模块间的解耦通信,这是一种轻量级的发布-订阅模式实现。
3.3.1 Signals基本概念
// Signal类基本结构
class Signal<T = any> {
// 添加监听器
add(callback: (data: T) => void): void;
// 添加一次性监听器
addOnce(callback: (data: T) => void): void;
// 移除监听器
remove(callback: (data: T) => void): void;
// 派发事件
dispatch(data: T): void;
// 移除所有监听器
removeAll(): void;
}
3.3.2 内置信号类型
Astral3D提供了60+种内置信号类型,覆盖了编辑器的各个方面:
// 场景相关信号
type SceneSignals = {
objectAdded: Signal<THREE.Object3D>; // 对象添加
objectRemoved: Signal<THREE.Object3D>; // 对象移除
objectSelected: Signal<THREE.Object3D>; // 对象选中
objectDeselected: Signal<THREE.Object3D>; // 对象取消选中
sceneChanged: Signal<void>; // 场景变化
};
// 渲染相关信号
type RenderSignals = {
beforeRender: Signal<number>; // 渲染前
afterRender: Signal<number>; // 渲染后
resized: Signal<{width: number, height: number}>; // 尺寸变化
};
// 加载相关信号
type LoaderSignals = {
loadStart: Signal<string>; // 加载开始
loadProgress: Signal<{url: string, loaded: number, total: number}>; // 加载进度
loadComplete: Signal<THREE.Object3D>; // 加载完成
loadError: Signal<Error>; // 加载错误
};
// 交互相关信号
type InteractionSignals = {
click: Signal<THREE.Intersection>; // 点击
doubleClick: Signal<THREE.Intersection>; // 双击
hover: Signal<THREE.Intersection>; // 悬停
drag: Signal<THREE.Object3D>; // 拖拽
};
3.3.3 使用示例
import { useAddSignal, useDispatchSignal, useRemoveSignal } from '@astral3d/engine';
// 添加信号监听
const handleObjectAdded = (obj: THREE.Object3D) => {
console.log('新对象添加:', obj.name);
};
useAddSignal('objectAdded', handleObjectAdded);
// 派发信号
const newObject = new THREE.Mesh();
useDispatchSignal('objectAdded', newObject);
// 移除信号监听
useRemoveSignal('objectAdded', handleObjectAdded);
3.3.4 自定义信号
import { Signal } from '@astral3d/engine';
// 创建自定义信号
const myCustomSignal = new Signal<{ message: string; data: any }>();
// 添加监听
myCustomSignal.add((payload) => {
console.log('收到消息:', payload.message);
console.log('数据:', payload.data);
});
// 派发信号
myCustomSignal.dispatch({
message: '自定义事件触发',
data: { timestamp: Date.now() }
});
3.4 模型加载系统
3.4.1 Loader类结构
class Loader {
// 支持的格式
static supportedFormats: string[];
// 加载器注册表
private loaders: Map<string, THREE.Loader>;
// 加载模型
load(url: string, options?: LoadOptions): Promise<THREE.Object3D>;
// 批量加载
loadMultiple(urls: string[]): Promise<THREE.Object3D[]>;
// 解析数据
parse(data: ArrayBuffer, format: string): Promise<THREE.Object3D>;
// 注册自定义加载器
registerLoader(format: string, loader: THREE.Loader): void;
}
3.4.2 支持的格式
// 通用3D格式
const commonFormats = [
'gltf', 'glb', // glTF格式(推荐)
'obj', // OBJ格式
'fbx', // FBX格式
'stl', // STL格式(3D打印常用)
'ply', // PLY格式
'dae', // Collada格式
'3ds', // 3DS Max格式
'mtl', // OBJ材质文件
];
// BIM格式
const bimFormats = [
'rvt', // Revit格式
'ifc', // IFC格式
'rfa', // Revit族文件
];
// CAD格式
const cadFormats = [
'dwg', // AutoCAD格式
'dxf', // DXF格式
'stp', 'step', // STEP格式
'iges', 'igs', // IGES格式
];
// 其他格式
const otherFormats = [
'pcd', // 点云数据
'xyz', // 点云数据
'3dm', // Rhino格式
'brep', // B-Rep格式
];
3.4.3 加载选项
interface LoadOptions {
// 基础选项
onProgress?: (progress: number) => void; // 进度回调
onError?: (error: Error) => void; // 错误回调
// 变换选项
position?: THREE.Vector3; // 位置
rotation?: THREE.Euler; // 旋转
scale?: THREE.Vector3; // 缩放
// 材质选项
castShadow?: boolean; // 投射阴影
receiveShadow?: boolean; // 接收阴影
// 优化选项
simplify?: boolean; // 简化网格
simplifyRatio?: number; // 简化比例
// BIM选项
lightweight?: boolean; // 轻量化处理
mergeGeometries?: boolean; // 合并几何体
}
3.4.4 加载示例
import { Loader } from '@astral3d/engine';
const loader = new Loader();
// 基本加载
loader.load('models/scene.gltf')
.then(model => {
viewer.scene.add(model);
})
.catch(error => {
console.error('加载失败:', error);
});
// 带进度的加载
loader.load('models/building.ifc', {
onProgress: (progress) => {
console.log(`加载进度: ${(progress * 100).toFixed(1)}%`);
},
lightweight: true,
mergeGeometries: true
}).then(model => {
model.position.set(0, 0, 0);
viewer.scene.add(model);
});
// 批量加载
const urls = [
'models/tree.glb',
'models/car.glb',
'models/building.glb'
];
loader.loadMultiple(urls).then(models => {
models.forEach((model, index) => {
model.position.x = index * 10;
viewer.scene.add(model);
});
});
3.5 场景管理
3.5.1 场景树结构
// 场景节点结构
interface SceneNode {
uuid: string; // 唯一标识
name: string; // 节点名称
type: string; // 节点类型
visible: boolean; // 是否可见
locked: boolean; // 是否锁定
children: SceneNode[]; // 子节点
parent?: SceneNode; // 父节点
object3D: THREE.Object3D; // Three.js对象引用
}
// 场景管理器
class SceneManager {
// 场景树
sceneTree: SceneNode;
// 添加对象
add(object: THREE.Object3D, parent?: SceneNode): SceneNode;
// 移除对象
remove(node: SceneNode): void;
// 查找对象
findByUUID(uuid: string): SceneNode | null;
findByName(name: string): SceneNode[];
// 遍历
traverse(callback: (node: SceneNode) => void): void;
// 序列化/反序列化
serialize(): object;
deserialize(data: object): void;
}
3.5.2 对象操作
import { SceneManager } from '@astral3d/engine';
const sceneManager = new SceneManager(viewer.scene);
// 添加对象
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x00ff00 })
);
const node = sceneManager.add(mesh);
// 修改属性
node.name = '绿色方块';
node.visible = true;
node.locked = false;
// 移动到其他父节点
const parentNode = sceneManager.findByName('建筑')[0];
if (parentNode) {
sceneManager.move(node, parentNode);
}
// 复制对象
const clonedNode = sceneManager.clone(node);
clonedNode.object3D.position.x += 5;
// 删除对象
sceneManager.remove(node);
3.5.3 分组管理
// 创建分组
const group = sceneManager.createGroup('车辆组');
// 将对象添加到分组
const car1 = sceneManager.findByName('汽车1')[0];
const car2 = sceneManager.findByName('汽车2')[0];
sceneManager.addToGroup(group, [car1, car2]);
// 解散分组
sceneManager.dissolveGroup(group);
// 设置分组属性(会应用到所有子对象)
sceneManager.setGroupProperty(group, 'visible', false);
3.6 相机系统
3.6.1 相机类型
// 透视相机
interface PerspectiveCameraConfig {
type: 'perspective';
fov: number; // 视场角 (默认: 60)
near: number; // 近裁面 (默认: 0.1)
far: number; // 远裁面 (默认: 10000)
position: THREE.Vector3;
target: THREE.Vector3;
}
// 正交相机
interface OrthographicCameraConfig {
type: 'orthographic';
left: number;
right: number;
top: number;
bottom: number;
near: number;
far: number;
position: THREE.Vector3;
target: THREE.Vector3;
}
3.6.2 相机控制器
class CameraController {
// 当前相机
camera: THREE.Camera;
// 控制器类型
controlsType: 'orbit' | 'firstPerson' | 'fly';
// 轨道控制
setOrbitControls(target: THREE.Vector3): void;
// 第一人称控制
setFirstPersonControls(): void;
// 飞行控制
setFlyControls(): void;
// 相机动画
flyTo(position: THREE.Vector3, target: THREE.Vector3, duration?: number): Promise<void>;
// 聚焦到对象
focusOn(object: THREE.Object3D, padding?: number): void;
// 重置视图
reset(): void;
// 保存/恢复视图
saveView(name: string): void;
restoreView(name: string): void;
}
3.6.3 相机使用示例
import { CameraController } from '@astral3d/engine';
const cameraController = viewer.cameraController;
// 设置轨道控制
cameraController.setOrbitControls(new THREE.Vector3(0, 0, 0));
// 飞行到指定位置
await cameraController.flyTo(
new THREE.Vector3(100, 50, 100), // 相机位置
new THREE.Vector3(0, 0, 0), // 观察目标
2000 // 动画时长(ms)
);
// 聚焦到选中对象
const selectedObject = viewer.selection.getSelected()[0];
if (selectedObject) {
cameraController.focusOn(selectedObject, 1.5);
}
// 保存当前视图
cameraController.saveView('正面视图');
// 切换到预设视图
cameraController.setView('top'); // 顶视图
cameraController.setView('front'); // 前视图
cameraController.setView('right'); // 右视图
cameraController.setView('iso'); // 等轴测视图
3.7 材质系统
3.7.1 内置材质类型
// 材质类型枚举
enum MaterialType {
Basic = 'basic', // 基础材质
Standard = 'standard', // 标准PBR材质
Physical = 'physical', // 物理材质
Lambert = 'lambert', // Lambert材质
Phong = 'phong', // Phong材质
Toon = 'toon', // 卡通材质
Matcap = 'matcap', // Matcap材质
}
// 材质配置
interface MaterialConfig {
type: MaterialType;
color?: number | string;
map?: string; // 贴图路径
normalMap?: string; // 法线贴图
roughnessMap?: string; // 粗糙度贴图
metalnessMap?: string; // 金属度贴图
aoMap?: string; // 环境光遮蔽贴图
emissiveMap?: string; // 发光贴图
roughness?: number; // 粗糙度
metalness?: number; // 金属度
opacity?: number; // 透明度
transparent?: boolean; // 是否透明
side?: THREE.Side; // 渲染面
}
3.7.2 材质管理器
class MaterialManager {
// 创建材质
create(config: MaterialConfig): THREE.Material;
// 从库中获取材质
getFromLibrary(id: string): THREE.Material;
// 添加到材质库
addToLibrary(id: string, material: THREE.Material): void;
// 应用材质到对象
apply(object: THREE.Object3D, material: THREE.Material): void;
// 替换材质
replace(object: THREE.Object3D, newMaterial: THREE.Material): void;
// 序列化材质
serialize(material: THREE.Material): object;
deserialize(data: object): THREE.Material;
}
3.7.3 材质使用示例
import { MaterialManager } from '@astral3d/engine';
const materialManager = new MaterialManager();
// 创建PBR材质
const pbrMaterial = materialManager.create({
type: MaterialType.Physical,
color: 0x1a1a1a,
roughness: 0.3,
metalness: 0.8,
normalMap: 'textures/metal_normal.jpg'
});
// 应用到对象
const mesh = viewer.scene.getObjectByName('零件');
materialManager.apply(mesh, pbrMaterial);
// 保存到材质库
materialManager.addToLibrary('dark-metal', pbrMaterial);
// 从库中复用
const sameMaterial = materialManager.getFromLibrary('dark-metal');
3.8 灯光系统
3.8.1 灯光类型
// 灯光类型
enum LightType {
Ambient = 'ambient', // 环境光
Directional = 'directional', // 平行光
Point = 'point', // 点光源
Spot = 'spot', // 聚光灯
Hemisphere = 'hemisphere', // 半球光
RectArea = 'rectArea', // 矩形区域光
}
// 灯光配置
interface LightConfig {
type: LightType;
color?: number;
intensity?: number;
position?: THREE.Vector3;
target?: THREE.Vector3; // 平行光/聚光灯目标
distance?: number; // 点光源/聚光灯距离
decay?: number; // 衰减
angle?: number; // 聚光灯角度
penumbra?: number; // 聚光灯半影
castShadow?: boolean; // 投射阴影
shadowMapSize?: number; // 阴影贴图尺寸
}
3.8.2 灯光管理
class LightManager {
// 添加灯光
add(config: LightConfig): THREE.Light;
// 移除灯光
remove(light: THREE.Light): void;
// 获取所有灯光
getAll(): THREE.Light[];
// 设置环境
setEnvironment(hdriPath: string): Promise<void>;
// 预设灯光方案
applyPreset(preset: 'studio' | 'outdoor' | 'night'): void;
}
3.8.3 灯光使用示例
import { LightManager, LightType } from '@astral3d/engine';
const lightManager = new LightManager(viewer.scene);
// 添加环境光
lightManager.add({
type: LightType.Ambient,
color: 0x404040,
intensity: 0.5
});
// 添加主灯光(平行光)
lightManager.add({
type: LightType.Directional,
color: 0xffffff,
intensity: 1,
position: new THREE.Vector3(50, 50, 50),
castShadow: true,
shadowMapSize: 2048
});
// 添加补光
lightManager.add({
type: LightType.Point,
color: 0xffffcc,
intensity: 0.3,
position: new THREE.Vector3(-20, 10, 20),
distance: 100,
decay: 2
});
// 应用预设
lightManager.applyPreset('studio');
// 设置HDRI环境
await lightManager.setEnvironment('hdri/studio.hdr');
3.9 选择系统
3.9.1 选择管理器
class SelectionManager {
// 当前选中对象
selected: THREE.Object3D[];
// 选择模式
mode: 'object' | 'face' | 'edge' | 'vertex';
// 选择对象
select(object: THREE.Object3D, additive?: boolean): void;
// 取消选择
deselect(object?: THREE.Object3D): void;
// 全选
selectAll(): void;
// 反选
invertSelection(): void;
// 按条件选择
selectBy(predicate: (obj: THREE.Object3D) => boolean): void;
// 获取选中对象
getSelected(): THREE.Object3D[];
// 选择事件
onSelect: Signal<THREE.Object3D[]>;
onDeselect: Signal<THREE.Object3D[]>;
}
3.9.2 选择使用示例
import { SelectionManager } from '@astral3d/engine';
const selection = viewer.selection;
// 监听选择变化
selection.onSelect.add((objects) => {
console.log('选中了:', objects.map(o => o.name));
});
// 选择单个对象
const mesh = viewer.scene.getObjectByName('立方体');
selection.select(mesh);
// 添加选择(不取消之前的选择)
const anotherMesh = viewer.scene.getObjectByName('球体');
selection.select(anotherMesh, true);
// 按条件选择(选择所有网格对象)
selection.selectBy(obj => obj instanceof THREE.Mesh);
// 取消全部选择
selection.deselect();
3.10 本章小结
本章深入介绍了Astral3D的核心架构和技术栈,主要内容包括:
- 整体架构:分层设计,SDK核心层与编辑器应用层分离
- Viewer核心类:3D渲染管线的核心入口和配置选项
- 事件系统:Signals发布-订阅模式,60+内置事件类型
- 模型加载:30+格式支持,BIM/CAD格式轻量化处理
- 场景管理:场景树结构,对象操作和分组管理
- 相机系统:多类型相机,轨道/第一人称/飞行控制
- 材质系统:PBR材质支持,材质库管理
- 灯光系统:多类型灯光,预设方案和HDRI环境
- 选择系统:多模式选择,条件选择
通过本章的学习,读者应该理解了Astral3D的内部工作原理和核心组件的使用方法,为后续的功能使用和二次开发打下基础。
下一章预告:第四章将详细介绍场景编辑与模型管理功能,包括场景创建、对象变换、层级管理、导入导出等实用功能的使用方法。

浙公网安备 33010602011771号