ThingJS 使用

ThingJS串结,注意不是 Three.js哑子,是比Three.js 封裝度更高得3D框架,但不是開源的肌割,使用得付費(fèi)卧蜓。也不是特別成熟,僅調(diào)研一波把敞。

1弥奸、場(chǎng)景導(dǎo)入

  • 控制臺(tái) 新建項(xiàng)目保存
  • 下載 CampusBuilder ,創(chuàng)建一個(gè)場(chǎng)景并導(dǎo)出為 Thingjs 場(chǎng)景包B奋早,如 hmf.tjs 格式
  • 控制臺(tái) "我的資源-我的場(chǎng)景-上傳場(chǎng)景"上傳導(dǎo)出的場(chǎng)景包B
  • 打開在線開發(fā)平臺(tái)盛霎,通過(guò) "資源-場(chǎng)景資源" 引入場(chǎng)景包B

2、模型制作

提供三種方式制作模型

  • 打開在線開發(fā)平臺(tái)耽装,通過(guò) "資源-模型資源" 搜索需要的模型
  • 資源中心愤炸,可找到很多付費(fèi)和免費(fèi)的模型,然后通過(guò)url創(chuàng)建
  • 個(gè)人 obj 模型掉奄,將 obj 資源按照以下格式打成zip包



    然后在 CampusBuilder 里的DIY模型庫(kù) tab 里點(diǎn)擊上傳資源

3规个、常用操作

  • 創(chuàng)建對(duì)象
var truck = app.create({
  type: "Thing",
  name: "truck",
  position: [-5, 0, 0],
  url: "https://www.thingjs.com/static/models/truck/",
  complete: function() {
    console.log("truck created!");
  }
});
參數(shù)含義

創(chuàng)建對(duì)象后,設(shè)置其世界坐標(biāo)即可展示在場(chǎng)景中。注意要設(shè)置其父元素诞仓,否則會(huì)直接掛到app下

  • 獲取對(duì)象
    主要通過(guò) query 方式以及層級(jí)關(guān)系查詢對(duì)象缤苫,query支持 id,類墅拭,屬性活玲,正則查詢等。查詢結(jié)果返回的是一個(gè) Selector 對(duì)象谍婉,查詢結(jié)果可以相加舒憾、排除,也可以直接綁定事件穗熬,或一些批量操作
// 查詢id是100的對(duì)象
app.query("#100")[0];

// 查詢名稱(name)是 car01 的對(duì)象
app.query("car01");

// 查詢物體類是Thing的對(duì)象
app.query(".Thing");

//有物體類型屬性的珍剑,無(wú)論值是什么
app.query("[alarm]");

//查詢物體類型屬性是糧倉(cāng)的對(duì)象
app.query("[報(bào)警=normal]");
app.query('["userData/物體類型"="糧倉(cāng)"]');

// 查詢levelNum屬性大于2的對(duì)象,目前支持 <= , < , = , > , >=
app.query("[levelNum>2]");

// 正則表達(dá)式(RegExp)對(duì)象,目前只是對(duì)名稱(name)屬性值進(jìn)行正則匹配
app.query(/car/);
// 上例等同于
var reg=new RegExp('car');
app.query(reg);
  • 控制對(duì)象
    可控制的有:
    1死陆、物體顯示與隱藏 visible招拙;
    2、物體移動(dòng) position措译,localPosition别凤,translate;
    3领虹、物體旋轉(zhuǎn) angles规哪,localAngles,rotateX塌衰,rotateY诉稍,rotate Y
    4、縮放 scale
    5最疆、位移杯巨、旋轉(zhuǎn)、縮放動(dòng)畫 moveTo努酸,rotateTo服爷,scaleTo
    6、CSS屬性控制获诈,如透明度 opacity仍源、描邊outline、顏色 color舔涎、進(jìn)出場(chǎng)動(dòng)畫 fadeIn fadeOut
    7笼踩、連接操作:通過(guò) add 接口可以添加子元素,添加子元素時(shí)亡嫌,子物體的世界位置不發(fā)生變化嚎于,并保持那一刻與父物體的相對(duì)位置關(guān)系進(jìn)行移動(dòng)
  • 鼠標(biāo)交互
    1桶至、picker,結(jié)合 mouseenter 和 mouseleave 事件實(shí)現(xiàn)鼠標(biāo)懸浮選中效果
