three.js - 将长边分成两个面

时间:2014-12-11 12:09:22

标签: javascript three.js geometry normals

我正在编写脚本,分割太长的面部边缘(使2个面部而不是1个面)

结果导出到.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 个答案:

答案 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

相关问题