2016-06-30 5 views
4

メッシュの頂点にスナップするスナップ機能を作りたかったのです。私はいくつかのソリューションを試しました。3つの頂点に効率よくスナップする

一つの解決策は、私のシーン内のすべての頂点のTHREE.Spriteインスタンスを追加し、その後intersects配列のsnapポイントがあるかどうかを決定するrayCasterを使用することです。それはかなりうまくいく。ここにis a fiddle with a demo
最終的なソリューションのスプライトを非表示にしてレンダリングされないようにすることですが、私のシーンはかなり大きいので、私のシーンにスプライトをたくさん追加することを意味します(あらゆる頂点1、私の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からの結果を用いて演算を行うことによって、代替ソリューションを考えました。その解決策はin this fiddleである。ここで
アイデアは、交差した後、ジオメトリから交差point及びそれらverticesdistanceスナップthreshold次に小さいかどうかチェックされる(メッシュ)objectの幾何学的形状から全てverticesをテストすることです。

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'; 
    } 
} 

悲しいことは、マウスが頂点に向かって交差する物体の表面から移動されたときに、第2の溶液スナップにのみ動作することです。マウスがオブジェクトの外側から移動する場合(交差がないため)、スナップは機能しません。その点で、スプライトを使った最初の解決策ははるかに使いやすくなります...

私の質問は、私はものをオーバーコンプリートしていますが、これを行うにはより簡単で効率的な方法がありますか?代替アプローチの提案は大歓迎です。

+0

私はあなたのクリックでスナップしたいと仮定?もしそうなら、私はあなたを助けることができますが、私は答える前に確かめたいのです。また、スナップしたときにどの角度を見たいですか?それが立方体ならば、それは明らかですが、頂点の平面を持っていれば、どの角度を見たいのか分かりません。 – Rush2112

+0

はい、それは最後になります。しかし、これを追加することは問題ではありません。私は効率的な方法でスナップするために正しい頂点を見つける方法にもっと苦労しています。モデルには1000以上の頂点があり、どの頂点がマウスの閾値距離内にあるかを計算する必要があります。 – Wilt

+0

レイキャスター。交差する[0]は常に交差する最も近いオブジェクトを返すべきである – Rush2112

答えて

0

オクツリーを使用するという彼の提案を見て、this threeoctree repository from githubを使用して以下の解決策を作成しました。 THREE.Octreeクラスは私の問題をすべて解決しませんでしたすぐに利用可能 このように使用できるクラスTHREE.OctreeにカスタムメソッドfindClosestVertexを追加しました。

var snap = octree.findClosestVertex(position, radius); 

snapは場合nullpositionradius内には頂点であり、そうでない場合はワールド空間内の最も近い点(THREE.Vector3)を返します。

私は新しい方法のためにプルリクエストhere on githubを作った。

Here is a demo in a fiddle

関連する問題