// 鼠標(biāo)拾取物體顯示邊框
    app.on(THING.EventType.MouseEnter, '.Thing', function(ev) {
        ev.object.style.outlineColor = '#FF0000';
    });
    // 鼠標(biāo)離開物體邊框取消
    app.on(THING.EventType.MouseLeave, '.Thing', function(ev) {
        ev.object.style.outlineColor = null;
    });

    // 每一幀判斷拾取的物體是否發(fā)生變化
    app.on('update', function () {
        if (app.picker.isChanged()) {
            console.clear();
            // 打印當(dāng)前被pick的物體
            if (app.picker.objects[0]) {
                console.log('當(dāng)前拾取的物體 ' + app.picker.objects[0].name);
            }
            // 打印之前被pick的物體
            if (app.picker.previousObjects[0]) {
                console.log('之前拾取的物體 ' + app.picker.previousObjects[0].name);
            }
        }
    });

2匾旭、selection,鼠標(biāo)點(diǎn)擊選中效果圃郊,這個(gè)跟click事件不一樣价涝,selection 相當(dāng)于在內(nèi)部給你保存了選中的所有物體

  • 攝像機(jī)
    攝像機(jī)包含兩個(gè)重要的位置參數(shù):鏡頭位置 position 和被拍攝物體的位置 target (又叫目標(biāo)點(diǎn))
    1、設(shè)置攝像機(jī)位置 position,target 和 object 二選一
// 直接設(shè)置
app.camera.position = [0, 20, 20]; // 鏡頭位置
app.camera.target = [-30, 10, 0]; // 目標(biāo)點(diǎn)位置
// fit 方法設(shè)置
app.camera.fit({
  position: [100, 100, 100],
  target: [0, 0, 0]
});
//設(shè)置攝像機(jī)到物體的“最佳看點(diǎn)”
app.camera.fit(obj);

//當(dāng)不傳參數(shù)時(shí)持舆,設(shè)置攝像機(jī)到當(dāng)前整個(gè)場(chǎng)景下的“最佳看點(diǎn)”
app.camera.fit();
// 自定義設(shè)置
app.camera.fit({
  'object': obj,
  'xAngle': 60,  //繞物體自身X軸旋轉(zhuǎn)角度
  'yAngle': 30,  //繞物體自身Y軸旋轉(zhuǎn)角度
  'radiusFactor':3,  //物體包圍球半徑的倍數(shù)
});

2色瘩、lookAt 設(shè)置相機(jī)觀察的物體

//攝像機(jī)一直“盯著”[0,0,0]點(diǎn)看
app.camera.lookAt([0, 0, 0]); //
//攝像機(jī)一直“盯著”某物體看
var obj = app.query("car01")[0];
app.camera.lookAt(obj);
//取消攝影機(jī)一直盯著物體看
app.camera.lookAt(null);

3、flyTo 讓攝像機(jī)從當(dāng)前位置逸寓,飛行到將要設(shè)置的位置

//以Quartic.In的插值方式 讓飛行速度漸增
app.camera.flyTo({
  position: [0, 20, 20],
  target: [-30, 10, 0],
  time: 3 * 1000,
  lerpType: THING.LerpType.Quartic.In
});

//自定義飛到物體的攝像機(jī)位置參數(shù)(同fit)
app.camera.flyTo({
  object: obj,
  xAngle: 30, //繞物體自身X軸旋轉(zhuǎn)角度
  yAngle: 60, //繞物體自身Y軸旋轉(zhuǎn)角度
  radiusFactor: 3, //物體包圍盒半徑的倍數(shù)
  time: 5 * 1000,
  complete: function() {
    console.log("飛行結(jié)束");
  }
});

4居兆、routateAround 設(shè)置相機(jī)環(huán)繞某點(diǎn)飛行

  //環(huán)繞[0,0,0]點(diǎn)旋轉(zhuǎn) 180 度,5s 轉(zhuǎn)完
  app.camera.rotateAround({
    target: [0,0,0],//環(huán)繞的坐標(biāo)點(diǎn)
    time: 5*1000,//環(huán)繞飛行的時(shí)間
    yRotateAngle : 180,//環(huán)繞y軸飛行的旋轉(zhuǎn)角度
    complete:function(){
        console.log('結(jié)束環(huán)繞飛行');
    }
  });

5竹伸、followObject 設(shè)置相機(jī)跟隨物體

 app.camera.followObject(obj);

6泥栖、move(),zoom()勋篓,rotateY()吧享,rotateX()來(lái)控制攝像機(jī)的移動(dòng)、縮放譬嚣、旋轉(zhuǎn)

