Эффективно привязать к вершинам в три раза
Я хотел сделать функцию привязки, чтобы привязываться к моим вершинам меша. Я экспериментировал с несколькими решениями.
Одним из решений является добавлениеTHREE.Sprite
экземпляры для всех вершин в моей сцене, а затем с помощьюrayCaster
решить, есть лиsnap
точка вintersects
массив. Это работает довольно хорошо; Вотэто скрипка с демо.
Идея состоит в том, чтобы скрыть спрайты в конечном решении, чтобы они не отображались, но мои сцены довольно большие, так что это все равно будет означать добавление большого количества спрайтов в мою сцену (для каждой вершины, возможно, тысячи спрайтов) для обнаружения оснастка точек с моимrayCaster
.
var intersects = rayCaster.intersectObject(scene, true);
var snap = null;
if (intersects.length > 0) {
var index = 0;
var intersect = intersects[index];
while (intersect && intersect.object.name === 'snap') {
snap = sprite.localToWorld(sprite.position.clone());
index++
intersect = intersects[index];
}
if (intersect) {
var face = intersect.face;
var point = intersect.point;
var object = intersect.object;
mouse3D.copy(point);
}
}
if (snap) {
renderer.domElement.style.cursor = 'pointer';
} else {
renderer.domElement.style.cursor = 'no-drop';
}
Я также подумал об альтернативном решении, делая математику, используя результаты изrayCaster
, Это решение продемонстрированов этой скрипке.
Идея здесь состоит в том, чтобы проверить всеvertices
из геометрииobject
(сетка), которая пересекается, а затем проверьте,distance
между пересечениемpoint
и теvertices
от геометрии меньше оснасткиthreshold
.
var intersects = rayCaster.intersectObject(mesh, true);
if (intersects.length > 0) {
var distance, intersect = intersects[0];
var face = intersects[0].face;
var point = intersects[0].point;
var object = intersects[0].object;
var snap = null;
var test = object.worldToLocal(point);
var points = object.geometry.vertices;
for (var i = 0, il = points.length; i < il; i++) {
distance = points[i].distanceTo(test);
if (distance > threshold) {
continue;
}
snap = object.localToWorld(points[i]);
}
if (snap) {
sphereHelper.position.copy(snap);
sphereHelper.visible = true;
renderer.domElement.style.cursor = 'pointer';
} else {
sphereHelper.visible = false;
renderer.domElement.style.cursor = 'no-drop';
}
}
Печально то, что во втором решении оснастка будет работать только тогда, когда мышь перемещается от поверхности пересекаемого объекта к вершине. В случае, если мышь перемещается извне объекта (поэтому пересечения нет), привязка не будет работать. В этом отношении первое решение со спрайтами гораздо удобнее ...
Мой вопрос, я слишком усложняю вещи и есть ли лучший / более простой / более эффективный способ сделать это? Любые предложения по альтернативным подходам приветствуются.