2

オブジェクトのジオメトリを動的に変更するまで、私の ray.intersectObjects はシーン内のオブジェクトで非常にうまく機能します。レンダラーはオブジェクトが変更されていることを示していますが (頂点が移動し、面が変更されています)、変更されたオブジェクトで交差を試みると、奇妙な結果が生じます。変更されたジオメトリでも機能するように交差が必要です!

交差がシーンでどのように機能しているかをデバッグおよび追跡するために、関数 makeMiniSphere() を追加しました。これにより、シーン内の交差が発生するポイントに新しい球体オブジェクトが作成されます。これを使用すると、立方体が変更された後、交点が立方体に当たることもあれば、通り抜けることもあります (ほとんどの場合、変更された面)。これはランダムな問題ではありませんが、変更された立方体の周りをクリックすればするほど、パターンが発達することがわかります。シーンのビジュアルのレンダラーはキューブが変更された方向を認識しているように見えますが、ray.intersectObjects はキューブが別の方向に変更されたと認識しています!

テスト Web サイトへのリンクは次のとおりです: http://www.littledrop.net/html/cadiverse/HelloWorld.html

問題を表示する手順:

  1. 立方体を左クリックして交点を表示します。Three.js が交差を検出すると、どこにでもミニ球体が作成されます。まだ選択されていない場合、選択されたオブジェクトの色は黄色に変わります。

  2. 立方体の任意の面をクリックします。A. まだ黄色でない場合は黄色にします。B. 立方体の面が選択されますが、選択された面は立方体の残りの部分と何ら変わりはありません。

  3. 「右」矢印キーを押して、選択した面を右に移動します。これにより、キューブのジオメトリが動的に変更されます。

ここで、特にキューブが変更された領域をクリックしてみてください。ここでも、ミニ球体は、ソフトウェアが交差が発生していると判断した場所を示します。

交差コードは次のとおりです。

function onDocumentMouseDown (event)
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
//event.preventDefault();   
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
document.getElementById('message1').innerHTML = window.innerHeight;
var isinworkingarea = window.innerHeight-menubarh;

if (event.clientY<=isinworkingarea)
{
    var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
    projector.unprojectVector( vector, camera );
    //var ray = new THREE.ReusableRay();
    var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
    // create an array containing all objects in the scene with which the ray intersects
    //  use this to select anything in the scene: 
    var intersects = ray.intersectObjects( scene.children );
    if ( intersects.length > 0 )
    {
        if (cadjectNow)
            cadjects[cadjectNow].material.color.setHex(cadjects[cadjectNow].oldColor);
        if (intersects[0].object.cadNum)                                                
            cadjectNow = intersects[0].object.cadNum;
        SELECTEDface=intersects[0].face;
        if (cadjectNow)
            cadjects[cadjectNow].material.color.setHex( selectColor );
        document.getElementById('message1').innerHTML = cadjects[cadjectNum].cadNum;

        ///// Information about selected /////
        var facestring = intersects[0].face.a  + " " + intersects[0].face.b + " " + intersects[0].face.c;
        if(intersects[0].face instanceof THREE.Face4) 
        {
            facestring=facestring + " " + intersects[0].face.d;
        }

        copyGeometry=cadjects[cadjectNow].geometry;
        //makeCopy(copyGeometry,cadjects[cadjectNow].position.x,cadjects[cadjectNow].position.y,cadjects[cadjectNow].position.z);
        makeMiniSphere(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z);

        document.getElementById('message1').innerHTML = facestring;
        //document.getElementById('message2').innerHTML = cadjects[cadjectNow].geometry.vertices[SELECTEDface.a].x + " " + cadjects[cadjectNow].geometry.vertices[intersects[0].face.a].y + " " + cadjects[cadjectNow].geometry.vertices[intersects[0].face.a].z;
        document.getElementById('message2').innerHTML = intersects[0].point.x + " " + intersects[0].point.y + " " + intersects[0].point.z;

    }
}
}

変更コードは次のとおりです。

if ( keyboard.pressed("right"))
{
    document.getElementById('message1').innerHTML = mouseMode;
    cadjects[cadjectNow].geometry.vertices[SELECTEDface.a].x+=10;
    cadjects[cadjectNow].geometry.vertices[SELECTEDface.b].x+=10;
    cadjects[cadjectNow].geometry.vertices[SELECTEDface.c].x+=10;
    if(SELECTEDface instanceof THREE.Face4) 
    {
        cadjects[cadjectNow].geometry.vertices[SELECTEDface.d].x+=10;
    }
    cadjects[cadjectNow].geometry.verticesNeedUpdate = true;
    cadjects[cadjectNow].geometry.elementsNeedUpdate = true;
    cadjects[cadjectNow].geometry.normalsNeedUpdate = true;
}

過去の質問を投稿して回答をくださった皆様、ありがとうございます。過去の質問を熟読してここまでたどり着けたので、もう大変お世話になりました。これについての助けを前もってありがとう。(これはここに投稿する最初の質問であるため、質問をより適切に提示する方法に関する提案も大歓迎です。)

更新 (2013 年 3 月 21 日) -- 提案どおりに r57 に移行しました。更新されたコードは上記のとおりです。また、少なくとも以前と同じように機能するようにデバッグしました。そのため、ジオメトリは依然として視覚的に動的に変更されていますが、交差は変更を適切に検出していません。これまでの励みになる投稿をありがとう@WestLangley。

4

2 に答える 2

7

正常に動作するようになりました。これが私が行った方法です(Westlangleyのガイダンスに感謝します)。

  1. Three.js を最新リビジョン (r49 から r57) にアップグレードします。
  2. 現在のコードを r57 で動作するように移行します。
  3. オブジェクトを更新しようとしていた以前のコードをすべて削除します。
  4. 「オブジェクトの変更」セクションに次のコードを追加しました。

    cadjects[cadjectNow].geometry.verticesNeedUpdate = true; cadjects[cadjectNow].geometry.normalsNeedUpdate = true; cadjects[cadjectNow].geometry.computeFaceNormals(); cadjects[cadjectNow].geometry.computeVertexNormals(); cadjects[cadjectNow].geometry.computeBoundingSphere();

于 2013-03-26T22:33:44.353 に答える