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 相关文章推荐
js 获取(接收)地址栏参数值的方法
Apr 01 Javascript
JS实现的省份级联实例代码
Jun 24 Javascript
使用VS开发 Node.js指南
Jan 06 Javascript
原创jQuery弹出层插件分享
Apr 02 Javascript
jquery拖拽排序简单实现方法(效果增强版)
Feb 16 Javascript
AngularJS 最常用的功能汇总
Feb 17 Javascript
跨域请求的完美解决方法(JSONP, CORS)
Jun 12 Javascript
bootstrap select下拉搜索插件使用方法详解
Nov 23 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
Jul 04 Javascript
JavaScript设计模式之构造器模式(生成器模式)定义与用法实例分析
Jul 26 Javascript
Angular服务Request异步请求的实例讲解
Aug 13 Javascript
JS前端可视化canvas动画原理及其推导实现
Aug 05 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删除特定数组内容并且重建数组索引的方法.
2011/03/25 PHP
使用ThinkPHP的自动完成实现无限级分类实例详解
2016/09/02 PHP
php set_include_path函数设置 include_path 配置选项
2016/10/30 PHP
PHP生成随机字符串实例代码(字母+数字)
2019/09/11 PHP
TopList标签和JavaScript结合两例
2007/08/12 Javascript
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
从阶乘函数对比Javascript和C#的异同
2012/05/31 Javascript
你必须知道的JavaScript 变量命名规则详解
2013/05/07 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
jquery实现效果比较好的table选中行颜色
2014/03/25 Javascript
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
2015/03/05 Javascript
使用jQuery UI库开发Web界面的简单入门指引
2016/04/22 Javascript
Bootstrap自定义文件上传下载样式
2016/05/26 Javascript
TypeScript学习之强制类型的转换
2016/12/27 Javascript
jQuery插件版本冲突的处理方法分析
2017/01/16 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
weui框架实现上传、预览和删除图片功能代码
2017/08/24 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
使用Angular CLI生成 Angular 5项目教程详解
2018/03/18 Javascript
Vue 动态组件与 v-once 指令的实现
2019/02/12 Javascript
解决vue 单文件组件中样式加载问题
2019/04/24 Javascript
vue3中轻松实现switch功能组件的全过程
2021/01/07 Vue.js
python代码实现ID3决策树算法
2017/12/20 Python
PyQt5每天必学之像素图控件QPixmap
2018/04/19 Python
PyQt5实现简易计算器
2020/05/30 Python
Django框架实现的分页demo示例
2019/05/25 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
简单聊聊H5的pushState与replaceState的用法
2018/04/03 HTML / CSS
.NET笔试题(20个问题)
2016/02/02 面试题
红旗方阵解说词
2014/02/12 职场文书
无房证明范本
2014/09/17 职场文书
授权收款委托书范本
2014/10/10 职场文书
合作协议书范本
2014/10/25 职场文书
2014年妇委会工作总结
2014/12/10 职场文书