import Geometry from '../Geometry'; /** * @constructor clay.geometry.ParametricSurface * @extends clay.Geometry * @param {Object} [opt] * @param {Object} [generator] * @param {Function} generator.x * @param {Function} generator.y * @param {Function} generator.z * @param {Array} [generator.u=[0, 1, 0.05]] * @param {Array} [generator.v=[0, 1, 0.05]] */ var ParametricSurface = Geometry.extend( /** @lends clay.geometry.ParametricSurface# */ { dynamic: false, /** * @type {Object} */ generator: null }, function() { this.build(); }, /** @lends clay.geometry.ParametricSurface.prototype */ { /** * Build parametric surface geometry */ build: function () { var generator = this.generator; if (!generator || !generator.x || !generator.y || !generator.z) { throw new Error('Invalid generator'); } var xFunc = generator.x; var yFunc = generator.y; var zFunc = generator.z; var uRange = generator.u || [0, 1, 0.05]; var vRange = generator.v || [0, 1, 0.05]; var uNum = Math.floor((uRange[1] - uRange[0] + uRange[2]) / uRange[2]); var vNum = Math.floor((vRange[1] - vRange[0] + vRange[2]) / vRange[2]); if (!isFinite(uNum) || !isFinite(vNum)) { throw new Error('Infinite generator'); } var vertexNum = uNum * vNum; this.attributes.position.init(vertexNum); this.attributes.texcoord0.init(vertexNum); var pos = []; var texcoord = []; var nVertex = 0; for (var j = 0; j < vNum; j++) { for (var i = 0; i < uNum; i++) { var u = i * uRange[2] + uRange[0]; var v = j * vRange[2] + vRange[0]; pos[0] = xFunc(u, v); pos[1] = yFunc(u, v); pos[2] = zFunc(u, v); texcoord[0] = i / (uNum - 1); texcoord[1] = j / (vNum - 1); this.attributes.position.set(nVertex, pos); this.attributes.texcoord0.set(nVertex, texcoord); nVertex++; } } var IndicesCtor = vertexNum > 0xffff ? Uint32Array : Uint16Array; var nIndices = (uNum - 1) * (vNum - 1) * 6; var indices = this.indices = new IndicesCtor(nIndices); var n = 0; for (var j = 0; j < vNum - 1; j++) { for (var i = 0; i < uNum - 1; i++) { var i2 = j * uNum + i; var i1 = (j * uNum + i + 1); var i4 = (j + 1) * uNum + i + 1; var i3 = (j + 1) * uNum + i; indices[n++] = i1; indices[n++] = i2; indices[n++] = i4; indices[n++] = i2; indices[n++] = i3; indices[n++] = i4; } } this.generateVertexNormals(); this.updateBoundingBox(); } }); export default ParametricSurface;