OpenZI Vue API文档

OpenZI Vue 概述

OpenZI是一套高性能的三维可视化引擎,专为Web端打造。openzi-vue是其Vue集成包,提供了在Vue应用中快速集成OpenZI功能的能力,支持高性能WebRTC实时渲染、丰富的场景API和便捷的Vue组件集成。

高性能WebRTC

支持低延迟实时渲染,提供流畅的三维交互体验

丰富的场景API

关卡加载、坐标转换、相机控制等全方位场景操作能力

便捷的Vue集成

专为Vue 3设计,提供简洁的组件接口和完整的类型支持

安装指南

安装依赖

npm
npm install openzi-vue
yarn
yarn add openzi-vue

快速开始

在您的Vue项目中引入并使用openzi-vue组件:

main.js
import { createApp } from 'vue'
import App from './App.vue'
import OpenZIVue from 'openzi-vue'

const app = createApp(App)
app.use(OpenZIVue)
app.mount('#app')

核心组件

OpenZIViewer

OpenZIViewer 是整个库的核心组件,负责与OpenZI引擎建立连接并渲染3D场景。

组件属性

属性名 类型 默认值 说明
ueIp String UE服务器IP地址,必填项
uePort Number 8080 UE服务器端口
peerConnectionOptions Object {} WebRTC连接配置选项
startVideoMuted Boolean false 是否静音启动视频
autoPlayAudio Boolean true 是否自动播放音频

组件事件

事件名 参数 说明
mapLoaded data: { OpenZIAPI } 地图加载完成时触发,返回OpenZIAPI实例
onConnected 连接成功时触发
onDisconnected 断开连接时触发
onError error: Error 发生错误时触发

API 参考

场景API (sceneApi)

sceneApi 提供了一系列操作3D场景的方法,用于控制场景、相机、关卡等元素。

初始化与基础操作

init(api)

初始化场景API,必须在使用其他API前调用。

参数

- api - OpenZIAPI实例

返回值

import { sceneApi } from 'openzi-vue'

// 地图加载完成后初始化
function onMapLoaded(data) {
  const OpenZIAPI = data?.OpenZIAPI
  if (OpenZIAPI) {
    sceneApi.init(OpenZIAPI)
  }
}
changeCoodinate(jsondata)

切换场景坐标系。

参数

- jsondata - 坐标系配置对象

返回值

Promise

await sceneApi.changeCoodinate({
  "coordinateOrigin": "117.4572,39.021101,140.402447",
  "projectionCoordinateSystem": "EPSG:4326",
  "planetShape": 1,
  "GISType": 0,
  "originOffset": "0,0,0",
  "scale": 100
})
loadLevel(levelName, removeOthersLevel, bHidden)

加载指定关卡。

参数

- levelName - 关卡名称
- removeOthersLevel - 是否移除其他关卡
- bHidden - 是否隐藏关卡

返回值

Promise

// 加载主要关卡并移除其他关卡
await sceneApi.loadLevel('TJ01_46', true)

// 加载天空场景但不移除其他关卡
await sceneApi.loadLevel('LV_skycreator', false)

相机控制

getCameraInfo()

获取当前相机信息。

参数

返回值

Promise,解析为相机信息对象

sceneApi.getCameraInfo().then(cameraInfo => {
  console.log('当前相机信息:', cameraInfo)
})
changeCamera(cameraInfo)

设置相机位置和角度。

参数

- cameraInfo - 相机信息对象

返回值

Promise

sceneApi.changeCamera({
  "cameraMode": "rts",
  "redirectionOrigin": false,
  "gisType": 0,
  "coordinates": {"X": 117.203776, "Y": 39.136764, "Z": 48.320563},
  "pitch": -79.25,
  "yaw": 180,
  "moveSpeed": 100,
  "rotationSpeed": 180,
  "zoomSpeed": 100
})

视频站与POI管理

addVideos()

添加视频站。

参数

返回值

Promise

sceneApi.addVideos().then(result => {
  console.log('添加视频站成功:', result)
})
clearPOI()

清除所有POI点。

参数

返回值

Promise

sceneApi.clearPOI().then(result => {
  console.log('清除POI成功:', result)
})

镜头漫游

addCameraPlay()

添加镜头漫游。

参数

返回值

Promise

sceneApi.addCameraPlay().then(result => {
  console.log('添加镜头漫游成功:', result)
})
startCameraPlay()

开始镜头漫游。

参数

返回值

Promise

sceneApi.startCameraPlay().then(result => {
  console.log('开始漫游成功:', result)
})
pauseCameraPlay()

暂停镜头漫游。

参数

返回值

Promise

sceneApi.pauseCameraPlay().then(result => {
  console.log('暂停漫游成功:', result)
})

levelUtils 工具

levelUtils 提供了一系列工具方法,用于处理关卡数据和相机配置。

fetchLevelData()

获取关卡配置数据。

参数

返回值

Promise<Array> - 关卡配置数据数组

import { levelUtils } from 'openzi-vue'

const { fetchLevelData } = levelUtils

async function loadLevelData() {
  const data = await fetchLevelData()
  console.log('关卡数据:', data)
}
findLevelByName(levelData, name)

