基於HTML5的WebGL經典3D虛擬機器房漫遊動畫
第一人稱在 3D 中的用法要參考第一人稱在射擊遊戲中的使用,第一人稱射擊遊戲(FPS)是以第一人稱視角為中心圍繞槍和其他武器為基礎的視訊遊戲型別 ; 也就是說,玩家通過主角的眼睛來體驗動作。自從流派開始以來,先進的 3D 和偽 3D 圖形已經對硬體發展提出了挑戰,而多人遊戲已經不可或缺。
Doom 的截圖,這個流派的突破遊戲之一,展示了第一人稱射擊遊戲的典型視角
現在博物館或者公司也經常使用到 3D 動畫做宣傳片等等,3D 動畫演繹最大的優勢,便是在於內容與形式上給人的真實感受。它比平面作品更直觀,比 2D 動畫更真實,所以更能給觀賞者以置身於廣告環境當中的感受,大大增強廣告的說服力。3D 技術的發展甚至挑戰受眾的分辨能力,使受眾的判斷遊離於與虛擬和現實之間。
而且 3D 特效的應用為創意提供了更加廣闊的思維空間,併成為創意執行的可靠保證,並豐富了創意的形式和風格手段。根據廣告主題的表現訴求,可以營造出夢幻般的神奇氛圍來刺激打動受眾,從而起到與受眾溝通的目的。
3D動畫宣傳片將 3D 動畫、特效鏡頭、企業視訊、照片、未來前景等內容通過後期合成、配音、解說形成一部直觀、生動、喜聞樂見的高品位的企業廣告宣傳片,讓社會不同層面的人士對企業產生正面的、積極的、良好的印象,從而建立對企業的好感與信任,並信賴該企業的產品或服務。
現在 3D 發展地如此迅速也要感謝人類對於“現實”的追求,所以學好用好 3D 是未來成功必不可少的一部分。
本文例子的思路是進入一個機房參觀,開啟門的動作是再生動不過了, 再加上適當地轉彎,基本上完全模擬了人在機房中參觀的效果。還有一個好處就是,如果要演示給領導看而又不用操作,這種炫酷的效果領導一定會很滿意!
http://www.hightopo.com/demo/room-walkthrough/index.html
介面上的“reset”和“start”兩個按鈕是直接加在 body 體中的 button,並在這兩個按鈕上新增點選事件:
<div class="button" style="right: 50px;background-image: url(run.png);" onclick="startAnim();"></div> <div class="button" style="right: 100px;background-image: url(reset.png);" onclick="reset();"></div>
整個場景由 HT 封裝的 3D 元件搭建形成的,構造這麼大的場景是需要一定量的程式碼的,為了簡化,我把場景單獨拿出來,並用 HT 封裝的 ht.JSONSerializer 類將場景序列化為 json,程式碼中只引入了生成後的 json 檔案,為了讓大家更明確,我這邊做個示例,假設已經搭建好 3D 場景了:
dm = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dm); //.......構建好場景 dm.serialize();//可以填入number引數,作為空格縮排值
既然我們已經搭建好環境,轉成了 json 檔案,程式碼中不好控制,這種情況下我們會將 DataModel 資料模型再反序列化,這個函式的功能就是將 json 格式轉成物件,並將反序列化的物件傳入到 DataModel 資料模型中,詳情請參考 HT for Web 序列化手冊(http://hightopo.com/guide/guide/core/serialization/ht-serialization-guide.html):
var g3d = window.g3d = new ht.graph3d.Graph3dView(), dataModel = g3d.dm(), view = g3d.getView(), path = null; g3d.setMovableFunc(function(data) { return false; }); g3d.setVisibleFunc(function(data) { if (data.getName() === "path") { return false; } return true; }); g3d.setEye([523, 5600, 8165]); g3d.setFar(60000); dataModel.deserialize(json);
我們目前需要操作場景中的“門”、以及我們將要走的路線“path”,遍歷 DataModel 資料模型,獲取這兩個資料:
for (var i = 0; i < dataModel.size(); i++) { var data = dataModel.getDatas().get(i); if (data.getName() === "門") {//json中設定的名稱 window.door = data; } if (data.getName() === "path") { path = data; } if (window.door && path) {//獲取到door 和 path 的data之後就跳出迴圈 break; } }
這個例子中簡單來說就只有四個動作,“重置”回到原點、“開始動作”、“向前移動”,“停止”。點選“開始”按鈕,在“開始動作”中我們只做了一個動作,“開門”動作,動作結束之後呼叫“forward”函式向前移動:
function startAnim() { if (window.isAnimationRunning) { return; } reset(); window.isAnimationRunning = true;//動畫是否正在進行 ht.Default.startAnim({ frames: 30, // 動畫幀數,預設採用`ht.Default.animFrames`。 interval: 20, // 動畫幀間隔,預設採用`ht.Default.animInterval`。 finishFunc: function() {// 動畫結束後呼叫的函式。 forward(); }, action: function(t){ // action函式必須提供,實現動畫過程中的屬性變化。 door.setRotationY(-120 * Math.PI / 180 * t); } }); }
這邊的“reset”函式就是“重置”回到原點的功能,我們通過這個函式將所有變化過的都恢復初始的位置,包括“門”的位置:
function reset() { if (window.isAnimationRunning) { return; } g3d.setCenter([0,0,0]); g3d.setEye([523, 5600, 8165]); window.forwardIndex = 0; door.setRotationY(0); }
要“移動”,肯定需要走路的“路徑”,也就是我們剛剛獲取到的“path”,程式碼中是通過 window.points = path.getPoints()._as 這種方式獲取“path”中的所有元素,但是這種直接呼叫私有變數的方法不好,因為 path.getPoints 函式獲取的是 ht.List 型別的物件,可以直接通過以下方式來獲取陣列中的節點(之後程式碼出現的 points[fowardIndex] 可以直接用 pointsArr[fowardIndex] 來替代):
var pointsArr = []; for(var i = 0; i < path.getPoints().size(); i++){ var point = path.getPoints().get(i); pointsArr.push(point); }
初始化 window.forwardIndex = 0; 通過控制“path”中前後兩點來設定 3D 場景中的 Eye 和 Center,這樣就能營造一個我們是第一人的效果:
var point1 = points[forwardIndex], point2 = points[forwardIndex + 1]; var distanceX = (point2.x - point1.x), distanceY = (point2.y - point1.y), distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY)-200;//兩點之間的距離通過三角形勾股定理計算 怕碰牆所以-200 g3d.setEye([point1.x, 1600, point1.y]);//眼睛的位置 g3d.setCenter([point2.x, 1600, point2.y]);//“我”的位置
HT 中 3D 元件有一個 walk(step, anim, firstPersonMode) 方法,該函式同時改變eye和center的位置,也就是eye和center在兩點建立的向量方向上同時移動相同的偏移量。step為偏移的向量長度值。firstPersonMode引數為空時則預設採用Graph3dView#isFirstPersonMode()當前值, 如果為第一人稱模式呼叫walk操作,該函式會考慮Graph3dView#getBoundaries()邊界限制。
g3d.walk(distance, { frames: 50, interval: 30, easing: function(t) {return t; }, finishFunc: function() { forwardIndex += 1; if (points.length - 2 > forwardIndex) {//points.length = 5 g3d.setCenter([point2.x, 1600, point2.y]);//把結束點變成起始點 g3d.rotate(Math.PI / 2, 0, { frames: 30, interval: 30, easing: function(t) {return t;}, finishFunc:function() { forward();} }); } else { var lastPoint = points[points.length - 1];//json 中path的points 的最後一個點 g3d.setCenter([lastPoint.x, 1400, lastPoint.y]); g3d.rotate(-Math.PI / 2, 0, { frames: 30, interval: 30, finishFunc: function() { window.isAnimationRunning = false; } }); } } });
不管“path”的點有多少個,這個判斷語句還是能運作,只在最後一個點是跳出 finishFunc 動畫結束後呼叫的函式,並將 window.isAnimationRunning 值設為 false 停止 startAnim 函式。如果不是最後一個點,使用者“旋轉”之後,回撥 forward 函式。至此,全部程式碼解釋完畢,很短的程式碼量,卻做出了這麼大的工程!
相關文章
- 基於 HTML5 WebGL 的 3D 機房HTMLWeb3D
- 基於 WebGl HTML5 的 3D 視覺化機房WebHTML3D視覺化
- 基於 HTML5 WebGL 的 3D 挖掘機HTMLWeb3D
- 基於HTML5的WebGL電信網管3D機房監控應用HTMLWeb3D
- 基於 HTML5 WebGL 的 3D 科幻風機HTMLWeb3D
- 基於 HTML5 Canvas 的 3D 機房建立HTMLCanvas3D
- Java 虛擬機器經典六問Java虛擬機
- 8個經典HTML5 3D動畫賞析HTML3D動畫
- 基於 HTML5 的 WebGL 3D 隧道監控HTMLWeb3D
- 基於 HTML5 WebGL 的 3D 風機視覺化系統HTMLWeb3D視覺化
- 基於 HTML5 WebGL 的挖掘機 3D 視覺化應用HTMLWeb3D視覺化
- 基於HTML5快速搭建3D機房裝置皮膚HTML3D
- 基於 WebGL 的 HTML5 3D 工控裙房系統WebHTML3D
- 基於 HTML5 WebGL 的 3D 模型斜面生成HTMLWeb3D模型
- 基於 WebGL HTML5 的 3D 模型分離控制WebHTML3D模型
- 基於 HTML5 WebGL 的 3D 工控裙房系統HTMLWeb3D
- 基於 HTML5 WebGL 的 3D “彈力”佈局HTMLWeb3D
- 基於 HTML5 WebGL 的發動機 3D 視覺化系統HTMLWeb3D視覺化
- 基於 HTML5 的 3D 機房視覺化實景監控HTML3D視覺化
- 基於HTML5 WebGL實現3D飛機葉輪旋轉HTMLWeb3D
- 基於 HTML5 WebGL 智慧城市的模擬執行HTMLWeb
- 基於 HTML5 WebGL 的 3D 網路拓撲圖HTMLWeb3D
- 基於 HTML5 + WebGL 的 3D 風力發電場HTMLWeb3D
- 基於 WebGL 的 HTML5 3D 網路拓撲圖WebHTML3D
- 基於 HTML5 WebGL 的 3D 倉儲管理系統HTMLWeb3D
- 基於HTML5的WebGL設計漢諾塔3D遊戲HTMLWeb3D遊戲
- 基於HTML5的電信網管3D機房監控應用HTML3D
- 基於 HTML5 WebGL 的 3D 伺服器與客戶端的通訊HTMLWeb3D伺服器客戶端
- pxe基於虛擬機器的自啟動虛擬機
- 基於 HTML5 WebGL + WebVR 的 3D 虛實現實視覺化培訓系統HTMLWebVR3D視覺化
- 基於 WebGL 實現的 HTML5 3D “彈力”佈局WebHTML3D
- 基於 HTML5 WebGL 實現的 3D “彈力”佈局HTMLWeb3D
- 基於 HTML5 + WebGL 的無人機 3D 視覺化系統HTMLWeb無人機3D視覺化
- 基於 HTML5 + WebGL 的太陽系 3D 展示系統HTMLWeb3D
- 基於 WebGL 的 HTML5 3D 棉花加工監控系統WebHTML3D
- 基於 WebGL 的 HTML5 3D SCADA 主站系統WebHTML3D
- 基於 HTML5 WebGL 的 3D SCADA 主站系統HTMLWeb3D
- 基於 HTML5 WebGL 的 3D 棉花加工監控系統HTMLWeb3D