UNPKG

@realsee/five

Version:

Realsee Renderer SDK

304 lines (242 loc) • 11.3 kB
# Work (VR 数据实体) - **Summary**: Work 是 Five 中最核心的数据实体,代表一个完整的 VR 项目,包含渲染场景所需的所有资源与配置。 - **Schema**: 包含 Observer, Model, Initial 等核心数据的接口。 - **Concepts**: Work Entity, Observer, WorkCode, Parsing。 - **Examples**: 数据加载、访问与多 Work 管理。 ## Schema > **Definition**: [Work](../../five/work/work.d.ts), [LooseWork](../../five/work/looseWorkType.d.ts), [WorkJson](../../five/work/workJsonType.d.ts) `Work` 及其相关核心接口定义如下: ```ts import * as THREE from "three"; import type { Mode } from "@realsee/five"; type CubeFace = 'up' | 'down' | 'left' | 'right' | 'front' | 'back'; /** Work 实体:VR 项目的根对象 */ export interface Work { /** 唯一标识 (Work ID) */ workCode: string; /** 项目名称 */ name: string; /** 资源加载的基础路径 (Base URL) */ baseURL: string; /** 数据签发人 */ issuer: string; /** 过期时间 */ expire: Date; /** 允许访问的安全域名列表 */ allowHosts: readonly string[]; /** 初始化参数 (默认模态、视角等) */ initial: WorkInitial; /** 相对位姿 (用于多 Work 拼接时的坐标变换) */ transform: THREE.Matrix4; /** 模型参数 (3D 模型资源信息) */ model?: WorkModel; /** 全景点位信息 (所有可观测点位的列表) */ observers: readonly WorkObserver[]; } /** 观察点:空间中可驻足观看的点位 */ export interface WorkObserver { /** 所属 Work 引用 */ work: Work; /** 在 observers 数组中的索引 */ index: number; /** 点位序号 (通常与 index 相同) */ panoIndex: number; /** 点位唯一 ID (通常格式为 `${workCode}[${panoIndex}]`) */ panoId: string; /** 点位是否激活可用 */ active: boolean; /** 点位是否可加载 */ loadable: boolean; /** 点位所在楼层索引 */ floorIndex: number; /** 点位在模型坐标系下的观察位置 (用于渲染相机位置) */ position: THREE.Vector3; /** 点位在模型坐标系下的地面位置 (用于导航和 UI 定位) */ standingPosition: THREE.Vector3; /** 点位和模型的旋转对齐四元数 */ quaternion: THREE.Quaternion; /** 点位和模型的旋转对齐矩阵 */ matrix: THREE.Matrix4; /** 可连通的相关点位序号 (用于全景游走) */ accessibleNodes: readonly number[]; /** 点位全景图资源信息 */ images: WorkImage; /** 获取点位的全局坐标 */ getWorldPosition(this: WorkObserver): THREE.Vector3; /** 获取点位的全局地面坐标 */ getWorldStandingPosition(this: WorkObserver): THREE.Vector3; /** 将方向向量转化为全景图 uv */ vectorToEquirectangularUv(vector: THREE.Vector3, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector2; /** 将全景图 uv 转化为方向向量 */ equirectangularUvToVector(uv: THREE.Vector2, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector3; /** 将方向向量转化为获六视图 uv */ vectorToCubemapUv(vector: THREE.Vector3, uvOrigin?: 'top-left' | 'bottom-left'): [cubeFace: CubeFace, cubemapUv: THREE.Vector2]; /** 将六视图 uv 转化为方向向量 */ cubemapUvToVector(cubeFace: CubeFace, uv: THREE.Vector2, uvOrigin?: 'top-left' | 'bottom-left'): THREE.Vector3; } /** 初始化位姿参数 */ export interface WorkInitial { work: Work; /** 模态 */ mode?: Mode; /** 点位序号 */ panoIndex?: number; /** 相机水平角 */ longitude?: number; /** 相机俯仰角 */ latitude?: number; /** 相机可视角度(垂直)*/ fov?: number; /** 相机观察点位置 [x, y, z] */ offset?: THREE.Vector3; /** 相机距离观察点距离 */ distance?: number; } /** 模型数据 */ export interface WorkModel { /** work */ work: Work; /** 模型文件地址 at3d / domez */ file?: string; /** 模型贴图文件地址 */ textures?: readonly string[]; /** 模型贴图文件地址的父目录 */ textureBase?: string; /** 指定上方向,对于 obj, ply 等定义不明确的需要指定上方向 */ upAxis?: string; /** 3d tile */ layers: readonly WorkModelLayer[]; } /** 模型图层信息 */ export interface WorkModelLayer { /** work */ work: Work; /** 模型类型 point_cloud mesh gaussian_splatting */ type: 'point_cloud' | 'mesh' | 'gaussian_splatting'; /** 模型名称 */ name: string; /** 指定上方向 */ upAxis: string; /** tileset.json 地址 */ tileset: string; } /** 全景图资源信息 */ export interface WorkImage { work: Work; /** 分辨率表 */ sizeList: readonly number[]; /** 瓦片信息 */ tiles: readonly WorkTile[]; /** 缩略图/预览图等 */ [key: string]: any; } ``` ## Concepts ### Work Entity (项目实体) Work 是 Five 渲染内容的基石。它不仅包含资源地址,还包含空间结构数据。由于数据通常带有数字签名(防止篡改),开发者**不应手动修改** Work 对象中的属性,尤其是资源路径和坐标数据。 ### Data Types (数据类型) Five 中有三种与 Work 相关的类型,它们分别对应不同的使用场景: * **LooseWork (宽泛数据)**: * **来源**: 通常是服务端下发的原始 JSON 数据。 * **特点**: 结构宽松,允许缺省值(如使用默认模态)、简写(如 URL 模板)和非标准类型(如数组表示向量)。 * **用途**: 作为 `parseWork(json)` 的输入。 * **Work (运行时实体)**: * **来源**: 由 `parseWork` 解析生成。 * **特点**: 结构严谨,数据已标准化(如 URL 已补全,向量转为 `THREE.Vector3`),且被冻结(不可变)。 * **用途**: Five 内部渲染使用的核心对象,传给 `five.load(work)`。 * **WorkJson (标准序列化)**: * **来源**: 由 `workToJson(work)` 生成。 * **特点**: 纯 JSON 结构,去除了运行时对象(如 THREE.Vector3),但保留了标准化的数据结构。 * **用途**: 用于数据持久化存储或跨端传输。 ### Layers vs File (数据源关系) `WorkModel` 提供了两种定义模型数据的方式,其中 `layers` 是现代标准,`file` 主要用于兼容旧数据或简单场景。 * **`layers`**: (推荐) 数组结构,用于定义多层级、多类型的模型资源。 * 支持 **3DTiles** 格式的分块加载。 * 支持多种类型混合:`mesh` (模型), `point_cloud` (点云), `gaussian_splatting` (高斯泼溅)。 * **默认行为**: 列表中的所有图层默认都会被加载并显示。 * **`file`**: (兼容) 字符串路径,用于定义单文件的 Mesh 模型。 * 仅支持部分格式(如 `.at3d`, `.obj`, `.glb`)。 * 不支持点云或高斯泼溅。 **加载优先级与兼容逻辑 (Fallback)**: Five 在运行时会将 `file` 视为一个虚拟的 `mesh` 图层。加载逻辑如下: 1. **优先加载 Layers**: Five 会遍历 `work.model.layers` 并加载其中定义的所有图层(包括 Mesh, PointCloud, GaussianSplatting 等)。 2. **File 的条件加载**: 检查当前已加载的图层中是否存在 `type: 'mesh'` 的图层。 * **存在 Mesh 层**: 忽略 `work.model.file` 字段(认为 `layers` 已经提供了更高精度的模型)。 * **不存在 Mesh 层**: 如果 `work.model.file` 有值,Five 会自动创建一个临时的 Mesh ViewLayer 来加载该文件。 ### Observer (观察点) Observer 是 VR 空间中预设的观察位置。在 **Panorama (全景)** 模式下,相机必须停留在某个 Observer 上。 * **position**: 相机镜头的物理位置。 * **standingPosition**: 对应的地面位置(脚底)。通常用于下绘制点位图标,或计算点位间的导航距离。 * **accessibleNodes**: 定义了该点位可以“走到”哪些相邻点位,构成了全景游走的图结构。 ### WorkCode (唯一标识) `workCode` 是 Work 的全局唯一标识符。 * **单 Work 场景**: 通常不需要显式关注。 * **多 Work 场景**: 当 Five 同时加载多个 Work(如拼接的大型空间)时,必须通过 `workCode` 来区分不同 Work 下的同名属性(如 `panoIndex`)。 ### Parsing (数据解析) 从服务端获取的原始 JSON 数据(LooseWork)可能包含相对路径或简写。`parseWork` 函数负责将其标准化为严格的 `Work` 对象,处理 URL 拼接、默认值填充和数据校验。 ## Examples ### 1. 解析与加载 Work 最基础的用法是从 API 获取数据并加载。 ```ts import { Five, parseWork } from "@realsee/five"; const five = new Five(); five.appendTo(document.getElementById("app")); // 1. 获取数据 fetch("https://vrlab-public.ljcdn.com/release/web/work.json") .then(res => res.json()) .then(json => { // 2. 解析数据 const work = parseWork(json); // 3. 加载到 Five five.load(work); }); ``` ### 2. 访问 Work 数据 加载完成后,可以通过 `five.work` 访问当前数据。 ```ts // 获取所有观察点 const observers = five.work.observers; // 获取当前所在的观察点 const currentPanoIndex = five.state.panoIndex; const currentObserver = observers[currentPanoIndex]; console.log("当前点位坐标:", currentObserver.position); console.log("可通往的点位:", currentObserver.accessibleNodes); ``` ### 3. 多 Work 加载与管理 Five 支持同时加载多个 Work,常用于楼盘小区的多个样板间拼接,或大型商业空间的区域拼接。 ```ts const work1 = parseWork(json1); const work2 = parseWork(json2); // 同时加载两个 Work five.load([work1, work2]); // 切换到指定 Work 的指定点位 five.setState({ mode: "Panorama", workCode: work2.workCode, // 必须指定 workCode panoIndex: 0 }); ``` ### 4. 追加与替换 Work 可以使用 `load` 方法的参数来控制是替换当前场景还是追加到当前场景。 ```ts const work3 = parseWork(json3); // 追加 Work (保留原有场景) // 第二个参数 "inherit" 表示保持当前相机视角和模态不变,不重置为新 Work 的初始视角 five.load(work3, "inherit", { mode: "add" }); // 替换 Work (清空原有场景) - 默认行为 five.load(work3, "inherit", { mode: "replace" }); ``` ## Common Pitfalls * **数据不可变性**: Work 数据包含签名信息,直接修改 `work.observers[0].position.x = 100` 虽不会报错,但可能导致渲染异常或签名验证失败。请视 Work 为只读对象。 * **坐标系**: Five 使用 **Y-Up 右手坐标系**,单位为**米**。与 Three.js 默认坐标系一致。 * **跨域问题 (CORS)**: `baseURL` 指向的资源服务器必须配置正确的 CORS 头,否则 WebGL 无法加载纹理。 * **parseWork 必选**: 永远不要尝试手动构造 `Work` 对象,总是使用 `parseWork`。服务端数据结构可能会升级,`parseWork` 会处理兼容性。 ## Related * [State](./state.md): 了解如何通过 State 切换点位。 * [Mode](./mode.md): 了解不同模态下 Work 数据的表现。 --- ```yaml tags: [VR数据, 数据加载, 点位, 全景点, 数据结构, 多work, work, core, entity, observer, parseWork, workCode, JSON, load] ```