根据名称查找关卡配置。

参数

- levelData - 关卡数据数组
- name - 关卡名称

返回值

Object|null - 找到的关卡配置对象或null

import { levelUtils } from 'openzi-vue'

const { fetchLevelData, findLevelByName } = levelUtils

async function getLevelConfig() {
  const data = await fetchLevelData()
  const level = findLevelByName(data, '耳闸')
  console.log('找到关卡:', level)
}
loadLevelWithChildren(sceneApi, levelConfig)

加载关卡及其子节点。

参数

- sceneApi - sceneApi实例
- levelConfig - 关卡配置对象

返回值

Promise<void>

import { sceneApi, levelUtils } from 'openzi-vue'

const { fetchLevelData, findLevelByName, loadLevelWithChildren } = levelUtils

async function loadLevel() {
  const data = await fetchLevelData()
  const level = findLevelByName(data, '耳闸')
  if (level) {
    await loadLevelWithChildren(level)
    console.log('关卡及其子节点加载完成')
  }
}
fetchCameraData()

获取相机配置数据。

参数

返回值

Promise<Array> - 相机配置数据数组

import { levelUtils } from 'openzi-vue'

const { fetchCameraData } = levelUtils

async function getCameraConfigs() {
  const data = await fetchCameraData()
  console.log('相机配置:', data)
}
findCameraConfig(cameraData, levelName, cameraName)

根据关卡名称和相机名称查找相机配置。

参数

- cameraData - 相机数据数组
- levelName - 关卡名称
- cameraName - 相机名称

返回值

Object|null - 找到的相机配置对象或null

import { sceneApi, levelUtils } from 'openzi-vue'

const { fetchCameraData, findCameraConfig } = levelUtils

async function setCameraView() {
  const data = await fetchCameraData()
  const cameraConfig = findCameraConfig(data, '耳闸', '耳闸-入口-中景')
  if (cameraConfig) {
    await sceneApi.changeCamera(cameraConfig)
    console.log('相机视角设置完成')
  }
}

OpenZIAPI 类

OpenZIAPI 类是与OpenZI引擎通信的核心类,负责WebSocket连接和消息传递。

构造函数
import { OpenZILab } from 'openzi-vue'

// 创建OpenZILab实例
const openZILab = new OpenZILab('ws://192.168.18.224:8080')
Call(cName, fName, data, callback)

调用OpenZI引擎中的方法。

参数

- cName - 类名
- fName - 方法名
- data - 参数数据
- callback - 回调函数

openZILab.Call(
  'SceneManager',
  'StartPlay',
  { "playbackSpeed": 1.0 },
  (data) => {
    console.log('播放开始:', data)
  }
)
destroy()

销毁连接。

参数

// 组件卸载时销毁连接
openZILab.destroy()

使用示例

以下是一个完整的使用示例,展示了如何集成和使用openzi-vue,包含组件初始化、场景配置、关卡加载和API操作等功能:

完整示例
<template>
  <div class="container">
    
    <div class="config-panel">
      <div class="config-item">
        <label for="ueIp">UE服务器IP:</label>
        <input id="ueIp" v-model="config.ueIp" type="text" placeholder="输入UE服务器IP">
      </div>
      <button class="tech-btn primary" @click="applyConfig">应用配置</button>
    </div>

    
    <div class="component-container" v-if="showComponent">
      <open-z-i-viewer @mapLoaded="onMapLoaded" />
    </div>

    
    <div class="api-panel">
      <div class="api-section">
        <h3>关卡管理</h3>
        <div class="button-group">
          <button class="tech-btn primary" @click="loadSingleLevel('耳闸', '耳闸-入口-中景')" :disabled="!apiReady">加载耳闸关卡</button>
          <button class="tech-btn secondary" @click="loadSingleLevel('二道闸','二道闸-上游-近景')" :disabled="!apiReady">加载二道闸关卡</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue';
// 从openzi-vue包导入OpenZIViewer sceneApi和levelUtils
import { sceneApi, levelUtils, OpenZIViewer } from 'openzi-vue';
// 解构levelUtils工具方法
const { fetchCameraData, fetchLevelData, findLevelByName, findCameraConfig, loadLevelWithChildren } = levelUtils;

// 组件配置
const config = reactive({
  ueIp: '192.168.18.224',
  levelConfigUrl: '/configs/map/levelData.json'
});

// 状态变量
const showComponent = ref(false);
const apiReady = ref(false);
let OpenZIAPI = null;

// 应用配置
function applyConfig() {
  if (!config.ueIp) {
    console.error('请输入有效的UE服务器IP地址');
    return;
  }
  window.ueIp = config.ueIp; // 将UE服务器IP赋值给全局变量
  showComponent.value = false;
  setTimeout(() => {
    showComponent.value = true;
  }, 100);
}

