three.js 利用uv和ThreeBSP制作一个快递柜功能


Posted in Javascript onAugust 18, 2020

最近有three网友,问我要不要学习blender,其实我感觉学习一下也无妨,不过花大量时间精通,尚可不必,术业有专攻给别人留一条路吧,哈哈。那我我们就是用ThreeBSP和uv贴图的知识来制作一个定制化的快递柜,先上图,在线案例请点击博客原文。

three.js 利用uv和ThreeBSP制作一个快递柜功能

下面我们来讲解一下这样一个柜子的制作。

1. 主角是一个JSON

这样一个快递柜的核心是JSON数据的创建,有了jSON数据,我们就可以通过循环遍历出柜子,柜门和uv映射关系。那面下面来看看我们的JSON数据(部分代码)。

var doorArray = [
  [94, 10, -176, 196, false], [94, 10, -76, 196, false], [94, 10, 76, 196, false], [94, 10, 176, 196, false], [46, 15, 0, 186, false], [46, 60, 0, 147, false],
  [46, 21, 0, 105.5, true], [46, 10, 0, 89, true], [46, 10, 0, 78, true], [46, 20, 0, 62, true], [46, 20, 0, 41, true], [46, 20, 0, 20, true]
]

他是以一个数组的形式表现的,每一个数组代表一个柜子数据,每一个数组中的第一项为当前柜子宽度,第二项为高度,第三项为中心x位置,第四项而中心y位置,第五项为柜子是否能打开(因为有的地方为操作面板等)。

2. ThreeBSP绘制柜子的整体架构。

说完核心,我们在看看柜子的整体框架。下面是柜子的侧面图,通过侧面图我们可以很清晰的看出我们做了什么

three.js 利用uv和ThreeBSP制作一个快递柜功能

其实加的不多,就是在上面加了一个檐,下面加了两个底座,还有就是在每个小快递柜中掏出一个洞。
我们看代码

var texture = new THREE.TextureLoader().load('/static/images/base/cabinet.jpg')
let pubMate = new THREE.MeshNormalMaterial();
let frameGeom = new THREE.BoxGeometry(450, 200, 50);
let frameMesh = new THREE.Mesh(frameGeom, pubMate);
frameMesh.position.y = 106;

let footShape = new THREE.Shape();
footShape.moveTo(0, 2);
footShape.lineTo(8, -2);
footShape.lineTo(8, -4);
footShape.lineTo(0, -4);
footShape.lineTo(0, 0);
footShape.lineTo(-12, 0);
footShape.lineTo(-12, 2);
footShape.lineTo(0, 2);

let footExtrudeSettings = {
  steps: 5,
  depth: 450,
  bevelEnabled: false
};
let footGeom = new THREE.ExtrudeGeometry(footShape, footExtrudeSettings);
let footMesh = new THREE.Mesh(footGeom, pubMate);
let footMesh1 = footMesh.clone();
footMesh1.rotation.y = -Math.PI / 2;
footMesh1.position.x = 225;
footMesh1.position.y = 4;
footMesh1.position.z = 25;
let footMesh2 = footMesh.clone();
footMesh2.rotation.y = Math.PI / 2;
footMesh2.position.x = -225;
footMesh2.position.y = 4;
footMesh2.position.z = -25;

let headGeom = new THREE.BoxGeometry(450, 5, 20);
let headMesh = new THREE.Mesh(headGeom, pubMate);
headMesh.position.z = 23;
headMesh.position.y = 206 - 2.5;

let framebsp = new ThreeBSP(frameMesh);
let foot1bsp = new ThreeBSP(footMesh1);
let foot2bsp = new ThreeBSP(footMesh2);
let headbsp = new ThreeBSP(headMesh);

res = framebsp.union(foot1bsp).union(foot2bsp).union(headbsp);

for(var i=0; i<doorArray.length; i++) {
  let geom = new THREE.BoxGeometry(doorArray[i][0]-1, doorArray[i][1]-1, 50);
  let mesh = new THREE.Mesh(geom, pubMate);
  mesh.position.set(doorArray[i][2], doorArray[i][3], 4)
  let meshbsp = new ThreeBSP(mesh);
  res = res.subtract(meshbsp);
}

let cabinetGeom = res.toGeometry();
let cabinetMate = new THREE.MeshPhongMaterial({color: 0xD8C513, specular: 0xD8C513, shininess: 10});
let cabinetMesh = new THREE.Mesh(cabinetGeom, cabinetMate);
cabinetMesh.position.y = 106;

scene.add(cabinetMesh);

这里就是在框架BoxGeometry的基础上加了两个底座ExtrudeGeometry,和一个檐BoxGeometry,然后遍历减去小柜子。掌握好各自的空间位置,制作其实并不难。

3. 柜子的统一贴图

将一张图作为贴图,贴到所有的mesh上,如最上面图的效果,因为上节课已经大致的说了关于uv的一点知识。

