1.概要

最近学习Three.js,尝试加载一些3d max导出的obj、stl模型,在展示模型的时候遇到了一些问题,模型的尺寸、位置和旋转角度每次都靠手工调整,非常的不方便,就想着写一个方法来随心所欲的控制模型的尺寸、位置、角度。

2.实现思路

先看看官方加载外部模型的标准代码:

var mtlLoader = new THREE.MTLLoader();
mtlLoader.load(mtlPath, function (materials) {
materials.preload(); var loader = new THREE.OBJLoader();
loader.setMaterials(materials);
loader.load(modelPath, function (obj) { obj.castShadow = true;
obj.receiveShadow = true; //场景加载
scene.add(obj);
//渲染
renderer.render(scene, camera); }});

通过以上代码,可以实现obj模型和mtl纹理的加载。但是在实际使用中,模型的尺寸和方向不是完美合适的,比如博主我在使用过程中就遇到了以下三个问题。

问题1 模型尺寸

外部模型往往是3d max导出,模型的大小尺寸和实际中往往不一样。three.js 官方有scale 属性可以更改模型的尺寸比例,代码如下。

obj.scale.set(x,y,z);

现在问题来了,我知道的参数其实是模型的长、宽、高,并不是比例。解决的方法如下,先计算出模型的实际长宽高,转换成比例。

//计算模型尺寸
var box = new THREE.Box3();
box.expandByObject(obj); var length = box.max.x - box.min.x;
var width = box.max.z - box.min.z;
var height = box.max.y - box.min.y; //l w h对应模型的长宽高
obj.scale.set(l / length, h / height, w / width);

问题2 模型角度

和模型尺寸一样,外部模型的朝向和实际中有时候不同,有时候一种模型会在场景中有多个朝向的分布,例如办公室的椅子。还是先看看官方的方法position属性可以设置模型x、y、z的转向。代码如下:

obj.position.set(angleX, angleY, angleZ);

现在看起来是没有问题了,不过当你遇到一个模型中心点坐标和场景中心点坐标相差几百万单位的时候,估计旋转后连模型影子都看不见了...例如博主我遇到的下图这种模型参数:

如上图,模型本身只有78.5单位长,但是中心x坐标却是2219638.25,导致博主我硬是找了一下午没有加载出模型来。

在此感谢 https://blog.csdn.net/ruangong1203/article/details/60476782 这篇博客给了我思路。解决方法是增加一个容器,将模型放入容器中,然后指定容器的中心点,然后旋转容器代替旋转模型即可。

let wrapper = new THREE.Object3D();
//模型在场景中的为准
wrapper.position.set(x,y,z);
wrapper.add(obj); wrapper.rotation.set(angleX, angleY, angleZ);

问题三 模型位置

模型的位置是最头痛的,three.js默认的以模型的中心偏移来定位的,同样看看官方的方法,有个position属性可以更改模型位置。如果遇到问题二里面那种偏移超级远的模型就尴尬了。

我的解决思路是先计算出模型的实际尺寸,然后再找到模型的中心点,根据x=0,y=0,z=0将模型移动到正常位置,然后通过问题二的容器解决方法来重新设置容器位置解决。代码如下:

//计算模型尺寸
var box = new THREE.Box3();
box.expandByObject(obj); var x = (box.max.x + box.min.x) / 2;
var y = (box.max.y + box.min.y) / 2;
var z = (box.max.z + box.min.z) / 2; obj.position.set(0 - x, 0 - y, 0 - z); obj.castShadow = true;
obj.receiveShadow = true; let wrapper = new THREE.Object3D();
//模型在场景中实际位置
var pt={x:0,y:0,z:0};
wrapper.position.set(pt.x, pt.y, pt.z);
wrapper.add(obj);

3.实现效果

放张效果图:

在线体验地址:http://www.88gis.cn/plugins/dgis3d/pages/index.html

4.代码

  详细代码请移步我的个人博客88gis.cn查看更多。

  代码下载地址:点击前往

【Three.js】实现随心所欲的展示外部三维模型的更多相关文章

  1. 利用WPF建立自己的3d gis软件(非axhost方式)(六)跳转,增加外部三维模型

    原文:利用WPF建立自己的3d gis软件(非axhost方式)(六)跳转,增加外部三维模型 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPe ...

  2. WebGL three.js学习笔记 加载外部模型以及Tween.js动画

    WebGL three.js学习笔记 加载外部模型以及Tween.js动画 本文的程序实现了加载外部stl格式的模型,以及学习了如何把加载的模型变为一个粒子系统,并使用Tween.js对该粒子系统进行 ...

  3. three.js实现3D模型展示

    由于项目需要展示3d模型,所以对three做了点研究,分享出来 希望能帮到大家 先看看效果: three.js整体来说 不是很难 只要你静下心来研究研究 很快就会上手的 首先我们在页面上需要创建一个能 ...

  4. js实现侧边栏信息展示效果

    目前的网页都右侧边栏,有的是在左侧,类似于导航栏,如一些购物商城,还有一些是在网页的右下角,一般是提示客服信息和微信/QQ等服务. 这里都涉及到一个动画效果的展示,即点击侧边栏时会在侧边栏的右侧或者左 ...

  5. js大数计算之展示

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. js中如何去获取外部css样式

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  7. js模拟import方法导入外部文件

    function Import() { for( var i=0; i<arguments.length; i++ ) { var file = arguments; if ( file.mat ...

  8. js整频滚动展示效果(函数节流鼠标滚轮事件)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. fiddler接口测试,js代码修改日志展示(埋点用)

    fiddler 通过fiddler 发送接口信息: http://blog.csdn.net/java2013liu/article/details/53380381 rules--automatic ...

随机推荐

  1. DataGridView相关代码

    加行号: private void dgv_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { //添加行号 var ...

  2. Nginx搭建成功后,无法访问Tomcat问题

    一.nginx搭建好后无法访问后端Tomcat项目 通过项目名称过滤的方式访问Tomcat,比如项目名称叫easy. 修改其server下的location目录,配置如下: server { #监听的 ...

  3. php利用mpdf生成pdf并保存到目录

    下载mpdf7.0两种方法 (1). github地址:https://github.com/mpdf/mpdf (2). composer require mpdf/mpdf <?php er ...

  4. .NET基础 (14)管理文件和文件夹的类型

    管理文件和文件夹的类型1 如何操作文件和文件夹2 如何实现文件和文件夹的监控功能 管理文件和文件夹的类型1 如何操作文件和文件夹 .NET内建类中提供了FileInfo和DictionaryInfo两 ...

  5. python int函数转换浮点型字符串的坑???

    python中的int函数可以将数字或字符串转换为整型数字类型,具体功能就不提了 最近发现一个问题,对于字符串'1.1'之类的,int转换的时候会报异常,这是为什么,个人感觉直接转换成1不就行了,干嘛 ...

  6. windows下 git+tortoiseGit的使用【转】

    一定要自己写出来才能牢记,所以我来写一下 git确实比svn好用的多了,最起码只有一个文件夹用来标记版本信息比svn所有文件夹下都要放一个文件夹来标记版本信息先进多了,不然你不想要版本管理这些文件的时 ...

  7. [转]使用WCF 4.0 构建 REST Service

    本文转自:http://www.cnblogs.com/lanvige/archive/2010/12/03/set_up_rest_service_with_wcf_4.html 用过一段时间的Ru ...

  8. 12、Docker的网络--bridge

    单机网络 Bridge Network Host Network None Network 多机网络 Overlay Network 12.1 网络命名空间   启动一个容器 docker run - ...

  9. TOAD连接ORACLE而不装ORACLE 客户端的方法

    TOAD连接ORACLE而不装ORACLE 客户端的方法 原来连接ORACLE总是要装ORACLE客户端,挺麻烦得,一方面要带ORACLE得盘,另一方面,装这么大得东西也让人很不爽. ORACLE好像 ...

  10. delphi 拆分字符串

    最近在使用Delphi开发一种应用系统的集成开发环境.其中需要实现一个字符串拆分功能,方法基本原型应该是:procedure SplitString(src: string ; ch: Char; v ...