function layoutMeshUVPacked(faces, verts, O, mapSize) {
        //Step 1: Flatten face, find maxima (bounding box) and translate it to the origin of the coordinate system
        //and cteate the the flattened array to store the values
        var flattened = [];
        faces.forEach(function (face, idx) {
            var flat = (mathFun.flattenFace(face, verts, face.normal.toArray()));
            var maxima = getMaxima(flat);

            var xT = maxima.xMin;
            var yT = maxima.yMin;

            flat.forEach(function (elem) {
                elem[0] -= xT;
                elem[1] -= yT;
            });

            flattened.push({w: maxima.getXD(), h: maxima.getYD(), faceIndex: idx, points: flat});
        });

        //sort the faces by the height to get best possible packing results
        flattened.sort(function (a, b) {
            return b.h - a.h;
        });

        //use the growing packer to optimize the uv layout
        var packer = new GrowingPacker();
        packer.fit(flattened);

        //find out the bounding box of the packed uvs. As the target uv system is a 1x1 square,
        //the values in the flattened array have to be scaled by the max size (with or height)
        var sx = packer.root.w;
        var sy = packer.root.h;
        var maxSize = Math.max(sx, sy);
        var scaleFactor = 1 / maxSize;

        //resulting uv array for assigning to the geometry and additional information (bounding box,origin)
        //for the light baking afterwards
        var uvs = [];
        var uvInfos = [];
        var centeringTranslate = (O / mapSize) / 2;

        //sort by faceIndex because the UV Index needs to match the corresponding face by the index
        flattened.sort(function (a, b) {
            return a.faceIndex - b.faceIndex;
        });

        //scale each face in the uv and translate it to its final position
        //fill the uv and uvInfos arrays
        flattened.forEach(function (elem) {
                elem.w *= scaleFactor;
                elem.h *= scaleFactor;
                elem.fit.x *= scaleFactor;
                elem.fit.y *= scaleFactor;

                var targetScale = new THREE.Vector2(elem.w * mapSize, elem.h * mapSize);
                var tmpFactor = new THREE.Vector2((targetScale.x - O) / targetScale.x, (targetScale.y - O) / targetScale.y);
                var offsetScaleFactor = new THREE.Vector2(scaleFactor * tmpFactor.x, scaleFactor * tmpFactor.y);

                var vecs = [];
                elem.points.forEach(function (pt) {
                    pt[0] = pt[0] * offsetScaleFactor.x + elem.fit.x + centeringTranslate;
                    pt[1] = pt[1] * offsetScaleFactor.y + elem.fit.y + centeringTranslate;
                    vecs.push(new THREE.Vector2(pt[0], pt[1]));
                });

                uvs.push(vecs);
                uvInfos.push({
                    h: elem.h,
                    w: elem.w,
                    origin: new THREE.Vector2(elem.fit.x, elem.fit.y)
                });
            }
        );

        return {uv: uvs, infos: uvInfos};
    }
/**
     * To generate the uv map for a geometry. The uv map is optimized by the bin packing algorythm
     * which can be found here: https://github.com/jakesgordon/bin-packing/
     * packer.growing.js has to be included to work appropriately
     * @param {THREE.Face3[]} faces - faces of the geometry
     * @param {THREE.Vector3[]} vertices - vertices of the geometry
     * @param {number} O - offset to prevent seams
     * @param {number] mapSize - The Size of the lightmap to calculate the offset
     * @returns {{uv: Array, infos: Array}}
     */
