楔子

在很多数字孪生项目中,都会涉及到楼层的建模。楼层的建模由于结构繁多,如果都是建模师进行手动建模,工作量会比较大。而楼层本身的结构,可以抽象成可以通过路径构造的对象(这和之前的文章提及的的管路以及道路类似),这方便我们通过代码的方式来生成房间楼层。

墙体几何对象PathCubeGeometry

楼层一般分成墙体和地板两个部分,首先来看下墙体对象。 以threejs为基础,扩展一个几何对象PathCubeGeometry。 该对象通过一个Path3D路径来构造一个墙的几何体,该几何体可以分成start,end,top,bottom,outside,inside等几个表面分组,这样就方便给内表面和外表面,以及顶面等设置不同的材质贴图的效果。 主要代码如下:

    this.vert = vert;
this.rawUV = rawUV;
this.pathU = pathU; this.indices = []
this.vertices = [];
this.uvs = [],
this.normals = []; this.generateSideWall(vert,inner,outer,innerTop, outerTop, true,closed);
this.generateSideWall(vert,inner,outer,innerTop, outerTop, false,closed); this.generateTopBottom(vert,inner,outer,innerTop,outerTop,true,closed);
this.generateTopBottom(vert,inner,outer,innerTop,outerTop,false,closed); if(!closed) {
this.generateAZSide(vert,inner,outer,innerTop,outerTop,true);
this.generateAZSide(vert,inner,outer,innerTop,outerTop,false);
}

通过PathCubeGeometry,我们可以方便的构建墙体,比如如下示例代码:

const materials = [m1, m2, m3, m3, m3, m3];
const points = json.outerWall.path;
const p0 = points[0];
const path = new Path3D();
const scale = 20;
path.moveTo(p0.x * scale, p0.y * scale, p0.z * scale);
for (let i = 1; i < points.length; i++) {
let p = points[i];
path.lineTo(p.x * scale, p.y * scale, p.z * scale);
}
path.closePath();
cosnt patCube = new PathCubeGeometry(path, 10, 50, 32, 500);
const mesh = new dt.Mesh(patCube, materials);

首先通过Path3D构造一个路径(路径来源于传入的一系列点points),然后通过路径构造一个结合体对象PathCubeGeometry,最后生成实体,效果如下图所示:

门和窗

构造门和窗的难度不大,一般都通过立方体 + 贴图的方式就可以生成。比如如下代码可以生成一个双开门:

function createDoor(pos) {
var cube = new CubeGeometry(200, 400, 5);
var material = createMaterial(graph, {
color: 0xffffff,
flatShading: true,
map: "./images/glass-wall6.png",
transparent: true,
}); material.map.repeat.set(0.5, 1);
var leftDoor = new Mesh(cube, material);
leftDoor.position.copy(pos.clone().sub(new Vec3(100)));
leftDoor.attr("type", "left_door");
leftDoor._type = "left_door";
dataModel.add(leftDoor); var rightDoor = new Mesh(cube, material);
rightDoor.position.copy(pos.clone().add(new Vec3(100)));
rightDoor._type = "right_door";
dataModel.add(rightDoor);
}

创建的门的效果如下图所示:

创建单开门和窗户的思路是一致的。不过难点的地方是门窗所在的位置,墙体本身需要挖洞。挖洞需要使用BSP功能。

BSP挖洞

BSP操作可以对模型进行交集 并集 差集的操作。 要在墙上挖洞,可以在墙的几何体上进行差集操作,比如减去一个立方体,这样就可以在墙面上生成一个方型的洞。

在THREEJS上面,有一个开源的BSP包,THREEBSP。

代码如下所示:

var csg = new CSG().setFromGeometry(patCube);
var csg2 = new CSG().setFromGeometry(cubeGeometry);
var csg3 = new CSG().setFromGeometry(cubeGeometry2);
csg.subtractOperand(csg2);
csg.subtractOperand(csg3);
var geometry = csg.toGeometry();
var mesh = new Mesh(geometry, materials);

最后生成的效果如下图所示:

在把创建好的门和窗放到相应的挖洞位置,效果如下所示:

创建地板

在threejs中,通过ExtrudeGeometry可以创建地板的几何体,然后指定地板的材质,既可以创建一个地板对象 代码如下所示:

  var path = new ShapePath();
var texture = graph.loadTexture("./images/floor.jpg", {
wrapT: RepeatWrapping,
wrapS: RepeatWrapping,
});
texture.repeat.set(1 / 400, 1 / 400);
texture.anisotropy = 16; let m1 = new BasicMaterial({
map: texture,
color: 0xffffff,
toneMapped: false,
});
const simpleShapes = path.toShapes(true); var geometry = new ExtrudeGeometry(simpleShapes, {
depth: 1,
bevelEnabled: false,
vertical: true,
});
var mesh = new Mesh(geometry, [m1, m1]);
dataModel.add(mesh);

最终的效果如下所示:

结语

本文介绍了通过代码生成楼层的功能,其中用到了PathCubeGeometry,ExtrudeGeometry,BSP相关技术,其中PathCubeGeometry由于需要自己构建,会稍晚难点; ExtrudeGeometry是threejs本身就存在的对象,BSP也可以找到开源的包可以使用。

如果你有好的思路,也欢迎和我交流。关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。

