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 网页黑白效果实现代码(兼容IE/FF等)
Apr 23 Javascript
Js获取下拉框选定项的值和文本的实现代码
Feb 26 Javascript
jquery实现点击弹出层效果的简单实例
Mar 03 Javascript
JS封装cookie操作函数实例(设置、读取、删除)
Nov 17 Javascript
JS弹出层遮罩,隐藏背景页面滚动条细节优化分析
Apr 29 Javascript
jQuery Ajax 异步加载显示等待效果代码分享
Aug 01 Javascript
深入理解JavaScript定时机制
Oct 27 Javascript
HTML的select控件美化
Mar 27 Javascript
微信小程序 本地数据存储实例详解
Apr 13 Javascript
Node学习记录之cluster模块
May 31 Javascript
layer.open关闭父窗口 以及调用父页面的方法
Aug 17 Javascript
详解vue中async-await的使用误区
Dec 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
php&amp;java(一)
2006/10/09 PHP
PHP中Session可能会引起并发问题
2015/06/26 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
PHP基于关联数组20行代码搞定约瑟夫问题示例
2017/11/07 PHP
PHP生成图表pChart的示例解析
2020/07/31 PHP
cookie的secure属性详解
2015/04/08 Javascript
基于Javascript实现返回顶部按钮
2016/02/29 Javascript
js阻止冒泡和默认事件(默认行为)详解
2016/10/20 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
详谈innerHTML innerText的使用和区别
2017/08/18 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
2018/01/09 Javascript
Vue引入sass并配置全局变量的方法
2018/06/27 Javascript
vue组件之间通信方式实例总结【8种方式】
2019/02/22 Javascript
Node.js 实现简单的无侵入式缓存框架的方法
2019/07/21 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
2019/10/23 Javascript
[01:10:49]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Django内容增加富文本功能的实例
2017/10/17 Python
python生成九宫格图片
2018/11/19 Python
Linux下Pycharm、Anaconda环境配置及使用踩坑
2018/12/19 Python
用sqlalchemy构建Django连接池的实例
2019/08/29 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
Python常用断言函数实例汇总
2020/11/30 Python
英国乐购杂货:Tesco Groceries
2018/11/29 全球购物
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
公务员政审单位鉴定材料
2014/05/16 职场文书
个人主要事迹材料
2014/08/26 职场文书
实习协议书
2015/01/27 职场文书
《1942》观后感
2015/06/08 职场文书
《花钟》教学反思
2016/02/17 职场文书
2016年“节能宣传周”活动总结
2016/04/05 职场文书
导游词之无锡丝业博物馆
2019/11/12 职场文书
go语言map与string的相互转换的实现
2021/04/07 Golang
pandas时间序列之pd.to_datetime()的实现
2022/06/16 Python
Win11 Dev 预览版25174.1000发布 (附更新修复内容汇总)
2022/08/05 数码科技