Эффективно привязать к вершинам в три раза

Я хотел сделать функцию привязки, чтобы привязываться к моим вершинам меша. Я экспериментировал с несколькими решениями.

Одним из решений является добавление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';
    }
}

Печально то, что во втором решении оснастка будет работать только тогда, когда мышь перемещается от поверхности пересекаемого объекта к вершине. В случае, если мышь перемещается извне объекта (поэтому пересечения нет), привязка не будет работать. В этом отношении первое решение со спрайтами гораздо удобнее ...

Мой вопрос, я слишком усложняю вещи и есть ли лучший / более простой / более эффективный способ сделать это? Любые предложения по альтернативным подходам приветствуются.

Ответы на вопрос(1)

Ваш ответ на вопрос