all files / src/geometry/ Cone.js

100% Statements 63/63
100% Branches 0/0
100% Functions 2/2
100% Lines 63/63
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142                                                                                    10×               10× 10× 10× 10× 10× 10×   10×   10× 10×   10× 10× 10×   10× 10× 10× 350× 350× 350× 350×   350× 350× 350×       10×   10× 10× 10× 350×   350× 350×       10× 10× 10× 10× 350×   350× 350×       10× 10× 10× 350× 770× 770× 770×     10× 350× 420× 420× 420× 420× 420× 420×       10× 10×   10×   10×   10× 10× 10× 10×          
import Geometry from '../Geometry';
import BoundingBox from '../math/BoundingBox';
import glMatrix from '../dep/glmatrix';
var vec3 = glMatrix.vec3;
var vec2 = glMatrix.vec2;
 
/**
 * @constructor clay.geometry.Cone
 * @extends clay.Geometry
 * @param {Object} [opt]
 * @param {number} [opt.topRadius]
 * @param {number} [opt.bottomRadius]
 * @param {number} [opt.height]
 * @param {number} [opt.capSegments]
 * @param {number} [opt.heightSegments]
 */
var Cone = Geometry.extend(
/** @lends clay.geometry.Cone# */
{
    dynamic: false,
    /**
     * @type {number}
     */
    topRadius: 0,
 
    /**
     * @type {number}
     */
    bottomRadius: 1,
 
    /**
     * @type {number}
     */
    height: 2,
 
    /**
     * @type {number}
     */
    capSegments: 20,
 
    /**
     * @type {number}
     */
    heightSegments: 1
}, function() {
    this.build();
},
/** @lends clay.geometry.Cone.prototype */
{
    /**
     * Build cone geometry
     */
    build: function() {
        var positions = [];
        var texcoords = [];
        var faces = [];
        positions.length = 0;
        texcoords.length = 0;
        faces.length = 0;
        // Top cap
        var capSegRadial = Math.PI * 2 / this.capSegments;
 
        var topCap = [];
        var bottomCap = [];
 
        var r1 = this.topRadius;
        var r2 = this.bottomRadius;
        var y = this.height / 2;
 
        var c1 = vec3.fromValues(0, y, 0);
        var c2 = vec3.fromValues(0, -y, 0);
        for (var i = 0; i < this.capSegments; i++) {
            var theta = i * capSegRadial;
            var x = r1 * Math.sin(theta);
            var z = r1 * Math.cos(theta);
            topCap.push(vec3.fromValues(x, y, z));
 
            x = r2 * Math.sin(theta);
            z = r2 * Math.cos(theta);
            bottomCap.push(vec3.fromValues(x, -y, z));
        }
 
        // Build top cap
        positions.push(c1);
        // FIXME
        texcoords.push(vec2.fromValues(0, 1));
        var n = this.capSegments;
        for (var i = 0; i < n; i++) {
            positions.push(topCap[i]);
            // FIXME
            texcoords.push(vec2.fromValues(i / n, 0));
            faces.push([0, i+1, (i+1) % n + 1]);
        }
 
        // Build bottom cap
        var offset = positions.length;
        positions.push(c2);
        texcoords.push(vec2.fromValues(0, 1));
        for (var i = 0; i < n; i++) {
            positions.push(bottomCap[i]);
            // FIXME
            texcoords.push(vec2.fromValues(i / n, 0));
            faces.push([offset, offset+((i+1) % n + 1), offset+i+1]);
        }
 
        // Build side
        offset = positions.length;
        var n2 = this.heightSegments;
        for (var i = 0; i < n; i++) {
            for (var j = 0; j < n2+1; j++) {
                var v = j / n2;
                positions.push(vec3.lerp(vec3.create(), topCap[i], bottomCap[i], v));
                texcoords.push(vec2.fromValues(i / n, v));
            }
        }
        for (var i = 0; i < n; i++) {
            for (var j = 0; j < n2; j++) {
                var i1 = i * (n2 + 1) + j;
                var i2 = ((i + 1) % n) * (n2 + 1) + j;
                var i3 = ((i + 1) % n) * (n2 + 1) + j + 1;
                var i4 = i * (n2 + 1) + j + 1;
                faces.push([offset+i2, offset+i1, offset+i4]);
                faces.push([offset+i4, offset+i3, offset+i2]);
            }
        }
 
        this.attributes.position.fromArray(positions);
        this.attributes.texcoord0.fromArray(texcoords);
 
        this.initIndicesFromArray(faces);
 
        this.generateVertexNormals();
 
        this.boundingBox = new BoundingBox();
        var r = Math.max(this.topRadius, this.bottomRadius);
        this.boundingBox.min.set(-r, -this.height/2, -r);
        this.boundingBox.max.set(r, this.height/2, r);
    }
});
 
export default Cone;