基于 HTML5 WebGL 构建智能数字化城市 3D 全景

本文介绍如何利用Hightopo的HT for Web产品构建轻量化的智慧城市3D全景。通过3DMax建模,结合HT的DataModel和SelectionModel,实现3D场景的序列化和反序列化,打造智慧城市3D动画效果,包括建筑浮现、视角转换等,为5G时代的数字化城市带来生动展示。
摘要由CSDN通过智能技术生成

前言

自 2011 年我国城镇化率首次突破 50% 以来,《新型城镇化发展规划》将智慧城市列为我国城市发展的三大目标之一,并提出到 2020 年,建成一批特色鲜明的智慧城市。截至现今,全国 95% 的副省级以上城市、76% 的地级以上城市,总计约 500 多个城市提出或在建智慧城市。

基于这样的背景,本系统采用 Hightopo 的  HT for Web  产品来构造轻量化的 智慧城市 3D 可视化场景,通过三个角度的转换,更清晰让我们感知到 5G 时代下数字化智能城市的魅力

预览地址:HT 智慧城市

整体预览图

第一个视角下,城市以市中心为圆心缓缓浮现,市中心就如同整座城的大脑

第二个视角下,在楼房间穿过,细致的感受这城市的面貌

 第三个视角下,鸟瞰整座城,体会智慧城市带来的不可思议的欣喜

 是不是觉得有些神奇,我们接下来就是对项目的具体分析,手把手教你如何搭建一个自己心中的梦想城市

场景搭建

该系统中的大部分模型都是通过 3dMax 建模生成的,该建模工具可以导出 obj 与 mtl 文件,在 HT 中可以通过解析 obj 与 mtl 文件来生成 3D 场景中的所有复杂模型,(当然如果是某些简单的模型可以直接使用 HT 来绘制,这样会比 obj 模型更轻量化,所以大部分简单的模型都是采用 HT for Web 产品轻量化 HTML5/WebGL 建模的方案)我们先看下项目结构,源码都在 src 文件夹中

 storage 保存的便是 3D 场景文件。 index.js 是 src 下的入口文件,创建了一个 由 main.js 中导出的 Main 类,Main 类创建了一个 3D 画布,用于绘制我们的 3D 场景,如下

 1 import event from '../util/NotifierManager';
 2 import Index3d from './3d/Index3d';
 3 import { INDEX, EVENT_SWITCH_VIEW } from '../util/constant';
 4 
 5 export default class Main {
 6     constructor() {
 7         let g3d = this.g3d = new ht.graph.Graph3dView(),
 8 
 9         //将3d图纸添加到dom对象中
10         g3d.addToDOM();
11 
12         this.event = event;
13         //创建一个Index3d类,作为场景初始化
14         this.index3d = new Index3d(g3d);
15         //调用switch方法派发EVENT_SWITCH_VIEW事件,并传入事件类型 INDEX
16         this.switch(INDEX);
17     }
18     switch(key = INDEX) {
19         event.fire(EVENT_SWITCH_VIEW, key);
20     }
21     // 
22 }

我们用  new ht.graph.Graph3dView()  的方式创建了一个 3D 画布,画布的顶层是 canvas 。并创建了一个 index3d 对象,看到后面我们就能知道其实这一步就如同我们把场景“画”上去。在 main 对象中我们还引用了 util 下的 NotifierManager 文件,这个文件中的 event 对象为穿插在整个项目中事件总线,使用了 HT 自带的事件派发器,可以很方便的手动的订阅事件和派发事件,感兴趣可以进一步了解  HT 入门手册 ,下面便是文件内容

 1 class NotifierManager {
 2     constructor() {
 3         this._eventMap ={};
 4     }
 5 
 6     add(key, func, score, first = false) {
 7         let notify = this._eventMap[key];
 8         if (!notify) notify = this._eventMap[key] = new ht.Notifier();
 9 
10         notify.add(func, score, first);
11     }
12 
13     remove(key, func, score) {
14         const notify = this._eventMap[key];
15         if (!notify) return;
16 
17         notify.remove(func, score);
18     }
19 
20     fire(key, e) {
21         const notify = this._eventMap[key];
22         if (!notify) return;
23 
24         notify.fire(e);
25     }
26 }
27 
28 const event = new NotifierManager();
29 export default event;

notify.fire() 和 notify.add() 分别是派发和订阅事件,类似于设计模式中的订阅者模式,我们很清楚的能看到,NotifierManager 类就是对 HT 原有的派发器做了一个简单地封装 ,并在创建 main 对象的时候,调用event.fire() 自动派发了 EVENT_SWITCH_VIEW 这一事件并且传入了事件类型 Index 。

画布我们有了,接下来我们就应在画布上“画”上我们的 3D 场景了。上面我们也说过了这一步由 new Index3d() 实现的, 那么它是如何实现 “画” 这一步骤的呢?

我们看看较为重要的两个文件 ui 文件夹下的 Index3d 文件和 View 文件,两个文件分别导出了 Index3d 和 View 两个类, Inde3d 类继承于 View 类,我们先来看一下 View 类的实现 

 1 import event from "../util/NotifierManager";
 2 import util from '../util/util';
 3 import { EVENT_SWITCH_VIEW } from "../util/constant";
 4 
 5 export default class View {
 6     constructor(view) {
 7         this.url = '';
 8         this.key = '';
 9         this.active = false;
10         this.view = view;
11         this.dm = view.dm();
12 
13         event.add(EVENT_SWITCH_VIEW, (key) => {
14             this.handleSwitch(key);
15         });
16     }
17     handleSwitch(key) {
18         if (key === this.key) {
19             if (!this.active) {
20                 this.active = true;
21 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值