2014-12-11 3 views
1

Я пишу сценарий, который разбивает слишком длинные края граней (сделать 2 лица вместо 1 большой)Three.js - Сплит лица с длинными кромками на два лица

экспорта Результат по .obj файлу

Геометрия уменьшена нормально, но после рендеринга результата уменьшенные лица имеют неправильное отражение света, а событие WebGl не показывает некоторые грани. https://yadi.sk/i/yU33fJ51dJaVP

Для новых (детей) лиц я сохраняю нормальные и все свойства от родительского большого лица.

Вот код:

var loader = new global.THREE.OBJMTLLoader(); 
var geometry = loader.load("source.obj").children[0].geometry; 

var uvs = []; 
var limiter = function() { 
      var baseLength = 80; 
      var createdVertex = {}; 
      var faces=[]; 
      var faceVertexUvs = []; 
      var l = geometry.faces.length; 
      geometry.faces.forEach(function(cFace, i){ 

       var fromToProgress = function (from, to, third, splitedEdge) { 
        var vFrom = geometry.vertices[from], 
         vTo = geometry.vertices[to], 
         vThird = geometry.vertices[third], 
         newVertexIndex; 

        if (vFrom.distanceTo(vTo) > baseLength) { 
         var exists = createdVertex[from + "_" + to] || createdVertex[to + "_" + from]; 
         if (exists) { 
          newVertexIndex = exists; 
         } else { 
          var newVertex = getTheCenter(vFrom, vTo); 
          geometry.vertices.push(newVertex); 
          newVertexIndex = geometry.vertices.length - 1; 
          createdVertex[from + "_" + to] = newVertexIndex; 
         } 

         makeFace(from, newVertexIndex, third, splitedEdge, 0); 
         makeFace(newVertexIndex, to, third, splitedEdge, 1); 
         return true; 
        } 
        return false; 
       }; 
       var makeFace = function (a, b, c, splitedEdge, side) { 

        var templ = cFace.clone(); 
        templ.a = a; 
        templ.b = b; 
        templ.c = c; 

        templ.vertexNormals = [ templ.normal, templ.normal, templ.normal]; 

        faces.push(templ); 
        splitUvs(templ, splitedEdge, side); 
       }; 
       var copyUvs = function() { 
        faceVertexUvs[faces.length - 1] = geometry.faceVertexUvs[0][i]; 
       }; 

       var splitUvs = function (face, splitedEdge, side) { 
        var a,b,c,d; 
        var bigTri = geometry.faceVertexUvs[0][i]; 
        if (splitedEdge === 'ab') { 
         if (side === 0) { 
          a = bigTri[0]; 
          b = getTheCenter(bigTri[0], bigTri[1]); 
          c = bigTri[2]; 
         } else { 
          a = getTheCenter(bigTri[0], bigTri[1]); 
          b = bigTri[1]; 
          c = bigTri[2]; 
         } 
        } 
        if (splitedEdge === 'ac') { 
         if (side === 0) { 
          a = bigTri[0]; 
          b = bigTri[1]; 
          c = getTheCenter(bigTri[0], bigTri[2]); 
         } else { 
          a = getTheCenter(bigTri[0], bigTri[2]); 
          b = bigTri[1]; 
          c = bigTri[2]; 
         } 
        } 
        if (splitedEdge === 'bc') { 
         if (side === 0) { 
          a = bigTri[0]; 
          b = bigTri[1]; 
          c = getTheCenter(bigTri[1], bigTri[2]); 
         } else { 
          a = bigTri[0]; 
          b = getTheCenter(bigTri[1], bigTri[2]); 
          c = bigTri[2]; 
         } 
        } 

        faceVertexUvs[faces.length - 1] = [a,b,c]; 
       }; 
       // Center of section 
       var getTheCenter = function (vFrom, vTo) { 
        return vFrom.clone().add(vTo).multiplyScalar(0.5); 
       } 

       if (fromToProgress(cFace.a, cFace.b, cFace.c, 'ab')) return; 
       if (fromToProgress(cFace.a, cFace.c, cFace.b, 'ac')) return; 
       if (fromToProgress(cFace.b, cFace.c, cFace.a, 'bc')) return; 
       faces.push(cFace); 
       copyUvs(); 

      }); 
      geometry.faces = faces; 
      geometry.faceVertexUvs[0] = faceVertexUvs; 
     }; 

limiter(); 

geometry.computeFaceNormals(); 
geometry.computeVertexNormals(); 
geometry.computeMorphNormals(); 

var exp = new THREE.OBJExporter(); 
console.log(exp.parse(geometry)); 

P.S mayby ​​кто-то знает, существующее решение для цели?

+1

ли [TessellateModifier] (http://threejs.org/examples/js/modifiers/TessellateModifier.js) то, что вы ищете? – WestLangley

+0

То есть! Я заново изобрел колесо, спасибо! –

ответ

2

Если вы хотите разделить грани с краями, превышающими заданное значение, на две грани, вы можете использовать THREE.TessellateModifier, которые вы найдете в папке examples/modifiers.

Вы можете позвонить ему повторно, если хотите. Как так:

var tessellateModifier = new THREE.TessellateModifier(LENGTH); 

for (var i = 0; i < N; i ++) { 

    tessellateModifier.modify(geometry); 

} 

Three.js R.69

Смежные вопросы