To generate the uv map for a geometry.
To generate the uv map for a geometry .
function layoutMeshUVPacked(faces, verts, O, mapSize) {
        var flattened = [];
        faces.forEach(function (face, idx) {
            var flat = (mathFun.flattenFace(face, verts, face.normal.toArray()));
            var maxima = getMaxima(flat);
            var xT = maxima.xMin;
            var yT = maxima.yMin;
            flat.forEach(function (elem) {
                elem[0] -= xT;
                elem[1] -= yT;
            });
            flattened.push({w: maxima.getXD(), h: maxima.getYD(), faceIndex: idx, points: flat});
        });
        flattened.sort(function (a, b) {
            return b.h - a.h;
        });
        var packer = new GrowingPacker();
        packer.fit(flattened);
        var sx = packer.root.w;
        var sy = packer.root.h;
        var maxSize = Math.max(sx, sy);
        var scaleFactor = 1 / maxSize;
        var uvs = [];
        var uvInfos = [];
        var centeringTranslate = (O / mapSize) / 2;
        flattened.sort(function (a, b) {
            return a.faceIndex - b.faceIndex;
        });
        flattened.forEach(function (elem) {
                elem.w *= scaleFactor;
                elem.h *= scaleFactor;
                elem.fit.x *= scaleFactor;
                elem.fit.y *= scaleFactor;
                var targetScale = new THREE.Vector2(elem.w * mapSize, elem.h * mapSize);
                var tmpFactor = new THREE.Vector2((targetScale.x - O) / targetScale.x, (targetScale.y - O) / targetScale.y);
                var offsetScaleFactor = new THREE.Vector2(scaleFactor * tmpFactor.x, scaleFactor * tmpFactor.y);
                var vecs = [];
                elem.points.forEach(function (pt) {
                    pt[0] = pt[0] * offsetScaleFactor.x + elem.fit.x + centeringTranslate;
                    pt[1] = pt[1] * offsetScaleFactor.y + elem.fit.y + centeringTranslate;
                    vecs.push(new THREE.Vector2(pt[0], pt[1]));
                });
                uvs.push(vecs);
                uvInfos.push({
                    h: elem.h,
                    w: elem.w,
                    origin: new THREE.Vector2(elem.fit.x, elem.fit.y)
                });
            }
        );
        return {uv: uvs, infos: uvInfos};
    }
function layoutMeshUVPacked ( faces , verts , O , mapSize ) { var flattened = [ ] ; faces . forEach ( function ( face , idx ) { var flat = ( mathFun . flattenFace ( face , verts , face . normal . toArray ( ) ) ) ; var maxima = getMaxima ( flat ) ; var xT = maxima . xMin ; var yT = maxima . yMin ; flat . forEach ( function ( elem ) { elem [ 0 ] -= xT ; elem [ 1 ] -= yT ; } ) ; flattened . push ( { w : maxima . getXD ( ) , h : maxima . getYD ( ) , faceIndex : idx , points : flat } ) ; } ) ; flattened . sort ( function ( a , b ) { return b . h - a . h ; } ) ; var packer = new GrowingPacker ( ) ; packer . fit ( flattened ) ; var sx = packer . root . w ; var sy = packer . root . h ; var maxSize = Math . max ( sx , sy ) ; var scaleFactor = 1 / maxSize ; var uvs = [ ] ; var uvInfos = [ ] ; var centeringTranslate = ( O / mapSize ) / 2 ; flattened . sort ( function ( a , b ) { return a . faceIndex - b . faceIndex ; } ) ; flattened . forEach ( function ( elem ) { elem . w *= scaleFactor ; elem . h *= scaleFactor ; elem . fit . x *= scaleFactor ; elem . fit . y *= scaleFactor ; var targetScale = new THREE . Vector2 ( elem . w * mapSize , elem . h * mapSize ) ; var tmpFactor = new THREE . Vector2 ( ( targetScale . x - O ) / targetScale . x , ( targetScale . y - O ) / targetScale . y ) ; var offsetScaleFactor = new THREE . Vector2 ( scaleFactor * tmpFactor . x , scaleFactor * tmpFactor . y ) ; var vecs = [ ] ; elem . points . forEach ( function ( pt ) { pt [ 0 ] = pt [ 0 ] * offsetScaleFactor . x + elem . fit . x + centeringTranslate ; pt [ 1 ] = pt [ 1 ] * offsetScaleFactor . y + elem . fit . y + centeringTranslate ; vecs . push ( new THREE . Vector2 ( pt [ 0 ] , pt [ 1 ] ) ) ; } ) ; uvs . push ( vecs ) ; uvInfos . push ( { h : elem . h , w : elem . w , origin : new THREE . Vector2 ( elem . fit . x , elem . fit . y ) } ) ; } ) ; return { uv : uvs , infos : uvInfos } ; }
To generate the uv map for a geometry.
To generate the uv map for a geometry .
//Step 1: Flatten face, find maxima (bounding box) and translate it to the origin of the coordinate system //and cteate the the flattened array to store the values //sort the faces by the height to get best possible packing results //use the growing packer to optimize the uv layout //find out the bounding box of the packed uvs. As the target uv system is a 1x1 square, //the values in the flattened array have to be scaled by the max size (with or height) //resulting uv array for assigning to the geometry and additional information (bounding box,origin) //for the light baking afterwards //sort by faceIndex because the UV Index needs to match the corresponding face by the index //scale each face in the uv and translate it to its final position //fill the uv and uvInfos arrays