主要研究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. LeetCode 1249. Minimum Remove to Make Valid Parentheses

    原题链接在这里:https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/ 题目: Given a string s ...

  2. js-Cannot read property 'innerHTML' of null

    原因:1.$('#xxx') 或$('.xxx')不存在 2.$('#xxx')或$('.xxx')的值为空

  3. 使用flow来规范javascript的变量类型

    众所周知, js是弱类型的语言,由此有了很多的优点,也出现了大量由此导致的错误,难以定位.当然有类似于ts之类的语法糖来解决此问题,ts因为是从c#演变而来的,所以入门有一定的门槛,所以我们来一下fl ...

  4. 关于单片机的RAM

    一块RAM 分为了 堆 和 栈   名词而已,知道就可以了, 各种内存溢出问题: 全局数组访问越界 出现的问题:直接重启,或者死机 解决办法 :  额,写好自己的程序吧!!!!!!! 函数的局部变量过 ...

  5. 洛谷 P1195 【口袋的天空】

    P1195 传送门 大体题意: 就是给你\(n\)个点\(m\)条边, 然后让你把这几个点连成\(k\)个部分. 解题思路: 很容易就可以想到生成树(别问我怎么想到的). 因为最小生成树中有一个判断 ...

  6. 大厂HR面试必备ES6中的深入浅出面试题知识点

    ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言可以写复杂的大型应用程序,成为企业级语言.那么ECMAScript和JavaScript的关系 ...

  7. libvirt原理

    引用原文: https://blog.csdn.net/BtB5e6Nsu1g511Eg5XEg/article/details/80142155 libvirt是目前使用最为广泛的针对KVM虚拟机进 ...

  8. javaScript 迭代器

    for ...of 语句 "use strict"; var name = ['a','b','c']; var mark = [1, 2, 3]; for(var i of na ...

  9. 第08组 Alpha事后诸葛亮

    组长博客 点这里! 总结思考 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 弥补Powerpoint中模板转换存在的缺陷,完善PPT模板一键转换的功能 ...

  10. Linux kill、kill-15、kill-9区别

    进程状态转换图 kill和kill -9,两个命令在linux中都有杀死进程的效果,然而两命令的执行过程却大有不同,在程序中如果用错了,可能会造成莫名其妙的现象. 执行kill(不加 -* 默认kil ...