three.js創(chuàng)建樓層布局圖的示例代碼
最近大半年一直在做三維部分的工作,之前做三維樓層都是外部加載使用建模工具創(chuàng)建的模型,但是渲染不夠靈活、無(wú)法綁定房間信息,所以決定來(lái)使用three.js來(lái)創(chuàng)建樓層布局。
1.調(diào)整光源
燈光有SpotLight、AmbientLight、DirectionalLight等、實(shí)際項(xiàng)目一般都是多個(gè)燈光組合的方式來(lái)創(chuàng)建光源。這里我使用的是DirectionalLight+AmbientLight的方式。
var ambientLight = new THREE.AmbientLight( 0xffffff, 0.8 ); //環(huán)境光 scene.add( ambientLight ); var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.3 ); //直射光 directionalLight.position.set( 1, 1, 0 ).normalize(); scene.add( directionalLight );
2.創(chuàng)建地板、房間
網(wǎng)絡(luò)上查的資料,別人都是以boxGeometry的方式創(chuàng)建房間和地板,但實(shí)際中這些不一定是盒子形狀,所以我根據(jù)底部頂點(diǎn)+高度獲取頂部頂點(diǎn),再根據(jù)各頂點(diǎn)計(jì)算和指定三角面,最終創(chuàng)建任意形狀的盒子模型。
Floor.prototype.getGeometry = function(points,height){ var topPoints = []; for(var i=0;i<points.length;i++){ var vertice = points[i]; topPoints.push([vertice[0],vertice[1]+height,vertice[2]]); } var totalPoints = points.concat(topPoints); var vertices =[]; //所有的頂點(diǎn) for(var i=0;i<totalPoints.length;i++){ vertices.push(new THREE.Vector3(totalPoints[i][0],totalPoints[i][1],totalPoints[i][2])) } var length = points.length; var faces = []; for(var j=0;j<length;j++){ //側(cè)面生成三角形 if(j!=length-1){ faces.push(new THREE.Face3(j,j+1,length+j+1)); faces.push(new THREE.Face3(length+j+1,length+j,j)); }else{ faces.push(new THREE.Face3(j,0,length)); faces.push(new THREE.Face3(length,length+j,j)); } } var data=[]; for(var i=0;i<length;i++){ data.push(points[i][0],points[i][2]); } var triangles = Earcut.triangulate(data); if(triangles && triangles.length != 0){ for(var i=0;i<triangles.length;i++){ var tlength = triangles.length; if(i%3==0 && i < tlength-2){ faces.push(new THREE.Face3(triangles[i],triangles[i+1],triangles[i+2])); //底部的三角面 faces.push(new THREE.Face3(triangles[i]+length,triangles[i+1]+length,triangles[i+2]+length)); //頂部的三角面 } } } var geometry = new THREE.Geometry(); geometry.vertices = vertices; geometry.faces = faces; geometry.computeFaceNormals(); //自動(dòng)計(jì)算法向量 return geometry; }
3.指定材質(zhì)
為了使房間看起來(lái)更清晰一點(diǎn),我們頂部指定材質(zhì)不受光照影響,側(cè)面加入光源變化效果。于是創(chuàng)建兩種材質(zhì),創(chuàng)建三角面的時(shí)候指定面的材質(zhì)。
var material = [ new THREE.MeshLambertMaterial({color:colorConst[colorIndex].fill,side:THREE.DoubleSide}), //受光照影響 new THREE.MeshBasicMaterial({color:colorConst[colorIndex].fill,side:THREE.DoubleSide}) //不受光照影響 ]; topface.materialIndex = 1; //頂部的三角面 指定材質(zhì)序號(hào)為1,其他默認(rèn)為0
4.創(chuàng)建盒子頂部的邊界線
我們需要添加頂部面界線,來(lái)使各個(gè)盒子之間分界看起來(lái)清晰一點(diǎn),于是我們根據(jù)頂部的坐標(biāo)創(chuàng)建一條線,添加盒子的同時(shí)添加這條線。
//生成頂部的線 Floor.prototype.getBorderGeometry = function(points,color){ var geometry = new THREE.Geometry(); for(var i=0;i<points.length;i++){ var point = points[i]; geometry.vertices.push(new THREE.Vector3(point[0],point[1],point[2])); if(i== point.length-1){ geometry.vertices.push(new THREE.Vector3(point[0][0],point[0][1],point[0][2])); } } return geometry; }
5.創(chuàng)建標(biāo)注
見(jiàn)我的另一篇筆記:使用three.js開(kāi)發(fā)3d地圖初探_凡事有果必有因-CSDN博客 第3、4點(diǎn)。
6.選中效果
raycaster類用于在3d中被鼠標(biāo)選中的物體,這同樣可以選中mesh對(duì)象,于是用此方法模擬設(shè)備的點(diǎn)擊。其中floorGroup是保存所有樓層mesh的object3d對(duì)象。
function onDocumentMouseClick(event){ var vector = new THREE.Vector3();//三維坐標(biāo)對(duì)象 vector.set( ( event.clientX / container.clientWidth ) * 2 - 1, - ( event.clientY / container.clientHeight ) * 2 + 1, 0.5 ); vector.unproject( camera ); var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize()); var intersects = raycaster.intersectObjects(floorGroup.children); //樓層中的元素 if (intersects.length > 0) { var item = intersects[0].object; item.material = new THREE.MeshBasicMaterial({color: "#f86332",side:THREE.DoubleSide}); //選中的樣式 } }
到此這篇關(guān)于three.js創(chuàng)建樓層布局圖的示例代碼的文章就介紹到這了,更多相關(guān)three.js 樓層布局圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- three.js開(kāi)發(fā)3d地圖的實(shí)現(xiàn)示例
- 基于Three.js實(shí)現(xiàn)酷炫3D地圖效果
- Three.js+React使二維圖片呈現(xiàn)3D效果
- 淺談Three.js截圖并下載的大坑
- 基于Three.js實(shí)現(xiàn)360度全景圖片
- Three.js開(kāi)發(fā)實(shí)現(xiàn)3D地圖的實(shí)踐過(guò)程總結(jié)
- Three.js的使用及繪制基礎(chǔ)3D圖形詳解
- 基于Three.js插件制作360度全景圖
- THREE.JS入門(mén)教程(6)創(chuàng)建自己的全景圖實(shí)現(xiàn)步驟
相關(guān)文章
JavaScript變量聲明var,let.const及區(qū)別淺析
這篇文章主要介紹了JavaScript變量聲明var,let.const及區(qū)別淺析,需要的朋友可以參考下2018-04-04javascript 獲取元素位置的快速方法 getBoundingClientRect()
有一種快速獲得網(wǎng)頁(yè)元素的位置。那就是使用getBoundingClientRect()方法。2009-11-11關(guān)閉瀏覽器輸入框自動(dòng)補(bǔ)齊 兼容IE,FF,Chrome等主流瀏覽器
這篇文章主要介紹了關(guān)閉瀏覽器輸入框自動(dòng)補(bǔ)齊 兼容IE,FF,Chrome等主流瀏覽器,需要的朋友可以參考下。希望對(duì)大家有所幫助2014-02-02詳解基于Vue cli生成的Vue項(xiàng)目的webpack4升級(jí)
這篇文章主要介紹了詳解基于Vue cli生成的Vue項(xiàng)目的webpack4升級(jí),本文將詳細(xì)介紹從webpack3到webpack4的升級(jí)過(guò)程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06深入淺出JS的Object.defineProperty()
這篇文章主要介紹了深入淺出JS的Object.defineProperty(),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06window.location不跳轉(zhuǎn)的問(wèn)題解決方法
window.location的跳轉(zhuǎn)失效的情況有沒(méi)有遇到過(guò)啊,這主要是冒泡傳遞影響了,下面有個(gè)不錯(cuò)的解決方法,大家可以參考下2014-04-04JavaScript切換搜索引擎的導(dǎo)航網(wǎng)頁(yè)搜索框?qū)嵗a
這篇文章主要介紹了javascript切換搜索引擎的導(dǎo)航網(wǎng)頁(yè)搜索框的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值 ,需要的朋友可以參考下2017-06-06