需求
公司XX产品线,有一些产品,都配合有专业的结构设计,因此产生了较多的结构设计文件,之前渲染过3D动画,效果还不错,但要想去向客户去直观展示还有点不够炫酷,因此决定采用web3D 页面的方式呈现出来。能达到更沉浸式体验。
结果
废话不多说,先上结果,看起来还是凑合,首次撸前端代码,不足之处,大神们莫要拍砖。
框架和库
three.js(3D) + jQuery + bootstrap + echart(图表)
脱坑记
- 3D文件到 three.js 展示 结构设计用的是 soildworks 3D设计文件格式为 SLDASM 此为组合结构文件 首先soildworks 转换为 SLDPART 文件(减小大小,只输出表面),再转换为STEP 文件,再使用3DS MAX 打开 STEP 转换为 obj+mtl 完成转换。 核心load代码如下:
function loadOBJ(loder, path, mtlfile, objfile, x, y, z, isadd) {
path = path || "/static/source3d/";
loder.setPath(path);
loder.load(mtlfile, function (materials) {
materials.preload();
new THREE.OBJLoader()
.setMaterials(materials)
.setPath(path)
.load(objfile, function (object) {
object.rotation.y = -3.141592653/2;
object.position.x = x;
object.position.y = y;
object.position.z = z;
scene.add(object);
}, onProgress, onError);
}
);
}
- 使用多render 为了将普通页面与three的3D页面进行融合,可使用多render,webgl读3D图,而CSS2DRenderer 读取普通2D 页面,在render函数中同时调用两个render 绘制。
function render() {
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
}
CSS2DRenderer 核心加载DIV代码如下:
var Div1 = document.getElementById('myModal2');
Div1.style.cssText = "width:420px;height:460px;border:0px solid #000;";
Label2 = new THREE.CSS2DObject(Div1);
Label2.position.set(-3000, 1000, 2000);
labelRenderer = new THREE.CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
container.appendChild(labelRenderer.domElement);
- three.js 点击选中 使用 THREE.Raycaster 按照网上搜的教程即可完成点选object,但注意一点:如果是load 进来的object ,如我load的 obj文件,并不一定都是object 大部分是 group 也就是object的集合,此处要注意如果是group集合的话,改成如下的代码:
intersects = raycaster.intersectObjects(scence.children); //scence的children 是group 无法选中
intersects = raycaster.intersectObjects(obj_1.children); //可以选中
- 其它,特效譬如水啦,太阳啦,都是three demo 中的示例,cp代码,根据需要改个场景大小即可。
sky.scale.setScalar(1000000);
var waterGeometry = new THREE.PlaneBufferGeometry(1000000, 1000000);
- 如需代码,可留言,如需求多,可考虑上传 github。