webgl(threejs)生成房间楼层的更多相关文章

  1. 基于webgl(threejs)的路面编辑

    楔子 在很多应用中,特别是一些园区类的应用. 都需要对园区的地面 环境进行展示,路面就是地面的一部分. 通常的做法是,都是建模的时候把相关的元素都建好,然后导入到展示系统中进行展示. 不过有些情况下, ...

  2. 基于WebGL/Threejs技术的BIM模型轻量化之图元合并

    伴随着互联网的发展,从桌面端走向Web端.移动端必然的趋势.互联网技术的兴起极大地改变了我们的娱乐.生活和生产方式.尤其是HTML5/WebGL技术的发展更是在各个行业内引起颠覆性的变化.随着WebG ...

  3. canvas svg webgl threejs d3js 的区别

    canvas 绘制2D位图. Echarts是基于Canvas技术的可视化工具,底层封装了原生的JavaScript的绘图 API. canvas里面绘制的图形不能被引擎抓取,canvas中我们绘制图 ...

  4. webgl,threejs教程、笔记

    发现一个不错的博客,学学. webgl和threejs教程

  5. 基于HTML5及WebGl下生成的json格式的工控SCADA风机叶轮旋转

    突然有个想法,如果能把一些用到不同的知识点放到同一个界面上,并且放到一个盒子里,这样我如果要看什么东西就可以很直接显示出来,而且这个盒子一定要能打开.我用HT实现了我的想法,代码一百多行,这么少的代码 ...

  6. WEBGL threejs 1

    首先感谢国内的这些研究者,先驱们~~~~~ 文章内容来自于webgl中文网,感谢~~~ -------------------------------------------------------- ...

  7. CesiumLab V1.4 分类3dtiles生成(倾斜单体化、楼层房间交互)我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了。不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化。就下面这个示例https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=

    我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了.不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化.就下面这个示例 http ...

  8. Unity 随机房间地图生成

    无论是在迷宫还是类似于地牢的游戏地图中,利用程序来生成每次都不一样的地图是一件叫人兴奋不已的事. 这时我们需要解决两个非常重要的随机事件: 1.在一定范围内随机出各不相同但又不能互相重叠的房间 2.优 ...

  9. Web三维编程入门总结之一:WebGL与Threejs入门知识

    /*在这里对这段时间学习的3D编程知识做个总结,以备再次出发.计划分成“webgl与three.js基础介绍”.“面向对象的基础3D场景框架编写”.“模型导入与简单3D游戏编写”三个部分,其他零散知识 ...

  10. Unity 随机地图房间通道生成

    之前的博客中已经说了随机房间生成: https://www.cnblogs.com/koshio0219/p/12604383.html 但实现房间生成只是整个地图生成最初最简单的一步.下面讨论如何随 ...

随机推荐

  1. 4G EPS 中的 PLMN 选择

    目录 文章目录 目录 前文列表 PLMN 选择 前文列表 <4G EPS 中的系统消息类型> PLMN 选择 UE 开机后的第一件事情就是完成小区搜索,即完成和 eNB 的牵手.在牵手成功 ...

  2. 基于webapi的websocket聊天室(四)

    上一篇实现了多聊天室.这一片要继续改进的是实现收发文件,以及图片显示. 效果 问题 websocket本身就是二进制传输.文件刚好也是二进制存储的. 文件本身的传输问题不太,但是需要传输文件元数据,比 ...

  3. 鸿蒙HarmonyOS实战-Stage模型(应用上下文Context)

    前言 应用上下文(Context)是应用程序的全局信息的接口.它是一个抽象类,提供了访问应用程序环境的方法和资源的方法.应用上下文可以用于获取应用程序的资源.启动Activity.发送广播等.每个应用 ...

  4. 容器docker技术

    我们先看看很久很久以前,服务器是怎么部署应用的! 由于物理机的诸多问题,后来出现了虚拟机. 但是虚拟化也是有局限性的,每一个虚拟机都是一个完整的操作系统,要分配系统资源,虚拟机多道一定程度时,操作系统 ...

  5. docker制作springboot镜像

    以下步骤在具有Docker环境的Linux机器上操作. 把springboot-1.0.0.jar放到/usr/local/springboot目录下,并在该目录下创建Dockerfile文件,内容为 ...

  6. 「C++」复杂模拟【壹】

    建议开启目录食用 阅读本文之前建议您先看这里,如果您已经看完了,那么就可以放心大胆的学习本文了. 我认为其实本文的难度还是比较大的,今天我们题是来自山东省省选,所以建议大家谨慎阅读,如果您是专业程序员 ...

  7. 用 Python 绘制现金流量图

    目录 用 Python 绘制现金流量图 Python 实现 实现原理 具体代码 使用示例 1:根据现金流量表绘制现金流量图 使用示例 2:绘制等额.等差.等比序列现金流量图 等额序列现金流量图 等差序 ...

  8. tampermonkey脚本 百度搜索屏蔽CSDN

    // ==UserScript==// @name         屏蔽CSDN// @namespace    http://tampermonkey.net/// @version      20 ...

  9. Pycharm创建的虚拟环境,使用命令行指定库的版本进行安装

    Pycharm创建的项目,使用了虚拟环境,对库的版本进行管理:有些项目的对第三方库的版本 要求不同,可使用虚拟环境进行管理 直接想通过pip命令安装,直接看第3点 操作步骤: 1.找到当前项目的虚拟环 ...

  10. MAC10.12Caps Lock失灵

    先说一下小弟的MAC系统是黑苹果来的,笔记本并没有那个显示大小写的指示灯,所以一开始的时候一直以为自己的键盘坏了还特意换了一个(结果质量比原来的更差),输入密码因为有大小写经常被提示密码错误所以蛋疼得 ...