//攝像機(jī)水平移動(dòng) 10m
app.camera.move(10, 0);
//攝像機(jī)垂直移動(dòng) 10m
app.camera.move(0, 10);
//攝像機(jī)向前推進(jìn) 10m
app.camera.zoom(10);
//設(shè)置攝像機(jī)target為圓心轉(zhuǎn)在水平方向上旋轉(zhuǎn)的夾角增量
app.camera.rotateY(20);
// 設(shè)置攝像機(jī)target為圓心轉(zhuǎn)在豎直方向上旋轉(zhuǎn)的夾角增量
app.camera.rotateX(20);
  • 界面元素
    1钢颂、3D元素 Marker,Webview,會(huì)隨著縮放進(jìn)大遠(yuǎn)小
app.create({
  type: "Marker",
  offset: [0, 2, 0],
  size: [4, 4],
  url: "https://thingjs.com/static/images/warning1.png",
  parent: app.query("car01")[0]
});

2拜银、2D元素UIAnchor殊鞭,需要自己寫 html

var uiAnchor = app.create({
  type: "UIAnchor",
  parent: app.query("car02")[0],
  element: document.getElementById("XXXX"),
  localPosition: [0, 2, 0],
  pivot: [0.5, 1]
});
uiAnchor.destroy();
uiAnchor.visible = true / false;

3、快捷界面庫(kù)尼桶,一些 panel 控件操灿,也可以綁定到模型上

// 創(chuàng)建UIAnchor面板
    var ui = app.create({
        // 類型
        type: 'UIAnchor',
        // 父節(jié)點(diǎn)設(shè)置
        parent: obj,
        // 要綁定的頁(yè)面的 element 對(duì)象
        element: panel.domElement,
        // 設(shè)置 localPosition 為[0, 0, 0]
        localPosition: [0, 0, 0],
        // 指定頁(yè)面的哪個(gè)點(diǎn)放到 localPosition 位置上
        pivot: [-0.15, 1.8]
    });
  • 數(shù)據(jù)對(duì)接
    1、ajax泵督,在 ThingJS 在線開發(fā)環(huán)境中牲尺,內(nèi)置了 JQuery 庫(kù),可以直接使用 JQurey 封裝的 Ajax 方法進(jìn)行數(shù)據(jù)對(duì)接
$.ajax({
    'url': "http://3dmmd.cn:83/getMonitorDataById", //Ajax請(qǐng)求服務(wù)的地址
    'type': "GET", //請(qǐng)求方式 "POST" 或 "GET"幌蚊,默認(rèn)為 "GET"
    'dataType': "json",    //服務(wù)返回的數(shù)據(jù)類型谤碳,推薦使用標(biāo)準(zhǔn)JSON數(shù)據(jù)格式
    //發(fā)送到服務(wù)器的數(shù)據(jù)
    'data': { 'id': 89757 },
    //請(qǐng)求成功后的回調(diào)函數(shù)
    'success': function (data) {
        console.log(data);
        // 處理返回的數(shù)據(jù)
    },
    //請(qǐng)求失敗時(shí)調(diào)用的函數(shù) 有以下三個(gè)參數(shù):XMLHttpRequest 對(duì)象、錯(cuò)誤信息溢豆、(可選)捕獲的異常對(duì)象
    'error': function (xhr, status, error) {
        console.log(xhr);
    },
});

2蜒简、websocket

// 創(chuàng)建一個(gè)WebSocket連接
var webSocket = new WebSocket('ws://3dmmd.cn:82');
// 建立 websocket 連接成功 觸發(fā)open事件
webSocket.onopen = function () {
    console.log("websocket服務(wù)器連接成功...");
};

// 接收服務(wù)端數(shù)據(jù) 觸發(fā)message事件
webSocket.onmessage = function (ev) {
    console.log("websocket接收到的數(shù)據(jù):" + ev.data);
};
// 關(guān)閉連接后 觸發(fā)close事件
webSocket.onclose = function (evt) {
    console.log("websocket關(guān)閉...");
};
// 通信發(fā)生錯(cuò)誤時(shí) 觸發(fā)error事件
webSocket.onerror = function () {
    console.log('發(fā)生錯(cuò)誤')
}
var dataObj = { 'id': 89785 };
// send 數(shù)據(jù)類型可以是 字符串 或 二進(jìn)制對(duì)象(Blob 對(duì)象、ArrayBuffer 對(duì)象)
webSocket.send(JSON.stringify(dataObj));

