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文件的代码
Jul 18 Javascript
javaScript 判断字符串是否为数字的简单方法
Jul 25 Javascript
js控制frameSet示例
Sep 10 Javascript
AngularJS基础 ng-value 指令简单示例
Aug 03 Javascript
使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)
Sep 01 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
Oct 18 Javascript
Jquery Easyui选项卡组件Tab使用详解(10)
Dec 18 Javascript
通过AngularJS实现图片上传及缩略图展示示例
Jan 03 Javascript
JavaScript实现获取远程的html到当前页面中
Mar 26 Javascript
webpack2.0搭建前端项目的教程详解
Apr 05 Javascript
Vue.js学习笔记之修饰符详解
Jul 25 Javascript
如何从头实现一个node.js的koa框架
Jun 17 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批量去除文件UTF8 BOM信息
2013/08/05 PHP
利用PHPExcel读取Excel的数据和导出数据到Excel
2017/05/12 PHP
Laravel5.5 实现后台管理登录的方法(自定义用户表登录)
2019/09/30 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
javascript重写alert方法的实例代码
2013/03/29 Javascript
jquery实现手风琴效果实例代码
2013/11/15 Javascript
Javascript对象属性方法汇总
2013/11/21 Javascript
JS阻止用户多次提交示例代码
2014/03/26 Javascript
js处理表格对table进行修饰
2014/05/26 Javascript
浅析JQuery中的html(),text(),val()区别
2014/09/01 Javascript
jQuery修改class属性和CSS样式整理
2015/01/30 Javascript
freemarker判断对象是否为空的方法
2015/08/13 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
2015/11/30 Javascript
简介AngularJS中$http服务的用法
2016/02/06 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
2016/10/16 Javascript
浅谈js在html中的加载执行顺序,多个jquery ready执行顺序
2016/11/26 Javascript
ES6新特性之类(Class)和继承(Extends)相关概念与用法分析
2017/05/24 Javascript
AngularJS实现与后台服务器进行交互的示例讲解
2018/08/13 Javascript
Vue项目数据动态过滤实践及实现思路
2018/09/11 Javascript
Vue CLI3 开启gzip压缩文件的方式
2018/09/30 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
Linux 下 Python 实现按任意键退出的实现方法
2016/09/25 Python
python pandas 组内排序、单组排序、标号的实例
2018/04/12 Python
python 实现将txt文件多行合并为一行并将中间的空格去掉方法
2018/12/20 Python
Python使用post及get方式提交数据的实例
2019/01/24 Python
Python中的元组介绍
2019/01/28 Python
python实现爬山算法的思路详解
2019/04/09 Python
PyQt5中QTableWidget如何弹出菜单的示例代码
2020/02/23 Python
新浪微博实习心得体会
2014/01/27 职场文书
淘宝活动总结范文
2014/06/26 职场文书
财政专业大学生职业生涯规划书
2014/09/17 职场文书
小学见习报告
2014/10/31 职场文书
小学生2015教师节演讲稿
2015/03/19 职场文书
外贸采购员岗位职责
2015/04/03 职场文书
2015年社区重阳节活动总结
2015/07/30 职场文书
html5移动端禁止长按图片保存的实现
2021/04/20 HTML / CSS