DigitalPerformanceV2Plugin 控制器(最小可用版)

试点 fork:独立于现有 DigitalPerformancePlugin(Legacy),不修改其既有行为。 本版本提供:剧本加载(复用 Shared_Core 加载 + 模型入场景)、播放/暂停/续播、 基于统一时钟的进度与 seek 预览。相机运镜(CameraTrack/CameraDirector)在后续任务叠加。

Constructors

Properties

five: Five
NAME: "Dnalogel-DigitalPerformanceV2Plugin" = PLUGIN_NAME
playground: PerformancePlayground
state: {
    continuousPlaying: boolean;
    currentChapter: DigitalChapter;
    currentScript: DigitalScript;
    enabled: boolean;
    playing: boolean;
    selectedShotIndex: number;
} = ...

Type declaration

  • continuousPlaying: boolean
  • currentChapter: DigitalChapter
  • currentScript: DigitalScript
  • enabled: boolean
  • playing: boolean
  • selectedShotIndex: number

    编辑端:当前选中的运镜项下标(无选中为 null)。切换章节时清除。

Methods

  • 在指定时间捕获当前 five 相机为一个运镜关键帧。

    • 位姿取自 five 当前 Mapview 状态(target=offset、longitude、latitude、distance);fov 取自 fiveState(缺省读 five.getCurrentState())。
    • 按 timeStamp 升序插入;同 timeStamp 覆盖。 拒绝(保持序列不变并返回 error):未加载 script / 无当前章节 / time 非负有限数校验失败。

    Parameters

    • time: number
    • OptionalfiveState: {
          fov?: number;
      }
      • Optionalfov?: number
    • Optionaloptions: CameraKeyframeOptions

    Returns CameraKeyframeResult

  • 应用章节默认视角到 five。

    • 章节存在关键帧:经 FiveModelCameraBridge 立即应用 sample(0)
    • 章节 0 关键帧:应用几何派生的 Mapview orbit(frame 本章节模型);无可用几何时 no-op。

    Parameters

    • chapterIndex: number

    Returns void

  • 进入运镜编辑:对全部章节运镜内存态打一次深快照(供 discardCameraChanges 还原)。 仅记录内存快照,不触碰持久化、不改相机/播放状态。

    Returns void

  • 续播(当前章节)。

    • continue() / continue({ prepare: false }):同步 plain 续播,直接 resume 时钟,返回 void(既有语义不变)。
    • continue({ prepare: true }):先 await prepareCameraTo(currentChapterTime) 平滑 glide-back(不计时)再 resume, 返回 Promise<void>。展示端与编辑端均传 prepare: true 以保证续播无跳变(D-RESUME)。

    Returns void

  • Parameters

    • options: {
          prepare?: false;
      }
      • Optionalprepare?: false

    Returns void

  • Parameters

    • options: {
          prepare: true;
      }
      • prepare: true

    Returns Promise<void>

  • 编辑态续播(当前章节):在恢复时钟前先 await prepareCameraTo(当前时间), 以内插动画平滑回到暂停瞬间对应的运镜视角(无突变 user→director 切换,Req 13.9 / 18.9), prepare 不计入播放时间(时钟在 prepare 期间不推进)后再 resume。 章节无运镜关键帧时 prepare 为 no-op。不改变通用 continue()/pause() 语义。

    Returns Promise<void>

  • 放弃运镜修改:将运镜内存态还原到 beginCameraEditSession 时的快照(不走服务端重载)。 未打过快照时为 no-op。还原后重建当前章节 director 轨道并派发关键帧变更事件。

    Returns void

  • 销毁插件、释放资源

    Returns void

  • 章节默认视角(Chapter_Default_View)。始终为 Mapview orbit 视角(与运镜编辑「仅 Mapview」一致)。

    • 章节存在 ≥1 个运镜关键帧:返回该章节相机轨道 sample(0)(因首帧夹紧,等于首帧 CameraState)。
    • 章节存在 0 个运镜关键帧:几何派生一个「frame 该章节模型 t=0」的 Mapview orbit (target=模型世界包围盒中心,distance 由包围盒尺寸派生,orbit 朝向沿用 five 当前角度以避免跳变)。 无可用模型几何时返回 undefined(调用方 no-op、保持当前视角)。 默认视角不单独持久化,完全派生(关键帧 / 模型几何),不在 cameraPlayers 新增字段。

    Parameters

    • chapterIndex: number

    Returns CameraState

  • 当前可用章节

    Returns DigitalChapter[]

  • 当前章节信息:{ index, name, duration };duration 为该章节模型动画时长(排除相机 player)

    Returns CurrentChapterInfo

  • 组级章节时间映射(加法式):每章 { index, name, startTime, endTime, duration } 逐章累计。

    • duration[i] = getChapterModelDuration(chapters[i])(排除 camera player)
    • startTime[0]=0、startTime[i]=endTime[i-1]、endTime[i]=startTime[i]+duration[i]
    • 未加载 / 空章节组返回 [];纯读,不修改任何引擎状态。 按 currentScript 引用缓存;loadScript / script 变更时失效重算。

    Returns GroupChapterTimeInfo[]

  • 组级进度聚合(加法式):由章节级 getProgress() + getGroupChapterTimeMap() 派生。

    • groupTotalTime = Σ duration
    • groupCurrentTime = startTime[currentChapterIndex] + clamp(currentTime, 0, duration[idx])(无当前章节为 0)
    • 0 ≤ groupCurrentTime ≤ groupTotalTime;percentage ∈ [0,100](groupTotalTime=0 时为 0) 纯读,不修改任何引擎状态。

    Returns GroupProgress

  • 当前进度(当前章节内 currentTime/totalTime,单位 ms;含当前章节索引/总章节数)

    Returns V2Progress

  • 当前状态快照

    Returns {
        currentChapter: DigitalChapter;
        playing: boolean;
    }

  • 按章节索引批量加载运镜(用于从持久化数据还原):替换对应章节 camera player 的关键帧。 调用方负责"对账"(只传锚点命中的章节),越界索引忽略。

    Parameters

    Returns void

  • 加载剧本:预加载资源 + 将模型加入 five 场景;autoPlay 时自动播放首章

    Parameters

    Returns Promise<void>

  • 注册关键帧序列变更监听(camera-keyframes-changed);返回反订阅函数

    Parameters

    • listener: CameraKeyframesChangedListener

    Returns (() => void)

      • (): void
      • Returns void

  • 注册当前章节变更监听(current-chapter-changed);返回反订阅函数

    Parameters

    • listener: CurrentChapterChangedListener

    Returns (() => void)

      • (): void
      • Returns void

  • 注册组级进度监听(加法式,独立监听集合);返回反订阅函数。 在既有 emitProgress() 内追加组级广播,每 tick / 章节切换 / pause / seek 时随章节级广播一并触发。

    Parameters

    • listener: GroupProgressListener

    Returns (() => void)

      • (): void
      • Returns void

  • 注册进度监听;返回反订阅函数

    Parameters

    Returns (() => void)

      • (): void
      • Returns void

  • 暂停

    Returns void

  • 编辑态暂停(playing→paused,相机由「导演」交还「用户」拥有)。 统一 Mapview 后,导演接管期间 five 始终是合法 Mapview orbit 状态,暂停瞬间画面不变、 且 five 手势天然为正常模型视角(左键绕 target orbit、右键平移),无需特殊转换。见设计 §5.3.1。 仅供编辑端(camera-mode)暂停路径调用。

    Returns void

  • 从第一章开始按顺序连续播放(用于"重播全部",保留已捕获的各章节运镜)

    Returns Promise<void>

  • 从当前章节连续播放到最后一章(连播中跨章 seek 可经 seekRedirect 令牌无缝重定向)

    Returns Promise<void>

  • 播放指定章节

    Parameters

    Returns Promise<void>

  • 通过索引播放章节

    Parameters

    • index: number

    Returns Promise<void>

  • 编辑态:仅播放当前章节(不连播下一章)。 章节自然播放到末尾(ended)后,由 controller 执行「进度归零 + 恢复当前章节默认视角」, SHALL NOT 自动连播下一章节(区别于展示端 playAllRemaining 的章节连续播放)。 无当前章节时为 no-op。

    Returns Promise<void>

  • 从指定章节索引开始,按顺序连续播放到本动画组最后一章(保留已捕获的各章节运镜)

    Parameters

    • index: number

    Returns Promise<void>

  • 移除指定下标关键帧。拒绝(保持序列不变):未加载 script / 无章节 / index 越界。

    Parameters

    • index: number

    Returns CameraKeyframeResult

  • 重置播放(保留已加载资源)

    Returns void

  • 跳转到组级百分比 [0,100](= seekToGroupTime(clamp(pct,0,100)/100 * groupTotalTime))

    Parameters

    • percentage: number

    Returns SetTimelineResult

  • 跳转到组级时间(ms):映射为 (章节 index, 章节内时间),必要时切章后 setTimelineTo。 保留 seek 前的播放/暂停状态(D-SEEK-LIVE,方案 A):

    • 暂停态:跨章则先 setCurrentChapterForPlayback 切章,再 setTimelineTo 预览该帧后交还用户。
    • 播放态同章:clock.seek 续播(经 setTimelineTo)。
    • 播放态跨章:置 seekRedirect 并 abortCurrentPlay,由连播循环跳到目标章节从 localTime 继续。 越界钳制到 [0, groupTotalTime];未加载 script 返回 { success:false } 不抛异常。

    Parameters

    • groupTimeMs: number

    Returns SetTimelineResult

  • 序列化全部章节中"含非空关键帧"的运镜 player,按章节索引返回。 供编辑端按"章节起始动画 id"聚合后整组保存。未加载 script 时返回空数组。

    Returns {
        chapterIndex: number;
        player: DigitalPerformanceV2.DigitalCameraPlayer;
    }[]

  • 序列化当前章节的运镜 player。 keyframes 按 timeStamp 升序,仅写入已设置的可选字段(不写 undefined 占位)。 空/无 camera player 返回 keyframes:[];未加载 script / 无章节 时拒绝并返回 error。

    Returns SerializeCameraResult

  • 运镜开关:关闭后播放仅驱动模型动画,不接管 five 相机(立即生效)

    Parameters

    • enabled: boolean

    Returns void

  • 加法式:设置「章节索引 → 楼层」映射,启用「播放/切章时 Mapview 只显示当前章节所在楼层」。

    • number:该章节单一楼层;null:该章节内跨楼层 → 显示全部;映射缺项按显示全部处理。
    • 传入非 null:立即对当前章节应用一次;此后在任意章节切换(连播推进 / 切章 / 播放预览切章)时自动应用。
    • 传入 null:停用该能力(不再随章节应用),但不主动恢复楼层可见性(恢复由 reset() 负责)。 楼层可见性是 five 空间模型的显隐(five.model.show),与运镜相机接管相互独立。 各消费方(workshop 编辑端 / NextVR 展示端)自行从各自数据算好映射注入,保证两端行为一致(parity)。

    Parameters

    • map: Record<number, number>
    • Optionalmodel: {
          show?: ((floorIndex?: number) => void);
      }

      楼层可见性作用的目标模型(缺省/undefined/null 回退到 five.model)。 单 VR 场景无需传(five.model 即唯一模型);沙盘/联合现场须传动画所属子 VR 的模型 (five.models.find(m => m.name === resourceCode)),否则楼层隔离会落到 models[0] 而非播放中的子 VR, 导致跨楼层动画所有楼层同时高亮。传入 null 时清空目标模型回退到 five.model

      • Optionalshow?: ((floorIndex?: number) => void)
          • (floorIndex?): void
          • Parameters

            • OptionalfloorIndex: number

            Returns void

    Returns void

  • 设为当前编辑章节(不开始播放)。该次调用内联动完成: 切暂停 → seek(0)(进度归零、各 DigitalHuman 渲染 t=0)→ 重建 director 轨道到该章节关键帧 → 应用该章节默认视角 → 读取并更新该章节总时长 → 清除已选中运镜项 → 派发 onCurrentChapterChanged。 越界索引为 no-op。

    Parameters

    • chapterIndex: number

    Returns void

  • 播放/预览专用:设为当前章节(不开始播放,区别于编辑端 setCurrentChapter)。 透传 playground.prepareChapter:切模型可见性 + 重绑相机轨道 + 配置时钟时长并 seek 到 fromTime(不 start)。 不做编辑端默认视角设置 / 选中清理等联动。越界索引为 no-op。

    Parameters

    • index: number
    • fromTime: number

    Returns void

  • seek 预览:跳转到指定时间并渲染当前帧(不改变播放/暂停状态)。

    • 无当前章节:不改时钟、不渲染,返回失败指示且不抛异常。
    • 运镜启用:经 director seek 应用相机;运镜禁用:仅驱动 DigitalHuman。

    Parameters

    • time: number

    Returns SetTimelineResult

  • 人物运动轨迹线开关(默认关闭、不显示)。仅 debug / 特殊需求由业务显式开启。 立即作用于当前所有 DigitalHuman,并记忆给后续加载的模型。

    Parameters

    • visible: boolean

    Returns void

  • 更新指定下标关键帧:合并 patch 中出现的字段,按 timeStamp 重排序。 拒绝(保持序列不变):未加载 script / 无章节 / index 越界 / patch.timeStamp 非负有限数校验失败。

    Parameters

    Returns CameraKeyframeResult