three.js引入3dmax生成的.obj和.mtl以及对引入模型的移动点击变色操作

如上图,为方便代码运行请使用3dmax画如上图的3d模型导出* .obj与* .mtl文件。

代码需要的JS:three.js所所所,OBJLoader.js,MTLLoader.js和jQuery的的1.9.1.min.js

运行代码如下:

<!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
						this.objects.push(childv)  
					} else if(childv instanceof THREE.Object3D) {
						meshDg(childv.children);
					}
				});
			}
			//浏览器发生变化时
			function onWindowResize() {
				windowHalfX = window.innerWidth / 2;
				windowHalfY = window.innerHeight / 2;
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize(window.innerWidth, window.innerHeight);
			}
			//渲染
			function render() {
				camera.lookAt(new THREE.Vector3(0, 70, 0));
				renderer.render(scene, camera);
			}
		</script>
	</body>
</html>

 

如果觉得自己画3d模型费事的话,下载路径https://download.csdn.net/download/fengyinshenlin/10747073,需要1积分,没办法上传时必须选择积分......

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值