for(var i=0; i<doorArray.length; i++) {
    let a0 = doorArray[i][0];
  let a1 = doorArray[i][1];
  let a2 = doorArray[i][2];
  let a3 = doorArray[i][3];

  let x1 = ((a2 - a0 / 2) + 223) / 446;
  let x2 = ((a2 + a0 / 2) + 223) / 446;
  let y1 = ((a3 - a1 / 2) - 10) / 191;
  let y2 = ((a3 + a1 / 2) - 10) / 191;

  doorMesh.geometry.faceVertexUvs[0][8] = [new THREE.Vector2(x1, y2), new THREE.Vector2(x1, y1), new THREE.Vector2(x2, y2)];
  doorMesh.geometry.faceVertexUvs[0][9] = [new THREE.Vector2(x1, y1), new THREE.Vector2(x2, y1), new THREE.Vector2(x2, y2)];
}

上面已经说过,这里的a0是柜子的宽,a1是柜子的高,a2是柜子中心x的坐标值,a3是柜子中心y的坐标值。因为柜子整体x的范围是[-223, 223],y的范围的[10, 201]。经过换算x1是纹理x坐标的最小值,x2是纹理x坐标的最大值,y1是纹理y坐标的最小值,y2是纹理y坐标的最大值,最后设置数组索引为8和9小三角面的uv映射(因为我们要设置的面为长方体的左面,就是8和9控制的面)。

最后加上一点点开柜子的动画就大功告成了。

转载请注明地址:郭先生的博客

到此这篇关于three.js 利用uv和ThreeBSP制作一个快递柜功能的文章就介绍到这了,更多相关three.js 制作快递柜内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript加密解密7种方法总结分析
Oct 07 Javascript
Extjs 几个方法的讨论
Jan 28 Javascript
jquery 跨域访问问题解决方法(笔记)
Jun 08 Javascript
jquery 元素控制(追加元素/追加内容)介绍及应用
Apr 21 Javascript
jQuery中ajax和post处理json的不同示例对比
Nov 02 Javascript
javascript中offset、client、scroll的属性总结
Aug 13 Javascript
又一枚精彩的弹幕效果jQuery实现
Jul 25 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
Dec 08 Javascript
JS原型与原型链的深入理解
Feb 15 Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 Javascript
Vue移动端项目实现使用手机预览调试操作
Jul 18 Javascript
微信小程序实现身份证取景框拍摄
Sep 09 Javascript
js+css实现扇形导航效果
Aug 18 #Javascript
js实现3D旋转效果
Aug 18 #Javascript
Vue elementui字体图标显示问题解决方案
Aug 18 #Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
Aug 18 #Javascript
javascript实现移动端上传图片功能
Aug 18 #Javascript
八种Vue组件间通讯方式合集(推荐)
Aug 18 #Javascript
小程序实现上传视频功能
Aug 18 #Javascript
You might like
第一个无线电台是由谁发明的
2021/03/01 无线电
PHP冒泡排序算法代码详细解读
2011/07/17 PHP
探讨多键值cookie(php中cookie存取数组)的详解
2013/06/06 PHP
php防止恶意刷新与刷票的方法
2014/11/21 PHP
PHP中生成UUID自定义函数分享
2015/06/10 PHP
PHP实现无限级分类(不使用递归)
2015/10/22 PHP
php验证码的制作思路和实现方法
2015/11/12 PHP
js跨域和ajax 跨域问题的实现思路
2009/09/05 Javascript
JavaScript 组件之旅(二)编码实现和算法
2009/10/28 Javascript
某页码显示的helper 少量调整,另附js版
2010/09/12 Javascript
jQuery队列控制方法详解queue()/dequeue()/clearQueue()
2010/12/02 Javascript
iphone safari不支持position fixed的解决方法
2012/05/04 Javascript
Javascript中的迭代、归并方法详解
2016/06/14 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
详解element-ui设置下拉选择切换必填和非必填
2019/06/17 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
js动态添加带圆圈序号列表的实例代码
2021/02/18 Javascript
[17:13]DOTA2 HEROS教学视频教你分分钟做大人-斯拉克
2014/06/13 DOTA
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
在Python中使用pngquant压缩png图片的教程
2015/04/09 Python
教你使用python实现微信每天给女朋友说晚安
2018/03/23 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
如何定义TensorFlow输入节点
2020/01/23 Python
python图形界面开发之wxPython树控件使用方法详解
2020/02/24 Python
Python函数默认参数常见问题及解决方案
2020/03/26 Python
python中id函数运行方式
2020/07/03 Python
实例代码讲解Python 线程池
2020/08/24 Python
利用 CSS3 实现的无缝轮播功能代码
2017/09/25 HTML / CSS
Canvas实现贝赛尔曲线轨迹动画的示例代码
2019/04/25 HTML / CSS
Lungolivigno Fashion官网:高级时装在线购物
2020/10/17 全球购物
如何提高JDBC的性能
2013/04/30 面试题
毕业生求职简历的自我评价
2013/10/07 职场文书
素质拓展感言
2014/01/29 职场文书
小学美术教学反思
2016/02/17 职场文书
MySQL提升大量数据查询效率的优化神器
2022/07/07 MySQL