Three.js實(shí)現(xiàn)簡(jiǎn)單3D房間布局

本文實(shí)例為大家分享了Three.js實(shí)現(xiàn)簡(jiǎn)單3D房間布局的具體代碼,供大家參考,具體內(nèi)容如下

劍河網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)公司2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)

廢話不說(shuō)了,直接上成果圖。

Three.js實(shí)現(xiàn)簡(jiǎn)單3D房間布局

 代碼如下

<!doctype html>
<html lang="en">
<head>
<title>房間布局</title>
<meta charset="utf-8">
<meta name="viewport"
 content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
 
 
 <script src="js/jquery-1.9.1.js"></script>
 <script src="js/Three.min.js"></script>
 <script src="js/OrbitControls.js"></script>
 <script src="js/ThreeBSP.js"></script>
 <script src="js/Detector.js"></script>
 <script src="js/Stats.js"></script>
 
 
 <script src="js/THREEx.KeyboardState.js"></script>
 <script src="js/THREEx.FullScreen.js"></script>
 <script src="js/THREEx.WindowResize.js"></script>
 
 
 <!-- people -->
 <script src="people/js/three.js"></script>
 <script src="people/js/DDSLoader.js"></script>
 <script src="people/js/MTLLoader.js"></script>
 <script src="people/js/OBJLoader.js"></script>
 <script src="people/js/Detector.js"></script>
 <script src="people/js/stats.min.js"></script>
 <script src="people/js/PathControls.js"></script>
 <script src="people/js/Tween.js"></script>
 <script src="people/js/RequestAnimationFrame.js"></script>
 
 
 <div id="ThreeJS" ></div>
 
 
 <script>
 // 設(shè)置全局變量
 var scene, camera, renderer, controls, tween, door;
 var keyboard = new THREEx.KeyboardState();//保持鍵盤(pán)的當(dāng)前狀態(tài),可以隨時(shí)查詢
 var clock = new THREE.Clock();
 var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
 //var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
 var VIEW_ANGLE = 75, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 10000;
 var materialArrayA = [];
 var materialArrayB = [];
 var matArrayA = [];//內(nèi)墻
 var matArrayB = [];//外墻
 var dummy = new THREE.Object3D();//仿制品
 init();
 animate();
 
 //1.場(chǎng)景   
 function initScene() {
 scene = new THREE.Scene();
 }
 
 //2.相機(jī)
 function initCamera() {
 camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
 camera.position.set(0, 1000, 1800);
 camera.lookAt(scene.position);
 camera.lookAt(0, 0, 0);
 scene.add(camera);
 }
 
 //3.渲染器
 function initRender() {
 if (Detector.webgl)
 renderer = new THREE.WebGLRenderer({
  antialias : true
 });
 else
 renderer = new THREE.CanvasRenderer();
 //設(shè)置渲染器的大小為窗口的內(nèi)寬度,也就是內(nèi)容區(qū)的寬度。
 renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
 container = document.getElementById('ThreeJS');
 container.appendChild(renderer.domElement);
 renderer.setClearColor(0x4682B4, 1.0);
 }
 
 //4.事件
 function initEvent() {
 THREEx.WindowResize(renderer, camera);
 THREEx.FullScreen.bindKey({
 charCode : 'm'.charCodeAt(0)
 });
 }
 
 //5.控制
 function initControls() {
 controls = new THREE.OrbitControls(camera, renderer.domElement);
 }
 
 //6.光源
 function initLight() {
 // 位置不同,方向光作用于物體的面也不同,看到的物體各個(gè)面的顏色也不同 
 // A start, 第二個(gè)參數(shù)是光源強(qiáng)度
 var directionalLight = new THREE.DirectionalLight(0xffffff, 1);//模擬遠(yuǎn)處類似太陽(yáng)的光源
 directionalLight.position.set(0, 100, 0).normalize();
 scene.add(directionalLight);
 //A end
 var ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影響整個(gè)場(chǎng)景的光源
 ambient.position.set(0, 0, 0);
 scene.add(ambient);
 //var pointlight = new THREE.PointLight(0x000000,1.5,2000);
 //scene.add(pointlight); 
 }
 
 //創(chuàng)建地板 
 function createFloor() {
 var loader = new THREE.TextureLoader();
 loader.load("images/floor.jpg", function(texture) {
 texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
 texture.repeat.set(10, 10);
 var floorGeometry = new THREE.BoxGeometry(1600, 1100, 1);
 var floorMaterial = new THREE.MeshBasicMaterial({
  map : texture,
  side : THREE.DoubleSide
 });
 var floor = new THREE.Mesh(floorGeometry, floorMaterial);
 floor.position.y = -0.5;
 floor.rotation.x = Math.PI / 2;
 scene.add(floor);
 });
 
 //茶色:0x58ACFA 透明玻璃色:0XECF1F3
 var glass_material = new THREE.MeshBasicMaterial({
 color : 0XECF1F3
 });
 glass_material.opacity = 0.4;
 glass_material.transparent = true;
 
 var left_wall = returnWallObject(20, 200, 1100, 0, matArrayB, -801,
  100, 0);
 var left_cube = returnWallObject(20, 110, 1100, 0, matArrayB, -801,
  100, 0);
 createResultBsp(left_wall, left_cube, 1);
 createCubeWall(1, 110, 1100, 0, glass_material, -801, 100, 0);
 
 var right_wall = returnWallObject(20, 200, 1100, 1, matArrayB, 801,
  100, 0);
 var right_cube = returnWallObject(20, 110, 1100, 0, matArrayB, 801,
  100, 0);
 createResultBsp(right_wall, right_cube, 1);
 createCubeWall(1, 110, 1100, 0, glass_material, 801, 100, 0);
 }
 
 //墻上挖門(mén),通過(guò)兩個(gè)幾何體生成BSP對(duì)象
 function createResultBsp(bsp, less_bsp, mat) {
 switch (mat) {
 case 1:
 var material = new THREE.MeshPhongMaterial({
  color : 0x9cb2d1,
  specular : 0x9cb2d1,
  shininess : 30,
  transparent : true,
  opacity : 1
 });
 break;
 case 2:
 var material = new THREE.MeshPhongMaterial({
  color : 0xafc0ca,
  specular : 0xafc0ca,
  shininess : 30,
  transparent : true,
  opacity : 1
 });
 break;
 default:
 }
 
 var sphere1BSP = new ThreeBSP(bsp);
 var cube2BSP = new ThreeBSP(less_bsp);//0x9cb2d1 淡紫,0xC3C3C3 白灰 , 0xafc0ca灰
 var resultBSP = sphere1BSP.subtract(cube2BSP);
 var result = resultBSP.toMesh(material);
 result.material.flatshading = THREE.FlatShading;
 result.geometry.computeFaceNormals(); //重新計(jì)算幾何體側(cè)面法向量
 result.geometry.computeVertexNormals();
 result.material.needsUpdate = true; //更新紋理
 result.geometry.buffersNeedUpdate = true;
 result.geometry.uvsNeedUpdate = true;
 scene.add(result);
 }
 
 //創(chuàng)建墻
 function createCubeWall(width, height, depth, angle, material, x, y, z) {
 var cubeGeometry = new THREE.BoxGeometry(width, height, depth);
 var cube = new THREE.Mesh(cubeGeometry, material);
 cube.position.x = x;
 cube.position.y = y;
 cube.position.z = z;
 cube.rotation.y += angle * Math.PI; //-逆時(shí)針旋轉(zhuǎn),+順時(shí)針
 scene.add(cube);
 }
 
 //返回墻對(duì)象
 function returnWallObject(width, height, depth, angle, material, x, y,
 z) {
 var cubeGeometry = new THREE.BoxGeometry(width, height, depth);
 var cube = new THREE.Mesh(cubeGeometry, material);
 cube.position.x = x;
 cube.position.y = y;
 cube.position.z = z;
 cube.rotation.y += angle * Math.PI;
 return cube;
 }
 
 //創(chuàng)建墻紋理
 function createWallMaterail() {
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //前 0xafc0ca :灰色
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //后 
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xd6e4ec
 })); //上 0xd6e4ec: 偏白色
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xd6e4ec
 })); //下 
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //左 0xafc0ca :灰色
 matArrayA.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //右
 
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //前 0xafc0ca :灰色
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0x9cb2d1
 })); //后 0x9cb2d1:淡紫
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0xd6e4ec
 })); //上 0xd6e4ec: 偏白色
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0xd6e4ec
 })); //下 
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //左 0xafc0ca :灰色
 matArrayB.push(new THREE.MeshPhongMaterial({
 color : 0xafc0ca
 })); //右
 
 }
 
 //創(chuàng)建房間布局
 function createLayout() {
 
 // 墻面1 立方體比較長(zhǎng)的面 左一
 createCubeWall(10, 200, 900, 0, matArrayB, -651, 100, 0);
 // 墻面2 立方體比較長(zhǎng)的面 右一
 createCubeWall(10, 200, 900, 1, matArrayB, 651, 100, 0);
 // 墻面3 門(mén)對(duì)面的墻 立方體比較短的面 
 createCubeWall(10, 200, 1310, 1.5, matArrayB, 0, 100, -451);
 
 // 墻面4 帶門(mén)的面 
 var wall = returnWallObject(1310, 200, 10, 0, matArrayB, 0, 100,
  455);
 // 門(mén)框 
 var door_cube = returnWallObject(100, 180, 10, 0, matArrayB, 0, 90,
  455);
 createResultBsp(wall, door_cube, 1);
 
 //為墻面安裝門(mén),右門(mén)
 var loader = new THREE.TextureLoader();
 loader.load("images/door_right.png", function(texture) {
 var doorgeometry = new THREE.BoxGeometry(100, 180, 2);
 var doormaterial = new THREE.MeshBasicMaterial({
  map : texture,
  color : 0xffffff
 });
 doormaterial.opacity = 1.0;
 doormaterial.transparent = true;
 door = new THREE.Mesh(doorgeometry, doormaterial);
 door.position.set(-50, 0, 0);
 var door1 = door.clone();
 door1.position.set(50, 0, 0);
 door1.visible = false;
 dummy.add(door);
 dummy.add(door1);
 dummy.position.set(50, 90, 451)
 scene.add(dummy);
 });
 
 // 房間A:隔墻1 
 createCubeWall(10, 200, 250, 0, matArrayA, -151, 100, 325);
 //房間A:隔墻2 無(wú)門(mén)
 createCubeWall(10, 200, 220, 0.5, matArrayA, -256, 100, 201);
 // 廚房:隔墻3 
 createCubeWall(350, 200, 10, 0, matArrayA, 481, 100, 131);
 // 廚房:隔墻4 無(wú)門(mén)
 createCubeWall(10, 200, 200, 0, matArrayA, 301, 100, 225);
 // 房間B 
 createCubeWall(350, 200, 10, 0, matArrayA, -471, 100, -50);
 //房間B 無(wú)門(mén)
 createCubeWall(200, 200, 10, 0.5, matArrayA, 0, 100, -350);
 // 房間C
 createCubeWall(220, 200, 10, 0, matArrayA, 540, 100, -50);
 //房間C 無(wú)門(mén)
 createCubeWall(200, 200, 10, 0.5, matArrayA, 250, 100, -350);
 //廁所
 var cube = returnWallObject(10, 200, 260, 0.5, matArrayA, 125, 100,
  -250);
 //廁所門(mén)框
 var door_cube1 = returnWallObject(10, 160, 80, 0.5, matArrayA, 155,
  90, -250);
 createResultBsp(cube, door_cube1, 2);
 
 //茶色:0x58ACFA 透明玻璃色:0XECF1F3
 var glass_material = new THREE.MeshBasicMaterial({
 color : 0x58ACFA
 });
 glass_material.opacity = 0.6;
 glass_material.transparent = true;
 createCubeWall(1, 180, 80, 0.5, glass_material, 155, 90, -250);
 }
 
 //7.初始化OBJ對(duì)象
 function initObject() {
 //墻紋理
 createWallMaterail();
 createFloor();
 createLayout();
 }
 
 //初始化函數(shù)
 function init() {
 initScene();
 initCamera();
 initRender();
 initEvent();
 initControls();
 initLight();
 initObject();
 //監(jiān)聽(tīng)鍵盤(pán)按鍵
 document.addEventListener("keydown", onkeyDown, false);
 }
 
 var door_state = true;//默認(rèn)是門(mén)是關(guān)閉的
 //Enter=13,Space=32;
 function onkeyDown(event) {
 switch (event.keyCode) {
 case 13:
 console.log(event.keyCode);
 if (door_state) {
  dummy.rotation.y += 0.5 * Math.PI;
  door_state = false;
 } else {
  dummy.rotation.y -= 0.5 * Math.PI;
  door_state = true;
 }
 break;
 default:
 console.log(event.keyCode);
 break;
 }
 }
 
 function animate() {
 requestAnimationFrame(animate);
 renderer.render(scene, camera);
 TWEEN.update();
 update();
 }
 
 function update() {
 var delta = clock.getDelta();
 var moveDistance = 200 * delta;
 var rotateAngle = Math.PI / 2 * delta;
 controls.update();
 }
 </script>
