2017-02-16 150 views
0

我正在嘗試製作一系列可以單擊以突出顯示它們的多維數據集。這將使我能夠改變顏色或添加紋理或以某種方式操縱它們。我已經瀏覽了所有在https://threejs.org/examples/的交互式示例的源代碼,看起來每個示例都使用了在場景中創建和選擇對象的稍微不同的方式。我不習慣使用JavaScript,所以也許我錯過了一些簡單的東西。three.js使用raycaster.intersectObject選擇Object3D的子代

我創建Object3D類命名塊來存儲所有的立方體的

blocks = new THREE.Object3D() 

我使用與用於循環來創建一個9×9陣列的立方體的起始於(0,0,0)座標它們之間有一個微小的差距,並將它們添加到塊中並將()塊添加到場景中。示例:(立方體大小2,2,2)

function stack(mx,my,mz){ 
     for (var i = 0; i < 9; i++){ 
      line(mx,my,mz); 
      mz += 3; 
     } 
    } 

    function line(mx,my,mz){ 
     for (var i = 0;i<9;i++){ 
      var block = new THREE.Mesh(Geometry, Material); 
      block.position.x = mx; 
      block.position.y = my; 
      block.position.z = mz; 

      blocks.add(block); 
      mx+=3; 
     } 
    } 
    stack(mx,my,mz) 
    scene.add(blocks) 

當我運行此代碼時,我可以看到它們呈現。我使用raycaster來.intersectObjects(),它需要一個對象數組。這是我遇到只選擇一個對象的問題。

function onDocumentMouseDown(event) { 

    var vector = new THREE.Vector3((event.clientX/window.innerWidth) * 2 - 1, -(event.clientY/window.innerHeight) * 2 + 1, 0.5); 
    projector.unprojectVector(vector, camera); 
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize()); 
    **var intersects = raycaster.intersectObjects(blocks.children, true);** 

    if (intersects.length > 0) { 
     intersects[0].object.material.transparent = true; 
     other code stuff blah blah blah 
    { 

這將使所有孩子都可點擊,但它們與創建的第一個對象具有相同的.id。所以如果我嘗試使用.getObjectById()以改變某些內容,那麼它不起作用。

我試圖生成每個元素並迭代地將它們添加到場景中,而不是創建一個對象數組來保存它們,它仍然有類似的效果。我試圖將它們存儲在一個常規數組中,然後使用true參數來遞歸搜索.intersectObject()數組,但是當它點擊它時,它會選擇所有對象。

var intersects = raycaster.intersectObjects(blocks, true); 

我已經考慮創建81個獨特的變量來保存每個元素和靜態輸入81個的數組變量(絕望的選項),但我不能找到一個安全的方式來動態地創建變量名for循環舉辦對象。這種方式發佈在stackoverflow上,作爲創建不同命名變量的解決方案,但它似乎根本沒有創建變量。

for (var i=0, i<9, i++){ 
    var window["cube" + i] = new THREE.Mesh(Geometry, Material) 
    { 

主要問題:我如何可以反覆創建多個網格的(以至於靜態輸入每個變量會被不明智的),因爲我可以選擇它們,單獨,而不是操縱它們作爲一組可控的方式?

回答

1

我想,爲什麼你遇到了這個問題的原因是您引用相同Material建立你Mesh,你是相交單個對象在blocks.children,但是當你改變材料的其他的一些性質網誰使用的材料將隨之改變。

function line(mx,my,mz){ 
    for (var i = 0;i<9;i++){ 
     material = new THREE.MeshLambertMaterial({color: 0xffffff}); 
     var block = new THREE.Mesh(Geometry, material); 
     block.position.x = mx; 
     block.position.y = my; 
     block.position.z = mz; 

     blocks.add(block); 
     mx+=3; 
    } 
} 

它適合我。

+0

謝謝!第一次通過。 –