昨天看到一篇文章说是学习如何开飞机的,然后我就想,如果我也可以开飞机那就好玩了,每个人小时候都想做飞行员!中国飞行员太难当了,再说也不轻易让你开飞机!后来我就想如果能用 HT 开飞机那就是真的有趣了,哈哈,这个实现的效果还是很不错的,可以让你满足一下开飞机的虚荣心

Demo 地址: http://hightopo.com/guide/guide/plugin/obj/examples/example_path.html

来看下具体实现的效果:

这个例子基本上完全模拟了飞机的飞行模式,包括起飞跑道,包括飞机的移动路径,螺旋桨的旋转,机尾的指示灯等部分。

首先,最重要的是我们的飞机模型,前面有文章写到过,HT 内部封装了一个方法 ht.Default.loadObj 来加载 OBJ 文件:

 ht.Default.loadObj('obj/plane.obj', 'obj/plane.mtl', {
center: true,
r3: [0, -Math.PI/2, 0], // make plane face right
s3: [0.15, 0.15, 0.15], // make plane smaller
finishFunc: function(modelMap, array, rawS3){
if(modelMap){
modelMap.propeller.r3 = {//propeller 螺旋桨
func: function(data){
return [data.a('angle'), 0, 0];
}
};
// make propeller a litter bigger
modelMap.propeller.s3 = [1, 1.2, 1.2];
modelMap.propeller.color = 'yellow';
}
});

这里面的 modelMap.propeller 是 OBJ 文件中定义好的 modelMap 对象中的 propeller 对象,你可以试着打印 modelMap 看看输出结果。

这个方法里的 finishFunc(modelMap, array, rawS3) 用于加载后的回调处理,具体查阅 HT for Web OBJ 手册,我们还添加了一个在 OBJ 模型中没有的飞机尾部的“红色闪烁指示灯”,这里用到的是组合模型 array(所有材质组成的数组,里面有至少一个模型),我们在 array中加入一个新的球模型:

 // add a sphere model as an indicator light 指示灯
array.push({
shape3d: ht.Default.createSmoothSphereModel(),
t3: [-40, 10, 0],
s3: [6, 6, 6],
color: {
func: function(data){
return data.a('light') ? 'red': 'black';
}
}
});

这里的 shape3d 是 HT 封装的一个属性名,通过 setShape3dModel(name, model) 函数注册的或者是通过 getShape3dModel(name) 函数返回的注册过的 3D 模型,如何注册 3D 模型可查阅 HT for Web 建模手册

color 属性名对应了一个对象,这边的定义是这样的,color 直接通过 data.getAttr('a') 获取 data.setAttr(‘a’, value) 中的值,这样做有两个好处,一是可以不污染 HT 的常用属性操作,所以 HT 专门定义了这个 attr 属性类型,是 HT 预留给用户存储业务数据的;二是这样也很方便数据绑定,我们可以通过在需要更改属性的地方调用 setAttr 方法,非常方便。

接着我们通过 ht.Default.setShape3dModel(name, model) 来将我们刚刚组合好的模型 array 注册成我们要的“plane”模型:

 ht.Default.setShape3dModel('plane', array);

注册好模型后肯定是要调用这个模型,我们可以通过 shape3d 属性来调用这个模型,并且在这个模型中自定义上面代码中出现过的 light 属性和 angle 属性:

 plane = new ht.Node();
plane.s3(200, 200, 200);
plane.s3(rawS3);
plane.s({
'shape3d': 'plane',
'shape3d.scaleable': false,
'wf.visible': true,//线框是否可见
'wf.color': 'white',
'wf.short': true //是否显示封闭的线框,true为不封闭的短线框
});
plane.a({
'angle': 0,
'light': false
});

因为飞机还有螺旋桨、指示灯两个功能,我们还得对这两个模型做动画效果,可查阅 HT for Web 动画手册,通过用户在 form 表单上选择的结果来决定飞机飞行持续时间、看飞机的视角、飞机沿着“航线”飞行所要旋转的角度、机尾指示灯的“闪烁”功能等等,最后别忘了飞机停止飞行时,如果要让飞机继续飞行,就得回调这个动画,并且设置灯不再闪烁,别忘了要启动动画:

 params = {
delay: 1500,
duration: 20000,
easing: function(t){
return (t *= 2) < 1 ? 0.5 * t * t : 0.5 * (1 - (--t) * (t - 2));
},
action: function(v, t){
var length = g3d.getLineLength(polyline),
offset = g3d.getLineOffset(polyline, length*v),
point = offset.point,
px = point.x,
py = point.y,
pz = point.z,
tangent = offset.tangent,
tx = tangent.x,
ty = tangent.y,
tz = tangent.z;
plane.p3(px, py, pz);
plane.lookAt([px + tx, py + ty, pz + tz], 'right'); var camera = formPane.v('Camera');
if(camera === 'Look At'){
g3d.setCenter(px, py, pz);
}
else if(camera === 'First Person'){
g3d.setEye(px - tx * 400, py - ty * 400 + 30, pz - tz * 400);
g3d.setCenter(px, py, pz);
} plane.a('angle', v*Math.PI*120);
if(this.duration * t % 1000 > 500){
plane.a('light', false);
}else{
plane.a('light', true);
}
},
finishFunc: function(){
animation = ht.Default.startAnim(params);
plane.a('light', false);
}
}; animation = ht.Default.startAnim(params);

其实最让我们好奇的是描绘的路径跟飞机本身的飞行并没有关系,还有那么多左拐右拐的,要如何做才能做到呢?

接下来我们来描绘路径,首先这个路径是由 ht.Polyline 作为基础来描绘的:

 polyline = new ht.Polyline();
polyline.setThickness(2);
polyline.s({
'shape.border.pattern': [16, 16],
'shape.border.color': 'red',
'shape.border.gradient.color': 'yellow',
'shape3d.resolution': 300,
'3d.selectable': false
});
dataModel.add(polyline);

上面的代码只是向 datamodel 数据模型中添加了一个 polyline 管线而已,不会显示任何东西,要显示“航道”首先就要设置航道所在的点,我们先设置航道的初始点:

 points = [{ x: 0, y: 0, e: 0 }];
segments = [1];

这个 points 和 segments 是 HT for Web Shape 手册中定义的,points 是 ht.List 类型数组的定点信息,顶点为 { x: 100, y: 200 } 格式的对象;segments 是 ht.List 类型的线段数组信息,代表 points 数组中的顶点按数组顺序的连接方式。

图中“航道”左侧的多个圆形轨道也是通过设置 points 和 segments 来设置的:

 for(var k=0; k<count+1; k++){
var angle = k * Math.PI * 2 * round / count;
points.push({
x: cx + radius * Math.cos(angle),
y: cy + radius * Math.sin(angle),
e: k * height / count
});
segments.push(2);
}

接下来几个拐点也是这种方法来实现的,这里就不赘述了,如果你还没看手册的话,这里标明一点,segments 只能取值 1~5,1 代表一个新路径的起点;2 代表从上次最后点连接到该点;3 占用两个点信息,第一个点作为曲线控制点,第二个点作为曲线结束点;4 占用3个点信息,第一和第二个点作为曲线控制点,第三个点作为曲线结束点;5 不占用点信息,代表本次绘制路径结束,并闭合到路径的起始点:

 points.push({ x: cx+radius, y: 0, e: height/2 });
points.push({ x: 0, y: 0, e: height/2 });
segments.push(3); points.push({ x: radius, y: -radius, e: height/2*0.7 });
points.push({ x: radius*2, y: radius, e: height/2*0.3 });
points.push({ x: radius*3, y: 0, e: 0 });
segments.push(4); points.push({ x: 0, y: 0, e: 0 });
segments.push(2);

我们已经把路径上的点都添加进“航道”中了,接下来要把点都设置到管道上去才会显示在界面上:

 polyline.setPoints(points);
polyline.setSegments(segments);

“跑道”就比较简单了,只是一个 Node 节点然后设置基础效果而已,没什么特别的:

 runway = new ht.Node();
runway.s3(-cx+radius*3, 1, 200);
runway.p3(cx+runway.getWidth()/2, -22, 0);
runway.s({
'all.color': '#FAFAFA',
'all.transparent': true,
'all.reverse.cull': true,
'all.opacity': 0.8,
'3d.selectable': false
});
dataModel.add(runway);

最后,在界面上添加一个 formPane 表单面板,定义好之后可以直接添加到 body 上,这样就不会跟 graph3dView 有显示的联系了。

formPane 可以用 formPane.addRow 方法动态添加行,这个方法中可以直接对动态变化的数据进行交互,例如本例中的是否有动画 Animation,我们利用 checkBox 来记录选中或者非选中的状态:

 {
checkBox: {
label: 'Animation',
selected: true,
onValueChanged: function(){
if(this.isSelected()){
animation.resume();
}else{
animation.pause();
}
}
}
}

也可以通过设置“id”来记录动态改变的值,然后 formPane就会通过调用 formPane.v(id) 来获取当前值。

至此,整个 Demo 的解释到此为止,如果还有不懂的可以先查阅我们官网 HT for Web,之后还有不懂的可以私信我,但还是希望你们能仔细阅读,不然很浪费我们双方的时间,谢谢~

基于HTML5及WebGL的工控SCADA模拟飞机飞行的更多相关文章

  1. 基于HTML5 Canvas的工控SCADA模拟飞机飞行

    昨天看到一篇文章说是学习如何开飞机的,然后我就想,如果我也可以开飞机那就好玩了,每个人小时候都想做飞行员!中国飞行员太难当了,再说也不轻易让你开飞机!后来我就想如果能用 HT 开飞机那就是真的有趣了, ...

  2. 基于HTML5 Canvas 实现矢量工控风机叶轮旋转

    之前在拓扑上的应用都是些静态的图元,今天我们将在拓扑上设计一个会动的图元--叶轮旋转. 先看看最后我们实现的效果:http://www.hightopo.com/demo/fan/index.html ...

  3. 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控

    前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...

  4. 基于 HTML5 的 WebGL 和 VR 技术的 3D 机房数据中心可视化

    前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...

  5. 基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型

    前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的同时,在监控系统中面临着严峻的现状问 ...

  6. 基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块

    基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块 前言 最近学习了 HT for Web flow 插件,除了正常的 flow 效果,其中还有两个十分好用的两个接口 getPercen ...

  7. 基于 HTML5 和 WebGL 的地铁站 3D 可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  8. 基于HTML5的WebGL电信网管3D机房监控应用

    先上段视频,不是在玩游戏哦,是规规矩矩的电信网管企业应用,嗯,全键盘的漫游3D机房: http://www.hightopo.com/guide/guide/core/3d/examples/exam ...

  9. 基于HTML5及WebGL开发的2D3D第一人称漫游进行碰撞检测

    为了实现一个基于HTML5的场景小游戏,我采用了HT for Web来实现,短短200行代码,我就能实现用“第一人称”来操作前进后退上下左右,并且实现了碰撞检测. 先来看下实现的效果:http://h ...

随机推荐

  1. JPA关系映射之one-to-many和many-to-one

    one-to-many(一对多)和many-to-one(多对一)双向关联 假设部门与员工是一对多关系,反过来员工与部门就是多对一关系. Dept.java类 public class Dept im ...

  2. 关于Linux的虚拟内存管理

    在linux中可以通过free指令查看当前内存,在后面加-m参数能让数字单位显示为MB. 一般机器,有一个实际内存和一个虚拟内存. swap就是虚拟内存,这个虚拟内存可以是文件,也可以是磁盘分区.通常 ...

  3. .NetCore之下载文件

    本篇将和大家分享的丝.NetCore下载文件,常见的下载有两种:A标签直接指向下载文件地址和post或get请求后台输出文件流的方式,本篇也将围绕这两种来分享:如果对您有好的帮助,请多多支持. 允许站 ...

  4. [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)

    之前,我写了一个arc函数的用法:[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形). arcTo: cxt.arcTo( cx, cy, x2, y2, ...

  5. Markdown 编写规范

    说明及目的 作为一个在博客园混迹了俩三年的人,一直在这里看别人的博客,现在准备开始写自己的博客,目的呢,就是一下几点吧: 项目过程中的历史经验教训积累记载,吃一堑长一智,不想在同一个坑掉进去好几次 学 ...

  6. windows下实现linux的远程访问以及linux上文件的上传和下载

    在网络性能.安全性.可管理性上,Linux有着其他系统无法比拟的强大优势,而服务器对这些方面要求特别高,因此Linux常常被用来做服务器使用.而当我们需要维护linux服务器的时候,就需要远程访问li ...

  7. (译)通过 HTML、JS 和 Electron 创建你的第一个桌面应用

    原文:Creating Your First Desktop App With HTML, JS and Electron 作者:Danny Markov 近年来 web 应用变得越来越强大,但是桌面 ...

  8. css 浮动和清除浮动

    在写页面布局的过程中,浮动是大家经常用的属性.在好多的排版布局中都是用的的浮动比如说下面这些地方都是应用到了浮动. 在我学习浮动的时候可是熬坏了脑筋,在这里我分享一下我对浮动这块知识的总结. 一.浮动 ...

  9. PIC32MZ 通过USB在线升级 -- USB HID bootloader

    了解 bootloader 的实现, 请加QQ: 1273623966(验证填bootloader); 欢迎咨询或定制bootloader; 我的博客主页 www.cnblogs.com/geekyg ...

  10. webapp 启动 手机app

    <div class="downLoad clearfix"> <div onclick="jsOpenApp.Close(this);" c ...