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 | 1× 1× 1× 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; |