three.js展示三维模型
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
three.js展示三维模型的更多相关文章
- Vue-3D-Model:用简单的方式来展示三维模型
为什么做这个组件 我经常听到前端朋友们抱怨,在网页上展示三维模型太麻烦了.但是这方面的需求又有很多,例如做房地产的需要展示户型.卖汽车的需要展示汽车模型等. 在网页上展示三维模型就只能用WebGL技术 ...
- JS展示预览PDF。
刚好遇到需求,需要在手机端--展示一个电子收据,电子收据返回是PDF格式的,所以需要在前端上面去做PDF预览. 在学习过程中,了解到一种很简单,不需要任何插件的方法做PDF预览,但是这方法有局限性. ...
- js展示long型精度问题解决(server端解决)
问题:后端返回了个Long型的数据,在前端展示时最后2位变为00了 例如返回Long型的数据为75874464836881101,结果接口返回变为75874464836881100了 解决方法: 1. ...
- Esri的开源JS项目杂谈
一提到Esri大家首先想到的是庞大的ArcGIS产品大家族,其产品包含从桌面端,到服务器/云端,再到web/移动端.作为一名极客,不聊开源逼格似乎上不去啊.其实,Esri作为一个开放的平台,不仅有稳定 ...
- PDF.js 分片下载的介绍2:分片下载demo
上一个章节,简要说了以下分片下载的几个特性.今天主要用示例说明一下pdf.js分片下载. 服务器环境: php7.2 nginx 1.14 ubuntu 18.04测试浏览器:谷歌浏览器 70.0.3 ...
- android listview展示图片
最近学习android开发,感触颇多,和网站开发对比,还是有很大的差距,在这里记录一下. android listview展示图片 在网站开发上,展示图片非常简单,一个HTML img标签就搞定,加上 ...
- 如何通过倾斜摄影数据手动配置s3c索引文件?
如何通过倾斜摄影数据手动配置s3c索引文件? 大家知道,倾斜摄影数据最常见的是OSGB格式,并且是由一个一个的Tile分级文件夹构成的Data文件夹.结构一般如下图所示: 那么,如何才能把模型的各个瓦 ...
- WebIM 聊天 Demo
最近 2 个月用业余时间写了一个 IM ,动手之前想了很多,包括前期设计.语言.数据库等,经过了一番思想斗争,最终前台用 Vue.js 展示,Server 使用 node ,数据库使用 MongoDB ...
- JS-006-表格元素操作
直接上菜咯... 以下为 HTML 表格源码: <html> <head> <meta http-equiv="Content-Type" conte ...
随机推荐
- 2-5 【ngFor指令 事件的处理和样式绑定】顶部导航支持选中状态
索引的获取 first和last是布尔类型的 奇数偶数 []方括号表示的是数据绑定 ()圆括号就是事件绑定 . 开始代码 我们要实现的功能是菜单点击后,就变色 这样我们就得到了索引. 新建一个clas ...
- net ads join 和net rpc join命令的区别
要将主机加入Active Directory(AD),请输入: #net ads加入-U administrator 输入管理员密码:Passw0rd 使用短域名 - SAMDOM 加入'M1'到dn ...
- [LeetCode] 195. Tenth Line 第十行
Given a text file file.txt, print just the 10th line of the file. Example: Assume that file.txt has ...
- [LeetCode] 217. Contains Duplicate 包含重复元素
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- python:单元测试框架pytest的一个简单例子
之前一般做自动化测试用的是unitest框架,发现pytest同样不错,写一个例子感受一下 test_sample.py import cx_Oracle import config from sen ...
- 【神经网络与深度学习】Win10+VS2015 caffe环境搭建(极其详细)
caffe是好用,可是配置其环境实在是太痛苦了,依赖的库很多不说,在VS上编译还各种报错,你能想象那种被一百多个红色提示所笼罩的恐惧. 且网上很多教程是VS2013环境下编译的,问人很多也说让我把1 ...
- Python3 列表list合并的4种方法
方法1: 直接使用"+"号合并列表 aList = [1,2,3] bList = ['www', 'pythontab.com'] cList = aList + bList ...
- 问题一:使用AndroidDriver而非原来的AppiumDriver的原因
AppiumDriver升级到2.0.0版本引发的问题--Cannot instantiate the type AppiumDriver 1. 问题描述和起因在使用Appium1.7.0及其以下版本 ...
- typeof与instanceof运算符
typeof运算符用来判断某个变量的数据类型.typeof()返回值类型有如下几种: 1.number :数值类型 2.string :字符串类型 3.boolean :布尔型 4.function: ...
- leetcode 55 Jump Game 三种方法,回溯、动态规划、贪心
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...