// 地图加载完成回调
async function onMapLoaded(data) {
  console.log('地图加载完成');

  // 获取OpenZIAPI实例
  OpenZIAPI = data?.OpenZIAPI;

  if (OpenZIAPI) {
    apiReady.value = true;
    // 初始化场景通用工具API
    sceneApi.init(OpenZIAPI);

    try {
      // 1 设置默认坐标系
      await sceneApi.changeCoodinate({
        "coordinateOrigin": "117.4572,39.021101,140.402447",
        "projectionCoordinateSystem": "EPSG:4326",
        "planetShape": 1,
        "GISType": 0,
        "originOffset": "0,0,0",
        "scale": 100
      });

      // 2 设置默认帧率
      sceneApi.changeFps(30);

      // 3 加载基础关卡
      await loadLevels();

      // 4 设置默认视角
      setDefaultCameraView();

    } catch (error) {
      console.error(`初始化设置出错: ${error.message}`);
    }
  }

  // 加载基础关卡函数
  async function loadLevels() {
    try {
      // 加载主要关卡
      await sceneApi.loadLevel('TJ01_46', true);
      // 加载天空场景
      await sceneApi.loadLevel('LV_skycreator', false);
      // 加载特效
      sceneApi.loadLevel('BP_TEXIAO', false);
    } catch (error) {
      console.error(`加载关卡时出错: ${error.message}`);
    }
  }

  // 设置默认视角函数
  function setDefaultCameraView() {
    try {
      // 设置RTS模式的默认视角
      const cameraInfo = {
        "cameraMode": "rts",
        "redirectionOrigin": false,
        "gisType": 0,
        "coordinates": {"X": 117.20377616700722, "Y": 39.136763510147595, "Z": 48.32056263554841},
        "pitch": -79.25000000000016,
        "pitchRange": {"X": -90, "Y": -5},
        "yaw": 179.99999999999966,
        "yawRange": {"X": -180, "Y": 180},
        "moveSpeed": 100,
        "rotationSpeed": 180,
        "zoomSpeed": 100
      };

      // 调用设置相机信息的API
      sceneApi.changeCamera(cameraInfo)
        .then(() => {
          console.log('默认视角设置完成');
        })
        .catch(error => {
          console.error(`默认视角设置失败: ${error.message}`);
        });
    } catch (error) {
      console.error(`设置默认视角时出错: ${error.message}`);
    }
  }
}

// 加载单关卡并设置指定视角
async function loadSingleLevel(name, cameraName = '默认', weaterName = 'Weather_Clear_02', time = 17) {
  try {
    // 0 检查参数是否有效
    if (!name) {
      console.error('加载单关卡时缺少必要参数');
      return;
    }

    console.log(`开始加载关卡: ${name}`);

    // 1 修改天气
    sceneApi.changeWeather(weaterName);
    console.log(`天气已设置为: ${weaterName}`);

    // 2 修改时间
    sceneApi.changeHour(time);
    console.log(`时间已设置为: ${time}时`);

    // 3 动态获取关卡配置数据
    const levelData = await fetchLevelData();
    const targetLevel = findLevelByName(levelData, name);

    if (!targetLevel) {
      console.warn(`未找到关卡${name}的配置信息`);
      // 尝试直接使用提供的名称加载
      try {
        await sceneApi.loadLevel(name, false);
        console.log(`关卡${name}加载完成`);
      } catch (error) {
        console.error(`加载关卡${name}失败: ${error.message}`);
      }
      return;
    }

    // 4 加载指定关卡及其子节点
    try {
      await loadLevelWithChildren(targetLevel);
      console.log(`关卡${targetLevel.title}加载完成`);
    } catch (error) {
      console.error(`加载关卡${targetLevel.title}失败: ${error.message}`);
      return;
    }

    // 5 动态获取相机配置数据并应用
    if (cameraName) {
      const cameraData = await fetchCameraData();
      const targetCameraInfo = findCameraConfig(cameraData, name, cameraName);

      if (!targetCameraInfo) {
        console.warn(`未找到关卡${name}对应的相机配置${cameraName || ''},使用默认视角`);
      } else {
        // 应用相机视角设置
        try {
          await sceneApi.changeCamera(targetCameraInfo);
          console.log(`视角${cameraName}设置完成`);
        } catch (error) {
          console.error(`设置视角失败: ${error.message}`);
        }
      }
    }

  } catch (error) {
    console.error(`加载关卡${name}时出错: ${error.message}`);
  }
}
</script>

<style scoped>
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.component-container {
  width: 100%;
  height: 600px;
  border: 1px solid #ddd;
  overflow: hidden;
  background-color: #000;
}

/* 确保open-z-i-viewer组件适应容器尺寸 */
.component-container >>> open-z-i-viewer {
  width: 100%;
  height: 100%;
  display: block;
}
</style>

兼容性

浏览器支持

  • Chrome 80+
  • Firefox 78+
  • Safari 14+
  • Edge 80+
注意: 需要支持WebRTC的浏览器环境,推荐使用Chrome浏览器以获得最佳性能。

系统要求

  • 操作系统:Windows 10+, macOS 11+, Linux (主流发行版)
  • 处理器:双核以上CPU
  • 内存:4GB以上
  • 网络:推荐稳定的网络连接,带宽不低于2Mbps
性能提示: 更高配置的硬件可以获得更流畅的渲染体验,特别是对于复杂场景。