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

代码如下

<!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" 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 = 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 = [];//内墙var matArrayB = [];//外墙var dummy = new THREE.Object3D();//仿制品init();animate();//1.场景         function initScene() {scene = new THREE.Scene();}//2.相机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});elserenderer = new THREE.CanvasRenderer();//设置渲染器的大小为窗口的内宽度,也就是内容区的宽度。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() {// 位置不同,方向光作用于物体的面也不同,看到的物体各个面的颜色也不同 // A start, 第二个参数是光源强度var directionalLight = new THREE.DirectionalLight(0xffffff, 1);//模拟远处类似太阳的光源directionalLight.position.set(0, 100, 0).normalize();scene.add(directionalLight);//A endvar ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源ambient.position.set(0, 0, 0);scene.add(ambient);//var pointlight = new THREE.PointLight(0x000000,1.5,2000);//scene.add(pointlight); }//创建地板  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   透明玻璃色:0XECF1F3var 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);}//墙上挖门,通过两个几何体生成BSP对象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(); //重新计算几何体侧面法向量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})); //前  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})); //右}//创建房间布局function createLayout() {// 墙面1 立方体比较长的面  左一createCubeWall(10, 200, 900, 0, matArrayB, -651, 100, 0);// 墙面2  立方体比较长的面   右一createCubeWall(10, 200, 900, 1, matArrayB, 651, 100, 0);// 墙面3 门对面的墙 立方体比较短的面  createCubeWall(10, 200, 1310, 1.5, matArrayB, 0, 100, -451);// 墙面4   带门的面  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);});// 房间A:隔墙1 createCubeWall(10, 200, 250, 0, matArrayA, -151, 100, 325);//房间A:隔墙2  无门createCubeWall(10, 200, 220, 0.5, matArrayA, -256, 100, 201);// 厨房:隔墙3 createCubeWall(350, 200, 10, 0, matArrayA, 481, 100, 131);// 厨房:隔墙4 无门createCubeWall(10, 200, 200, 0, matArrayA, 301, 100, 225);// 房间B createCubeWall(350, 200, 10, 0, matArrayA, -471, 100, -50);//房间B  无门createCubeWall(200, 200, 10, 0.5, matArrayA, 0, 100, -350);// 房间CcreateCubeWall(220, 200, 10, 0, matArrayA, 540, 100, -50);//房间C 无门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);//茶色:0x58ACFA   透明玻璃色:0XECF1F3var 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对象function initObject() {//墙纹理createWallMaterail();createFloor();createLayout();}//初始化函数function init() {initScene();initCamera();initRender();initEvent();initControls();initLight();initObject();//监听键盘按键document.addEventListener("keydown", onkeyDown, false);}var door_state = true;//默认是门是关闭的//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>

通过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房间相关推荐

  1. JS——实现简单的随机3D骰子

    描述: JS--实现简单的随机3D骰子. 效果: 实现: html文件: <!DOCTYPE html> <html lang="en"><head& ...

  2. html制作3d筛子,JS实现简单随机3D骰子

    本文实例为大家分享了JS实现简单随机3D骰子的具体代码,供大家参考,具体内容如下 描述: JS--实现简单的随机3D骰子. 效果: 实现: html文件: Document PLAY css文件: @ ...

  3. moment转换时间戳_酷炫时间轮盘:JS元素圆形布局制作时间轮盘动画效果

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 前段时间看抖音,有人用时间轮盘作为动态的桌面壁纸,感觉很好玩,于是突发奇想,可以用JS来实现这个功能. 来来来,先看看成果 ...

  4. Three.js 绘图之不规则路径 3D 墙体生成算法

    HTML5 是当前最流行的 Web 前端开发技术,其中最大的改变即是 Canvas 对象在各大浏览器平台中变得通用,在 HTML5 流行之前在 Web 端显示三维图形有很多种技术,但各种技术之间存在很 ...

  5. css画钟表_利用css+原生js制作简单的钟表

    利用css+原生js制作简单的钟表.效果如下所示 实现该效果,分三大块:html.javascript.css html部分html部分比较简单,定义一个clock的div,内部有原点.时分秒针.日期 ...

  6. 记录--Three.js的简单使用,Three.js在vue3.x中导入.pcd三维模型文件

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 本文说明 本文主要简单介绍了,在Vue3.x项目中如何简单的使用Three.js,导入PCD三维模型文件. 模型显示 项目实现 第一步 首 ...

  7. 1、Three.js 实现元宇宙汽车 3D 模型(网络)

    Three.js 实现元宇宙汽车 3D 模型 技术采用three.js+React实现. Step1:创建一个React项目 create-react-app your-app Step2:加载thr ...

  8. (转)使用Three.js制作一个基本的3D飞行游戏

    今天,我们将使用Three.js创建一个简单的3D飞机,使WebGL更简单.由于GLSL的复杂性和语法,WebGL对许多开发人员来说是一个相当陌生的世界.但是通过Three.js,浏览器中的3D变得非 ...

  9. Vue Grid Layout -️ 适用Vue.js的栅格布局系统(保姆级使用教程)

    目录 一. Vue Grid Layout 简介 二.vue-grid-layout 的安装与使用 三. 属性 3.1 gridItem 的必须属性 3.2 框架元素的实际宽度高度计算方式 3.3 元 ...

最新文章

  1. sm2加密算法实例_实例说明加密算法
  2. 2014025630《嵌入式程序设计》第七周学习总结
  3. Android对话框dialog大全
  4. 探索Julia(part9)--字符串处理
  5. 使用JSTL视图探索Spring Controller
  6. JavaScript中DOM操作
  7. logstash mysql 准实时同步到 elasticsearch
  8. 汇编笔记1:debug
  9. NAT,PAT、OSPF的相关配置
  10. 开机LOGO与动画修改
  11. vscode代码对比功能
  12. 解决:启动springboot项目,Unable to start web server; nested exception is org.springframework.beans.factory
  13. Python练习题答案: 纳特拼音alaphabeta【难度:1级】--景越Python编程实例训练营,1000道上机题等你来挑战
  14. WinMerge文字重叠问题
  15. 31省市自治区农村居民消费价格指数(2010-2020年)
  16. 骨传导耳机是什么意思?骨传导耳机工作原理是什么
  17. 刚刚!微软又放大招!让草稿几秒钟变App!
  18. 令人愉快的 Nuxt3 教程 (二): 快速轻松地搭建博客
  19. pandas, dataframe获取最后一行的三种方法
  20. 视频监控网络传输计算方法

热门文章

  1. 调试进行不下去,你需要的只是你女儿的一个小玩具
  2. 单片机RS485通信接口、控制线、原理图及程序实例
  3. 袁春栋的MySQL的学习笔记
  4. 监控平台前端SDK开发实践
  5. webpack打包工具及原理
  6. 什么视频播放器最好用?
  7. 华为和荣耀手机升级鸿蒙系统之后与matebook无法多屏协同的问题
  8. Policy gradient Method of Deep Reinforcement learning (Part One)
  9. 大型物流运输管理系统源码 TMS源码
  10. 阿里云斩获2022全球分布式云大会两项大奖