# Web3D 场景 SDK 使用说明

本 SDK 用于在 Web 场景中快速完成三维展示与交互，核心能力包括：相机修改、灯光调参、环境贴图切换、按配置渲染热点、热点驱动抛出事件、模型热加载/热销毁/热替换，以及按部件切换材质。

---

## 功能概览
- 相机控制：支持位置/目标点/FOV/远近裁剪的即时更新，带缓动动画。
- 灯光调参：主光、辅光、环境光强度、颜色、方向、阴影开关与软硬度。
- 环境贴图：HDRI 切换、曝光度、旋转（偏航/俯仰）、模糊度。
- 热点系统：基于配置渲染热点 UI，可按 click/hover/focus 抛出事件。
- 模型热更新：按 ID 进行加载、销毁、替换，支持队列并行与完成回调。
- 材质切换：按部件或分组应用/还原材质，支持预设表与回滚。
- 事件总线：统一事件接口，便于业务侧订阅热点/相机/模型状态。

---

## 快速开始
```bash
npm install your-web3d-sdk
```

```ts
import { createViewer } from 'your-web3d-sdk'

const sdk = await createViewer({
  container: '#viewer',
  assetsBase: '/assets',
  background: '#0f172a',
})

// 加载初始场景或模型
await sdk.model.load({ id: 'scene', url: '/models/showroom.glb' })
```

### 基础生命周期
1. 初始化 viewer：`createViewer({ container })`
2. 加载模型或场景：`sdk.model.load(...)`
3. 设置环境贴图/灯光：`sdk.environment.setHDRI(...)`、`sdk.lights.update(...)`
4. 渲染热点：`sdk.hotspot.render(config.hotspots)`
5. 订阅事件：`sdk.on('hotspot:click', handler)`
6. 在业务侧按需调用相机/材质/模型热更新 API

---

## 相机控制
```ts
// 直接设置视角
sdk.camera.set({
  position: [2.5, 1.6, 3.2],
  target: [0, 0.8, 0],
  fov: 45,
  near: 0.1,
  far: 200,
})

// 平滑过渡到指定视角
sdk.camera.animateTo(
  { position: [1.2, 1, 2.4], target: [0, 0.8, 0], fov: 50 },
  { duration: 0.8, easing: 'easeOutCubic' }
)
```

---

## 灯光调参
```ts
// 更新主方向光
sdk.lights.update('key', {
  intensity: 1.5,
  color: '#ffffff',
  direction: [0.3, -1, 0.25],
  castShadow: true,
})

// 环境光/辅光
sdk.lights.update('fill', { intensity: 0.6, color: '#dfe8ff' })
sdk.lights.update('ambient', { intensity: 0.25 })
```

---

## 环境贴图
```ts
await sdk.environment.setHDRI('/envs/showroom_2k.hdr', {
  exposure: 1.1,
  rotation: [0, 45, 0], // yaw/pitch/roll
  blur: 0.2,
})
```

---

## 热点渲染与事件
```ts
const hotspots = [
  {
    id: 'engine',
    position: [0.8, 0.6, -0.2],
    icon: 'info',
    label: '发动机舱',
    event: 'show-engine',
    payload: { part: 'engine' },
  },
  {
    id: 'door',
    position: [1.1, 0.9, 0.4],
    icon: 'action',
    label: '开启车门',
    event: 'toggle-door',
    payload: { side: 'left' },
  },
]

sdk.hotspot.render(hotspots)

sdk.hotspot.on('click', ({ id, payload }) => {
  // 业务侧根据 id/payload 触发操作
})

sdk.hotspot.on('hover', ({ id, hovering }) => {
  // hover 高亮或提示
})
```

事件命名建议（可按需扩展）：
- `hotspot:click`、`hotspot:hover`、`hotspot:focus`
- `hotspot:rendered`（所有热点就绪）

---

## 模型热加载 / 热销毁 / 热替换
```ts
// 加载
await sdk.model.load({ id: 'car', url: '/models/car.glb', draco: true })

// 销毁
await sdk.model.destroy('car')

// 替换（内部自动销毁旧实例并加载新实例）
await sdk.model.replace('car', { url: '/models/car-white.glb' })
```

可以通过 `sdk.model.on('loaded' | 'replaced' | 'destroyed', handler)` 监听模型状态。

---

## 材质切换
```ts
// 应用材质预设
sdk.material.apply({
  target: 'body',           // 部件或分组名称
  material: 'paint/blue',   // 预设 Key
})

// 批量切换
sdk.material.batch([
  { target: 'wheel', material: 'rim/chrome' },
  { target: 'glass', material: 'glass/clear' },
])

// 还原默认材质
sdk.material.reset('body')
```

---

## 推荐的配置结构
```json
{
  "camera": { "position": [2.5, 1.6, 3.2], "target": [0, 0.8, 0], "fov": 45 },
  "environment": { "hdr": "/envs/showroom_2k.hdr", "exposure": 1.1, "rotation": [0, 45, 0] },
  "lights": {
    "key": { "intensity": 1.5, "color": "#ffffff", "direction": [0.3, -1, 0.25] },
    "fill": { "intensity": 0.6, "color": "#dfe8ff" },
    "ambient": { "intensity": 0.25 }
  },
  "hotspots": [
    { "id": "engine", "position": [0.8, 0.6, -0.2], "icon": "info", "label": "发动机舱", "event": "show-engine" },
    { "id": "door", "position": [1.1, 0.9, 0.4], "icon": "action", "label": "开启车门", "event": "toggle-door" }
  ]
}
```

---

## 事件清单（示例）
- 相机：`camera:changed`
- 热点：`hotspot:click`、`hotspot:hover`、`hotspot:rendered`
- 模型：`model:loaded`、`model:replaced`、`model:destroyed`
- 材质：`material:applied`、`material:reset`

订阅方式：
```ts
sdk.on('hotspot:click', (evt) => console.log(evt))
sdk.off('hotspot:click', handler) // 移除监听
```

---

## 调试建议
- 启用 `sdk.debug(true)` 查看加载、事件、帧率等日志。
- 逐步应用配置：先确认相机与灯光，再添加环境贴图与热点，最后再做材质/模型热更新。
- 热更新前后记录 ID/实例，避免重复销毁或遗漏解绑事件。
