Интерактивная Сетка в ThreeJs

1

Мне нужно нарисовать прямоугольную (не квадратичную) сетку поддержки: пользователи могут навешивать плитку этой сетки и размещать там определенный объект. Например, я навешиваю (x: 0 y: 15), и я нажимаю, я получаю объект в (x: 0 y: 15).

Изображение 174551

Эта сетка была выполнена с помощью PlaneGeometry и нарисована как каркас (в r58).

new THREE.PlaneGeometry(x,y,16, 9);
var mat = new THREE.MeshBasicMaterial({
    color: 0x004488,
    wireframe: true
});
mat.color.r = r;
mat.color.g = g;
mat.color.b = b;

После того, как я обновил базу кода до r94, я теперь получаю треугольники вместо квадов для разных фрагментов плоскости.

Я попробовал следующее:

Линии рисования: посмотрев исходный код GridHelper, я создал прямоугольную версию. Это выглядит очень красиво, но обнаружение хита на плитке отключено. Обнаружение обнаружения происходит с помощью Raycaster. Я думаю, проблема в том, что строки thaht обнаруживаются только в том случае, если мышь фактически находится над линией. С помощью 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, но теперь он выглядит очень уродливым, если угол обзора плоский:

Изображение 174551

У меня заканчиваются идеи, поэтому я был бы признателен за подсказку или что-то, что я могу нарисовать красиво выглядящую сетку, которая представляет собой одну геометрию, чтобы можно было использовать текущую систему обнаружения ударов.

TL; DR; Мне нужна сетка, которая ведет себя как PlaneGeometry (обнаружение попадания), но только квадраты рисования вместо треугольников.

Теги:
three.js

1 ответ

2
Лучший ответ

У вас может быть сетка, построенная из линий. Для этого вы можете создать THREE.PlaneBufferGeometry() и изменить его .index. Затем используйте эту геометрию с помощью THREE.LineSegments().

Изображение 174551

Ссылка

И исходный код для изменения индексов:

  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"}));
  • 0
    Что именно делает это «переписывание» индексов? Удаление треугольников или ...? Кстати, очень крутая картинка
  • 1
    @ morpheus05 позволяет использовать так называемую технику «индексированных линий» . Таким образом, нет лиц, только линии. Имея это, подход с raycaster должен быть изменен для работы с линиями. Или вы можете иметь обычную плоскость (для raycaster) и сетку поверх нее. В справочной ссылке посмотрите на jsfiddle и его исходный код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню