专栏首页郭先生的博客three.js 利用uv和ThreeBSP制作一个快递柜

three.js 利用uv和ThreeBSP制作一个快递柜

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

捕获11111111111.PNG

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

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

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

捕获1111.PNG

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

我们看代码

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控制的面)。

最后加上一点点开柜子的动画就大功告成了。

转载请注明地址:郭先生的博客

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • three.js 制作机房(上)

    three.js使用的人太少了,一个博文就几百个人看,之前发js基础哪怕是d3都会有几千的阅读量,看看以后考虑说一说d3了,哈哈。吐槽完毕回归正题。前几天郭先生...

    郭先生的博客
  • 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    通读完上一篇博文中提及的教程,觉得应该搞个大作业巩固一下所学的知识,想起刚上映的漫威宇宙第三阶段收官之作《蜘蛛侠·英雄远征》,于是决定仿一个MARVEL的片头动...

    大史不说话
  • 现在做 Web 全景合适吗?

    villainhr
  • 解剖 WebGL & Three.js 工作原理

    本文主要通过两方面来解剖 WebGL & Three.js :WebGL背后的工作原理和以Three.js为例,讲述框架在背后扮演什么样的角色,希望对大家学习有...

    万技师
  • 现在做 Web 全景合适吗?

    Web 全景在以前带宽有限的条件下常常用来作为街景和 360° 全景图片的查看。它可以给用户一种 self-immersive 的体验,通过简单的操作,自由的查...

    企鹅号小编
  • ThreeJS 立方体贴图

    在上一篇《ThreeJS 掏洞术》中,利用ThreeBSP完成了在‘墙’上掏出‘门’或‘窗户’洞的效果。但那个所谓的‘墙’一点也不像,试想谁家的墙是绿色的呀,而...

    Melody132
  • three.js 着色器材质之纹理

    今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击着色器纹理。

    郭先生的博客
  • 云图三维 | Three.js 后期处理

    后置处理通常是指应用到2D图像上的某种特效或者是滤镜。在ThreeJs的场景中,我们有由很多网格(mesh)构成的场景(scene)渲染成的2D图像。一般来说,...

    玖柒的小窝
  • three.js 实现火花特效

    上周末刚在原神里抽到了“火花骑士”可莉,于是就心血来潮,想用three.js来实现一种火系的特效,不是炸弹的爆炸,而是炸弹爆炸后在草上留下的火花效果

    落落落洛克
  • three.js 自制骨骼动画(一)

    上一篇郭先生解析了一下官方的骨骼动画案例,这篇郭先生就要做一个稍微复杂一点的骨骼动画了,就拿一个小人下手吧。在线案例请点击three.js自制骨骼动画。话不多说...

    郭先生的博客
  • 响铃:好生意还是好故事,这或是快递最后100米的真相

    好消息是,由于快递人工成本的上升,社区安全等限制条件或快递员配送时间紧等原因,往往在最后的末端配送环节达不到“门到门”的服务标准,于是给了创业者机会。目前站在这...

    曾响铃
  • 工业互联网可视化系统风格的抉择:线框模式之 3D 数据中心机房的实现

    3D 可视化,就是把复杂抽象的数据信息,以合适的视觉元素及视角去呈现,方便系统的展示、维护和管理。而在可视化系统的搭建选择上,所呈现的风格样式效果多种多样,各自...

    HT for Web
  • 用three.js渲染上海外滩模型

    天空的实现有多种方式,最常见的是一个包围全部的天空球,通常是UV球,也叫经纬球,其UV很方便映射到一张天空图片,比如:

    Jean
  • 基于WebGL无插件虚拟场景漫游关键技术(完整版)ThingJS

    如果要构建一个具有交互性和拓展性的沉浸式漫游场景,常用到3DSMAX、three.js等软件技术,学习门槛较高;ThingJS可视化组件更加轻量化,B/S架构下...

    森友鹿锘
  • 丰巢后撤,便宜了菜鸟驿站、京东快递柜?

    最近许多人取快递的时候发现,黄绿色的丰巢快递柜已经变成了红色的京东快递柜。这也让很多刚刚经历了丰巢收费风波的用户不禁产生疑问,京东不会要收更多的“管理费”吧。

    刘旷
  • three.js 数学方法之Matrix3

    今天郭先生来说一说three.js的三维矩阵,这块知识需要结合线性代数的一些知识,毕业时间有点长,线性代数的知识大部分都还给了老师。于是一起简单的复习了一下。

    郭先生的博客
  • 丰巢“5毛钱”矛盾的背后,还是快递到家的“老大难”

    一周时间,从丰巢宣布收费,杭州、上海部分小区陆续“罢用”丰巢,到5月15日首个抵制小区恢复使用丰巢快递柜,丰巢方面也公开道歉,宣布延长免费时间,事件似乎迎来了一...

    用户2908108
  • 丰巢科技CTO黄明:与时俱进,让AI推动智能快递柜行业多元化发展

    从最初的信使、驿站到现代的高铁、空运,物流行业作为时代技术能力的窗口,承载运转的交通工具从最初的保证速度,发展到保证安全甚至是提供更加优质的服务,究其缘由,无不...

    腾讯云互联网TechDay
  • 穹顶之下 看机器人如何成就绿色高效喷涂

    柴静的《雾霾调查:穹顶之下》再次把公众的目光聚焦到环保上,如何让雾霾逐渐消散,还我们一个长久的蓝天,是每个人都非常关注的问题。而涂装是一个对大气污染和环境危害比...

    机器人网

扫码关注云+社区

领取腾讯云代金券