THREE.js метод raycaster intersectObject не возвращает пересечение при проверке, находится ли точка внутри сетки

#three.js #autodesk-forge #autodesk-viewer

Вопрос:

Я хочу проверить, находится ли точка внутри сетки или нет. Для этого я использую raycaster, устанавливаю его в исходную точку, и если луч пересекает сетку только один раз, он должен быть внутри. К сожалению, объект intersectObject всегда не возвращает пересечение, даже в тех случаях, когда я знаю, что точка находится внутри сетки. Начало координат точки указано в мировых координатах, и матрица сетки также обновлена. Кроме того, я установил сетку.материал.сторона на ТРИ.Двойная сторона, так что пересечение изнутри должно быть обнаружено. Я также попытался установить рекурсивный атрибут в значение true, но, как и ожидалось, это не возымело никакого эффекта (поскольку сетка представляет собой прямоугольную геометрию). Сетка поступает из интерфейса Autodesk Forge viewer. Вот мой код:

 mesh.material.side = THREE.DoubleSide;
const raycaster = new THREE.Raycaster();
let vertex = new THREE.Vector3();
vertex.fromArray(positions, positionIndex);
vertex.applyMatrix4(matrixWorld);
const rayDirection = new THREE.Vector3(1, 1, 1).normalize();
raycaster.set(vertex, rayDirection);
const intersects = raycaster.intersectObject(mesh);
if (intersects.length % 2 === 1) {
   isPointInside = true;
}
 

Вершина выглядит так (и она, очевидно, находится внутри ограничивающего прямоугольника):

координаты вершинного мира

Сетка представляет собой комнату в форме коробки со следующей ограничительной рамкой:

ограничительная коробка комнаты

Сетка выглядит так:

меш

Геометрия сетки содержит вершины в vb. После применения мировой матрицы вершины сетки правильно расположены в мировом пространстве. Вот часть списка vb:

введите описание изображения здесь

Почему райкастер не возвращает никаких пересечений? Учитывается ли матричный мир сетки при вычислении пересечений?

Спасибо за любую помощь!

Комментарии:

1. Попробуйте установить материал side: THREE.DoubleSide и снова проверьте пересечения.

2. @prisoner849 Спасибо за ваш совет. Как написано в тексте, я уже сделал это. Кроме того, материальная сторона сетки поставляется с ТРЕМЯ. Двусторонний набор.

3. другой вариант — попытаться установить второй параметр .intersectObject() в true => const intersects = raycaster.intersectObject(mesh, true);

4. И еще одна вещь, если вы работаете mesh.geometry.attributes.position.array напрямую, то, когда вы звоните vertex.fromArray() , positionIndex нужно умножить на 3. И альтернативой этому может быть vertex.fromBufferAttribute(mesh.geometry.attributes.position, positionIndex);

5. Еще раз спасибо вам за ваши подсказки! Я уже пробовал » raycaster.intersectObject(mesh, true);», но это не имеет эффекта, что имеет смысл, так как сетка имеет только одну геометрию (это комната с коробчатой формой). Что касается вашего второго намека: координаты вершин выглядят нормально и расположены внутри ограничивающей рамки комнаты. Я предоставлю более подробную информацию о вершине, сетке и ее геометрии в вопросе.

Ответ №1:

Обратите внимание, что средство просмотра Forge основано на three.js версия R71, и ей пришлось изменить/переопределить некоторые части библиотеки для обработки больших и сложных моделей (особенно архитектуры и инфраструктурных проектов), поэтому THREE.Mesh объекты могут иметь несколько иную структуру. В этом случае я бы предложил использовать raycast с использованием собственных механизмов Forge Viewer, например, с помощью viewer.impl.rayIntersect(ray, ignoreTransparent, dbIds, modelIds, intersections); .

Комментарии:

1. Спасибо тебе, Петр! Использование этой viewer.impl.rayIntersect функции сделало свое дело за меня.