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 相关文章推荐
基于jquery的实现简单的表格中增加或删除下一行
Aug 01 Javascript
js实现图片轮换效果代码
Apr 16 Javascript
探讨JavaScript中的Rest参数和参数默认值
Jul 29 Javascript
深入浅析JavaScript中的3DES
Aug 24 Javascript
JavaScript设计模式之单体模式全面解析
Sep 09 Javascript
移动设备手势事件库Touch.js使用详解
Aug 18 Javascript
原生js实现简单的焦点图效果实例
Dec 14 Javascript
解决Vue中引入swiper,在数据渲染的时候,发生不滑动的问题
Sep 27 Javascript
vue生命周期与钩子函数简单示例
Mar 13 Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 Javascript
JavaScript 装逼指南(js另类写法)
May 10 Javascript
解决vue初始化项目一直停在downloading template的问题
Nov 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
php实现的Timer页面运行时间监测类
2014/09/24 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
在 IE 中调用 javascript 打开 Excel 表
2006/12/21 Javascript
通过jquery实现tab标签浏览效果
2007/02/20 Javascript
jQuery照片伸缩效果不影响其他元素的布局
2014/05/09 Javascript
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
2015/06/29 Javascript
jQuery实现点击按钮弹出可关闭层的浮动层插件
2015/09/19 Javascript
Bootstrap中表单控件状态(验证状态)
2016/08/04 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
基于JavaScript实现图片剪切效果
2017/03/07 Javascript
Vue如何实现组件的源码解析
2017/06/08 Javascript
zTree获取当前节点的下一级子节点数实例
2017/09/05 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
angular2组件中定时刷新并清除定时器的实例讲解
2018/08/31 Javascript
javascript头像上传代码实例
2019/09/28 Javascript
JS数组splice操作实例分析
2019/10/12 Javascript
CentOS中使用virtualenv搭建python3环境
2015/06/08 Python
Python的包管理器pip更换软件源的方法详解
2016/06/20 Python
一篇文章读懂Python赋值与拷贝
2018/04/19 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
2020/05/26 Python
使用py-spy解决scrapy卡死的问题方法
2020/09/29 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
2021/01/24 Python
css3中检验表单的required,focus,valid和invalid样式
2014/02/21 HTML / CSS
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
HTML文本属性&amp;颜色控制属性的实现
2019/12/17 HTML / CSS
墨西哥网上超市:Superama
2018/07/10 全球购物
公务员的自我鉴定
2013/10/26 职场文书
预备党员公开承诺书
2014/05/28 职场文书
优秀大专毕业生求职信
2014/08/04 职场文书
涉外离婚协议书怎么写
2014/11/20 职场文书
银行实习推荐信
2015/03/27 职场文书
物业客服专员岗位职责
2015/04/07 职场文书