|
@@ -0,0 +1,126 @@
|
|
|
+/**
|
|
|
+ * @author Mugen87 / https://github.com/Mugen87
|
|
|
+ */
|
|
|
+
|
|
|
+THREE.TorusBufferGeometry = function ( radius, tube, radialSegments, tubularSegments, arc ) {
|
|
|
+
|
|
|
+ THREE.BufferGeometry.call( this );
|
|
|
+
|
|
|
+ this.type = 'TorusBufferGeometry';
|
|
|
+
|
|
|
+ this.parameters = {
|
|
|
+ radius: radius,
|
|
|
+ tube: tube,
|
|
|
+ radialSegments: radialSegments,
|
|
|
+ tubularSegments: tubularSegments,
|
|
|
+ arc: arc
|
|
|
+ };
|
|
|
+
|
|
|
+ radius = radius || 100;
|
|
|
+ tube = tube || 40;
|
|
|
+ radialSegments = Math.floor( radialSegments ) || 8;
|
|
|
+ tubularSegments = Math.floor( tubularSegments ) || 6;
|
|
|
+ arc = arc || Math.PI * 2;
|
|
|
+
|
|
|
+ // used to calculate buffer length
|
|
|
+ var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );
|
|
|
+ var indexCount = radialSegments * tubularSegments * 2 * 3;
|
|
|
+
|
|
|
+ // buffers
|
|
|
+ var indices = new ( vertexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );
|
|
|
+ var vertices = new Float32Array( vertexCount * 3 );
|
|
|
+ var normals = new Float32Array( vertexCount * 3 );
|
|
|
+ var uvs = new Float32Array( vertexCount * 2 );
|
|
|
+
|
|
|
+ // offset variables
|
|
|
+ var vertexBufferOffset = 0;
|
|
|
+ var uvBufferOffset = 0;
|
|
|
+ var indexBufferOffset = 0;
|
|
|
+
|
|
|
+ // helper variables
|
|
|
+ var center = new THREE.Vector3();
|
|
|
+ var vertex = new THREE.Vector3();
|
|
|
+ var normal = new THREE.Vector3();
|
|
|
+
|
|
|
+ var j, i;
|
|
|
+
|
|
|
+ // generate vertices, normals and uvs
|
|
|
+
|
|
|
+ for ( j = 0; j <= radialSegments; j ++ ) {
|
|
|
+
|
|
|
+ for ( i = 0; i <= tubularSegments; i ++ ) {
|
|
|
+
|
|
|
+ var u = i / tubularSegments * arc;
|
|
|
+ var v = j / radialSegments * Math.PI * 2;
|
|
|
+
|
|
|
+ // vertex
|
|
|
+ vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
|
|
|
+ vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
|
|
|
+ vertex.z = tube * Math.sin( v );
|
|
|
+
|
|
|
+ vertices[ vertexBufferOffset ] = vertex.x;
|
|
|
+ vertices[ vertexBufferOffset + 1 ] = vertex.y;
|
|
|
+ vertices[ vertexBufferOffset + 2 ] = vertex.z;
|
|
|
+
|
|
|
+ // this vector is used to calculate the normal
|
|
|
+ center.x = radius * Math.cos( u );
|
|
|
+ center.y = radius * Math.sin( u );
|
|
|
+
|
|
|
+ // normal
|
|
|
+ normal.subVectors( vertex, center ).normalize();
|
|
|
+
|
|
|
+ normals[ vertexBufferOffset ] = normal.x;
|
|
|
+ normals[ vertexBufferOffset + 1 ] = normal.y;
|
|
|
+ normals[ vertexBufferOffset + 2 ] = normal.z;
|
|
|
+
|
|
|
+ // uv
|
|
|
+ uvs[ uvBufferOffset ] = i / tubularSegments;
|
|
|
+ uvs[ uvBufferOffset + 1 ] = j / radialSegments;
|
|
|
+
|
|
|
+ // update offsets
|
|
|
+ vertexBufferOffset += 3;
|
|
|
+ uvBufferOffset += 2;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // generate indices
|
|
|
+
|
|
|
+ for ( j = 1; j <= radialSegments; j ++ ) {
|
|
|
+
|
|
|
+ for ( i = 1; i <= tubularSegments; i ++ ) {
|
|
|
+
|
|
|
+ // indices
|
|
|
+ var a = ( tubularSegments + 1 ) * j + i - 1;
|
|
|
+ var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
|
|
|
+ var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
|
|
|
+ var d = ( tubularSegments + 1 ) * j + i;
|
|
|
+
|
|
|
+ // face one
|
|
|
+ indices[ indexBufferOffset ] = a;
|
|
|
+ indices[ indexBufferOffset + 1 ] = b;
|
|
|
+ indices[ indexBufferOffset + 2 ] = d;
|
|
|
+
|
|
|
+ // face two
|
|
|
+ indices[ indexBufferOffset + 3 ] = b;
|
|
|
+ indices[ indexBufferOffset + 4 ] = c;
|
|
|
+ indices[ indexBufferOffset + 5 ] = d;
|
|
|
+
|
|
|
+ // update offset
|
|
|
+ indexBufferOffset += 6;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // build geometry
|
|
|
+ this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
|
|
|
+ this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
|
|
|
+ this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
|
|
+ this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+THREE.TorusBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
|
|
|
+THREE.TorusBufferGeometry.prototype.constructor = THREE.TorusBufferGeometry;
|