文章前,先聊點啥吧。
最近元宇宙炒的挺火熱,在所有人都爭相定義元宇宙的時候,資本就開始著手入場了。當定義明確,全民皆懂之後,風口也就過去了。
前兩天看到新聞,新世界CEO宣佈購入最大的數字地塊,這塊虛擬土地的投資金額約為 3200 萬元人民幣。在這之前新世界以及他購買的虛擬土地持有公司名稱也都是鮮為人知的。這就是資本的力量,即打了廣告,又佔了風口坑位,一舉多得,好像現在沒個幾千萬上億的動態,都不足以博得大眾眼球。
那麼何為元宇宙,為何不是元世界、元地球,而是瘋狂到了宇宙這個範圍。如果真的虛擬到了宇宙的無窮無盡,試想一下,一塊虛擬土地能賣到幾千萬?所以重點不在虛擬土地的價格。重點是資本想讓你看到什麼。正所謂,見山不是山,見水不是水......
元宇宙,無論是使用還是創造,只有落實到具體應用,普及到全民參與,才能真正體現它的價值。試想一下,全球大部分公司都參與到元宇宙的研發,全球很多人都為元宇宙添磚加瓦,真正做到全民參與。那麼元宇宙才真正的發展起來。
所以解決問題的痛點在工具,為全民提供創造元宇宙的工具,才是方向....
序:
前段時間,做了一個數字孿生的專案,所謂數字孿生,百度百科解釋說,就是充分利用物理模型、感測器更新、執行歷史等資料,整合多學科、多物理量、多尺度、多概率的模擬過程,在虛擬空間中完成對映,從而反映相對應的實體裝備的全生命週期過程。數字孿生是一種超越現實的概念,可以被視為一個或多個重要的、彼此依賴的裝備系統的數字對映系統。是個普遍適應的理論技術體系,可以在眾多領域應用,在產品設計、產品製造、醫學分析、工程建設等領域應用較多。在國內應用最深入的是工程建設領域,關注度最高、研究最熱的是智慧製造領域。
通俗的講,就是利用三維技術,將生產過程、資料監測監控展示出來。
隨著物聯網技術發展,資料展示、大屏展示在IT界也是越發的流行與時尚,而這其中所應用到了關鍵的技術WebGL(three.js),也就理所當然的成為了集萬千寵愛於一生的前端焦點。
一、解決方案
數字孿生,解決主要在三大步驟:
1、資料採集:主要在感測器方面,如何選用感測器,適用不同場景,比如鍊鋼廠,需要採用耐高溫感測器,煤礦採用防靜電感測器等
2、資料傳輸與儲存:跟感測器配套方案,是否採用無線方案,或者是有線傳輸,都需要根據實際場景來判斷,還有這中間是否採用中間閘道器,做資料轉發等。然後就是資料如何儲存與處理。這涉及到平臺側的具體框架方案。
3、資料展示:展示方面,為了配合數字孿生這個名詞,只能採用3D顯示方案。對於3D的方案,光是展時端,我們就可以選擇CS、BS兩種方式的一種。當然,本篇我們選擇BS(webgl)方案。
前兩個部分,後面考慮用較詳細的文章篇幅詳細介紹。本文主要講解資料展示這一層的方案。
二、展示效果與程式碼實現
2.1、工業園區整體效果與實現
這裡主要是建模,與流光效果的實現。對於非重點監控車間,我們可以用虛擬建築模型方塊代替。
程式碼實現:
var initOption = { far:100000000, antialias: true, // 啟用平滑、抗鋸齒效果 loadSyn: false, // 是否啟用非同步載入 showHelpGrid: false, // 是否顯示網格線 clearCoolr: 0x4068b0, // 背景色 clearColorOp: 0, // 透明度 }; var AllModelJsons = []; //獲取園區模型; httpGetSyn("../js/models/build.json", function (rs) { AllModelJsons = rs; });
WT3DModel.initWT3D('canvas-frame', initOption, Aobjects);
2.2、雙擊重點展示工作車間,進入車間
這裡採用最簡單的頁面跳轉方式,顯示攝像頭推進,然後直接跳轉到另一個頁面,簡單而不失流程。還能充分回收資源。
程式碼實現:
if (_obj.name.indexOf("b1_112_out") >= 0) {//通過模型名稱判斷 setTimeout(function () { window.location = ("room.html"); }, 2000); modelBussiness.nearCameraPostion(_obj, _face); }
2.3、雙擊加熱爐,展示加熱爐內部鍛件的詳細資訊,與位置
這裡採用虛化周邊的方案。
modelBussiness.currentState = 10; modelBussiness.removeAllMsgs(); modelBussiness.commonFunc.hideAllModels(function () { if (_obj.name.indexOf("OBJCREN") > 0) { _obj = WT3DObj.commonFunc.findObject(_obj.name.split("OBJCREN")[0]); } if (_obj.oldPositionY) { _obj.position.y = _obj.oldPositionY; } _obj.visible = true; // modelBussiness.commonFunc.showJRLDetailMsg(_obj, function () { }); var tkname = "jlr_tiekuai_1"; if (_obj.name.indexOf("xsjrl_1135") >= 0) { tkname = "jlr_tiekuai_1"; } else if (_obj.name.indexOf("xsjrl_1136") >= 0) { tkname = "jlr_tiekuai_2"; } else if (_obj.name.indexOf("xsjrl_1137") >= 0) { tkname = "jlr_tiekuai_3"; } tk = WT3DObj.commonFunc.findObject(tkname); tk.visible = true; if (tk.oldPositionY) { tk.position.y = tk.oldPositionY; } WT3DObj.commonFunc.changeObjsOpacity([tk], 0, 1, 100, function () { }); WT3DObj.commonFunc.changeObjsOpacity([_obj], 0, 0.2, 1000, function () { modelBussiness.commonFunc.showNetDetail(WT3DObj.commonFunc.findObject(config.Mrelation[_obj.name + "_tiekuai"])); }); });
2.4、明顯標註感測器,並且檢視各部位感測器資訊。
這裡注意繫結感測器資料,並且使用突顯方案,顯示感測器標籤,在任何角度,都能看到感測器位置。
程式碼實現:
if (_obj.name.indexOf("wycgq_") >= 0) { $(".jrlDetail").hide(); // name = "位移感測器"; var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position); $("#MarkMessageHelper").remove(); $("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>"); $("#airConfig2Detail").show(); $("#airConfig2Detail").css("left", $("#MarkMessageHelper").css("left")); $("#airConfig2Detail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px"); } else if (_obj.name.indexOf("dajiliybp") >= 0) { $(".jrlDetail").hide(); // name = "打擊力應變片"; var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position); $("#MarkMessageHelper").remove(); $("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>"); $("#rackDetail").show(); $("#rackDetail").css("left", $("#MarkMessageHelper").css("left")); $("#rackDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px"); } else if (_obj.name.indexOf("_qiya") >= 0) { $(".jrlDetail").hide(); var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position); //name = "氣壓感測器"; $("#MarkMessageHelper").remove(); $("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>"); $("#upsDetail").show(); $("#upsDetail").css("left", $("#MarkMessageHelper").css("left")); $("#upsDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px"); } else if (_obj.name.indexOf("yeyacgq_") >= 0) { $(".jrlDetail").hide(); var screenPostion = WT3DObj.commonFunc.transToScreenCoord(_obj.position); //name = "液壓感測器"; $("#MarkMessageHelper").remove(); $("body").append("<div id='MarkMessageHelper' style='position:absolute;left:" + (screenPostion.x) + "px;top:" + screenPostion.y + "px;height:2px;width:2px;z-index:1000;'></div>"); $("#upsDetail").show(); $("#upsDetail").css("left", $("#MarkMessageHelper").css("left")); $("#upsDetail").css("top", (parseFloat($("#MarkMessageHelper").css("top")) - 170) + "px"); } else { $(".jrlDetail").show(); }
三、資料驅動,根據車間實時動作,在三維內展示實時動作
3.1、軌道機械臂,從加熱爐中取料
實現程式碼:
isDoAction = true; var jxb = WT3DObj.commonFunc.findObject("jxbct_369"); var jxbdp = WT3DObj.commonFunc.findObject("jxbdp_373"); if(name=="xsjrl_1135"){ new TWEEN.Tween(jxb.position).to({ x: 7054.110 }, 1000).onComplete(function () { }).start(); new TWEEN.Tween(jxbdp.position).to({ x: 7054.110 }, 1000).onComplete(function () { WT3DObj.commonFunc.changeCameraPosition( {x: 11987.945516911437, y: 5821.875816333479, z: 639.598300399881}, {x: 5418.917462960544, y: -132.7956226536168, z: 2029.241082946989}, 500, function () { jrlAnimation(700, name) setTimeout(function () { jxbAnimation("sc", null, 500); setTimeout(function () { jxbAnimation("showtk"); setTimeout(function () { jxbAnimation("ss"); setTimeout(function () { WT3DObj.commonFunc.changeCameraPosition( { x: 10739.533256704372, y: 4071.9019928732682, z: 4924.279861011403 }, { x: 6579.256577472461, y: 55.12686192176127, z: 1749.5443318108976 }, 500, function () { jxbAnimation("xz"); setTimeout(function () { jxbAnimation("sc"); setTimeout(function () { jxbAnimation("hidetk"); WT3DObj.commonFunc.findObject("tiekuai_0").visible = true; setTimeout(function () { isDoAction = false; jxbAnimation("ss"); jxbAnimation("backxz"); }, 200); }, 600); }, 600); }); }, 600); }, 300); }, 800); }, 1000); }); }).start(); }
加熱爐動畫:
//加熱爐 function jrlAnimation(moveLength,name) { var ylj_1 = WT3DObj.commonFunc.findObject(name?name:"xsjrl_1135").children[19];//394 var ylj_2 = WT3DObj.commonFunc.findObject(name ? name : "xsjrl_1135").children[11];//-112 var ylj_3 = WT3DObj.commonFunc.findObject(name ? name : "xsjrl_1135").children[12];//-112 if (!ylj_1.oldPostionY) { ylj_1.oldPostionY = ylj_1.position.y; } if (!ylj_2.oldPostionY) { ylj_2.oldPostionY = ylj_2.position.y; } if (!ylj_3.oldPostionY) { ylj_3.oldPostionY = ylj_3.position.y; } ylj_1.currentPostionY = ylj_1.position.y; ylj_2.currentPostionY = ylj_2.position.y; ylj_3.currentPostionY = ylj_3.position.y; var movePosition = { y: 0 } new TWEEN.Tween(movePosition).to({ y: moveLength }, 500).onUpdate(function () { ylj_1.position.y = ylj_1.currentPostionY + this.y; if (ylj_1.position.y < ylj_1.oldPostionY - moveLength) { ylj_1.position.y =ylj_1.oldPostionY - moveLength } ylj_1.matrixAutoUpdate = true; ylj_2.position.y = ylj_2.currentPostionY + this.y; if (ylj_2.position.y < ylj_2.oldPostionY - moveLength) { ylj_2.position.y = ylj_2.oldPostionY - moveLength } ylj_2.matrixAutoUpdate = true; ylj_3.position.y = ylj_3.currentPostionY + this.y; if (ylj_3.position.y < ylj_3.oldPostionY - moveLength) { ylj_3.position.y = ylj_3.oldPostionY - moveLength } ylj_3.matrixAutoUpdate = true; }).onComplete(function () { }).start(); }
3.2、機械臂從中間臺上取料
實現程式碼:
case "ql"://取料 isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false; WT3DObj.commonFunc.findObject("tiekuai_1").visible = false; WT3DObj.commonFunc.changeCameraPosition( { x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() { var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = true; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = false; jxb_zz_6_3A0(function() { jxb_zz_6_3A01(function() { isDoAction = false; }) }) }); break;
3.3、機械臂將取到的料放置到壓力機下面
實現程式碼:
case "2": case "fl"://放料 isDoAction = true; WT3DObj.commonFunc.changeCameraPosition( { x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() { jxb_zz_6_3A2(function () { WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false; WT3DObj.commonFunc.findObject("tiekuai_1").visible = true; jxb_zz_6_3A3(function () { var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = false; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = true; jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false; isDoAction = false; }) }); });
3.4、壓力機摧壓貨料。
程式碼實現:
case "3": case "ylj"://壓力機打擊 isDoAction = true; var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = false; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = true; jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false; WT3DObj.commonFunc.changeCameraPosition( { x: 7193.942917022709, y: 1335.12023764365, z: 1186.3353004352634 }, { x: 6790.381940272481, y: 763.1919527866438, z: -44.54061049048587 }, 500, function() { yaliji_1126_A1(function () { isDoAction = false; }, 0) }); break;
3.5、機械臂噴霧
這裡實現比較簡單,本可以用粒子方案,後來為了省事,直接用流體方案實現
case "4": case "qbjqbcp"://噴霧 isDoAction = true; var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = false; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = true; jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false; WT3DObj.commonFunc.changeCameraPosition( { x: 6992.126352231225, y: 548.5464812898373, z: 1331.9129698522017 }, { x: 6795.575361553676, y: 631.1769732337358, z: -557.178527158633 }, 500, function() { pqj_6_1266A2(function() { WT3DObj.commonFunc.findObject("flowtube_1368").visible = true; setTimeout(function(){ WT3DObj.commonFunc.findObject("flowtube_1368").visible = false; pqj_6_1266A3(function() { isDoAction = false; }); },3000); }); }); break;
3.6、機械臂取出鍛件半成品
程式碼實現:
case "qcyljdj"://取出壓力機鍛件 WT3DObj.commonFunc.findObject("tiekuai_3").visible = false; isDoAction = true; var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = false; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = true; jxb_zz_6_3_1.children[4].children[2].children[4].children[10].children[2].children[5].visible = false; WT3DObj.commonFunc.changeCameraPosition( { x: 7131.978477911106, y: 2829.502314368439, z: 2197.1946670176567 }, { x: 6411.024615439089, y: 528.9277768783592, z: 856.9774806044239 }, 500, function() { // jxb_zz_6_3_1A2(function () { WT3DObj.commonFunc.findObject("tiekuai_1").visible = false; WT3DObj.commonFunc.findObject("tiekuai_1_1").visible = false; jxb_zz_6_3_1A3(true,function () { isDoAction = false; }) }) }); break;
case "6": case "fxyljdj"://放下壓力機鍛件 WT3DObj.commonFunc.findObject("tiekuai_3").visible = false; isDoAction = true; var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = false; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = true; jxb_zz_6_3_1A4(function () { isDoAction = false; WT3DObj.commonFunc.findObject("tiekuai_3").visible = true; jxb_zz_6_3_1A1(function () { isDoAction = false; }) }) break;
3.7、機械臂將鍛件放置到傳送帶上
程式碼實現:
case "7": case "yd"://移動 var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = true; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = false; /* else if (data.conveyorToCut==1) {//傳送到切邊機 state = "7"; } */ isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_3").visible = true; WT3DObj.commonFunc.changeCameraPosition( { x: 3088.224325931938, y: 2460.282161815149, z: 3740.1275634657304 }, { x: 4081.729182608692, y: 203.35568280176042, z: 654.5133357334003 }, 500, function() { tiekuai3_A1(function () { isDoAction = false; }); }); break;
3.8、傳送帶,傳送鍛件至切邊機一側
case "7": case "yd"://移動 var jxb_zz_6_3 = WT3DObj.commonFunc.findObject("jxb_zz_6_3"); jxb_zz_6_3.visible = true; var jxb_zz_6_3_1 = WT3DObj.commonFunc.findObject("jxb_zz_6_3_1"); jxb_zz_6_3_1.visible = false; /* else if (data.conveyorToCut==1) {//傳送到切邊機 state = "7"; } */ isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_3").visible = true; WT3DObj.commonFunc.changeCameraPosition( { x: 3088.224325931938, y: 2460.282161815149, z: 3740.1275634657304 }, { x: 4081.729182608692, y: 203.35568280176042, z: 654.5133357334003 }, 500, function() { tiekuai3_A1(function () { isDoAction = false; }); }); break;
3.9、機械臂取出鍛件,放置到切邊機上
case "8": case "qbjqj"://切邊機機取料 /* else if (data.conveyorToPress == 1 || data.r2ConveyorCatch == 1) {//從傳送帶抓料子並復原傳送帶 state = "8"; } */ WT3DObj.commonFunc.changeCameraPosition( { x: 1176.799334050281, y: 2261.502847148386, z: -3176.64624829932 }, { x: 2172.7062907541617, y: -1082.7207373607675, z: 549.2316313972628 }, 500, function() { jxb_zz_6_795A4(function () { jxb_zz_6_795A1(function () { csddzsbbf_1212A2();//復原傳送帶 isDoAction = false; }); }); }); break; case "9": case "qbjfl"://切邊機機放料 /* if (data.r2SendCut == 1) {//機械臂往切邊機送料 state = "9"; } else if (data.cutStrike == 1) {//切邊 state = "10"; } else if (data.r2CutCatch == 1) {//取料 state = "11"; } else if (data.r2CutOverlap == 1) {//取飛邊 state = "12"; } */ WT3DObj.commonFunc.findObject("tiekuai_2").visible = false; WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = false; isDoAction = true; WT3DObj.commonFunc.changeCameraPosition( { x: 1176.799334050281, y: 2261.502847148386, z: -3176.64624829932 }, { x: 2172.7062907541617, y: -1082.7207373607675, z: 549.2316313972628 }, 500, function() { jxb_zz_6_795A2(function () { WT3DObj.commonFunc.findObject("tiekuai_2").visible = true; WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = true; jxb_zz_6_795A3(function() { isDoAction = false; }); }); }); break;
3.10、切邊機,切邊
case "10": case "qbjqb"://切邊機切邊 isDoAction = true; WT3DObj.commonFunc.changeCameraPosition( { x: 1268.7356763452408, y: 1568.1044843402083, z: -2963.5457047272607 }, { x: 1348.071262611549, y: 377.4064330677588, z: 594.0594238388968 }, 500, function() { qiebianji_1293_A1(function() { isDoAction = false; }); }); break;
3.11、取出切好的鍛件,放到觀測臺上觀測
case "11": case "qbjqbcp"://取出成品 WT3DObj.commonFunc.findObject("duanjian_1_2355").visible = false; isDoAction = true; WT3DObj.commonFunc.changeCameraPosition( { x: 1242.5999280327703, y: 3110.0888878135233, z: -6003.8189588224295 }, { x: 127.35800599694372, y: -857.7840251121656, z: -414.9639298471293 }, 500, function () { WT3DObj.commonFunc.findObject("tiekuai_2").visible = false; jxb_zz_6_795A6(function () { WT3DObj.commonFunc.findObject("duanjian_1_2355").visible = true; var duanjian_1_2355 = WT3DObj.commonFunc.findObject("duanjian_1_2355"); //duanjian_1_2355.position.y = 577.047; //duanjian_1_2355.position.x = 1109.776; duanjian_1_2355.visible = true; setTimeout(function () { jxb_zz_6_795A3(); setTimeout(function () { isDoAction = false; }, 1000); }, 1000); //new TWEEN.Tween(duanjian_1_2355.position).to({ // x: -522.392, //}, 1500).onUpdate(function () { //}).onComplete(function () { // jxb_zz_6_795A3(); // new TWEEN.Tween(duanjian_1_2355.position).to({ // x: -691.733, // y: 33.214, // }, 1500).onUpdate(function () { // }).onComplete(function() { // isDoAction = false; // }).start(); //}).start(); }); }); break;
3.12、取出飛邊毛料,放到對應的框中
case "12": case "qbjqbfb"://取出飛邊 isDoAction = true; WT3DObj.commonFunc.findObject("tiekuai_2_1").visible = false; WT3DObj.commonFunc.findObject("tiekuai_2_123").visible = false; WT3DObj.commonFunc.changeCameraPosition( { x: 1242.5999280327703, y: 3110.0888878135233, z: -6003.8189588224295 }, { x: 127.35800599694372, y: -857.7840251121656, z: -414.9639298471293 }, 500, function() { jxb_zz_6_795A5(function() { isDoAction = false; WT3DObj.commonFunc.findObject("tiekuai_2_123").visible = true; jxb_zz_6_795A3(); }); }); break;
技術交流 1203193731@qq.com
交流微信:
如果你有什麼要交流的心得 可郵件我
其它相關文章:
使用webgl(three.js)建立3D機房,3D機房微模組詳細介紹(升級版二)
如何用webgl(three.js)搭建一個3D庫房-第一課
如何用webgl(three.js)搭建一個3D庫房,3D密集架,3D檔案室,-第二課
使用webgl(three.js)搭建一個3D建築,3D消防模擬——第三課
使用webgl(three.js)搭建一個3D智慧園區、3D建築,3D消防模擬,web版3D,bim管理系統——第四課
如何用webgl(three.js)搭建不規則建築模型,客流量熱力圖模擬
使用webgl(three.js)搭建一個3D智慧園區、3D建築,3D消防模擬,web版3D,bim管理系統——第四課(炫酷版一)