</body>
</html>

通過(guò)Enter鍵可控制開(kāi)門(mén)和關(guān)門(mén)動(dòng)作。門(mén)的旋轉(zhuǎn)是通過(guò),把門(mén)克隆一份,把克隆的那個(gè)設(shè)置為不可見(jiàn),然后把兩個(gè)門(mén)打個(gè)組 ,這個(gè)時(shí)候中旋轉(zhuǎn)組就可以了。

 此時(shí)的旋轉(zhuǎn)中心實(shí)際是在組的中心,但設(shè)置一半不可見(jiàn) ,看起來(lái)就像是門(mén)在旋轉(zhuǎn)了。注意的是,組內(nèi)的東西的坐標(biāo)是相對(duì)于組的組內(nèi),兩個(gè)門(mén)的坐標(biāo)應(yīng)該分別是x軸的正負(fù)軸上,整個(gè)組的位置應(yīng)該是原來(lái)門(mén)應(yīng)該在的位置。

這也是我向一位大神請(qǐng)教的,真的很感謝他那么耐心的教我。

運(yùn)行方式:

在支持webgl的瀏覽器上打開(kāi)room.html,即可看到效果圖。如果加載不出來(lái),打開(kāi)Chrome快捷方式的屬性中設(shè)置:右擊Chrome瀏覽器快捷方式, 選擇“屬性”,在“目標(biāo)”中加上"--allow-file-access-from-files",注意前面有個(gè)空格。修改完成,點(diǎn)擊應(yīng)用,確定后,關(guān)閉所有chrome上的窗口,重啟chrome。再找到該資源room.html文件,以Google Chrome瀏覽器方式打開(kāi)即可。

Three.js實(shí)現(xiàn)簡(jiǎn)單3D房間布局

錯(cuò)誤解決。

如果出現(xiàn)地板和門(mén)的兩張圖片加載不出來(lái)時(shí),提示已被跨源資源共享策略阻止加載。解決辦法第一種是如上圖所示在Chrome的屬性加"--allow-file-access-from-files";第二種就是把圖片位置的相對(duì)路徑改成絕對(duì)路徑。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)頁(yè)名稱:Three.js實(shí)現(xiàn)簡(jiǎn)單3D房間布局
本文鏈接:http://muchs.cn/article18/jidogp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)企業(yè)網(wǎng)站制作、網(wǎng)站收錄、網(wǎng)頁(yè)設(shè)計(jì)公司、定制網(wǎng)站、定制開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)