1. 程式人生 > >基於WebGL(ThingJS)的家具城 商場 3D展示 3D可視化 DEMO

基於WebGL(ThingJS)的家具城 商場 3D展示 3D可視化 DEMO

ott 移除 設計 ane 餐廳 控件 wal ont 技術分享

本文將模擬一個家具城,讓大家足不出戶在家裏就能更加直觀立體的挑選家具。

技術分享圖片

技術分享圖片

第一步,利用CampusBuilder搭建模擬場景。CampusBuilder的模型庫有各種各樣的模型,使我們搭建出的場景更逼真。使用CampusBuilde創建層級,之後再給層級加外立面就出現了當前的效果。這次我們其實只是需要一個樓層,所以我們就把上次使用的過的場景拿來改造一下。詳情移步:CampusBuilder3D場景制作工具
點擊查看demo

技術分享圖片

	//加載場景代碼
var app = new THING.App({
    // 場景地址
    "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/家具城",
    //背景設置
    "skyBox": "BlueSky"
});

  第二步,開啟層級切換。因為我們模擬的“宜家”是某建築中的一層,所以這裏要開啟層級切換以便進入家具城。

app.on(‘load‘, function (ev) {
    //開啟層級切換
    app.level.change(ev.campus);
});

  同時給家具城創建一個廣告牌,防止我們在第一人稱下行走會“迷路”。貼圖可以自行上傳。

//創建廣告牌
var advertisingSign = app.create({
    type: ‘Box‘,
    width: 15.0, // 寬度 
    height: 5.0, // 高度 
    depth: 0.5, // 深度 
    widthSegments: 1.0, //寬度上的節數 
    heightSegments: 1.0, // 高度上的節數 
    depthSegments: 1.0, // 深度上的節數 
    center: ‘Bottom‘, // 中心點 
    style: {
        color: ‘#ffffff‘,
        opacity: 2,
        image: ‘/uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/file/家具展銷/歐派.jpg‘
    },
    parent: app.query(‘building_01‘)[0],
});
advertisingSign.position = [50.957, 15.883, -16];

  這裏給我們給整個場景用抽象物體圍起來了,以免第一人稱控件開啟時會造成無碰撞體系墜落出場景。記得要給他們組合並命名為‘碰撞盒’,在場景加載完成後將他們“隱藏”起來。

技術分享圖片

app.on(‘load‘, function (ev) {
    //開啟層級切換
    app.level.change(ev.campus);
    //將碰撞盒的透明度設置為0,並且將他們的pickable屬性設置為false,不可被選中。
	var crashBox = app.query(‘碰撞盒‘)[0];
    crashBox.style.opacity = 0;
    crashBox.pickable = false;
});

  第三步,添加第一人稱控件。

先創建兩個按鈕來控制第一人稱控件。

	new THING.widget.Button(‘第一人稱‘, add_control);
    new THING.widget.Button(‘自由視角‘, remove_control);

  

添加第一人稱控件

//第一人稱組件
var ctrl = null;
function add_control() {
    if (app.level.current.name == ‘Campus‘) {
        app.camera.position = [75.28812158204005, 1.8016147124541857, 29.699063489018236];
        app.camera.target = [53.32909358623788, 4.541642332131091, -9.470748625431646];

    }
    if (app.level.current.name != ‘Campus‘) {
        app.level.change(app.query(‘新樓層‘)[0]);
        app.camera.flyTo({
            ‘position‘: [41.05650213795261, 1.3469938677565356, -18.6143831867287],
            ‘target‘: [38.982251559488404, 0.7081383467333933, -23.867802267306008],
            ‘time‘: 2000,
            ‘complete‘: function () {
            }
        });
    }
    if (ctrl) return;
    ctrl = app.addControl(
        new THING.WalkControl({
            walkSpeed: 0.02,
            turnSpeed: 0.25,
            gravity: 30,
            eyeHeight: 1.7,
            jumpSpeed: 0,
            enableKeyRotate: false,
            useCollision: true,//app.scene
            useGravity: true,
            groundObjects: [app.scene] //把整個場景都添加,可把樓層或其他需要檢測的添加進入碰撞體系裏 | 默認值 園區地板
        })
    );
}

  移除第一人稱控件

	function remove_control() {
    if (!ctrl)
        return;
    app.removeControl(ctrl);
    ctrl = null;
}

  第四步,創建界面panel用於顯示家居的詳細信息。
添加界面

	var panel = null;
