基于HTML5 WebGL实现3D飞机叶轮旋转

在上一篇《基于HT for Web矢量实现2D叶轮旋转》中讲述了叶轮旋转在2D拓扑上的应用,今天我们就来讲讲叶轮旋转在3D上的应用。

3D拓扑上可以创建各种各样的图元,在HT for Web系统中提供了一些常规的3D模型,但是对于那些比较复杂的模型,比如汽车、人物等模型就无能为力了,那再项目中需要用到这样的模型该肿么办呢?这时候就需要借助专业的3ds Max工具来建模了,然后通过3ds Max工具将模型导出成obj文件,然后再项目中引用导出的obj文件,这样就能成功的使用上复杂的图元了。

在《HT图形组件设计之道(四)》一文中有提及HT for Web引入obj文件的介绍,在这里我就不做重复介绍了,我们先来看看今天作为演示的Demo模型长什么样:

http://www.hightopo.com/guide/guide/plugin/obj/ht-obj-guide.html

嘿嘿,是不是感觉今天的模型有些大材小用了,没办法,怪只怪自己不懂3ds Max工具,只能先用这个大家熟悉的模型来做Demo演示了。

首先我们需要有3ds Max工具将模型导出成obj及mtl文件,然后调用HT for Web的ht.Default.loadObj()方法读取并解析模型文件,在解析完成后,通过调用ht.Default.setShape3dModel()方法将模型注册到系统中,如此在后续的代码中就能够应用到该模型了,模型文件的读取及注册具体代码如下:

ht.Default.loadObj(‘plane.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){  
            ht.Default.setShape3dModel(‘plane‘, array);

            var plane = new ht.Node();
            plane.s3(rawS3);
            plane.s({
                ‘shape3d‘: ‘plane‘,
                ‘shape3d.scaleable‘: false,
                ‘wf.visible‘: true,
                ‘wf.color‘: ‘white‘,
                ‘wf.short‘: true
            });
            dataModel.add(plane);
        }
    }
});

注册完3D模型后,我们马上创建了一个3D图元,并将其添加到了dataModel容器中,这时我们需要一个3D拓扑来显示这个3D图元,具体的创建代码如下:

var dataModel = new ht.DataModel();
var g3d = new ht.graph3d.Graph3dView(dataModel);
g3d.setEye(200, 50, 300);
g3d.setDashDisabled(false);
g3d.getView().style.background = ‘#4C7BBB‘;
g3d.addToDOM();

3D拓扑上做了些简单的属性设置,让拓扑看起来舒服些,如此我们就可以看到我们创建出来的飞机模型到底长什么样了

怎么样,创建一个复杂模型好像并没有想象中的复杂(复杂的东西都让美工做完了)。

我们仔细观察飞机会发现,飞机前面的螺旋桨颜色和机身一样,一眼看去不太容易注意到它的存在,那能否将其颜色改掉呢?我们可以查看下mtl文件,看飞机的螺旋桨是否分离机身独立成一个材质,mtl文件的内容如下:

newmtl body
    Ns 10.0000
    Ni 1.5000
    d 1.0000
    Tr 0.0000
    Tf 1.0000 1.0000 1.0000 
    illum 2
    Ka 0.3608 0.4353 0.2549
    Kd 0.3608 0.4353 0.2549
    Ks 0.0000 0.0000 0.0000
    Ke 0.0000 0.0000 0.0000

newmtl propeller
    Ns 10.0000
    Ni 1.5000
    d 1.0000
    Tr 0.0000
    Tf 1.0000 1.0000 1.0000 
    illum 2
    Ka 0.3608 0.4353 0.2549
    Kd 0.3608 0.4353 0.2549
    Ks 0.0000 0.0000 0.0000
    Ke 0.0000 0.0000 0.0000

正如我们所想,飞机模型的机身和螺旋桨是分开了两个独立的材质,并将螺旋桨的材质名字定义为propeller,因此我们可以独立控制机身及螺旋桨,那么我们就来修改下螺旋桨的颜色吧,在loadObj()方法中的finishFunc回调函数中添加上如下代码即可:

modelMap.propeller.s3 = [1, 1.2, 1.2];
modelMap.propeller.color = ‘yellow‘;

在代码中,我们不仅改变了螺旋桨的颜色,我们还对螺旋桨做了缩放处理,令螺旋桨的宽度和长度变大一点。

到这里,模型就算完成了,接下来要做的就是让螺旋桨动起来,和2D叶轮旋转类似,在3D模型上也可以做数据绑定,要想让螺旋桨旋转起来,我们就需要设置螺旋桨的rotation属性,和3D上的图元不同的是,设置3D图元的rotation属性需要设置一个数组,定义3D上三个方向的旋转值。

