all files / src/geometry/ ParametricSurface.js

2% Statements 1/50
0% Branches 0/16
0% Functions 0/2
2% Lines 1/50
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                                                                                                                                                                                                         
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;