function add_panel(title, total, goodsInfo) {
    panel = new THING.widget.Panel({
        titleText: ‘商品名稱:‘ + title,
        closeIcon: true, // 是否有關閉按鈕 
        dragable: false, // 是否可以拖拽 
        retractable: true,
        opacity: 0.9, // 透明度 
        hasTitle: true
    });
    panel.position = [1000, 0];
    var dataObj = {
        total: total,
        goodsInfo: goodsInfo
    };
    var total = panel.addString(dataObj, ‘total‘).caption(‘總價‘);
    var goodsInfo = panel.addString(dataObj, ‘goodsInfo‘).caption(‘商品介紹‘);

}

  

移除界面

	function remove_panel() {
    if (panel) {
        panel.destroy();
        panel = null;
    }
}

  

最後一步,為商品和大樓添加點擊事件。這裏我們也要卸載雙擊事件,因為鼠標雙擊時會聚焦當前物體,與我們的業務邏輯有沖突所以這裏給他卸載掉。首先是普通的點擊事件,鼠標左鍵點擊時會出現商品的信息。右鍵點擊時,會移除第一人稱控件。

	//鼠標點擊事件
app.on(‘click‘, function (ev) {
    if (ev.button == 2) {
        remove_control();
        return;
    }
    remove_panel();
    switch (ev.object.name) {
        case "桌椅組合1": add_panel(‘自然風格餐桌系列‘, "2598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "桌椅組合2": add_panel(‘線代都市餐桌系列‘, "2198.00", "  利落線條,刻畫幾何形底座。自然致簡的淺木色橡木拼花,帶有淡淡的手工白蠟處理,搭配內斂的深灰色線條,形成微妙平衡,線代感呼之欲出。");
            break;
        case "桌椅組合3": add_panel(‘緊湊家庭餐桌系列‘, "1998.00", "  緊湊家庭餐廳,享四人圍坐的寬適與愜意。精巧的尺寸,圓融包容的圓桌設計,即便是緊湊的客餐廳一體空間,也能歡暢小談。");
            break;
        case "沙發組合1": add_panel(‘本色筆記組合沙發‘, "2598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合2": add_panel(‘雲海闌珊組合沙發‘, "8888.00", "  全家人圍坐的恬淡時刻,更多一份舒適。借一抹海天的藍,再偷來雲朵的舒軟,只為全家圍坐的時刻,盡享舒適怡然。");
            break;
        case "沙發組合3": add_panel(‘商務舒適組合沙發‘, "8598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合4": add_panel(‘自然風格餐桌系列‘, "5508.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合5": add_panel(‘自然風格餐桌系列‘, "2578.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
    }
});
app.off(‘dblclick‘); 	

  代碼塊 => 層級 => 觸發 => 修改進入層級操作

技術分享圖片

這裏我們將進入層級的操作改為直接進入我們的家具城這一層“新樓層”。

//修改singleClick點擊之後進入級的操作
app.on(THING.EventType.SingleClick, function (ev) {
    var object = ev.object;
    if (object.name == "building_01") {
        app.level.change(app.query(‘新樓層‘)[0]);
        app.camera.flyTo({
            ‘position‘: [41.05650213795261, 1.3469938677565356, -18.6143831867287],
            ‘target‘: [38.982251559488404, 0.7081383467333933, -23.867802267306008],
            ‘time‘: 2000,
            complete: function () {
                console.log("我已經進來了" + app.level.current.name);
            }
        });
    }
    return;
}, ‘customLevelEnterMethod‘);

  小結:
第一人稱控件的問題,Campus => 新樓層 ,如果不設置攝像機飛到一合理位置,攝像機將脫離樓層,因為進入樓層的時候攝像機的默認位置不在樓層上,所以每次在樓層內添加第一人稱控件時我們必須要將攝像機放到一個合理的位置。

全部代碼:

//加載場景代碼
var app = new THING.App({
    // 場景地址
    "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/家具城",
    //背景設置
    "skyBox": "BlueSky"
});

app.on(‘load‘, function (ev) {
    app.level.change(ev.campus);
    var crashBox = app.query(‘碰撞盒‘)[0];
    crashBox.style.opacity = 0;
    crashBox.pickable = false;
    new THING.widget.Button(‘第一人稱‘, add_control);
    new THING.widget.Button(‘自由視角‘, remove_control);

});

//修改singleClick點擊之後進入級的操作
app.on(THING.EventType.SingleClick, function (ev) {
    var object = ev.object;
    if (object.name == "building_01") {
        app.level.change(app.query(‘新樓層‘)[0]);
        app.camera.flyTo({
            ‘position‘: [41.05650213795261, 1.3469938677565356, -18.6143831867287],
            ‘target‘: [38.982251559488404, 0.7081383467333933, -23.867802267306008],
            ‘time‘: 2000,
            complete: function () {
                console.log("我已經進來了" + app.level.current.name);
            }
        });
    }
    return;
}, ‘customLevelEnterMethod‘);

//鼠標點擊事件
app.on(‘click‘, function (ev) {
    if (ev.button == 2) {
        remove_control();
    }
    if (typeof (ev.object) == undefined)
        return;
    remove_panel();
    switch (ev.object.name) {
        case "桌椅組合1": add_panel(‘自然風格餐桌系列‘, "2598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "桌椅組合2": add_panel(‘線代都市餐桌系列‘, "2198.00", "  利落線條,刻畫幾何形底座。自然致簡的淺木色橡木拼花,帶有淡淡的手工白蠟處理,搭配內斂的深灰色線條,形成微妙平衡,線代感呼之欲出。");
            break;
        case "桌椅組合3": add_panel(‘緊湊家庭餐桌系列‘, "1998.00", "  緊湊家庭餐廳,享四人圍坐的寬適與愜意。精巧的尺寸,圓融包容的圓桌設計,即便是緊湊的客餐廳一體空間,也能歡暢小談。");
            break;
        case "沙發組合1": add_panel(‘本色筆記組合沙發‘, "2598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合2": add_panel(‘雲海闌珊組合沙發‘, "8888.00", "  全家人圍坐的恬淡時刻,更多一份舒適。借一抹海天的藍,再偷來雲朵的舒軟,只為全家圍坐的時刻,盡享舒適怡然。");
            break;
        case "沙發組合3": add_panel(‘商務舒適組合沙發‘, "8598.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合4": add_panel(‘自然風格餐桌系列‘, "5508.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
        case "沙發組合5": add_panel(‘自然風格餐桌系列‘, "2578.00", "  簡約的圓桌設計,微冷的現代居室圍成一桌大自然的感覺。自然本色,簡介的設計,彰顯質樸、實用、少即是多的線代生活哲學。");
            break;
    }
});
//卸載雙擊事件
app.off(‘dblclick‘);

// 界面組件 
var panel = null;
function add_panel(title, total, goodsInfo) {
    panel = new THING.widget.Panel({
        titleText: ‘商品名稱:‘ + title,
        closeIcon: true, // 是否有關閉按鈕 
        dragable: false, // 是否可以拖拽 
        retractable: true,
        opacity: 0.9, // 透明度 
        hasTitle: true
    });
    panel.position = [1000, 0];
    var dataObj = {
        total: total,
        goodsInfo: goodsInfo
    };
    var total = panel.addString(dataObj, ‘total‘).caption(‘總價‘);
    var goodsInfo = panel.addString(dataObj, ‘goodsInfo‘).caption(‘商品介紹‘);

}
function remove_panel() {
    if (panel) {
        panel.destroy();
        panel = null;
    }
}

//創建廣告牌
var advertisingSign = app.create({
    type: ‘Box‘,
    width: 15.0, // 寬度 
    height: 5.0, // 高度 
    depth: 0.5, // 深度 
    widthSegments: 1.0, //寬度上的節數 
    heightSegments: 1.0, // 高度上的節數 
    depthSegments: 1.0, // 深度上的節數 
    center: ‘Bottom‘, // 中心點 
    style: {
        color: ‘#ffffff‘,
        opacity: 2,
        image: ‘/uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/file/家具展銷/歐派.jpg‘
    },
    parent: app.query(‘building_01‘)[0],
});
advertisingSign.position = [50.957, 15.883, -16];

//第一人稱組件
var ctrl = null;
function add_control() {
    if (app.level.current.name == ‘Campus‘) {
        app.camera.position = [75.28812158204005, 1.8016147124541857, 29.699063489018236];
        app.camera.target = [53.32909358623788, 4.541642332131091, -9.470748625431646];

    }
    if (app.level.current.name != ‘Campus‘) {
        app.level.change(app.query(‘新樓層‘)[0]);
        app.camera.flyTo({
            ‘position‘: [41.05650213795261, 1.3469938677565356, -18.6143831867287],
            ‘target‘: [38.982251559488404, 0.7081383467333933, -23.867802267306008],
            ‘time‘: 2000,
            ‘complete‘: function () {
            }
        });
    }
    if (ctrl) return;
    ctrl = app.addControl(
        new THING.WalkControl({
            walkSpeed: 0.02,
            turnSpeed: 0.25,
            gravity: 30,
            eyeHeight: 1.7,
            jumpSpeed: 0,
            enableKeyRotate: false,
            useCollision: true,//app.scene
            useGravity: true,
            groundObjects: [app.scene] //把整個場景都添加,可把樓層或其他需要檢測的添加進入碰撞體系裏 | 默認值 園區地板
        })
    );
}
function remove_control() {
    if (!ctrl)
        return;
    app.removeControl(ctrl);
    ctrl = null;
}

  

基於WebGL(ThingJS)的家具城 商場 3D展示 3D可視化 DEMO