# ViewLayer (视图层)

- **Summary**: ViewLayer 是 Model 的组成部分，负责管理具体的 3D 资源（如 Mesh 或 PointCloud），支持独立的渲染配置和可见性控制。
- **Schema**: 继承自 `Tile3D`，由 `Model` 统一管理。
- **Concepts**: Layer Fallback, 3DTile Integration, Parameter Inheritance.
- **Examples**: 可见性控制、参数配置、事件监听。

## Schema

> **Definition**: [ViewLayer](../../five/model/view-layer.d.ts), [ViewLayerInit](../../five/model/view-layer.d.ts)

ViewLayer 是一个具体的渲染图层，它对应一个具体的 3D 数据源（通常是一个 `.gltf` / `.b3dm` / `.pnts` 等 Tileset 入口）。

```typescript
// 简化定义
interface ViewLayer extends Tile3D {
  /** 图层名称 (如 'mesh', 'point_cloud') */
  name: string;
  /** 图层类型 */
  type: "point_cloud" | "mesh" | "gaussian_splatting";
  /** 独立的参数配置对象 */
  parameter: Parameter;
  /** 是否可见 */
  visible: boolean;
  /** 对应的 Tileset URL */
  tilesetUrl: string;
}
```

## Concepts

### 1. ViewLayer vs Work.Model

`ViewLayer` 的生成逻辑严格依赖于 `Work` 数据中的定义，但也包含了向后兼容的 Fallback 机制。

#### 数据来源 (Data Source)

1.  **优先使用 `work.model.layers`**:
    这是标准的定义方式。`work.model.layers` 是一个数组，每个元素显式定义了一个 Layer 的 `name`, `type`, `tileset` (URL) 等信息。
    Five 会遍历这个数组，为每一项创建一个 `ViewLayer` 实例。

2.  **Fallback to `work.model.file`**:
    如果 `work.model.layers` 中没有定义 `mesh` 类型的层，且 `work.model.file` 存在（旧版数据字段），Five 会自动创建一个 **虚拟的 Mesh Layer**。
    *   **Name**: 默认为 `model` (或其他内部标识)。
    *   **Type**: `mesh`。
    *   **URL**: 指向 `work.model.file`。
    *   **UpAxis**: 根据文件后缀自动推断 (如 `.obj` 可能需要特殊处理)。

> **总结**: `ViewLayer` 是 `work.model` 数据的运行时表现。`layers` 字段提供了精细的控制，而 `file` 字段提供了旧数据的兼容支持。

### 2. ViewLayer vs 3DTile

`ViewLayer` 本质上是一个 **3DTile** 加载器实例（继承自 `Tile3D`）。

*   **加载机制**: 每个 ViewLayer 独立维护一个 3DTiles 的遍历器 (Traverser) 和调度器 (Scheduler)。这意味着 Mesh 层、PointCloud 层和 GaussianSplatting 层是独立加载、独立计算 LOD (Level of Detail) 的。
*   **空间变换**: ViewLayer 负责处理数据的坐标系转换 (如 ECEF 转 ENU，Y-Up 转 Z-Up)，确保不同格式的数据在 Five 场景中正确对齐。

### 3. ViewLayer, Model, ModelScene & Parameter

这是 Five 渲染架构的核心层级关系，`Parameter` 在其中起到了“胶水”的作用。

#### 层级关系 (Hierarchy)

```mermaid
graph TD
  Scene[ModelScene] -->|包含| Model[Model]
  Model -->|包含| LayerA[ViewLayer (Mesh)]
  Model -->|包含| LayerB[ViewLayer (PointCloud)]
```

#### Parameter 的作用 (Inheritance)

`Parameter` 系统贯穿了上述三层，实现了**“配置继承与覆盖”**。

1.  **ModelScene (全局配置)**:
    *   持有 `five.modelScene.parameter`。
    *   定义了场景级的默认值（如：默认显存上限 `512MB`）。
2.  **Model (模型级配置)**:
    *   持有 `model.parameter`。
    *   可以覆盖全局配置（如：特定模型需要 `1024MB` 显存）。
3.  **ViewLayer (图层级配置)**:
    *   持有 `viewLayer.parameter`。
    *   **最具体的控制点**。它在计算最终值时，会依次继承 `Model` 和 `ModelScene` 的配置。

