Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 3JS中的可交互网格_Javascript_Three.js - Fatal编程技术网

Javascript 3JS中的可交互网格

Javascript 3JS中的可交互网格,javascript,three.js,Javascript,Three.js,我需要画一个矩形(不是二次的)“支撑”网格:用户可以悬停在这个网格的一块瓷砖上,然后在那里放置一个特定的对象。例如,我将鼠标悬停在(x:0y:15)上,然后单击,我在(x:0y:15)处得到一个对象 该网格使用平面几何体绘制,并绘制为线框(在r58中) 在我将代码库更新为r94之后,我现在得到的是三角形,而不是平面不同分片的四边形 我尝试了以下方法: 绘制线条:查看GridHelper的源代码后,我创建了一个矩形版本。它看起来很不错,但瓷砖的命中检测已关闭。命中检测是通过光线投射器实现的。我认

我需要画一个矩形(不是二次的)“支撑”网格:用户可以悬停在这个网格的一块瓷砖上,然后在那里放置一个特定的对象。例如,我将鼠标悬停在(x:0y:15)上,然后单击,我在(x:0y:15)处得到一个对象

该网格使用平面几何体绘制,并绘制为线框(在r58中)

在我将代码库更新为r94之后,我现在得到的是三角形,而不是平面不同分片的四边形

我尝试了以下方法:

绘制线条:查看GridHelper的源代码后,我创建了一个矩形版本。它看起来很不错,但瓷砖的命中检测已关闭。命中检测是通过光线投射器实现的。我认为问题是,只有当鼠标确实在一条线上时,才会检测到这些线。使用PlaneGeometry,鼠标可以位于瓷砖内部,并且可以正确检测几何体

使用纹理绘制PlaneGeometry我尝试的下一个想法是使用带有自定义纹理的PlaneGeometry,如下所示:

let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.height = 32;
canvas.width = 32;
context.beginPath();
context.rect(0, 0, 32, 32);
context.lineWidth = 2;
context.strokeStyle = color.getStyle();
context.stroke();

// canvas contents will be used for a texture
let texture = new THREE.Texture(canvas);

texture.needsUpdate = true;

let material = new THREE.MeshBasicMaterial();
// let material = new THREE.LineBasicMaterial();
material.map = texture;
material.flatShading = true;
material.fog = false;
material.lights = false;
material.side = THREE.DoubleSide;
material.transparent = true;

return material;
现在命中检测就像一个魔咒,就像r54一样,但现在如果视角是平的,它看起来非常难看:

我的想法已经没有了,所以我希望你能给我一个提示或是一些东西,告诉我如何画出好看的网格,这是一个几何体,可以使用当前的命中检测系统


TL;博士我需要一个网格,它的行为类似于平面几何体(命中检测),但只绘制正方形而不是三角形

您可以使用线构建网格。为此,您可以创建
THREE.PlaneBufferGeometry()
并更改其
.index
属性。然后将此几何图形与
THREE.LineSegments()
一起使用

以及更改索引的源代码:

  Object.assign(THREE.PlaneBufferGeometry.prototype, {
    toGrid: function() {
      let segmentsX = this.parameters.widthSegments || 1;
      let segmentsY = this.parameters.heightSegments || 1;
      let indices = [];
      for (let i = 0; i < segmentsY + 1; i++) {
        let index11 = 0;
        let index12 = 0;
        for (let j = 0; j < segmentsX; j++) {
          index11 = (segmentsX + 1) * i + j;
          index12 = index11 + 1;
          let index21 = index11;
          let index22 = index11 + (segmentsX + 1);
          indices.push(index11, index12);
          if (index22 < ((segmentsX + 1) * (segmentsY + 1) - 1)) {
            indices.push(index21, index22);
          }
        }
        if ((index12 + segmentsX + 1) <= ((segmentsX + 1) * (segmentsY + 1) - 1)) {
          indices.push(index12, index12 + segmentsX + 1);
        }
      }
      this.setIndex(indices);
      return this;
    }
  });

这种指数的“重写”到底是做什么的?删除三角形还是。。。?顺便说一句,很酷picture@morpheus05它允许您使用所谓的技术。因此,没有面,只有线。有了这一点,使用raycaster的方法应该改变为使用线条。或者,你可以有一个普通的平面(对于raycaster)和一个网格。在参考链接中,请查看JSFIDLE及其源代码。
  Object.assign(THREE.PlaneBufferGeometry.prototype, {
    toGrid: function() {
      let segmentsX = this.parameters.widthSegments || 1;
      let segmentsY = this.parameters.heightSegments || 1;
      let indices = [];
      for (let i = 0; i < segmentsY + 1; i++) {
        let index11 = 0;
        let index12 = 0;
        for (let j = 0; j < segmentsX; j++) {
          index11 = (segmentsX + 1) * i + j;
          index12 = index11 + 1;
          let index21 = index11;
          let index22 = index11 + (segmentsX + 1);
          indices.push(index11, index12);
          if (index22 < ((segmentsX + 1) * (segmentsY + 1) - 1)) {
            indices.push(index21, index22);
          }
        }
        if ((index12 + segmentsX + 1) <= ((segmentsX + 1) * (segmentsY + 1) - 1)) {
          indices.push(index12, index12 + segmentsX + 1);
        }
      }
      this.setIndex(indices);
      return this;
    }
  });
var planeGeom = new THREE.PlaneBufferGeometry(10, 5, 10, 5).toGrid();
var gridPlane = new THREE.LineSegments(planeGeom, new THREE.LineBasicMaterial({color: "yellow"}));