# 路径漫游(Walkthrough)
在基础教程 (opens new window)中,我们已经搭建了一个简易的运维平台。而在进阶模式教程中,我们将教你如何在平台上添加一些常用功能,让平台变得更实用。
在运维应用中,对设备、场地进行巡检是一个常见的场景,本节我们将通过路径漫游的功能来实现这项功能。
# 教程内容
在已搭建的运维平台上,接下来我们将要
- 通过按钮来添加关键帧
- 通过按钮来播放漫游视频
- 漫游过程中触发关键帧事件
# 路径漫游概念
我们首先阐述路径漫游、关键帧等相关的概念。
# 1. 路径漫游
即让相机沿着某个预先设定好的轨迹行进,以此来展现模型场景的功能。
# 2. 关键帧
控制漫游路径的若干个关键的相机位,即漫游的路径是由这几个关键帧按序排列形成的,每个关键帧包含position(相机的位置)、target(相机的视线方向)等信息。
# 3. 关键帧事件
即漫游过程中到达某个关键帧,即触发一个预先定义好的事件。
# 添加路径漫游
# 1. 添加关键帧
我们首先添加一个“添加关键帧”的按钮:
<button class="button" id="btnAddKeyFrame" onclick="addKeyFrame()">添加关键帧</button>
在script标签中分别构造创建漫游、添加关键帧的函数:
// ************************** 路径漫游 **************************
let walkThrough = null;
function createWalkThrough() {
if (walkThrough == null) {
// 构造路径漫游配置wtConfig
let walkThroughConfig = new Glodon.Bimface.Plugins.Walkthrough.WalkthroughConfig();
// 设置路径漫游配置匹配的viewer对象
walkThroughConfig.viewer = viewer3D;
// 构造路径漫游对象
walkThrough = new Glodon.Bimface.Plugins.Walkthrough.Walkthrough(walkThroughConfig);
}
}
function addKeyFrame() {
createWalkThrough();
//添加关键帧
walkThrough.addKeyFrame();
}
现在,我们已经可以通过点击按钮来添加漫游的关键帧了。
# 2. 播放路径漫游
路径漫游的关键帧已经设置好,接下来我们只要设置播放的时间,就能开始播放了。
同样的,我们再新建一个按钮。
<button class="button" id="btnPlayWalkThrough" onclick="playWalkThrough()">播放路径漫游</button>
在script标签中构造函数playWalkthrough。
function playWalkThrough() {
if (walkThrough != null) {
// 设置播放时间为5秒
walkThrough.setWalkthroughTime(5);
// 播放路径漫游
walkThrough.play();
} else {
window.alert("Please add keyframes first.");
}
}
到此,我们已经可以实现在场景中进行路径漫游的播放了。
# 3. 关键帧事件
我们在第二个关键帧处添加一个事件,通过console.log来告知用户信息。
先构造一个函数kfCallback:
function kfCallback(idx) {
switch (idx) {
case 0:
break;
case 1:
console.log('Hello, BIM!');
break;
}
}
再对playWalkthrough进行改造,设置关键帧事件即可。
function playWalkThrough() {
if (walkThrough != null) {
// 设置播放时间为5秒
walkThrough.setWalkthroughTime(5);
// 设置关键帧事件
walkThrough.setKeyFrameCallback(kfCallback);
// 播放路径漫游
walkThrough.play();
} else {
window.alert("Please add keyframes first.");
}
}
刷新页面并重新设置关键帧后,我们会在漫游至第2个关键帧时在控制台打印信息“Hello, BIM!”。
# 完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BIMFACE model scene</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
.buttons {
font-size: 0;
}
.button {
margin: 5px 0 5px 5px;
width: 90px;
height: 30px;
border-radius: 3px;
border: none;
background: #11DAB7;
color: #FFFFFF;
}
.main {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
}
#domId {
flex: 1;
}
</style>
</head>
<body>
<div class='main'>
<div class='buttons'>
<button class="button" id="btnIsolation" onclick="isolateComponents()">构件隔离</button>
<button class="button" id="btnZoomToSelection" onclick="zoomToSelectedComponents()">构件定位</button>
<button class="button" id="btnOverrideColor" onclick="overrideComponents()">构件着色</button>
<button class="button" id="btnBlinkComponent" onclick="blinkComponents()">构件强调</button>
<button class="button" id="btnSaveState" onclick="getCurrentState()">保存状态</button>
<button class="button" id="btnRestoreState" onclick="setState()">恢复状态</button>
<button class="button" id="btnStartAutoRotate" onclick="startAutoRotate()">开始旋转场景</button>
<button class="button" id="btnAddKeyFrame" onclick="addKeyFrame()">添加关键帧</button>
<button class="button" id="btnPlayWalkThrough" onclick="playWalkThrough()">播放路径漫游</button>
</div>
<div id="domId"></div>
</div>
<script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js"></script>
<script>
let viewToken = 'yourViewToken';
// 声明Viewer及App
let viewer3D;
let app;
// 配置JSSDK加载项
window.onload = function() {
let loaderConfig = new BimfaceSDKLoaderConfig();
loaderConfig.viewToken = viewToken;
BimfaceSDKLoader.load(loaderConfig, successCallback, failureCallback);
}
// 加载成功回调函数
function successCallback(viewMetaData) {
let dom4Show = document.getElementById('domId');
// 设置WebApplication3D的配置项
let webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig();
webAppConfig.domElement = dom4Show;
// 创建WebApplication3D,用以显示模型
app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig);
app.addView(viewToken);
viewer3D = app.getViewer();
}
// 加载失败回调函数
function failureCallback(error) {
console.log(error);
}
// ************************** 隔离 **************************
let isIsolationActivated = false;
function isolateComponents() {
if (!isIsolationActivated) {
// 设置隔离选项,指定其他构件为半透明状态
let makeOthersTranslucent = Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent;
// 调用viewer3D.method,隔离楼层为"F2"的构件
viewer3D.getModel().isolateComponentsByObjectData([{"levelName":"F2"}], makeOthersTranslucent);
// 渲染三维模型
viewer3D.render();
// 修改按钮的文字内容
setButtonText("btnIsolation", "取消隔离");
} else {
// 清除隔离
viewer3D.getModel().clearIsolation();
// 渲染三维模型
viewer3D.render();
// 修改按钮的文字内容
setButtonText("btnIsolation", "构件隔离");
}
isIsolationActivated = !isIsolationActivated;
}
// ************************** 定位 **************************
let isZoomToSelectionActivated = false;
function zoomToSelectedComponents(){
if (!isZoomToSelectionActivated) {
// 选中id为"271431"的构件
viewer3D.getModel().addSelectedComponentsById(["271431"]);
// 定位到选中的构件
viewer3D.getModel().zoomToSelectedComponents();
// 清除构件选中状态
viewer3D.getModel().clearSelectedComponents();
setButtonText("btnZoomToSelection", "回到主视角");
} else {
// 切换至主视角
viewer3D.setView(Glodon.Bimface.Viewer.ViewOption.Home);
setButtonText("btnZoomToSelection", "构件定位");
}
isZoomToSelectionActivated = !isZoomToSelectionActivated;
}
// ************************** 着色 **************************
let isOverrideActivated = false;
function overrideComponents(){
if (!isOverrideActivated) {
// 新建color对象,指定关注构件被染色的数值
let color = new Glodon.Web.Graphics.Color("#11DAB7", 0.5);
// 对关注构件进行着色
viewer3D.overrideComponentsColorById(["389601"], color);
viewer3D.render();
setButtonText("btnOverrideColor", "清除着色");
} else {
// 清除构件着色
viewer3D.getModel().clearOverrideColorComponents();
viewer3D.render();
setButtonText("btnOverrideColor", "构件着色");
}
isOverrideActivated = !isOverrideActivated;
}
// ************************** 构件闪烁 **************************
let isBlinkActivated = false;
function blinkComponents() {
if (!isBlinkActivated) {
let blinkColor = new Glodon.Web.Graphics.Color("#B22222", 0.8);
// 打开构件强调开关
viewer3D.enableBlinkComponents(true);
// 给需要报警的构件添加强调状态
viewer3D.getModel().addBlinkComponentsById(["389617"]);
// 设置强调状态下的颜色
viewer3D.getModel().setBlinkColor(blinkColor);
// 设置强调状态下的频率
viewer3D.getModel().setBlinkIntervalTime(500);
viewer3D.render();
setButtonText("btnBlinkComponent", "清除强调");
} else {
// 清除构件强调
viewer3D.getModel().clearAllBlinkComponents();
viewer3D.render();
setButtonText("btnBlinkComponent", "构件强调");
}
isBlinkActivated = !isBlinkActivated;
}
// ************************** 状态 **************************
let state;
function getCurrentState(){
// 保存当前模型浏览状态
state = viewer3D.getCurrentState();
}
function setState(){
if (state != null) {
// 恢复模型浏览状态
viewer3D.setState(state);
viewer3D.render();
} else {
window.alert("请先保存一个模型浏览状态!");
}
}
// ************************** 旋转场景 **************************
let isAutoRotateActivated = false;
function startAutoRotate() {
if (!isAutoRotateActivated) {
// 开始场景旋转
viewer3D.startAutoRotate(5);
setButtonText("btnStartAutoRotate", "结束旋转场景");
} else {
// 结束场景旋转
viewer3D.stopAutoRotate();
setButtonText("btnStartAutoRotate", "开始旋转场景");
}
isAutoRotateActivated = !isAutoRotateActivated;
}
// ************************** 路径漫游 **************************
let walkThrough = null;
function createWalkThrough() {
if (walkThrough == null) {
// 构造路径漫游配置wtConfig
let walkThroughConfig = new Glodon.Bimface.Plugins.Walkthrough.WalkthroughConfig();
// 设置路径漫游配置匹配的viewer对象
walkThroughConfig.viewer = viewer3D;
// 构造路径漫游对象
walkThrough = new Glodon.Bimface.Plugins.Walkthrough.Walkthrough(walkThroughConfig);
}
}
function addKeyFrame() {
createWalkThrough();
//添加关键帧
walkThrough.addKeyFrame();
}
function playWalkThrough() {
if (walkThrough != null) {
// 设置播放时间为5秒
walkThrough.setWalkthroughTime(5);
// 设置关键帧事件
walkThrough.setKeyFrameCallback(kfCallback);
// 播放路径漫游
walkThrough.play();
} else {
window.alert("Please add keyframes first.");
}
}
function kfCallback(idx) {
switch (idx) {
case 0:
break;
case 1:
console.log('Hello, BIM!');
break;
}
}
// ************************** 按钮文字 **************************
function setButtonText(btnId, text) {
let dom = document.getElementById(btnId);
if (dom != null && dom.nodeName == "BUTTON") {
dom.innerText = text;
}
}
</script>
</body>
</html>
恭喜你,你已完成了在运维场景中进行路径漫游的功能。接下来,你可以继续学习在场景中添加批注 (opens new window)的功能。
← 效果管理 批注(Annotation) →