3d obj文件 c语言,【threejs学习随记(三)】3D模型导入问题

想想复杂的模型就交给3D设计师进行创作,而我们开发时只需引入模型文件,是不是很美滋滋?

当然,如果你时间充裕,又对模型创作感兴趣,那你确实可以花时间好好学习3D建模软件的使用,这样以后就可以自己创建所需模型,由自己导出与导入模型文件。因为从建模软件导出模型的过程中,其实有特别多的坑,一个不小心,导出的模型可能就大相径庭。所以依赖于别人导出的模型文件,有时你都不知道到底问题出在哪里。

一、Threejs支持的常见导出模型的文件格式有哪些?

JSON(*.js/ *.json):专门为Three.js自己设计的JSON格式,你可以使用它以声明的方式定义模型,及模型材质和动画。

OBJ和MTL(*.obj/ *.mtl):OBJ是一种简单的三维文件格式,只用来定义对象的几何体。MTL文件通常和OBJ文件一起使用,在一个MTL文件中,定义对象的材质。

Collada (*.dae):用来定义XML类文件中数字内容的格式。差不多所有的三维软件和渲染引擎都支持这个格式。

STL (*.stl):立体成型术 。 广泛用于快速成型。例如,三维打印机的模型文件通常是STL文件。Three.js有一个可定制的STL导出工具,STLExporter.js。可以将Three.js中的模型导出到一个STL文件。

FBX (*.fbx):是FilmBoX这套软件所使用的格式,其最大的用途是用在诸如在max、maya、softimage等软件间进行模型、材质、动作和摄影机信息的互导,因此在创建三维内容的应用软件之间具有无与伦比的互用性。

CTM (*.ctm):由openCTM创建的格式。可以用来压缩存储表示三维网格的三角形面片。

VTK(*.vtk):Visualization Tookit 定义的文件格式,用来指定顶点和面。VTK有两种格式,Three.js支持旧的格式,即Asscii格式。

PDB(*.pdb):特别的数据格式,由 蛋白质数据银行 场景,用来定义蛋白质的形状。Three.js可以加载并显示这种描述格式的蛋白质。

PLY (*.ply):多边形文件格式。通常保存三维扫描仪的数据。

二、Threejs中导入以上外部模型文件所需的辅助函数是哪些?

threejs中导入外部文件所需的辅助函数都在https://github.com/mrdoob/three.js/tree/dev/examples/js/loaders下可以找到。这里除了JSON模型文件的导入外,其余模型文件都需要引用其对应名称的辅助函数。例如:导入OBJ格式的模型,除了导入必要的three.js文件外,还需要在界面中引用OBJLoader.js文件。而JSONLoader函数集成在three.js中,所以无需再导入其他辅助文件!

三、3D软件导出的模型文件可以解析哪些东西呢?

可解析出网格(模型)的有:JSON, STL, OBJ

可解析出模型材质的有:JSON, MTL

可解析出模型动画的有:FBX, DAE,  JSON

理解就是,如:导出的json文件既可以存物体的模型,也可以存其材质及动画信息。

四、Threejs中几个常用模型文件导入示例

4.1  JSON格式文件导入——使用JSONLoader函数

// 实例化一个JSONLoader类

var loader = new THREE.JSONLoader();

// 导入资源

loader.load(

// 导入的模型文件所在 URL

'models/animated/monster/monster.js',

// 资源加载成功后执行的函数

//@params geometry 传入的模型,只能是单个模型,不能是一个场景

// @params materials 传入的材质,是个数组

function ( geometry, materials ) {

var material = materials[ 0 ];

var object = new THREE.Mesh( geometry, material );

scene.add( object );

}

);

4.2  OBJ格式文件导入——使用OBJLoader函数

敲黑板!!!!!前面已经讲过,obj格式文件都是和mtl格式文件搭配使用,因为obj格式的文件只能存模型,不能存模型材质和动画,而材质都存于mtl文件中。

4.2.1 当只导入模型,不导入材质,模型的材质由导入后用代码定义

//图片加载loader

var texture = new THREE.Texture();

var loader = new THREE.ImageLoader( );

//导入资源

loader.load(

//材质图片所在url

'textures/UV_Grid_Sm.jpg',

function ( image ) {

texture.image = image;

texture.needsUpdate = true;

} );

//obj文件加载loader

var loader = new THREE.OBJLoader( );

//导入资源

loader.load(

//obj模型所在url

'obj/male02/male02.obj',

// 资源加载成功后执行的函数

//@params object 传入的模型,只能是单个模型,也可能是一个group,视构建的model而定

function ( object ) {

//taverse函数为遍历object的每个子mesh,传入的child为每个mesh

//该示例中的object为一个group,有多个mesh组成

object.traverse( function ( child ) {

if ( child instanceof THREE.Mesh ) {

child.material.map = texture;

}

} );

object.position.y = - 95;

scene.add( object );

});

