V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
xiangbulala
V2EX  ›  JavaScript

基于 WebGL 架构的 3D 可视化平台—实现汽车行走路线演示

  •  
  •   xiangbulala · 2018-11-27 14:38:57 +08:00 · 3361 次点击
    这是一个创建于 2188 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小车行走路线演示 New VS Old

    刚接触ThingJS的时候,写的一个小车开进小区的演示,今天又看了教程中有 movePath 这个方法就重新写了一遍,其中也遇到了一些问题,尤其突出的问题就是小车过弯的尴尬表现。

    先给大家看看 Old 版本,Old 版演示地址。
    在这里插入图片描述


    再看看 New 版本,AE86 过弯不再笨拙顺畅无比,New 版演示地址。
    在这里插入图片描述

    第二张效果图上可以看到由点连起来的路线,我的 AE86 也是严格按照路线行进的,相比于 Old 版本过弯的时候舒畅多了。Old 版本是用 setTimout(),rotateY(),moveTo()方法设置了几个点跑出来的。New 版本放弃了这种办法,这种过弯实在让人看着不舒服,也不符合现实世界(排除醉酒驾驶司机)。下面就说一下 New 版本。

    第一步,进入 ThingJS 在线开发,将场景地址替换成我们今天要用的,也可以自己去搭一个场景,campusBuilder 下载地址

    /**
     * 说明:创建 App,url 为场景地址(可选)
     */
    var app = new THING.App({
    	//场景地址
        url: 'http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/2018-10-30-17-20-23'     
    });
    

      第二步,在模型库里挑选一个你喜欢的车,种类丰富任你选择。

    app.create({ 
       type: 'Car', 
       name: 'Car01',
       angle: 90, // 旋转 
       //这里我选了一台黑车,没找到 AE86
       url: 'http://model.3dmomoda.cn/models/c6ed424627234a298c1921950eb8534c/0/gltf/', 
       //位置
       position: [-32, 0, 26.2],
       complete: function () {
           console.log('Black Car !');
       }
    });
    

      

    第三步,创建小车的行进路线和演示按钮。

    app.on('load', function () {
    
    // 创建 blackCar 行进路线
    var points = [];
    for (var x = -32, y = 0, z = 26.2 ; x <= 28; x += 4) {
        points.push([x, y, z]);
    }
    var radius = 1.75;
    for (var degree = 0, y = 0; degree <= 180; degree += 20) {
        var x = Math.sin(degree * 2 * Math.PI / 360) * radius + 28.5;
        var z = Math.cos(degree * 2 * Math.PI / 360) * radius + 24.45;
        points.push([x, y, z]);
    }
    for (var x = 27.5, y = 0, z = 22.7 ; x >= -6; x -= 4) {
        points.push([x, y, z]);
    }
    for (var degree = 0, y = 0; degree >= -90; degree -= 20) {
        var x = Math.sin(degree * 2 * Math.PI / 360) * radius -5.5;
        var z = Math.cos(degree * 2 * Math.PI / 360) * radius + 20.95;
        points.push([x, y, z]);
    }
    for (var x = -7.2, y = 0, z = 20.25 ; z >= 6; z -= 2) {
        points.push([x, y, z]);
    }
    
    //创建轨迹线
    line = app.create({
        type: 'Line',
        color: 0xFFFF00, // 轨迹线颜色
        dotSize: 2, // 轨迹点的大小
        points: points,
    })
    
     THING.widget.Button('车辆路线', play);
    

    });

      最后一步,让小车动起来创建 play()方法。

    function play() {
        var car = app.query('Car01')[0];
        car.movePath({
            'path': line.points, // 轨迹路线
            'time': 10000, // 移动时间
            'orientToPath': true, 
        });
        app.camera.lookAt(car);
    
    // app.camera.followObject({
    //     object:car,
    // });
    

    }

      做到这里小车已经可以动起来了,但是这个视角并不好,下面介绍一下摄像机中的 followObject(params)。
    API 地址

    创建一个 Car 类继承 THING.BaseObject,将物体类型转换成 Car 类型

    //创建 Car 类
    class Car extends THING.BaseObject{
        constructor(app) {
            super(app);
        }
    }
    THING.Utils.addCastType('Car', /Car/);  
    THING.factory.registerClass('Car', Car);
    

      

    //加到 play()
    app.camera.followObject({
            object:car,
        });
    

      下图是加了摄像机跟随物体的效果
    跟随物体
    短短 80 行代码,其中我也遇到了不少问题划重点的就是 app.camera.followObject()中 object 的类型问题,还有就是模型库里有一些车的模型比较奇怪,比如下图。
    在这里插入图片描述
    以下是完整代码

    //加载场景代码
    var app = new THING.App({ 
        // 场景地址
        "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/2018-10-30-17-20-23",
        //背景设置
    

    });

    // 创建 Car app.create({ type: 'Car', name: 'Car01', angle: 90, // 旋转 url: 'http://model.3dmomoda.cn/models/c6ed424627234a298c1921950eb8534c/0/gltf/', //位置 position: [-32, 0, 26.2], complete: function () { console.log('Black Car !'); } }); //创建 Car 类 class Car extends THING.BaseObject{ constructor(app) { super(app); } } THING.Utils.addCastType('Car', /Car/);
    THING.factory.registerClass('Car', Car);

    person.on('load',function())

    app.on('load', function () {

    // 创建 blackCar 行进路线
    var points = [];
    for (var x = -32, y = 0, z = 26.2 ; x <= 28; x += 4) {
        points.push([x, y, z]);
    }
    var radius = 1.75;
    for (var degree = 0, y = 0; degree <= 180; degree += 20) {
        var x = Math.sin(degree * 2 * Math.PI / 360) * radius + 28.5;
        var z = Math.cos(degree * 2 * Math.PI / 360) * radius + 24.45;
        points.push([x, y, z]);
    }
    for (var x = 27.5, y = 0, z = 22.7 ; x >= -6; x -= 4) {
        points.push([x, y, z]);
    }
    for (var degree = 0, y = 0; degree >= -90; degree -= 20) {
        var x = Math.sin(degree * 2 * Math.PI / 360) * radius -5.5;
        var z = Math.cos(degree * 2 * Math.PI / 360) * radius + 20.95;
        points.push([x, y, z]);
    }
    for (var x = -7.2, y = 0, z = 20.25 ; z >= 6; z -= 2) {
        points.push([x, y, z]);
    }
    
    //创建轨迹线
    line = app.create({
        type: 'Line',
        color: 0xFFFF00, // 轨迹线颜色
        dotSize: 2, // 轨迹点的大小
        points: points,
    })
    
     THING.widget.Button('车辆路线', play);
    

    });

    function play() { var car = app.query('Car01')[0]; car.movePath({ 'path': line.points, // 轨迹路线 'time': 10000, // 移动时间 'orientToPath': true, }); //app.camera.lookAt(car);

    app.camera.followObject({
        object:car,
    });
    

    }

    2 条回复    2018-11-27 18:08:07 +08:00
    abc635073826
        1
    abc635073826  
       2018-11-27 16:26:56 +08:00   ❤️ 1
    很棒啊,这种交互会不会成为趋势呢
    xiangbulala
        2
    xiangbulala  
    OP
       2018-11-27 18:08:07 +08:00
    @abc635073826
    公司主要做物联网行业的可视化管理,感觉 5G 商用会是个机会吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2842 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:20 · PVG 22:20 · LAX 06:20 · JFK 09:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.