<!DOCTYPE html>
<html lang="en">
<head>
<title>webgl</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#alert {
z-index: 200;
position: absolute;
top: 100px;
width: 100%;
height: 150px;
}
#alert_center {
width: 300px;
height: 150px;
text-align: center;
background-color: rgb(255, 255, 255);
display: none;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display: block;
}
#info a,
.button {
color: #f00;
font-weight: bold;
text-decoration: underline;
cursor: pointer
}
</style>
</head>
<body onload="init();">
<div id="alert">
<div id="alert_center">
<p style="color: red" id="alert_font">
</p>
</div>
</div>
<div id="info">
<h1>
<a href="#" target="_blank">3D Demo</a>
</h1>
<p style="color: darkred">正向控制键:Z X C<br/> 反向控制键:A S D
</p>
</div>
<script src="build/three.js"></script>
<script src="build/OBJLoader.js"></script>
<script src="build/MTLLoader.js"></script>
<script src="js/jquery-1.9.1.min.js"></script>
<script>
var container;
var objects = [];
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var camera, scene, renderer;
var m1, m2, m3;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var cord1 = new THREE.Object3D;
var cord2 = new THREE.Object3D;
var cord3 = new THREE.Object3D;
var fov = 60, //拍摄距离 视野角值越大,场景中的物体越小
near = 1, //相机离视体积最近的距离
far = 10000, //相机离视体积最远的距离
aspect = (window.innerWidth / window.innerHeight); //纵横比
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(200, 100, 150);
scene = new THREE.Scene(); //创建场景
var ambient = new THREE.AmbientLight(0x101030, 5);
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd, 1); //光源颜色
directionalLight.position.set(0, 10, 10);
scene.add(directionalLight);
var helper = new THREE.GridHelper(1200, 50, 0xCD3700, 0x4A4A4A);
scene.add(helper);
var onProgress = function(xhr) {
if(xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
}
};
var onError = function(xhr) {};
//加载3dmax的 obj 与 mtl 文件
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('obj2/');
mtlLoader.load('object.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('obj2/');
objLoader.load('object.obj', function(object) {
object.scale.multiplyScalar(1);
object.traverse(function(child) {
if(child instanceof THREE.Mesh) {
if(child.name == 'Box001') {
m1 = child;
} else if(child.name == 'Box002') {
m2 = child;
} else if(child.name == 'Cylinder001') {
//圆柱
m3 = child;
}
}
})
cord3.add(m3);
cord3.position.set(0, 0, -60);
m3.position.x -= (cord3.position.x);
m3.position.y -= (cord3.position.y);
m3.position.z -= (cord3.position.z);
cord2.add(m2, cord3);
cord2.position.set(0, 96, 0);
m3.position.x -= (cord2.position.x);
m3.position.y -= (cord2.position.y);
m3.position.z -= (cord2.position.z);
m2.position.x -= (cord2.position.x);
m2.position.y -= (cord2.position.y);
m2.position.z -= (cord2.position.z);
cord1.add(m1, cord2);
scene.add(cord1);
render();
return object;
}, onProgress, onError);
});
renderer = new THREE.WebGLRenderer({
antialias: true
}); //渲染器
renderer.setClearColor(0xffffff); //画布颜色
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
//浏览器改变事件
window.addEventListener('resize', onWindowResize, false);
//鼠标单击书剑
window.addEventListener('click', clickTest, false);
//鼠标滚轮控制模型放大缩小
document.addEventListener('mousewheel', mousewheel, false);
//键盘事件
document.addEventListener('keydown', onKeyDown, false);
}
//鼠标滑轮
function mousewheel(e) {
e.preventDefault();
if(e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if(e.wheelDelta > 0) { //当滑轮向上滚动时
fov -= (near < fov ? 1 : 0);
}
if(e.wheelDelta < 0) { //当滑轮向下滚动时
fov += (fov < far ? 1 : 0);
}
} else if(e.detail) { //Firefox滑轮事件
if(e.detail > 0) { //当滑轮向上滚动时
fov -= 1;
}
if(e.detail < 0) { //当滑轮向下滚动时
fov += 1;
}
}
camera.fov = fov;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
}
//监听键盘事件
function onKeyDown(event) {
//A
if(event.keyCode == 65) {
cord1.rotation.y -= 0.1;
}
//Z
if(event.keyCode == 90) {
cord1.rotation.x += 0.1;
}
//X
if(event.keyCode == 88) {
cord2.rotation.x += 0.1;
}
//s
if(event.keyCode == 83) {
cord2.rotation.y -= 0.1;
}
//c
if(event.keyCode == 67) {
cord3.rotation.x += 0.1;
}
//d
if(event.keyCode == 68) {
cord3.rotation.y -= 0.1;
}
render();
}
//点击事件
function clickTest(event) {
event.preventDefault();
objects = [];
this.mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
this.mouse.y = -(event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
this.raycaster.setFromCamera(this.mouse, this.camera);
this.scene.children.forEach(child => {
//根据需求判断哪些加入objects,也可以在生成object的时候push进objects
if(!(child instanceof THREE.GridHelper) && !(child instanceof THREE.DirectionalLight) && !(child instanceof THREE.AmbientLight)) {
child.children.forEach(childv => {
if(childv instanceof THREE.Mesh) { //根据需求判断哪些加入objects,也可以在生成object的时候push进objects
this.objects.push(childv)
} else if(childv instanceof THREE.Object3D) {
meshDg(childv.children);
}
});
}
})
var intersects = this.raycaster.intersectObjects(this.objects);
if(intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) {
selectObject = intersects[0].object;
changeMaterial(selectObject);
$("#alert_center").css({
"display": "block"
});
$("#alert_font").html("当前点击的模块名字是:" + selectObject.name);
render();
}
}
// 改变当前对象属性
function changeMaterial(object) {
var material = new THREE.MeshLambertMaterial({
color: 0xffffff * Math.random()
});
object.material = material;
}
//递归 收集 THREE.Mesh
function meshDg(child) {
child.forEach(childv => {
if(childv instanceof THREE.Mesh) { //根据需求判断哪些加入objects,也可以在生成object的时候push进objects