我们先来尝试下让螺旋桨沿着x轴旋转45度试下:

modelMap.propeller.r3 = [Math.PI / 4, 0, 0];

果然可以,那么接下来我们就可以为螺旋桨的rotation属性做数据绑定的处理了:

modelMap.propeller.r3 = {
    func: function(data){
        return [data.a(‘angle‘), 0, 0];
    }
};

我们将螺旋桨的x轴上的旋转角度绑定到图元的angle自定义属性上,我们可以通过改变angle属性值令螺旋桨沿着x轴转动起来,那么接下来我们就通过定时器来动态改变angle属性吧,看看螺旋桨是不是真的可以动起来:

window.setInterval(function() {
    var rotation = plane.a(‘angle‘) + Math.PI / 10;
    if (rotation > Math.PI * 2) {
        rotation -= Math.PI * 2;
    }
    plane.a(‘angle‘, rotation);
}, 40);

螺旋桨果然动起来了,这个定时器让螺旋桨做匀速运动,但是飞机的螺旋桨在起飞和降落的时候其旋转速度都不是匀速,我们要模拟飞机起飞和降落时螺旋桨的旋转速度该如何处理呢?这个时候我们可以考虑用HT for Web中的动画来解决这个问题,关于动画的内容由于比较复杂,在这里就不深入探讨,等以后有机会再和大家分享动画的相关内容,今天就先讲诉下动画的基本用法,简单实现螺旋桨模拟起飞和降落的效果,具体的代码如下:

var 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){
        plane.a(‘angle‘, v*Math.PI*120);
    },
    finishFunc: function(){
        ht.Default.startAnim(params);
    }
};

ht.Default.startAnim(params);

我们来分析下代码:

1. delay属性:定义动画播放前的停顿时间;

2. duration属性:定义动画持续时间;

3. easing函数:定义动画缓动函数;

4. action函数:action函数必须提供,实现动画过程中的属性变化,在这里设置angle属性;

5. finishFunc函数:动画结束后调用的函数,在这里又启动了动画,让螺旋桨不断的旋转。

运行代码,你会发现螺旋桨在1.5秒后进入旋转状态,并且旋转速度由慢变快,再变慢直至停止,然后再过1.5秒后继续旋转,如此周而复始。

好了,今天的内容到这里就结束了,整个Demo的运行效果可以通过下面的视频查看,最后再附上本次Demo的所有代码。

http://v.youku.com/v_show/id_XMTI5NDI5MzYyOA==.html

http://www.hightopo.com/guide/guide/plugin/obj/ht-obj-guide.html

<!DOCTYPE html>
<html>
    <head>
        <title>HT for Web - Plane</title>
        <meta charset="UTF-8" name="viewport" content="user-scalable=yes, width=600">
        <script src="../../../build/ht-debug.js"></script>
        <script src="../../../build/ht-obj-debug.js"></script>
        <script>
            function init(){
                var dataModel = new ht.DataModel();
                var g3d = new ht.graph3d.Graph3dView(dataModel);
                g3d.setEye(200, 50, 300);
                g3d.setDashDisabled(false);
                g3d.getView().style.background = ‘#4C7BBB‘;
                g3d.addToDOM();
                
                ht.Default.loadObj(‘plane.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 = {
                                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‘;
                
                            ht.Default.setShape3dModel(‘plane‘, array);
                
                            var plane = new ht.Node();
                            plane.s3(rawS3);
                            plane.s({
                                ‘shape3d‘: ‘plane‘,
                                ‘shape3d.scaleable‘: false,
                                ‘wf.visible‘: true,
                                ‘wf.color‘: ‘white‘,
                                ‘wf.short‘: true
                            });
                            dataModel.add(plane);
                
                            var 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){
                                    plane.a(‘angle‘, v*Math.PI*120);
                                },
                                finishFunc: function(){
                                    ht.Default.startAnim(params);
                                }
                            };
                            
                            ht.Default.startAnim(params);
                
                            /*window.setInterval(function() {
                                var rotation = plane.a(‘angle‘) + Math.PI / 10;
                                if (rotation > Math.PI * 2) {
                                    rotation -= Math.PI * 2;
                                }
                                plane.a(‘angle‘, rotation);
                            }, 40);*/
                        }
                    }
                });
            }
        </script>
    </head>
    <body >                         
    </body>
</html>
时间: 2024-10-07 22:56:44

基于HTML5 WebGL实现3D飞机叶轮旋转的相关文章

基于 HTML5 + WebGL 实现 3D 可视化地铁系统

前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个地铁站的现实场景,包括地铁的实时运行情况,地铁上下行情况,视频监控,烟雾报警,电梯运行情况等等,帮助我们直观的了解当前的地铁站. 系统中

