自TWaver 3D产品发布以来,TWaver 3D的定位一直在于为企业提供3D应用的快速开发工具,方便企业开发适合自己的高效、实时的监控系统。
基于这样的产品定位,我们在过去的一年多时间里,一直将重心放在提升引擎效率,增加可视化工具上。对于我们的优势应用行业——电信行业,我们在3D机房应用上做了比较多的优化和定制。近期,有不少客户向我们提出,总觉用TWaver 3D开发出来的界面,不像主流的3D效果那么精美。首先,我们想说,效果图终归是效果图,和实际的系统一般来说还是有一些差异。其次,3D Max这些专业3D建模工具,和TWaver并不是对立的,而是相辅相成的工具。我们已经支持将3D max的文件导入TWaver进行展示,也正在研究使得TWaver能对接更多的模型类型。大家可以一起讨论,如何让TWaver的3D模型做得更好。最后,我们始终相信,作为开发工具的我们,是前途无限的,因此我们决定挑战一下效果图,看看TWaver的3D效果,到底有多强。
首先我们先找来一张效果图,真的是效果图哦~~
这张效果图和TWaver 3D以往的demo风格都大不相同,我们就来按图索个机房吧~
地板
第一个要做,也是应该比较简单的,就是地板。这个地板应该是一个有点厚度、有格子贴图的薄薄立方体平面。还好经过封装,就写一段json对象就能定义了:
{
name: '地板',
type: 'cube',
width: 1600,
height: 10,
depth: 1300,
style: {
'm.color': '#BEC9BE',
'm.ambient': '#BEC9BE',
}
}
通过定义,创建了一个13米*16米的地板块:
调整到合适的角度看,效果还不错,但颜色欠缺了些,需要找一个材质纹理图。纹理图的尺寸都需要是宽和高都是2的幂,例如128×128、256*256等,这样出来效果才会好。这也是3D软件一般所要求的。另外纹理要能连续拼接不露破绽,这样才好。例如下面我google出来的图:
在style里面添加:
'top.m.texture.image': 'images/floor.png',
'top.m.texture.repeat': new mono.Vec2(10,10),
效果如下:
虽然不是很华丽,但作为机房的地板,也绰绰有余了。好像有点so easy,决定加大难度,给地板加一个方便运送设备的斜坡!
这里就给大家普及下TWaver的好处了。Twaver里面的对象可以支持运算,这个斜坡,可以定义一个斜的立方体,让地板剪掉立方体,应该可以做到。于是继续定义json:
{
name: '地板切坡',
type: 'cube',
width: 200,
height: 20,
depth: 260,
translate: [-348,0,530],
rotate: [Math.PI/180*3, 0, 0],
op: '-',
style: {
…,
}
}
这里定义的一个倾斜的立方体,通过translate定义位置,通过rotate定义旋转角度,然后再通过op定义运算符,这里是“减去”,就用“-”。被剪掉的立方体也可以设置材质、纹理、贴图、颜色….等等。看看效果:
走廊桌
效果图的房间有点狭窄,决定加一条宽敞的走廊,并在走廊上放一个接待桌。对于桌子这种没有业务属性的对象,为了简单就偷懒做一个立方体表示吧!这个简单,继续使用上述办法:
{
name: '走廊板凳',
type: 'cube',
width: 300,
height: 50,
depth: 100,
translate: [350, 0, -500],
}
有点简单,再加点阴影效果:
简简单单一个接待桌就做好啦!下面继续造房子,盖墙体。
墙体
墙体是一个不规则的路径,不过放心,TWaver的引擎不光支持不规则路径,连曲线路径都可以噢。所以看上去挺麻烦实际还是比较简单的。在json里面定义一组数字的坐标,让这些数字依次连接,组成一个墙体,最后生成3D对象放入场景中。
Json定义大致如下:
{
name: '主墙体',
type: 'path',
width: 20,
height: 200,
translate: [-500, 0, -500],
data:[
[0, 0],
[1000, 0],
[1000, 500],
[500, 500],
[500, 1000],
[0, 1000],
[0,0],
],
}
注意这里的类型变成了path,data中定义了一个二维坐标数组来描述墙体。由于墙都是从底面开始的,所以只定义它的平面的x、y坐标就行了。吸取刚才的经验教训,启用阴影并咨询设计师美眉几个颜色值加上,看看效果:
再瞅瞅细节,好像缺点啥,没门!
门
门如果直接放上去,会被墙盖住;如果比墙厚,又难看不符合实际。还是应该先定义一个门洞立方体,把门所在的位置挖掉:
{
name: '门洞',
type: 'cube',
width: 195,
height: 170,
depth: 30,
op: '-',
translate:[-350,2,500],
}
刚好挖在斜坡的位置,这样设备进屋就方便了:
不过这门没有一个门框,感觉不太生动。多一个门框会感觉立体感强一些。门框可以是一个比门洞略大的立方体,在挖门洞之前添加:
{
name: '门框',
type: 'cube',
width: 205,
height: 180,
depth: 26,
translate: [-350, 0, 500],
op: '+',
}
加上阴影和光线等综合效果,还不错,挺有档次的。
还少点东西,对,门还没装上去。作为机房,应该来个清爽透亮的玻璃门。门体较大,就来个双开门吧。门的定义比较简单,就是一个薄的立方体。不过为了做到玻璃效果,要设置透明度,让他看上去更像一个玻璃,再让设计师美眉弄一张好看一点的门的图,贴上去。先做左边的门:
{
name: '左门',
type: 'cube',
width: 93,
height: 165,
depth: 2,
translate:[-397,4,500],
style:{
'm.transparent': true,
'm.texture.image': 'images/door_left.png',
}
上面增加的style主要是透明和贴图两项。看看效果:
再把右边的也加上,位置对称而已,json就不贴了。为了增加体验,门上再设置动画:双击可以自动打开,再双击可以直接关闭。TWaver的动画功能引擎做好了封装,在json中直接指定动画类型就行了。不过要注意左右门的动画旋转方向要相反,要不然一个向里开一个向外开感觉比较怪异。
窗
有门就要有窗。有窗才有“窗明几净”的清爽干净的赶脚。就在门的旁边开一扇大窗户吧!谁不喜欢大窗户呢?方法和门类似,先放窗框后挖窗体。不过为了有点变化,这里不做窗框了,做一个窗台,方法和道理与门相同。
{
name: ‘主窗户洞’,
type: ‘cube’,
width: 420,
height: 150,
depth: 50,
translate: [200, 30, 500],
op: ‘-‘,
},{
name: ‘主窗户台’,
type: ‘cube’,
width: 420,
height: 10,
depth: 40,
translate: [200, 30, 510],
op: ‘+’,
}
定义了一个窗洞(挖掉)、一个窗台(添加)。一个大窗户就做好了:
再添加一个略带颜色的透明玻璃。玻璃设置点高光和反射,增加“玻璃”感觉:
{
name: '主窗户玻璃',
type: 'cube',
width: 420,
height: 150,
depth: 2,
translate: [200, 30, 500],
op: '+',
style: {
'm.transparent': true,
'm.opacity':0.4,
'm.color':'#58ACFA',
},
}
Json中玻璃设置了透明度和颜色。这样一个半透明的茶色玻璃就好了:
到这里突然在想:盖房子如果像写程序一样简单就好了,所有的程序猿就不会是无房一族单身狗了。当然写程序和盖房子一样:该封装好的要封装好,最后就是搭积木组装就行了。如果盖房子都是从挖土活泥巴开始,那就杯具了。写程序也是一样,如果从webgl的main开始写….这3D机房的系统要几个月甚至几年才能做出来呢?
外侧墙
房间外侧的两道走廊隔墙,由于是直线墙,没有复杂走向,直接用立方体定义便可:
{
name: '左外墙',
type: 'cube',
width: 20,
height: 200,
depth: 1300,
translate: [-790, 0, 0],
op: '+',
}
再继续挖掉中间的窗户部分,并添加玻璃:
{
name: '左外墙洞',
type: 'cube',
width: 30,
height: 110,
depth: 1300,
translate: [-790, 60, 0],
op: '-',
}
[/javacsript]
添加玻璃:
{
name: '左外墙玻璃',
type: 'cube',
width: 4,
height: 110,
depth: 1300,
translate: [-790, 60, 0],
op: '+',
style: {
'm.transparent': true,
'm.opacity':0.6,
},
}
机柜
最后再来点重点的内容:机柜,以及其中的服务器设备。这才是3D机房里面最终要管理的内容。在我们的实际项目中,这些资产都是在数据库中存储,并通过json接口加载到浏览器中显示。这里为了演示方便,直接写几个机柜的片段,看一下显示效果。
机柜对象在项目中是这样封装的:用一个立方体来表示机柜,并加上贴图。项目中,为了提高显示速度,机柜一开始并不加载内部服务器内容,而是只显示自身一个立方体。当用户双击后,会触发一个延迟加载器,从服务器端加载机柜内部服务器,并加载到对应的位置上。此时,机柜会被挖空成一个空心的立方体,以便视觉上更像一个机柜。
定义机柜的json如下:
{
name: '机柜',
type: 'rack',
lazy: true,
width: 70,
depth: 100,
height: 220,
translate: [-370, 0, -250],
severity: CRITICAL,
}
上面的机柜定义中,有一个lazy标记,标记它是否延迟加载其内容。如果延迟加载,则双击触发,否则程序显示时直接加载其内容。Severity是定义了机柜的告警信息,它是否有业务告警。如果有告警,会用一个气泡显示在机柜的上方,同时机柜也会被染色成告警对应的颜色。
继续添加更多的机柜:
设备
简单起见,这里管理的设备假设都是机架设备,尺寸规格比较规整,因此比较容易在机柜中组织。一个设备的外观确定后,在数据库中定义好模板,加载时根据其所在机柜的位置放置即可。这里只是随机生成了几个服务器设备,并按位置摆放。在实际应用中,可以通过手工录入或者智能机架报送的信息来确定服务器的类型和位置。
如果需要监控到端口级别,还可以在服务器弹出后,再进一步延迟加载设备商的板卡、端口对象,并点击后进一步进行配置、监控等操作。当然加载的数据越细,对3D引擎和浏览器的压力会越大。可以通过动态延迟加载/卸载策略,获取一些平衡折中。
到这里,机房就基本搭建完成了,看下效果,比起效果图,是不是有过之而无不及呢?
从显示效果来看,基本不输前面看到的广告公司的效果图,但和它和一张死图片太不一样了,我们这是一个能操作、能漫游、能缩放、有动画、显示流畅、浏览器无需插件就能直接打开的3D机房小程序,就一个json文件和一百多行代码和一天的时间就搞定了,还是让人有点惊讶的。不用插件、不用3Dmax,不用模型库,我喜欢这样干干净净纯粹的小程序。小而美、干净而纯粹。手机和平板也能用哦,而且还很流畅!经过优化,场景加载已经控制在600毫秒以内,缩放漫游也很流畅。当然技术和美化永无止境,用户的需求也千变万化绵绵不绝。但只要我们选择好了技术和工具,就能事半功倍。Html5就是极佳的一个选择。
需要相关代码的同学可以发邮件到:tw-service@servasoft.com