javascript - 如何在 ThreeJS 中从路径或二维数组绘制墙壁?

标签 javascript 3d three.js fabricjs

我需要从我构建的 FabricJS 编辑器收到的 2d 路径或数组(稍后解释)中绘制 3d 房屋模型(仅墙壁)。从 2d View 发送到 3d View 的数据类型并不重要。

我的第一次(也是非常接近我想要得到的)尝试是根据我想要绘制的房间创建 1 和 0 的数组,然后在 ThreeJS 中将其渲染为每个“网格”一个长方体。我将此方法基于 this ThreeJS game demo 。因此,如果数组如下所示:

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,],
       ];

我迭代数组并为每个 1 渲染一个 block ,并根据 2d“ map ”(我的数组)的索引计算它的位置。

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);
        }
    }
}

它工作得很好,直到我想在墙壁附近放置其他模型(.obj,但这并不重要。我们称它们为家具)。每件家具在模型的中心都有它的 (x=0, y=0, z=0) 点,并且由于墙是立方体(具有相同的坐标系,0 点在中心),家具渲染在墙的中心(当我们将其放置在 Angular 落时,只有模型的 1/4 可见)。这或多或少是这样的:

kitchen in 3d (黑色 - 墙壁应该是什么样子,蓝色 - 墙壁的每个长方体,红色 - 一件家具)

这就是为什么我想将墙壁渲染为平面,可能来自 2d 闭合补丁(我可以毫无问题地从 Fabric 导出它)。当相机穿过墙壁时,我不需要墙壁很厚,也不需要“从后面”可见。关于如何实现这样的目标有任何线索吗?

“帮助我 StackOverflow,你是我唯一的希望。”

最佳答案

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

类似这样的事情

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());

关于javascript - 如何在 ThreeJS 中从路径或二维数组绘制墙壁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35436056/

相关文章:

javascript - Eclipse:设置 HTML/Javascript 文件的运行配置

javascript - React 循环遍历数组并渲染多个子组件的实例

python - 如何在 matplotlib 中为 3D 散点图上的数据点着色

javascript - Three.js - 如何检查对象是否对相机可见

javascript - three.js 在鼠标向下旋转对象并移动

JavaScript 变量回退

javascript - 使用循环将事件设置为 DOM 对象

python - 将数组从 C 代码返回到 python

python - Python 中的 3D 网格图

javascript - 是否可以随着时间的推移更改 widthSegments 参数(来自 SphereGeometry)?