基于 HTML5 WebGL 的 3D 网络拓扑图

在数据量很大的2D 场景下,要找到具体的模型比较困难,并且只能显示出模型的的某一部分,显示也不够直观,这种时候能快速搭建出 3D 场景就有很大需求了.但是搭建 3D 应用场景又依赖于通过 3ds Max 或 Maya 的专业 3D 设计师来建模,Unity 3D 引擎做图形渲染等,这对用户来说都是挑战!不过,HT 一站式的提供了从建模到渲染,包括和 2D 组件呈现和数据融合的一站式解决方案.HT 基于 WebGL 的 3D 技术的图形组件 ht.graph3dView 组件通过对 WebGL 底

基于 HTML5 WebGL 的 3D 智慧隧道漫游巡检

前言 这次为大家展示的是通过 HT for Web 灵活的图型化编辑工具打造的智慧隧道监控系统.通过 HTML5 技术实现了桌面和移动端的跨平台性,同时现实了可视化运维. 这次主要跟大家分享里面的漫游巡检功能,完美进行第一人称视角体验整体结构环境,酷似游戏一样给人一种真实的感受,比平面更加直观,随意游离与虚拟和现实之间. 代码实现 整个场景是由 3D 组件搭建而成的,需要大量的代码,为了简化,我用 HT 封装的 ht.JSONSerializer 来将场景序列化为一个 json 文件.在代码中,

基于 HTML5 + WebGL 的 3D 太阳系系统

前言 近年来随着引力波的发现.黑洞照片的拍摄.火星上存在水的证据发现等科学上的突破,以及文学影视作品中诸如<三体>.<流浪地球>.<星际穿越>等的传播普及,宇宙空间中那些原本遥不可及的事物离我们越来越近,人们对未知文明的关注和对宇宙空间的好奇达到了前所未有的高度.站在更高的立足点上,作为人类这个物种中的一员,我们理所应当对我们生活的星球.所在的太阳系有一定的认识,对 8 大行星各自的运行轨道.质量.资源存储量甚至是地形有一定的了解. 本系统采用 Hightopo 的 H

基于HTML5 WebGL的工业化3D电子围栏

前言 现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个现代化工厂的现实场景,包括工厂工人的实时位置.电子围栏的范围.现场的安全情况等等,帮助我们直观的了解当前工厂人员的安全状况. 本篇文章通过对工厂可视化场景的搭建和模型的加载,人物实时定位代码的实现.电子围栏和轨

基于HTML5的燃气3D培训仿真系统

最近上线了的基于HTML5的燃气3D培训仿真系统,以前的老系统是采用基于C++和OpenGL的OpenSceneGraph引擎设计的,OSG引擎性能和渲染效果各方面还是不错的,但因为这次新产品需求要求能运行多移动终端,多年前基于MFC封装OSG的老系统架构也实在该退休了,这年头找能维护MFC这种古董级GUI的靠谱人也非易事. 系统最终采用HT for Web的3D框架实现,项目中的程序员也很高兴有这样的机会终于摆脱维护MFC老系统的宿命,虽然大家都只有C++的开发经验,对HTML/CSS/JS并

基于 H5 + WebGL 实现 3D 可视化地铁系统

前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个地铁站的现实场景,包括地铁的实时运行情况,地铁上下行情况,视频监控,烟雾报警,电梯运行情况等等,帮助我们直观的了解当前的地铁站. 系统中

wwwlyjustcom基于HTML5快速搭建3D机房设备面板199O8836661

以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观.今天我们就在HT for Web的3D技术上完成设备面板的搭建. 我们今天模拟的设备是机房设备,先来目睹下最终效果: 基于HTML5快速搭建3D机房设备面板我来解释下这个模型,一个带有透明玻璃门的机柜,机柜里装有5台设备,门可以开合,设备可以插拔,那么我么该如何搭建这样的设备呢?方法不难,我们一步一步来.基于HTML5快速搭建3D机房设备面板看起来有模有样的,其实呢,它就是一

基于 HTML5 WebGL 的智慧城市(一)

前言 中共中央.国务院在今年12月印发了<长江三角洲区域一体化发展规划纲要>(下文简称<纲要>),并发出通知,要求各地区各部门结合实际认真贯彻落实. <纲要>强调,要提升基础设施互联互通水平,打造数字长三角,协同建设新一代信息基础设施,共同推动重点领域智慧应用.大力发展基于物联网.大数据.人工智能的专业化服务,提升各领域融合发展.信息化协同和精细化管理水平.围绕城市公共管理.公共服务.公共安全等领域,支持有条件的城市建设基于人工智能和 5G 物联的城市大脑集群. 城市治