UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

230 lines (190 loc) 7.15 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = computeBuffers; var THREE = _interopRequireWildcard(require("three")); function computeBuffers(params) { // Create output buffers. var outBuffers = { index: null, position: null, normal: null, // 2 UV set per tile: wgs84 (uv_0) and pm (uv_1) // - wgs84: 1 texture per tile because tiles are using wgs84 projection // - pm: use multiple textures per tile. // +-------------------------+ // | | // | Texture 0 | // +-------------------------+ // | | // | Texture 1 | // +-------------------------+ // | | // | Texture 2 | // +-------------------------+ // * u = wgs84.u // * v = textureid + v in builder texture uvs: [] }; var computeUvs = []; var builder = params.builder; var nSeg = params.segment; // segments count : // Tile : (nSeg + 1) * (nSeg + 1) // Skirt : 8 * (nSeg - 1) var nVertex = (nSeg + 1) * (nSeg + 1) + (params.disableSkirt ? 0 : 4 * nSeg); var triangles = nSeg * nSeg * 2 + (params.disableSkirt ? 0 : 4 * nSeg * 2); outBuffers.position = new Float32Array(nVertex * 3); outBuffers.normal = new Float32Array(nVertex * 3); var uvCount = params.builder.uvCount; if (uvCount > 1) { outBuffers.uvs[1] = new Float32Array(nVertex); } computeUvs[0] = function () {}; if (params.buildIndexAndUv_0) { outBuffers.index = new Uint32Array(triangles * 3); outBuffers.uvs[0] = new Float32Array(nVertex * 2); computeUvs[0] = function (id, u, v) { outBuffers.uvs[0][id * 2 + 0] = u; outBuffers.uvs[0][id * 2 + 1] = v; }; } var widthSegments = Math.max(2, Math.floor(nSeg) || 2); var heightSegments = Math.max(2, Math.floor(nSeg) || 2); var idVertex = 0; var vertices = []; var skirt = []; var skirtEnd = []; builder.prepare(params); for (var y = 0; y <= heightSegments; y++) { var verticesRow = []; var v = y / heightSegments; builder.vProjecte(v, params); if (uvCount > 1) { (function () { var u = builder.computeUvs[1](params); computeUvs[1] = function (id) { outBuffers.uvs[1][id] = u; }; })(); } for (var x = 0; x <= widthSegments; x++) { var u = x / widthSegments; var id_m3 = idVertex * 3; builder.uProjecte(u, params); var vertex = builder.vertexPosition(params, params.projected); var normal = builder.vertexNormal(params); // move geometry to center world vertex.sub(params.center); // align normal to z axis if (params.quatNormalToZ) { vertex.applyQuaternion(params.quatNormalToZ); normal.applyQuaternion(params.quatNormalToZ); } vertex.toArray(outBuffers.position, id_m3); normal.toArray(outBuffers.normal, id_m3); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = computeUvs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var computeUv = _step.value; computeUv(idVertex, u, v); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (!params.disableSkirt) { if (y !== 0 && y !== heightSegments) { if (x === widthSegments) { skirt.push(idVertex); } else if (x === 0) { skirtEnd.push(idVertex); } } } verticesRow.push(idVertex); idVertex++; } vertices.push(verticesRow); if (y === 0) { skirt = skirt.concat(verticesRow); } else if (y === heightSegments) { skirt = skirt.concat(verticesRow.slice().reverse()); } } if (!params.disableSkirt) { skirt = skirt.concat(skirtEnd.reverse()); } function bufferize(va, vb, vc, idVertex) { outBuffers.index[idVertex + 0] = va; outBuffers.index[idVertex + 1] = vb; outBuffers.index[idVertex + 2] = vc; return idVertex + 3; } var idVertex2 = 0; if (params.buildIndexAndUv_0) { for (var _y = 0; _y < heightSegments; _y++) { for (var _x = 0; _x < widthSegments; _x++) { var v1 = vertices[_y][_x + 1]; var v2 = vertices[_y][_x]; var v3 = vertices[_y + 1][_x]; var v4 = vertices[_y + 1][_x + 1]; idVertex2 = bufferize(v4, v2, v1, idVertex2); idVertex2 = bufferize(v4, v3, v2, idVertex2); } } } var iStart = idVertex; // TODO: WARNING beware skirt's size influences performance // The size of the skirt is now a ratio of the size of the tile. // To be perfect it should depend on the real elevation delta but too heavy to compute if (!params.disableSkirt) { // We compute the actual size of tile segment to use later for the skirt. var segmentSize = new THREE.Vector3().fromArray(outBuffers.position).distanceTo(new THREE.Vector3().fromArray(outBuffers.position, 3)); var buildIndexSkirt = function () {}; var buildUVSkirt = function () {}; if (params.buildIndexAndUv_0) { buildIndexSkirt = function (id, v1, v2, v3, v4) { id = bufferize(v1, v2, v3, id); id = bufferize(v1, v3, v4, id); return id; }; buildUVSkirt = function (id) { outBuffers.uvs[0][idVertex * 2 + 0] = outBuffers.uvs[0][id * 2 + 0]; outBuffers.uvs[0][idVertex * 2 + 1] = outBuffers.uvs[0][id * 2 + 1]; }; } for (var i = 0; i < skirt.length; i++) { var id = skirt[i]; var _id_m = idVertex * 3; var id2_m3 = id * 3; outBuffers.position[_id_m + 0] = outBuffers.position[id2_m3 + 0] - outBuffers.normal[id2_m3 + 0] * segmentSize; outBuffers.position[_id_m + 1] = outBuffers.position[id2_m3 + 1] - outBuffers.normal[id2_m3 + 1] * segmentSize; outBuffers.position[_id_m + 2] = outBuffers.position[id2_m3 + 2] - outBuffers.normal[id2_m3 + 2] * segmentSize; outBuffers.normal[_id_m + 0] = outBuffers.normal[id2_m3 + 0]; outBuffers.normal[_id_m + 1] = outBuffers.normal[id2_m3 + 1]; outBuffers.normal[_id_m + 2] = outBuffers.normal[id2_m3 + 2]; buildUVSkirt(id); if (uvCount > 1) { outBuffers.uvs[1][idVertex] = outBuffers.uvs[1][id]; } var idf = (i + 1) % skirt.length; var _v2 = idVertex; var _v3 = idf === 0 ? iStart : idVertex + 1; var _v4 = skirt[idf]; idVertex2 = buildIndexSkirt(idVertex2, id, _v2, _v3, _v4); idVertex++; } } return outBuffers; }