**示例场景**:
*   如果你想让**整个场景**变暗，设置 `modelScene.parameter.set('opacity', 0.5)`。
*   如果你只想让**点云层**变暗，保留模型层亮度，设置 `pointCloudLayer.parameter.set('opacity', 0.5)`。

### 4. Visibility Control (可见性控制)

默认情况下，Five **不会**加载所有图层，而是根据优先级**仅加载一个**图层，以节省资源。
优先级顺序：`mesh` > `point_cloud` > 其他类型。

**可见性与内存管理 (Visibility & Memory)**:
*   **显示 (Show)**: 当图层设置为可见 (`visible = true`) 时，Five 会开始加载该图层的资源。
*   **隐藏 (Hide)**: 当图层设置为隐藏 (`visible = false`) 时，Five 会**释放该图层占用的所有内存资源** (Geometry, Texture 等)。这意味着“隐藏”等同于“卸载”。

Five 提供了两种层级的可见性控制方式：

1.  **初始化配置 (Load Options)**:
    在 `five.load` 时，通过 `model["3d-tiles"].showLayers` 参数指定初始显示的图层。
    *   `true` (默认): 使用上述的默认优先级策略（仅加载一个最佳图层）。
    *   `string[]`: 仅显示名称在数组中的图层（例如 `['mesh', 'point_cloud']` 可以强制同时显示模型和点云）。

2.  **运行时控制 (Runtime Control)**:
    加载完成后，可以直接修改 `viewLayer.visible` 属性来切换可见性。

## Configuration

ViewLayer 的配置主要通过其 `parameter` 属性进行。

### Common Configuration

| Parameter | Type | Description |
| :--- | :--- | :--- |
| `visible` | `boolean` | 控制图层的可见性 (也可直接修改 `viewLayer.visible`)。 |
| `opacity` | `number` | 图层透明度 (0.0 - 1.0)。 |
| `pointSize` | `number` | (仅点云) 点的大小。 |

> 更多配置项请参考 [Parameter](./parameter.md) 和 [3DTile Params](./3dtile.md)。

## Examples

### 1. 访问 ViewLayer

```typescript
// 获取当前模型
const model = five.model;

// 遍历所有图层
model.viewLayers.forEach(layer => {
  console.log(`Layer Name: ${layer.name}, Type: ${layer.type}`);
});

// 查找特定的图层 (例如点云层)
const pointCloudLayer = model.viewLayers.find(layer => layer.type === 'point_cloud');
```

### 2. 独立控制图层可见性

```typescript
// 方式 A: 运行时控制
const meshLayer = five.model.viewLayers.find(layer => layer.type === 'mesh');

if (meshLayer) {
  // 隐藏模型层，只看点云
  meshLayer.visible = false;
  // 或者通过 parameter 设置
  // meshLayer.parameter.set('visible', false);
}

// 方式 B: 加载时控制 (初始化时仅显示 mesh)
five.load(work, {
  model: {
    "3d-tiles": {
      showLayers: ['mesh'] // 仅显示 mesh 层，隐藏 point_cloud 等其他层
    }
  }
});
```

### 3. 修改特定图层的渲染参数

```typescript
const pointCloudLayer = five.model.viewLayers.find(layer => layer.type === 'point_cloud');

if (pointCloudLayer) {
  // 仅修改点云层的点大小，不影响其他模型
  pointCloudLayer.parameter.set('pointSize', 2.0);

  // 仅修改点云层的最大显存占用
  pointCloudLayer.parameter.set('maxMemoryUsage', 128);
}
```

## Related

*   [Model](./model.md): ViewLayer 的父级容器。
*   [Work](./work.md): 定义 ViewLayer 数据结构的数据源。
*   [Parameter](./parameter.md): 控制 ViewLayer 渲染表现的配置系统。
*   [3DTile](./3dtile.md): ViewLayer 的底层技术实现。

---

```yaml
tags: [图层, 视图层, 可见性, 显隐控制, 图层切换, 分层渲染, viewlayer, model, 3dtile, parameter, layer, mesh, point-cloud, gaussian-splatting]
```
