如何从路径或二维数组中在ThreeJS中绘制墙? [英] How to draw walls in ThreeJS from path or 2d array?

查看:511
本文介绍了如何从路径或二维数组中在ThreeJS中绘制墙?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从我构建的 FabricJS 编辑器收到的2d路径或阵列(稍后说明)绘制3d房屋模型(仅墙)。从2d到3d视图发送的数据类型无关紧要。



我的第一个尝试(也是非常接近我想要的)尝试是创建数组根据我要绘制的房间设置1和0,然后在ThreeJS中将其渲染为每个网格一个长方体。我基于
(黑色-墙壁的外观,蓝色-墙壁的每个长方体,红色-家具)



这就是为什么我想将墙壁渲染为平面,可能是从2d封闭的贴片渲染的原因(我可以导出从Fabric毫无问题)。当摄像机移动穿过墙壁时,我不需要墙壁很厚也不从后面看到。关于如何实现类似目标的任何线索?



帮我StackOverflow,您唯一的希望。

解决方案

您可以手动填充THREE.js网格的顶点和面数组,因此,如果可以将所需的闭合路径导出为坐标数组,则可以对其进行迭代,并将所需的信息推送到墙对象。



类似这样的东西



  var coordArray = [...]; //来自您的源的闭合形状的角点数组。为简单起见,这里假定为THREE.Vector2()。var墙=新的THREE.Geometry(); for(var i = 0; i< coordArray.length(); i ++){//在坐标数组上迭代,按下几何顶点var坐标= coordArray [i]; wall.vertices.push(new THREE.Vector3(coordinates.x,坐标.y,0)); //位于地面上的顶点wall.vertices.push(new THREE.Vector3(coordinates.x,坐标.y,10)); //顶点在墙的顶部,在墙的最后}} var previousVertexIndex = wall.vertices.length-2; //在墙底部的顶点索引,在该段中,我们正在创建面forfor(var i = 0; i  


I need to draw a 3d house model (walls only) from a 2d path or array (explained later) I receive from FabricJS editor I've built. The type of data sent from 2d to 3d views doesn't matter.

My first (and only quite close to what I want to get) attempt was to create the array of 1s and zeros based on the room I want to draw, and then render it in ThreeJS as one cuboid per 'grid'. I based this approach on this ThreeJS game demo. So if the array look like this:

var map = [ //1  2  3  4  5  6  7  8
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1,],
          [1, 1, 0, 0, 0, 0, 0, 1, 1, 1,], // 1
          [1, 1, 0, 0, 1, 0, 0, 0, 0, 1,], // 2
          [1, 0, 0, 0, 1, 1, 0, 0, 0, 1,], // 3
          [1, 0, 0, 1, 1, 1, 1, 0, 0, 1,], // 4
          [1, 0, 0, 0, 1, 1, 0, 0, 1, 1,], // 5
          [1, 1, 1, 0, 0, 0, 0, 1, 1, 1,], // 6
          [1, 1, 1, 0, 0, 1, 0, 0, 1, 1,], // 7
          [1, 1, 1, 1, 1, 1, 0, 0, 1, 1,], // 8
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1,],
       ];

I iterate through the array and render one block for every 1, and calculate it's position from indexes from the 2d 'map' (my array).

var UNITSIZE = 250, units = mapW;
for (var i = 0; i < mapW; i++) {
    for (var j = 0, m = map[i].length; j < m; j++) {
        if (map[i][j]) {
            var wall = new t.Mesh(cube, material);
            wall.position.x = (i - units/2) * UNITSIZE;
            wall.position.y = WALLHEIGHT/2;
            wall.position.z = (j - units/2) * UNITSIZE;
            scene.add(wall);
        }
    }
}

It worked great till I wanted to place other models (.obj, but it doesn't matter. Let's call them furniture) near the walls. Each piece of furniture has it's (x=0, y=0, z=0) point in the center of the model, and since walls are cubes (with the same coord system, with 0 point in the center), furniture are rendered in the center of the wall (when we place it in the corner, only 1/4 of the model is visible). This is more/less how it looks like:

(black - how the walls should look like, blue - each cuboid of the wall, red - piece of furniture)

Thats why I would like to render walls as planes, probably from a 2d closed patch (I can export it from Fabric without a problem). I don't need walls to be thick nor to be visible "from behind", when camera moves through the wall. Any clues on how to achieve something like this?

"Help me StackOverflow, your my only hope."

解决方案

You can manually populate the vertex and face arrays of a THREE.js mesh, so if you can export the closed path you need for example as an array of coordinates, you can iterate over it, and push needed information to your wall object.

Something like this

var coordArray = [...]; //Array of corner points of a closed shape from your source. Here assumed to be THREE.Vector2() for simplicity.

var walls = new THREE.Geometry();

for(var i = 0; i < coordArray.length(); i++){ //iterate over the coordinate array, pushing vertices to the geometry
  var coordinates = coordArray[i];
  walls.vertices.push(new THREE.Vector3(coordinates.x, coordinates.y, 0)); //vertex at floor level
  walls.vertices.push(new THREE.Vector3(coordinates.x, coordinates.y, 10)); //vertex at the top part of the wall, directly above the last
}
var previousVertexIndex = walls.vertices.length - 2; // index of the vertex at the bottom of the wall, in the segment we are creating faces for
for(var i = 0; i < walls.vertices.length; i += 2){
  walls.faces.push(new THREE.Face3(i, i + 1, previousVertexIndex));
  walls.faces.push(new THREE.Face3(i + 1, previousVertexIndex + 1, previousVertexIndex));
  previousVertexIndex = i;
}
walls.computeVertexNormals();
walls.computeFaceNormals();

scene.add(new THREE.Mesh(walls, new THREE.MeshLambertMaterial());

这篇关于如何从路径或二维数组中在ThreeJS中绘制墙?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