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

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

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绘制柜子的整体架构。

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

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

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制作一个快递柜的更多相关文章

  1. js利用点击事件做一个简单的计算器

    先放一个样式图: 源代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...

  2. 一起学HTML基础-利用CSS和JavaScript制作一个切换图片的网页

    由于个人原因,不详细写步骤 思路: 一.布局 二.制作图片区和按钮区的div及颜色.边框.背景属性等 三.用PS将四张图片剪切到同一个尺寸,重叠放置在图片切换区,透明度设置为0 四.点击对应按钮时,将 ...

  3. 利用yacc和lex制作一个小的计算器

    买了本<自制编程语言>,这本书有点难,目前只是看前两章,估计后面的章节,最近一段时间是不会看了,真的是好难啊!! 由于本人是身处弱校,学校的课程没有编译原理这一门课,所以就想看这两章,了解 ...

  4. 百度前端技术学院2018笔记 之 利用 CSS animation 制作一个炫酷的 Slider

    前言 题目地址 利用 CSS animation 制作一个炫酷的 Slider 思路整理 首先页面包含三种东西 一个是type为radio的input其实就是单选框 二是每个单选框对应的label 三 ...

  5. three.js cannon.js物理引擎制作一个保龄球游戏

    关于cannon.js我们已经学习了一些知识,今天郭先生就使用已学的cannon.js物理引擎的知识配合three基础知识来做一个保龄球小游戏,效果如下图,在线案例请点击博客原文. 我们需要掌握的技能 ...

  6. 用JS制作一个信息管理平台完整版

      前  言 JRedu 在之前的文章中,介绍了如何用JS制作一个实用的信息管理平台. 但是那样的平台功能过于简陋了,我们今天来继续完善一下. 首先我们回顾一下之前的内容.   1.JSON的基础知识 ...

  7. JS制作一个创意数字时钟

    通过js代码制作一个创意数字时钟 通过JS代码实现创意数字时钟效果如下:由数字化的卡通形象图片取代常规的数字显示当前实时北京时间.具体效果示例: 核心重点: (1)Date方法的初步了解 (2)构建模 ...

  8. three.js 制作一个三维的推箱子游戏

    今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...

  9. 利用DreamweaverCS5制作一个含有动态标题的教程

    DreamweaverCS5怎么制作一个含有动态标题?做一个网页就先要做一个标题,一个好标题会让网页让人印象深刻,有动态的标题会让网页更生动,下面我就介绍一下怎么制作一个含有动态的标题   做一个网页 ...

随机推荐

  1. 在 Docker 搭建 Maven 私有库

    在 Docker 搭建 Maven 私有库 小引 If you are developing software without a repository manager you are likely ...

  2. 【Unity3D】简单常用的功能实现2——视角的跟随、旋转、缩放

    [视角的跟随.旋转.缩放实现] 首先,在实现这些功能之前,我们给Hierarchy面板中的主摄像机额外包装几层Empty Object,形成一个新的摄像机结构,如下图(当然这些空物体的命名大家按自己方 ...

  3. 基于.Net Core的Redis:基本数据类型及其应用场景与命令行操作

    参考自:https://blog.csdn.net/only_yu_yy/article/details/78873735 https://blog.csdn.net/fenghuoliuxing99 ...

  4. turtle库常用函数

  5. Django学习路

    1.脚本不能随便运行,没准 linux 运行完就上不去了 2.pip 在 linux 上 写 pip3 同理 python 写为 python3 3.在 pycharm 上安装库之后,在命令提示符中依 ...

  6. Upload 上传 el-upload 上传配置请求头为Content-Type: "multipart/form-data"

    api接口处添加属性 (标红处) // 校验台账 export const checkEquiment = (data) => { return axios({ url: '/job/equip ...

  7. nginx静态资源防盗链

    含义: 用于阻止 Referer 头字段为无效值的请求访问站点.需记住的是,使用适当的 Referer 字段值来伪造请求非常容易,因此本模块的预期目的不是要彻底阻止此类请求,而是阻止常规浏览器发送的大 ...

  8. PHP array_diff_assoc() 函数

    实例 比较两个数组的键名和键值,并返回差集: <?php$a1=array("a"=>"red","b"=>"g ...

  9. PHP preg_replace_callback() 函数

    preg_replace_callback 函数执行一个正则表达式搜索并且使用一个回调进行替换.高佣联盟 www.cgewang.com 语法 mixed preg_replace_callback ...

  10. Canvas知识点补充

    Canvas笔记 复习 初识canvas <canvas> 是 HTML5 新增的,一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素.它可以用来制作照片集 ...