4.2.2 当既导入模型,又导入材质时

//当mtl中引用了dds类型的图片时,还需导入DDSLoader文件。

//这里的src路径视实际开发而定

THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );

var mtlLoader = new THREE.MTLLoader();

//设置路径,也可不是设置,在load中加载完整路径也可

mtlLoader.setPath( 'obj/male02/' );

mtlLoader.load( 'male02_dds.mtl',

// 资源加载成功后执行的函数

//@params materials THREE.MTLLoader.MaterialCreator

function( materials ) {

materials.preload();

var objLoader = new THREE.OBJLoader();

objLoader.setMaterials( materials );

objLoader.setPath( 'obj/male02/' );

objLoader.load( 'male02.obj', function ( object ) {

object.position.y = - 95;

scene.add( object );

});

});

4.3  其他模型文件导入类似,具体可参考官网examples

五、常见问题

模型导出为obj格式后,文件太大,想将其转化为json格式以减少文件大小。那么该怎样操作呢?

threejs R86版本中,有convert-to-threejs.py这样一个python文件,该文件的作用是将模型文件(.fbx,.dae, .obj, .3ds)转换成json格式。详细地转换操作可参考以下链接文章:

注意事项:

对以上链接文章做个小补充,这里箭头所引入的python版本最好一致,反正我当时不一致好像最后转化出bug了。

aHR0cDovL2ttLm9hLmNvbS9maWxlcy9waG90b3MvY2FwdHVyZXMvMjAxNzA3LzE1MDE0MDMwNTlfODhfdzk0OF9oNDA3LnBuZw==

aHR0cDovL2ttLm9hLmNvbS9maWxlcy9waG90b3MvY2FwdHVyZXMvMjAxNzA3LzE1MDE0MDMxMzZfNzlfdzkzN19oNTc4LnBuZw==

虽然threejs R86仍然保留convert-to-threejs.py,但是该文件作者已很久没维护,处于已过时的文件。所以即便成功将obj转换成json文件,仍有存在json文件不可用的情况(就问你绝不绝望??)。笔者在开发的过程中,就遇到该问题:成功转换成json文件后,用JSONLoader导入该文件后报错,因为转换后的json文件中“type“类型为”scene“,因此既不符合JSONLoader,也不符合ObjectLoader的导入格式要求。查询相关资料,发现有许多小伙伴也遇到过这种bug,暂时没找到解决方法。如果有大大发现,请务必分享下解决方案,万分感谢!

2. 如何用Threejs导入基于JSON格式的场景文件?

所谓场景文件,也就是文件中列出了各个物体和变换层级,以及所有的材质,纹理,相机和光源信息。讲道理,如果成功导入一个场景文件后,进行基本渲染就可以查看整个3D场景了。之前threejs的版本中进行场景渲染调用THREE.SceneLoader即可,不过现在threejs R86版本已用THREE.ObjectLoader替代。

给个简单示例:

//@params url 场景文件所在路径

new THREE.ObjectLoader().load( url, function ( loadedScene ) {

scene = loadedScene;

// If the loaded file contains a perspective camera, use it with adjusted aspect ratio...

scene.traverse( function ( sceneChild ) {

if ( sceneChild.type === 'PerspectiveCamera' ) {

camera = sceneChild;

camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;

camera.updateProjectionMatrix();

}

} );

六、干货分享

threejs入门指南

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 准备OBJ校园模型文件 首先,需要准备一个校园模型OBJ文件,可以使用3D建模软件(如Blender)制作,也可以从网上找到已有的OBJ文件。 2. 引入three.js库文件 在HTML文件中引入three.js库文件,可以通过以下方式: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> ``` 3. 创建场景、相机和渲染器 ```javascript // 创建场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); ``` 4. 加载OBJ文件 使用THREE.OBJLoader()加载OBJ文件,并将其添加到场景中: ```javascript // 加载OBJ文件 var loader = new THREE.OBJLoader(); loader.load('path/to/campus.obj', function (object) { scene.add(object); }); ``` 5. 其他设置 可以设置一些其他的属性,如光照和控制器等: ```javascript // 添加光照 var light = new THREE.PointLight(0xffffff, 1, 100); light.position.set(0, 0, 50); scene.add(light); // 添加控制器 var controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.25; controls.enableZoom = true; // 渲染场景 function render() { requestAnimationFrame(render); renderer.render(scene, camera); controls.update(); } render(); ``` 完成以上步骤,就可以在浏览器中看到导入OBJ校园模型了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值