2013-03-19 69 views
1

我的ray.intersectObjects與我的場景中的對象非常協調,直到我動態修改對象的幾何。雖然渲染器正在顯示對象被修改(頂點移動並改變了面孔),但當修改對象上的交叉點時,它會產生奇怪的結果。即使在修改後的幾何圖形上,我也需要交叉點才能工作!ray.interstectObjects在幾何被動態修改後不正確相交

爲了幫助調試和跟蹤交點在我的場景中的工作方式,我添加了一個函數:makeMiniSphere()。這會在交叉點發生的位置在場景中創建一個新的球體對象。使用這個,你可以看到在修改了多維數據集之後,有時候這個相交點會碰到這個多維數據集,並且有時會直接通過(主要是修改過的面)。這不是一個隨機問題,但您在修改後的多維數據集中點擊的次數越多,您可以看到模式開發越多。就好像場景的視覺渲染器知道立方體被修改了哪個方向,但是ray.intersectObjects認爲它已經在不同的方向上被修改了!

下面是測試網站的鏈接:http://www.littledrop.net/html/cadiverse/HelloWorld.html

路線顯示問題:

  1. 多維數據集左鍵單擊顯示相交點。在Three.js看到交叉點的任何地方都會創建迷你球體。如果尚未選擇,所選對象的顏色將變爲黃色。

  2. 單擊立方體的任何一個面。這將答:如果它不是黃色,請將其變爲黃色。 B.它將選擇立方體的面部,儘管選定的面部與立方體的其餘部分沒有任何區別。

  3. 按下「右」箭頭鍵將選定的面向右移動。這將動態地改變立方體的幾何形狀。

現在嘗試點擊多維數據集 - 特別是在它已被修改的區域。 Mini球體再次顯示軟件認爲相交正在發生的位置。

下面是相交代碼:

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

感謝大家誰張貼過去的問題,並給出答案。通過閱讀過去的問題,我已經能夠得到這麼多 - 所以你們已經得到了很大的幫助。在此先感謝您的幫助。 (因爲這是我在這裏發佈的第一個問題,所以關於如何更好地提出問題的任何建議也都非常受歡迎。)

更新(3/21/13) - 我已按照建議遷移到r57,更新後的代碼如上所示。我也調試過它,至少和以前一樣。所以現在幾何圖形仍然在視覺上被動態地改變,但是相交點沒有正確檢測到改變。感謝@WestLangley迄今爲止的令人鼓舞的帖子。

+0

您正在使用一個已有一年的圖書館版本。請更新至當前版本r.57,如果仍有問題,請重新發帖。 – WestLangley 2013-03-21 05:48:59

+0

好點,@WestLangley。我今天下午試試! – 2013-03-21 07:44:36

+0

我已更新到r57,現在正在遷移。會讓你知道結果如何。 – 2013-03-21 21:57:38

回答

6

現在工作正常。這是我如何做到的(感謝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();

+0

奇怪但真實 - computeBoundingSphere()確實是必需的。人們會認爲AABB /飛機通常足夠用於這個,但顯然不在three.js中。 – 2014-11-19 19:41:42

+1

我只花了3個小時試圖解決這個問題。我所缺少的是computeBoundingSphere,謝謝你的回答 – 2014-12-27 15:54:13

+0

ComputeBoundingSphere !? aaah id曾經以爲computeBoundingBox會有足夠的相似/工作。謝謝! – 2017-05-25 14:35:16