用Three.js实现简单布局的3D房间

发布时间:2024-12-13 20:06

家居空间布局体现主人的生活哲学:简约不等于简单,讲究实用与艺术的结合 #生活知识# #家居生活# #居家生活哲学# #家居生活哲学应用#

废话不说了,直接上成果图。

 代码如下

<!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>

<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" style="position: absolute; left: 0px; top: 0px"></div>

<script>

var scene, camera, renderer, controls, tween, door;

var keyboard = new THREEx.KeyboardState();

var clock = new THREE.Clock();

var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;

var VIEW_ANGLE = 75, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 10000;

var materialArrayA = [];

var materialArrayB = [];

var matArrayA = [];

var matArrayB = [];

var dummy = new THREE.Object3D();

init();

animate();

function initScene() {

scene = new THREE.Scene();

}

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);

}

function initRender() {

if (Detector.webgl)

renderer = new THREE.WebGLRenderer({

antialias : true

});

else

renderer = new THREE.CanvasRenderer();

renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);

container = document.getElementById('ThreeJS');

container.appendChild(renderer.domElement);

renderer.setClearColor(0x4682B4, 1.0);

}

function initEvent() {

THREEx.WindowResize(renderer, camera);

THREEx.FullScreen.bindKey({

charCode : 'm'.charCodeAt(0)

});

}

function initControls() {

controls = new THREE.OrbitControls(camera, renderer.domElement);

}

function initLight() {

var directionalLight = new THREE.DirectionalLight(0xffffff, 1);

directionalLight.position.set(0, 100, 0).normalize();

scene.add(directionalLight);

var ambient = new THREE.AmbientLight(0xffffff, 1);

ambient.position.set(0, 0, 0);

scene.add(ambient);

}

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);

});

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);

}

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);

var resultBSP = sphere1BSP.subtract(cube2BSP);

var result = resultBSP.toMesh(material);

result.material.flatshading = THREE.FlatShading;

result.geometry.computeFaceNormals();

result.geometry.computeVertexNormals();

result.material.needsUpdate = true;

result.geometry.buffersNeedUpdate = true;

result.geometry.uvsNeedUpdate = true;

scene.add(result);

}

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;

scene.add(cube);

}

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;

}

function createWallMaterail() {

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xd6e4ec

}));

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xd6e4ec

}));

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayA.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0x9cb2d1

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0xd6e4ec

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0xd6e4ec

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

matArrayB.push(new THREE.MeshPhongMaterial({

color : 0xafc0ca

}));

}

function createLayout() {

createCubeWall(10, 200, 900, 0, matArrayB, -651, 100, 0);

createCubeWall(10, 200, 900, 1, matArrayB, 651, 100, 0);

createCubeWall(10, 200, 1310, 1.5, matArrayB, 0, 100, -451);

var wall = returnWallObject(1310, 200, 10, 0, matArrayB, 0, 100,

455);

var door_cube = returnWallObject(100, 180, 10, 0, matArrayB, 0, 90,

455);

createResultBsp(wall, door_cube, 1);

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);

});

createCubeWall(10, 200, 250, 0, matArrayA, -151, 100, 325);

createCubeWall(10, 200, 220, 0.5, matArrayA, -256, 100, 201);

createCubeWall(350, 200, 10, 0, matArrayA, 481, 100, 131);

createCubeWall(10, 200, 200, 0, matArrayA, 301, 100, 225);

createCubeWall(350, 200, 10, 0, matArrayA, -471, 100, -50);

createCubeWall(200, 200, 10, 0.5, matArrayA, 0, 100, -350);

createCubeWall(220, 200, 10, 0, matArrayA, 540, 100, -50);

createCubeWall(200, 200, 10, 0.5, matArrayA, 250, 100, -350);

var cube = returnWallObject(10, 200, 260, 0.5, matArrayA, 125, 100,

-250);

var door_cube1 = returnWallObject(10, 160, 80, 0.5, matArrayA, 155,

90, -250);

createResultBsp(cube, door_cube1, 2);

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);

}

function initObject() {

createWallMaterail();

createFloor();

createLayout();

}

function init() {

initScene();

initCamera();

initRender();

initEvent();

initControls();

initLight();

initObject();

document.addEventListener("keydown", onkeyDown, false);

}

var door_state = true;

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>

通过Enter键可控制开门和关门动作。门的旋转是通过,把门克隆一份,把克隆的那个设置为不可见,然后把两个门打个组 ,这个时候中旋转组就可以了。

 此时的旋转中心实际是在组的中心,但设置一半不可见 ,看起来就像是门在旋转了。注意的是,组内的东西的坐标是相对于组的组内,两个门的坐标应该分别是x轴的正负轴上,整个组的位置应该是原来门应该在的位置。

(这也是我向一位大神请教的,真的很感谢他那么耐心的教我,O(∩_∩)O)

运行方式:

在支持webgl的浏览器上打开room.html,即可看到效果图。如果加载不出来,打开Chrome快捷方式的属性中设置:右击Chrome浏览器快捷方式, 选择“属性”,在“目标”中加上"--allow-file-access-from-files",注意前面有个空格。修改完成,点击应用,确定后,关闭所有chrome上的窗口,重启chrome。再找到该资源room.html文件,以Google Chrome浏览器方式打开即可。

错误解决。

如果出现地板和门的两张图片加载不出来时,提示已被跨源资源共享策略阻止加载。解决办法第一种是如上图所示在Chrome的属性加"--allow-file-access-from-files";第二种就是把图片位置的相对路径改成绝对路径。

原demo发邮件索取的太多了,都从网盘自取吧。就是个demo,不喜勿喷,渣渣博主很玻璃心。

链接:https://pan.baidu.com/s/1UmBcjFCQ5QzdLcfGp-gpug 密码:r5c8

网址:用Three.js实现简单布局的3D房间 https://www.yuejiaxmz.com/news/view/467409

相关内容

Three.js三维开发0基础教程:(2) 搭建开发环境
现代简约卧室3D模型:打造舒适宜居的睡眠空间
厨房布局有哪几种以及怎样布局合理?
现代简约风,简单且舒适的生活空间!
简单舒适的现代风,打造出理想的生活空间!
简约现代的家庭休闲空间布局
厨房的布局一般有哪几种类型 厨房怎么布置好看又简单
房间布局设计方法 房间布局设计要点
房间布局设计方法有哪些?房间布局设计风格
全网超细的5大厨房黄金布局,轻松打造完美厨房!

随便看看