Three.js构造一个简单的房间
主要研究three.js在3D场景中基本使用:画一个简单的房子、房子上画门和玻璃、房间内放一个床、定义鼠标事件可以移动场景、动画的使用等。
1.Three.js画的一个简单的房子,模拟地板以及四堵墙
准备素材:
3.jpg模拟地板
4.jpg模拟墙
代码:
<!DOCTYPE html> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/OBJLoader.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> var scene,camera,webGLRenderer,stats; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ paintFloor(); paintWalls(40, 2, 10, 0, 0, -20, 1/2,0);//后面墙 paintWalls(40, 2, 10, 0, 0, 20, 1/2, 0);//前面墙 paintWalls(42, 2, 10, -20, 0, 0, 1/2, 0, 1/2);//左面墙 paintWalls(42, 2, 10, 20, 0, 0, 1/2, 0, 1/2);//右面墙 } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ){ var loader = new THREE.TextureLoader; loader.load('./img/4.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ){ mesh.rotation.z = Math.PI * rotationZ; } scene.add(mesh); }); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); if(stats){ stats.update(); } } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
结果:
2.增加鼠标事件和键盘事件控制摄像头进而模拟在房间内行走
控制器的使用,主要的控制器如下:
- 轨迹球控制器的使用:(使用鼠标改变场景以及在界面实时显示相机的位置)
可用的鼠标事件如下:
(1)引入相关JS:
<script type="text/javascript" src="../libs/TrackballControls.js"></script>
(2)创建控制器并绑定到相机上
//鼠标控制动画相关组件
var trackballControls, clock;
function initTrackballControls(){
clock = new THREE.Clock();
trackballControls = new THREE.TrackballControls(camera);
trackballControls.rotateSpeed = 1.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
// trackballControls.noZoom=false;
// trackballControls.noPan=false;
trackballControls.staticMoving = true;
// trackballControls.dynamicDampingFactor=0.3;
}
(3)摄像机的位置更新在render循环中完成
function render() {
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
//鼠标事件
var delta = clock.getDelta();
trackballControls.update(delta);
logCameraPosition();
if(stats){
stats.update();
}
}
function logCameraPosition(){
var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z;
$("#logInfo").html(logInfo);
}
如果禁用鼠标缩放可以将noZoom设为true。
代码如下:
<!DOCTYPE html> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/OBJLoader.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <script type="text/javascript" src="../libs/TrackballControls.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var trackballControls, clock; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ paintFloor(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2,0);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2);//左面墙 paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2);//右面墙 initTrackballControls(); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); //鼠标事件 var delta = clock.getDelta(); trackballControls.update(delta); logCameraPosition(); if(stats){ stats.update(); } } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initTrackballControls(){ clock = new THREE.Clock(); trackballControls = new THREE.TrackballControls(camera); trackballControls.rotateSpeed = 1.0; trackballControls.zoomSpeed = 1.0; trackballControls.panSpeed = 1.0; // trackballControls.noZoom=false; // trackballControls.noPan=false; trackballControls.staticMoving = true; // trackballControls.dynamicDampingFactor=0.3; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ){ var loader = new THREE.TextureLoader; loader.load('./img/4.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ){ mesh.rotation.z = Math.PI * rotationZ; } scene.add(mesh); }); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
效果:
- 轨道控制器(支持鼠标和键盘事件)
其支持的事件如下:
(1)使用的类库是:https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.js
(2)初始化control即可
function initOrbitControls(){ controls = new THREE.OrbitControls(camera,webGLRenderer.domElement); controls.minDistance = 1; controls.maxDistance = 5000; }
代码如下:
<!DOCTYPE html> <!--房子中间加个床,采用封装过的API实现 (采用轨道控制器)--> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs2/three.js"></script> <script type="text/javascript" src="../libs2/OBJLoader.js"></script> <script type="text/javascript" src="../libs2/stats.js"></script> <script type="text/javascript" src="../libs2/WebGL.js"></script> <script type="text/javascript" src="../libs2/OrbitControls.js"></script> <script type="text/javascript" src="../libs2/onEvent.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var controls; //事件相关 var threeOnEvent; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.setPixelRatio(window.devicePixelRatio); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ initEvent(); paintFloor(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2,0);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2);//左面墙 paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2);//右面墙 initOrbitControls(); paintBed(); } var paintBed = function(){ var textures = []; loadBedTextures(textures, 0, "./img/bedplate.jpg"); //right loadBedTextures(textures, 1, "./img/bedplate.jpg"); //left loadBedTextures(textures, 2, "./img/bedplate.jpg"); //front loadBedTextures(textures, 3, "./img/bedplate.jpg");//back loadBedTextures(textures, 4, "./img/bedplate.jpg"); //bottom loadBedTextures(textures, 5, "./img/mattess.jpg"); //top //创建长方体几何体 var gemotery = new THREE.BoxGeometry(10, 10, 5); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery, textures); mesh.position.set(0, 2.5, 0) mesh.rotation.x = Math.PI * 1/2; //绑定一些数据 mesh.tags = "bed"; mesh.userData.ID = 1; mesh.name = "myBed"; //增加事件(点击事件) mesh.on('click',function(m) {//m代表mesh对象 alert('1'); }) // hover eventLisener(鼠标悬浮事件) mesh.on('hover',function(m) { // mouse enter the mesh alert(m.name + " " + m.tags + " " + mesh.userData.ID); },function(m) { // mouse leave out the mesh }); scene.add(mesh); } function loadBedTextures(textures, index, url){ textures[index] = new THREE.MeshBasicMaterial({ map : new THREE.TextureLoader().load(url) }); } function initEvent(){ threeOnEvent = new THREE.onEvent(scene,camera); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); //鼠标事件 logCameraPosition(); if(stats){ stats.update(); } //更新事件 threeOnEvent.update(); } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initOrbitControls(){ controls = new THREE.OrbitControls(camera,webGLRenderer.domElement); controls.minDistance = 1; controls.maxDistance = 5000; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ){ var loader = new THREE.TextureLoader; loader.load('./img/4.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ){ mesh.rotation.z = Math.PI * rotationZ; } scene.add(mesh); }); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
3.场景中添加一个床 (六面体),并且自定义鼠标点击事件悬浮在床上的时候弹出框
这个都采用的是git上封装过的JS库来实现的,参考git地址:https://github.com/mrdoob/three.js/
three.js的事件机制用到的是onEvent,参考:https://github.com/YoneChen/three-onEvent
也通过tags、userData、name进行数据的绑定。
代码如下:
<!DOCTYPE html> <!--房子中间加个床,采用封装过的API实现--> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs2/three.js"></script> <script type="text/javascript" src="../libs2/OBJLoader.js"></script> <script type="text/javascript" src="../libs2/stats.js"></script> <script type="text/javascript" src="../libs2/WebGL.js"></script> <script type="text/javascript" src="../libs2/TrackballControls.js"></script> <script type="text/javascript" src="../libs2/onEvent.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var trackballControls, clock; //事件相关 var threeOnEvent; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.setPixelRatio(window.devicePixelRatio); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ initEvent(); paintFloor(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2,0);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2);//左面墙 paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2);//右面墙 initTrackballControls(); paintBed(); } var paintBed = function(){ var textures = []; loadBedTextures(textures, 0, "./img/bedplate.jpg"); //right loadBedTextures(textures, 1, "./img/bedplate.jpg"); //left loadBedTextures(textures, 2, "./img/bedplate.jpg"); //front loadBedTextures(textures, 3, "./img/bedplate.jpg");//back loadBedTextures(textures, 4, "./img/bedplate.jpg"); //bottom loadBedTextures(textures, 5, "./img/mattess.jpg"); //top //创建长方体几何体 var gemotery = new THREE.BoxGeometry(10, 10, 5); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery, textures); mesh.position.set(0, 2.5, 0) mesh.rotation.x = Math.PI * 1/2; //绑定一些数据 mesh.tags = "bed"; mesh.userData.ID = 1; mesh.name = "myBed"; //增加事件(点击事件) mesh.on('click',function(m) {//m代表mesh对象 alert('1'); }) // hover eventLisener(鼠标悬浮事件) mesh.on('hover',function(m) { // mouse enter the mesh alert(m.name + " " + m.tags + " " + mesh.userData.ID); },function(m) { // mouse leave out the mesh }); scene.add(mesh); } function loadBedTextures(textures, index, url){ textures[index] = new THREE.MeshBasicMaterial({ map : new THREE.TextureLoader().load(url) }); } function initEvent(){ threeOnEvent = new THREE.onEvent(scene,camera); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); //鼠标事件 var delta = clock.getDelta(); trackballControls.update(delta); logCameraPosition(); if(stats){ stats.update(); } //更新事件 threeOnEvent.update(); } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initTrackballControls(){ clock = new THREE.Clock(); trackballControls = new THREE.TrackballControls(camera); trackballControls.rotateSpeed = 1.0; trackballControls.zoomSpeed = 1.0; trackballControls.panSpeed = 1.0; // trackballControls.noZoom=false; // trackballControls.noPan=false; trackballControls.staticMoving = true; // trackballControls.dynamicDampingFactor=0.3; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ){ var loader = new THREE.TextureLoader; loader.load('./img/4.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ){ mesh.rotation.z = Math.PI * rotationZ; } scene.add(mesh); }); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
结果:
4. 在墙上挖一个玻璃
在墙上挖玻璃需要用到ThreeBSP.js,实际上就是求两个物体的差集之后进行添加;如果需要挖一个门,需要做的操作是:先在墙上求墙和门的差集得到一个mesh对象添加到scene中,并将门也添加到scene即可实现。
代码如下:
<!DOCTYPE html> <!--房子中间加个床,采用封装过的API实现--> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs2/three.js"></script> <script type="text/javascript" src="../libs2/OBJLoader.js"></script> <script type="text/javascript" src="../libs2/stats.js"></script> <script type="text/javascript" src="../libs2/WebGL.js"></script> <script type="text/javascript" src="../libs2/TrackballControls.js"></script> <script type="text/javascript" src="../libs2/onEvent.js"></script> <script type="text/javascript" src="../libs2/ThreeBSP.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var trackballControls, clock; //事件相关 var threeOnEvent; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.setPixelRatio(window.devicePixelRatio); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ initEvent(); paintFloor(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2, 0, 0,true);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0, 0,true);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2, true);//左面墙 //添加带玻璃的墙 var wallMesh = paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2, false);//右面墙 var windowMesh = paintGlass(10, 2, 6, 20, 3, 0, 1/2, 0, 1/2, false); var resultMesh = createResultMesh(wallMesh, windowMesh, true); scene.add(resultMesh); initTrackballControls(); paintBed(); } function createResultMesh(srcMesh, destMesh, addDest){ var srcBSP = new ThreeBSP(srcMesh); var destBSP = new ThreeBSP(destMesh); var resultBSP = srcBSP.subtract(destBSP); var result = resultBSP.toMesh(srcMesh.material); result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); if(addDest){ scene.add(destMesh); } return result; } var paintBed = function(){ var textures = []; loadBedTextures(textures, 0, "./img/bedplate.jpg"); //right loadBedTextures(textures, 1, "./img/bedplate.jpg"); //left loadBedTextures(textures, 2, "./img/bedplate.jpg"); //front loadBedTextures(textures, 3, "./img/bedplate.jpg");//back loadBedTextures(textures, 4, "./img/bedplate.jpg"); //bottom loadBedTextures(textures, 5, "./img/mattess.jpg"); //top //创建长方体几何体 var gemotery = new THREE.BoxGeometry(10, 10, 5); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery, textures); mesh.position.set(0, 2.5, 0) mesh.rotation.x = Math.PI * 1/2; //绑定一些数据 mesh.tags = "bed"; mesh.userData.ID = 1; mesh.name = "myBed"; //增加事件(点击事件) mesh.on('click',function(m) {//m代表mesh对象 alert('1'); }) // hover eventLisener(鼠标悬浮事件) mesh.on('hover',function(m) { // mouse enter the mesh alert(m.name + " " + m.tags + " " + mesh.userData.ID); },function(m) { // mouse leave out the mesh }); scene.add(mesh); } function loadBedTextures(textures, index, url){ textures[index] = new THREE.MeshBasicMaterial({ map : new THREE.TextureLoader().load(url) }); } function initEvent(){ threeOnEvent = new THREE.onEvent(scene,camera); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); //鼠标事件 var delta = clock.getDelta(); trackballControls.update(delta); logCameraPosition(); if(stats){ stats.update(); } //更新事件 threeOnEvent.update(); } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initTrackballControls(){ clock = new THREE.Clock(); trackballControls = new THREE.TrackballControls(camera); trackballControls.rotateSpeed = 1.0; trackballControls.zoomSpeed = 1.0; trackballControls.panSpeed = 1.0; // trackballControls.noZoom=false; // trackballControls.noPan=false; trackballControls.staticMoving = true; // trackballControls.dynamicDampingFactor=0.3; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var loader = new THREE.TextureLoader; var texture = new THREE.TextureLoader().load('./img/4.jpg'); texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } var paintGlass = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var material = new THREE.MeshBasicMaterial({ color : 0x58ACFA, transparent : true, opacity : 0.6 }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
结果:
5.Tween动画实现旋转床
tween.js是一款可生成平滑动画效果的js动画库。你只需要告诉tween你想修改什么值,以及动画结束时它的最终值是什么,动画花费多少时间等信息,tween引擎就可以计算从开始动画点到结束动画点之间值,来产生平滑的动画效果。 其详细用法参考: https://www.cnblogs.com/jiangxiaobo/p/6207264.html
代码:
<!DOCTYPE html> <!--房子中间加个床,采用封装过的API实现,动态改变床的位置--> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs2/three.js"></script> <script type="text/javascript" src="../libs2/OBJLoader.js"></script> <script type="text/javascript" src="../libs2/stats.js"></script> <script type="text/javascript" src="../libs2/WebGL.js"></script> <script type="text/javascript" src="../libs2/TrackballControls.js"></script> <script type="text/javascript" src="../libs2/onEvent.js"></script> <script type="text/javascript" src="../libs2/ThreeBSP.js"></script> <script type="text/javascript" src="../libs2/tween.min.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var trackballControls, clock; //事件相关 var threeOnEvent; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.setPixelRatio(window.devicePixelRatio); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ initEvent(); paintFloor(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2, 0, 0,true);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0, 0,true);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2, true);//左面墙 //添加带玻璃的墙 var wallMesh = paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2, false);//右面墙 var windowMesh = paintGlass(10, 2, 6, 20, 3, 0, 1/2, 0, 1/2, false); var resultMesh = createResultMesh(wallMesh, windowMesh, true); scene.add(resultMesh); initTrackballControls(); paintBed(); } function createResultMesh(srcMesh, destMesh, addDest) { var srcBSP = new ThreeBSP(srcMesh); var destBSP = new ThreeBSP(destMesh); var resultBSP = srcBSP.subtract(destBSP); var result = resultBSP.toMesh(srcMesh.material); result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); if(addDest){ scene.add(destMesh); } return result; } var paintBed = function(){ var textures = []; loadBedTextures(textures, 0, "./img/bedplate.jpg"); //right loadBedTextures(textures, 1, "./img/bedplate.jpg"); //left loadBedTextures(textures, 2, "./img/bedplate.jpg"); //front loadBedTextures(textures, 3, "./img/bedplate.jpg");//back loadBedTextures(textures, 4, "./img/bedplate.jpg"); //bottom loadBedTextures(textures, 5, "./img/mattess.jpg"); //top //创建长方体几何体 var gemotery = new THREE.BoxGeometry(10, 10, 5); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery, textures); mesh.position.set(0, 2.5, 0) mesh.rotation.x = Math.PI * 1/2; //绑定一些数据 mesh.tags = "bed"; mesh.userData.ID = 1; mesh.name = "myBed"; //增加事件(点击事件) mesh.on('click',function(m) {//m代表mesh对象 alert('1'); }) // hover eventLisener(鼠标悬浮事件) mesh.on('hover',function(m) { // mouse enter the mesh alert(m.name + " " + m.tags + " " + mesh.userData.ID); },function(m) { // mouse leave out the mesh }); scene.add(mesh); startAnnotation(mesh); } function startAnnotation(mesh) { var indexNumber = { indexNumber : 0 }; var currentTween = new TWEEN.Tween(indexNumber).to({ indexNumber : 2 },5000); currentTween.easing(TWEEN.Easing.Sinusoidal.InOut); currentTween.repeat(60);//重复次数 currentTween.yoyo(true);//结束之后反方向反弹 currentTween.onUpdate(function(){ var indexNumber = this.indexNumber; //改变床的旋转角度实现旋转床 mesh.rotation.z = Math.PI * indexNumber; //也可以根据数字的范围进行一些其他动画(比如说实现闪烁效果等) if(indexNumber < 1){ } else { } }); currentTween.start(); } function loadBedTextures(textures, index, url){ textures[index] = new THREE.MeshBasicMaterial({ map : new THREE.TextureLoader().load(url) }); } function initEvent(){ threeOnEvent = new THREE.onEvent(scene,camera); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); //鼠标事件 var delta = clock.getDelta(); trackballControls.update(delta); logCameraPosition(); if(stats){ stats.update(); } //更新事件 threeOnEvent.update(); //动画 TWEEN.update(); } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initTrackballControls(){ clock = new THREE.Clock(); trackballControls = new THREE.TrackballControls(camera); trackballControls.rotateSpeed = 1.0; trackballControls.zoomSpeed = 1.0; trackballControls.panSpeed = 1.0; // trackballControls.noZoom=false; // trackballControls.noPan=false; trackballControls.staticMoving = true; // trackballControls.dynamicDampingFactor=0.3; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var loader = new THREE.TextureLoader; var texture = new THREE.TextureLoader().load('./img/4.jpg'); texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } var paintGlass = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var material = new THREE.MeshBasicMaterial({ color : 0x58ACFA, transparent : true, opacity : 0.6 }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
结果:
床会一直旋转。。。
6. 增加一个玻璃天窗,完成最终的房子
旋转床、鼠标和键盘对场景缩放。
<!DOCTYPE html> <!--房子中间加个床,采用封装过的API实现,动态改变床的位置--> <html> <head> <title>myHouse</title> <script type="text/javascript" src="../libs/jquery-1.9.0.js"></script> <script type="text/javascript" src="../libs2/three.js"></script> <script type="text/javascript" src="../libs2/OBJLoader.js"></script> <script type="text/javascript" src="../libs2/stats.js"></script> <script type="text/javascript" src="../libs2/WebGL.js"></script> <script type="text/javascript" src="../libs2/OrbitControls.js"></script> <script type="text/javascript" src="../libs2/onEvent.js"></script> <script type="text/javascript" src="../libs2/ThreeBSP.js"></script> <script type="text/javascript" src="../libs2/tween.min.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <div id="logInfo" style="position: absolute; top: 0px; left: 20%; width: 50%; padding: 5px;"></div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> //基本组件 var scene, camera, webGLRenderer, stats; //鼠标控制动画相关组件 var controls; //事件相关 var threeOnEvent; function init() { stats = initStats(); scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.x = 20; camera.position.y = 40; camera.position.z = 50; camera.lookAt(scene.position); scene.add(camera); // create a render and set the size webGLRenderer = new THREE.WebGLRenderer({ antialias : true, alpha:true }); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.setPixelRatio(window.devicePixelRatio); webGLRenderer.setClearColor(0xEEEEEE, 1.0); webGLRenderer.shadowMapEnabled = true; // add spotlight for the shadows var spotLight = new THREE.PointLight(0xffffff); spotLight.position.set(30, 40, 50); scene.add(spotLight); initObjects(); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); render(); } function initObjects(){ initEvent(); paintFloor(); paintCell(); //画墙--一般y取高度的1/2 paintWalls(40, 2, 10, 0, 5, -20, 1/2, 0, 0,true);//后面墙 paintWalls(40, 2, 10, 0, 5, 20, 1/2, 0, 0,true);//前面墙 paintWalls(42, 2, 10, -20, 5, 0, 1/2, 0, 1/2, true);//左面墙 //添加带玻璃的墙 var wallMesh = paintWalls(42, 2, 10, 20, 5, 0, 1/2, 0, 1/2, false);//右面墙 var windowMesh = paintGlass(10, 2, 6, 20, 3, 0, 1/2, 0, 1/2, false); var resultMesh = createResultMesh(wallMesh, windowMesh, true); scene.add(resultMesh); initOrbitControls(); paintBed(); } function createResultMesh(srcMesh, destMesh, addDest) { var srcBSP = new ThreeBSP(srcMesh); var destBSP = new ThreeBSP(destMesh); var resultBSP = srcBSP.subtract(destBSP); var result = resultBSP.toMesh(srcMesh.material); result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); if(addDest){ scene.add(destMesh); } return result; } var paintBed = function(){ var textures = []; loadBedTextures(textures, 0, "./img/bedplate.jpg"); //right loadBedTextures(textures, 1, "./img/bedplate.jpg"); //left loadBedTextures(textures, 2, "./img/bedplate.jpg"); //front loadBedTextures(textures, 3, "./img/bedplate.jpg");//back loadBedTextures(textures, 4, "./img/bedplate.jpg"); //bottom loadBedTextures(textures, 5, "./img/mattess.jpg"); //top //创建长方体几何体 var gemotery = new THREE.BoxGeometry(10, 10, 5); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery, textures); mesh.position.set(0, 2.5, 0) mesh.rotation.x = Math.PI * 1/2; //绑定一些数据 mesh.tags = "bed"; mesh.userData.ID = 1; mesh.name = "myBed"; //增加事件(点击事件) mesh.on('click',function(m) {//m代表mesh对象 alert('1'); }) // hover eventLisener(鼠标悬浮事件) mesh.on('hover',function(m) { // mouse enter the mesh alert(m.name + " " + m.tags + " " + mesh.userData.ID); },function(m) { // mouse leave out the mesh }); scene.add(mesh); startAnnotation(mesh); } function startAnnotation(mesh) { var indexNumber = { indexNumber : 0 }; var currentTween = new TWEEN.Tween(indexNumber).to({ indexNumber : 2 },5000); currentTween.easing(TWEEN.Easing.Sinusoidal.InOut); currentTween.repeat(60);//重复次数 currentTween.yoyo(true);//结束之后反方向反弹 currentTween.onUpdate(function(){ var indexNumber = this.indexNumber; //改变床的旋转角度实现旋转床 mesh.rotation.z = Math.PI * indexNumber; //也可以根据数字的范围进行一些其他动画(比如说实现闪烁效果等) if(indexNumber < 1){ } else { } }); currentTween.start(); } function loadBedTextures(textures, index, url){ textures[index] = new THREE.MeshBasicMaterial({ map : new THREE.TextureLoader().load(url) }); } function initEvent(){ threeOnEvent = new THREE.onEvent(scene,camera); } function render() { requestAnimationFrame(render); webGLRenderer.render(scene, camera); logCameraPosition(); if(stats){ stats.update(); } //更新事件 threeOnEvent.update(); //动画 TWEEN.update(); } function logCameraPosition(){ var logInfo = "[info]: x - " + camera.position.x + " ;y - " + camera.position.y + " ;z - " + camera.position.z; $("#logInfo").html(logInfo); } function initOrbitControls(){ controls = new THREE.OrbitControls(camera,webGLRenderer.domElement); controls.minDistance = 1; controls.maxDistance = 5000; } var paintFloor = function (){ var loader = new THREE.TextureLoader; loader.load('./img/3.jpg', function (texture) { //x和y超过图片像素之后重复绘制图片 texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1, 1); //设置材质是双面材质 var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建普通的平面几何体 var gemotery = new THREE.PlaneGeometry(40,40); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 0; mesh.rotation.x = Math.PI/2; scene.add(mesh); }); } var paintCell = function (){ //设置材质是双面材质 var material = new THREE.MeshBasicMaterial({ color : 0x58ACFA, transparent : true, opacity : 0.6 }); //创建普通的平面几何体 //创建长方体几何体 var gemotery = new THREE.BoxGeometry(40, 40, 1); //创建网格对象 var mesh = new THREE.Mesh(gemotery,material); mesh.position.y = 9; mesh.rotation.x = Math.PI/2; scene.add(mesh); } var paintWalls = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var loader = new THREE.TextureLoader; var texture = new THREE.TextureLoader().load('./img/4.jpg'); texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //设置地板重复绘制的密度是1 * 1 texture.repeat.set(1,1); var material = new THREE.MeshLambertMaterial({ map : texture, side : THREE.DoubleSide }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } var paintGlass = function (width, depth, height, x, y, z, rotationX, rotationY, rotationZ, addMesh){ var material = new THREE.MeshBasicMaterial({ color : 0x58ACFA, transparent : true, opacity : 0.6 }); //创建长方体几何体 var gemotery = new THREE.BoxGeometry(width, depth, height); //创建网格对象以及进行位置的设定 var mesh = new THREE.Mesh(gemotery,material); mesh.position.set(x,y,z) mesh.rotation.x = Math.PI * rotationX; mesh.rotation.y = Math.PI * rotationY; if(rotationZ) { mesh.rotation.z = Math.PI * rotationZ; } if(addMesh) { scene.add(mesh); } return mesh; } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } window.onload = init; </script> </body> </html>
结果:
git源码地址: https://github.com/qiao-zhi/threejsDemo
总结:
一般物体的y取的是高度是1/2;
旋转角度的单位是Math.PI (乘以对应的角度,1就是180度,0.5就是90度)