一些概念

  • 資源:場(chǎng)景資源(場(chǎng)景+模型) + 頁(yè)面資源 + 全景圖資源

  • 層級(jí)
    1漩仙、層級(jí)可以讓我們方便管理和查詢到場(chǎng)景中物體 && 批量操作物體
    2搓茬、可以通過(guò) app.level.change(obj) 切換到對(duì)應(yīng)層級(jí)犹赖,app.level.back() 返回
    3、有兩套層級(jí)體系:父子樹和分類對(duì)象屬性樹
    父子樹卷仑,通過(guò) children 連接層級(jí):root => campus => building峻村,ground,thing

    父子樹

    分類對(duì)象屬性樹:每個(gè)對(duì)象都內(nèi)置了一些屬性锡凝,如 root.campuses粘昨,campus.ground,campus.buildings窜锯,campus.things张肾,building.facade,building.floors锚扎,building.things吞瞪,floor.rooms,floor.things
    分類對(duì)象屬性樹

    4驾孔、當(dāng)進(jìn)入層級(jí)時(shí)會(huì)觸發(fā) EnterLevel 事件芍秆。
    當(dāng)退出層級(jí)時(shí)會(huì)觸發(fā) LeaveLevel 事件。
    當(dāng)默認(rèn)的層級(jí)切換飛行結(jié)束后翠勉,會(huì)觸發(fā) THING.EventType.LevelFlyEnd 事件

  • 坐標(biāo)系
    1浪听、世界坐標(biāo)系
    2、父級(jí)坐標(biāo)系
    3眉菱、自身坐標(biāo)系

基本套路

  • 加載場(chǎng)景
  • 創(chuàng)建面板
  • load 事件中處理邏輯
// 加載場(chǎng)景
var app = new THING.App({
    // 場(chǎng)景地址
    "url": "models/silohouse",
    // 天空盒
    "skyBox": "Universal"
});
// load 處理
app.on('load', function (ev) {
    // 獲取糧倉(cāng)
    siloHouse = app.query("[物體類型=糧倉(cāng)]");
    // 添加糧倉(cāng)自定義屬性monitorData迹栓,用來(lái)存儲(chǔ)監(jiān)控信息
    siloHouse.forEach(function (obj) {
        obj.monitorData = {};
    });

    // 創(chuàng)建開關(guān)控件
    createSwitchControl();
});

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俭缓,隨后出現(xiàn)的幾起案子克伊,更是在濱河造成了極大的恐慌,老刑警劉巖华坦,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愿吹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惜姐,警方通過(guò)查閱死者的電腦和手機(jī)犁跪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)歹袁,“玉大人坷衍,你說(shuō)我怎么就攤上這事√跆颍” “怎么了枫耳?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)孟抗。 經(jīng)常有香客問(wèn)我迁杨,道長(zhǎng)钻心,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任铅协,我火速辦了婚禮捷沸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狐史。我一直安慰自己痒给,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布预皇。 她就那樣靜靜地躺著,像睡著了一般婉刀。 火紅的嫁衣襯著肌膚如雪吟温。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天突颊,我揣著相機(jī)與錄音鲁豪,去河邊找鬼。 笑死律秃,一個(gè)胖子當(dāng)著我的面吹牛爬橡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棒动,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼糙申,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了船惨?” 一聲冷哼從身側(cè)響起柜裸,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎粱锐,沒(méi)想到半個(gè)月后疙挺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怜浅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年铐然,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恶座。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搀暑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跨琳,到底是詐尸還是另有隱情险掀,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布湾宙,位于F島的核電站樟氢,受9級(jí)特大地震影響冈绊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜埠啃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一死宣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碴开,春花似錦毅该、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至巴碗,卻和暖如春朴爬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背橡淆。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工召噩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逸爵。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓具滴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親师倔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子构韵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自VR設(shè)計(jì)云課堂[http://www.reibang.com/u/c7ffdc4b379e]Unity S...
    水月凡閱讀 1,016評(píng)論 0 0
  • 更新:【面試題含答案】http://bbs.9ria.com/thread-288394-1-1.html 高頻問(wèn)...
    好怕怕閱讀 4,747評(píng)論 3 52
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,103評(píng)論 1 32
  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,152評(píng)論 3 23
  • 相信同學(xué)們都一樣,當(dāng)上課鈴響起趋艘,都開始期待著下課鈴贞绳。 每當(dāng)課上到結(jié)尾時(shí),我都喜歡盯著音箱致稀,當(dāng)有紅色的字...
    胡雨huyu閱讀 529評(píng)論 2 4