第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的核心架构和技术栈,主要内容包括:

  1. 整体架构:分层设计,SDK核心层与编辑器应用层分离
  2. Viewer核心类:3D渲染管线的核心入口和配置选项
  3. 事件系统:Signals发布-订阅模式,60+内置事件类型
  4. 模型加载:30+格式支持,BIM/CAD格式轻量化处理
  5. 场景管理:场景树结构,对象操作和分组管理
  6. 相机系统:多类型相机,轨道/第一人称/飞行控制
  7. 材质系统:PBR材质支持,材质库管理
  8. 灯光系统:多类型灯光,预设方案和HDRI环境
  9. 选择系统:多模式选择,条件选择

通过本章的学习,读者应该理解了Astral3D的内部工作原理和核心组件的使用方法,为后续的功能使用和二次开发打下基础。


下一章预告:第四章将详细介绍场景编辑与模型管理功能,包括场景创建、对象变换、层级管理、导入导出等实用功能的使用方法。


posted @ 2026-01-10 13:17  我才是银古  阅读(9)  评论(0)    收藏  举报