前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >webgl(threejs)生成房间楼层

webgl(threejs)生成房间楼层

作者头像
用户3158888
发布2022-09-23 11:17:05
1.3K0
发布2022-09-23 11:17:05
举报

楔子

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

墙体几何对象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也可以找到开源的包可以使用。

如果你有好的思路,也欢迎和我交流。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 楔子
  • 墙体几何对象PathCubeGeometry
  • 门和窗
  • BSP挖洞
  • 创建地板
  • 结语
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档