# 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

    1×

     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;