#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
функции сделало свое дело за меня.