2017-10-27 11 views
1

マージドジオメトリに追加される100k +ボックスがあります。この結合されたジオメトリから時々いくつかのジオメトリを削除する必要があります。これらのボックスの位置を取り出すためにキューブあたり108または72頂点のステップで位置属性をループすることはできますか、またはマージして頂点をマージしますか?THREE JS Merged GeometryからBOXジオメトリを削除する

function blockCubeAlter(grid, blockModel) { 

     function getGridElevation(n, e, grid) { 
      var y_grid = Math.floor((grid.metaData.yMax - n)/grid.metaData.yStep) + 1; 
      var x_grid = Math.floor((e - grid.metaData.xMin)/grid.metaData.xStep); 

      var array_pos = Math.round(y_grid * (grid.metaData.nCol + 1) + x_grid); 
      return isNaN(grid.elevations[array_pos]) ? Infinity : grid.elevations[array_pos]; 
     } 

     var tmpBox = new THREE.BoxBufferGeometry(blockModel.x_step, blockModel.y_step, 2); 

     var myBlock = scene.getObjectByName('blockModel'); 

     var pointsPerVertex = 3, 
      vertexPerFace = 4,// this might be 3 triangles? 
      facePerSide = 1, // this might be 2 triangles per face? 
      sidePerBox = 6; 

     var pointsPerCube = pointsPerVertex * vertexPerFace * facePerSide * sidePerBox; 
     for (var i = 0, j = myBlock.geometry.attributes.position.array.length; i < j; i += pointsPerCube) { 
      var above = false, 
       below = false; 

      for (var k = i; k < i + pointsPerCube; k += pointsPerVertex) { 
       var n = myBlock.geometry.attributes.position.array[k + 1]; 
       var e = myBlock.geometry.attributes.position.array[k + 0]; 
       var z = myBlock.geometry.attributes.position.array[k + 2]; 
       if (z > getGridElevation(n + WEBGLyTranslate, e + WEBGLxTranslate, grid)) 
        above = true; 
       else 
        below = true; 
       if (above && below) break; // intersect surface 
      } 
      if (above) { 
       if (below) { 
        var newBoxGeometry = tmpBox.clone(); 
        newBoxGeometry.attributes.position.array = myBlock.geometry.attributes.position.array.slice(i, i + pointsPerCube); 
        for (var materialGroupIndex = 0, z = myBlock.geometry.groups.length; materialGroupIndex < z; materialGroupIndex++) { 
         var myGeometryGroup = myBlock.geometry.groups[materialGroupIndex]; 
         if (i >= myGeometryGroup.start && i < myGeometryGroup.start + myGeometryGroup.count) { 
          var newMaterial = myBlock.material.materials[myGeometryGroup.materialIndex].clone(); 
          var mesh = new THREE.Mesh(newBoxGeometry, newMaterial) 
          scene.add(mesh); 
          break; 
         } 
        } 
       } 
       for (var k = i; k < i + pointsPerCube; k++) { 
        myBlock.geometry.attributes.position.array[k] = undefined; 
       } 
      } 
     } 

     myBlock.geometry.attributes.position.needsUpdate = true; 

    } 

私はかなりランダムな結果を得ています。マージはどのように位置配列を設定しますか、それは頂点をマージするか、単に追加しますか?

答えて

0

私のコメントに見られるように、tmpBoxとマージされたblockModelのボックスあたりの頂点の間の頂点の数は同じではありませんでした。この頂点の変化は、元のマージがboxGeometryから作成され、マージされ、バッファジオメトリに変換されたためです。これは、マージされたメッシュがどのように変換されたかでした。

finalGeometry = new THREE.BufferGeometry().fromGeometry(tmpGeometry); 

私が使用してtmpBoxを作成することで問題を解決することができた:

var tmpBox = new THREE.BufferGeometry().fromGeometry(new THREE.BoxGeometry(blockModel.x_step, blockModel.y_step, 2)); 

は奇数

new THREE.BufferGeometry().fromGeometry(new THREE.BoxGeometry(blockModel.x_step, blockModel.y_step, 2)) != new THREE.BoxBufferGeometry(blockModel.x_step, blockModel.y_step, 2); 

ようです。しかし、彼らは、頂点の数が異なります。 1つは4頂点の面を使用し、もう1つは3頂点の面を使用していると思います。

+0

この混乱は、索引付けされていないジオメトリと非索引付けされたジオメトリのためです。コードを最適化している間、boxBufferGeometryは位置配列のインデックス頂点を使用しますが、一旦マージされると、インデックス付き頂点のない「三角形スープ」を使用します。実際にすべてのマージを取り除き、位置配列をバッファーメトリーに直接割り当てます。 – LrakWortep

関連する問題