使用three.js加载obj+mtl模型完整案例

时间:2024-03-17 07:54:07

使用说明

这里我借鉴了threejs案例的部分代码 (传送门:https://threejs.org/examples/?q=obj#webgl_loader_obj_mtl
),但是这个案例并不能满足我们的需求,我们的需求是能在页面上随意盘弄模型。

资源下载

首先我先得先去下面这个页面下载threejs的所有demo,然后去掉所有的案例,替换上自己的demo文件
使用three.js加载obj+mtl模型完整案例

目录结构

这是我的目录结构
使用three.js加载obj+mtl模型完整案例
千万别把js文件删了,基本上大量的库都在这里
下面开始上代码

js部分

js是最关键的部分,记住,threejs加载模型需要启动一个服务 很重要+很重要+很重要
你可以找个前端编辑器比如hbuilder开启服务器访问,也可以将项目放在tomcat里

下面是需要引入的js文件 也很重要,路径别错了

		<script src="../three.js"></script>
		<script src="../js/loaders/DDSLoader.js"></script>
		<script src="../js/loaders/MTLLoader.js"></script>
		<script src="../js/loaders/OBJLoader.js"></script>
		<script src="../js/controls/TrackballControls.js"></script>
		<script src="../js/Detector.js"></script>
// 相关测试参数 
// path是绝对路径
// pathName是案例文件名
var objArr = {
	"test":{
		path:"../model/obj/fangkouping/",
		pathName:"fangkouping"
	},
};

// 设置名称
setName("test");
var path , pathName ;
function setName(name){
	path = objArr[name].path;
	pathName = objArr[name].pathName;
}
// 容器
var container,
// 控制器
controls;
// 镜头
var camera, 
// 场景
scene,
// 渲染
renderer;

// 检测浏览器兼容
   if(Detector.webgl){
       //alert('浏览器支持');
       init();
       animate();
   }else{
       alert('浏览器不支持');
   }


//初始化
function init() {
	
	container = document.createElement( 'div' );
	document.body.appendChild( container );
	
	//创建一个一个视角
	camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 );
	
	//设置视角离原点的位置(眼睛距离模型的距离) 
	camera.position.z = 700;

	//控制器
	controls = new THREE.TrackballControls( camera );
	//设置旋转速度
	controls.rotateSpeed = 3;

	// 使动画循环使用时阻尼或自转 意思是否有惯性 
	controls.enableDamping = true; 
	//是否可以缩放 
	controls.enableZoom = true; 
	//是否自动旋转 
	controls.autoRotate = true; 
	//设置相机距离原点的最远距离 
	controls.minDistance = 500; 
	//设置相机距离原点的最远距离 
	controls.maxDistance = 2000; 
	//是否开启右键拖拽 
	controls.enablePan = true;

	// scene 创建一个场景
	scene = new THREE.Scene();
	// 设置场景背景色 
	// scene.background = new THREE.Color( 0xffffff);
	scene.fog = new THREE.Fog( 0x000, 1000, 4000 );

	console.log(scene)
	//创建一个环境灯光
	var ambientLight = new THREE.AmbientLight( 0xffffff, 0.4 );
	scene.add( ambientLight );

	//创建一个点灯光
	var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
	
	//给模型添加灯光
	camera.add( pointLight );
	
	//把视角放入环境
	scene.add( camera );

	// model  开始创建模型
	//进度通知
	var onProgress = function ( xhr ) {
			console.log(xhr)
		if ( xhr.lengthComputable ) {

			var percentComplete = xhr.loaded / xhr.total * 100;
			console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
			play(Math.round( percentComplete, 2 ))

		}

	};
	//报错通知
	var onError = function ( xhr ) { };
	
	// 添加操作器
	THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
	
	// 加载mtl
	var mtlLoader = new THREE.MTLLoader()
		.setPath( path )
		.load( pathName + '.mtl', function ( materials ) {
			console.log(materials)
			materials.preload();
			
			// 加载obj
			new THREE.OBJLoader()
				.setMaterials( materials )
				.setPath( path )
				.load( pathName + '.obj', function ( object ) {
					// console.log(object)
     						
     				// 设置旋转中心点
	                object.children[0].geometry.computeBoundingBox();

					object.children[0].geometry.center()

					object.position.y = 0;
					// 将模型加入到场景
					scene.add( object );

				}, onProgress, onError );
		});

	//创建一个webgl对象
	renderer = new THREE.WebGLRenderer({
		antialias: false,
     			alpha: true // 设置透明
	}
	);
	// 设置颜色
	renderer.setClearColor(0xffffff,0);
	// 设置分辨率
	renderer.setPixelRatio( window.devicePixelRatio );
	// 设置渲染尺寸
	renderer.setSize( window.innerWidth, window.innerHeight );
	container.appendChild( renderer.domElement );
	// 自适应监听
	window.addEventListener( 'resize', resize, false );

}

// 监听窗口自适应
function resize() {

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

	renderer.setSize( window.innerWidth, window.innerHeight );

}

// 时刻渲染
function animate() {

	controls.update();
	renderer.render( scene, camera );
	requestAnimationFrame( animate );

}

// 获取参数
function GetUrlParam(paraName) {
	var url = document.location.toString();
	var arrObj = url.split("?");
	if (arrObj.length > 1) {
		var arrPara = arrObj[1].split("&");
		var arr;
		for (var i = 0; i < arrPara.length; i++) {
			arr = arrPara[i].split("=");
			if (arr != null && arr[0] == paraName) {
				return arr[1];
			}
		}
		return "";
	} else {
		return "";
	}
}

// 这是一个进度条函数进度条函数
function play(a){
	document.getElementsByClassName("trends")[0].style.width = a + "%";
	if(a < 100 ){
		document.getElementById("progress").style.display = "block";
	}else{
		document.getElementById("progress").style.display = "none";
	}
}

css

body {
				font-family: Monospace;
				color: #fff;
				margin: 0px;
				overflow: hidden;
			    background-color: #E9E9E9;
			    background-image: url(../img/background.jpg);
			    background-size: cover;
			    -moz-background-size: cover;
			    -webkit-background-size: cover;
			    -o-background-size: cover;
			}
			    
		html,body{
			margin: 0;
			padding: 0;
		}
		/* 进度条 */
		.progress{
			position: fixed;
			width:  100%;
			height: 100%;
		}
		.progress .mask{
			position: fixed;
			width:  100%;
			height: 100%;
			background:  rgba(0,0,0,0.2);
			z-index: 99;
		}
		.progress .loading{
			width: 30em;
			height: 1em;
			background: #fff;
			position: absolute;
			left: 50%;
			top: 50%;
			transform: translate(-50%, -50%);
			z-index: 100;
			border-radius: 1em;
		}
		.progress .trends{
			width: 0;
			height: 100%;
			background: red;
			box-shadow: 1px 1px 10px red;
			border-radius: 1em;
		}

html

		<!--进度条-->
		<div id="progress" class="progress">
			<div class="mask"></div>
			<div class="loading">
				<div class="trends"></div>
			</div>
		</div>

效果图

加载中
使用three.js加载obj+mtl模型完整案例
效果一
使用three.js加载obj+mtl模型完整案例
效果二
使用three.js加载obj+mtl模型完整案例

后记

不同的模型的具体大小以及占据的空间是不一样的,所以我们就需要好好调节以下这几个参数
使用three.js加载obj+mtl模型完整案例

最后,假如需要加载别的模型,参考(传送门:https://threejs.org/examples
),替换一下引入的js文件以及更换一下加载模型的方法就行了,没了