主要研究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度)

Three.js构造一个简单的房间的更多相关文章

  1. 用JS做一个简单的电商产品放大镜功能

    使用js制作一个简单的产品放大图 购物网站的产品页经常会放有一个产品展示图区.该图区有一个功能就是产品图的放大功能,移动左侧的焦点区域,可以放大细节部分观看,详情如下图.实现该功能的方法也非常简单. ...

  2. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  3. Linux内核设计第三周——构造一个简单的Linux系统

    Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...

  4. 第三节 构造一个简单的Linux系统MenuOS——20135203齐岳

    第三节 构造一个简单的Linux系统MenuOS By 20135203齐岳 Linux内核源代码 arch/ 支持不同cpu的源代码 Documentations/ 文档存储 init/ 内核启动相 ...

  5. Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...

  6. JS实现一个简单的计算器

    使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除.效果如上: 第一步: 创建构建运算函数count(). 第二步: 获取两个输入框中的值和获取选择 ...

  7. tensorflow笔记(二)之构造一个简单的神经网络

    tensorflow笔记(二)之构造一个简单的神经网络 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7425200.html ...

  8. js实现一个简单钟表动画(javascript+html5 canvas)

    第一次在博客园注册发博.有一次去人家单位开标,看到开标网站上有个钟表动画,一时兴起,就写了个简单的钟表动画. 用js和html5 canvas对象实现一个简单钟表程序 主要用到的就是h5的canvas ...

  9. 如何构造一个简单的USB过滤驱动程序

    本文分三部分来介绍如何构造一个简单的USB过滤驱动程序,包括"基本原理"."程序的实现"."使用INF安装".此文的目的在于希望读者了解基本 ...

随机推荐

  1. go语言 函数return值的几种情况

    分三种情况 (以下 “指定返回值”这句话, 仅指return后面直接跟着的返回值) 退出执行,不指定返回值 (1) 函数没有返回值 package main import ( "fmt&qu ...

  2. Java中lambda表达式学习

    一.Lambda表达式的基础语法: Java8中引入了一个新的操作符"->"该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分为两部分: 左侧:L ...

  3. 插入排序;至少要比较N(N-1)/2次;N表示元素个数

    <script type="text/javascript"> //冒泡排序:至少要比较N(N-1)/2次:N表示元素个数 function get(){ var nu ...

  4. 你真的知道Java中boolean类型占用多少个字节吗?

    为什么要问这个问题,首先在Java中定义的八种基本数据类型中,除了其它七种类型都有明确的内存占用字节数外,就boolean类型没有给出具体的占用字节数,因为对虚拟机来说根本就不存在 boolean 这 ...

  5. Mongoose 内置 CURD 方 法、扩展 Mongoose Model 的静态方法和 实例方法

    Mongoose 内置 CURD 方 法 Mongoose 内置 CURD 方 法文档地址:https://mongoosejs.com/docs/queries.html 常用的方法如下: Mode ...

  6. Shell 逐行读取文件的4中方法

    方法1:while循环中执行效率最高,最常用的方法. function while_read_LINE_bottm(){ While read LINE do echo $LINE done < ...

  7. UDF——定制窗口

    获取实例句柄的代码来自:https://blog.csdn.net/xie1xiao1jun/article/details/22180815 在Fluent当中我们可以使用scheme来为Fluen ...

  8. 2018-2019-2 20175217 实验四《Android开发基础》实验报告

    一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:吴一凡 学号:20175217 指导教师:娄嘉鹏 实验日期:2019年5月16日 实验时间:--- 实验序号:实验四 实验名称:And ...

  9. 如何查看电脑的GPU信息

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_33690342/article/ ...

  10. shell整数与小数比较,小数之间比较的方法【转】

    在shell脚本中,无法对浮点数进行比较,如: max=0.1 min=0.01 if [ "$max" -gt "$min" ] then echo &quo ...