Browse Source

New LatheBufferGeometry

Mugen87 9 years ago
parent
commit
f09d2faee1

+ 52 - 0
docs/api/extras/geometries/LatheBufferGeometry.html

@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:LatheGeometry].</div>
+
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#LatheBufferGeometry'></iframe>
+
+		<code>
+		var points = [];
+		for ( var i = 0; i < 10; i ++ ) {
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+		}
+		var geometry = new THREE.LatheBufferGeometry( points );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var lathe = new THREE.Mesh( geometry, material );
+		scene.add( lathe );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Array points], [page:Integer segments], [page:Float phiStart], [page:Float phiLength])</h3>
+		<div>
+		points — Array of Vector2s.<br />
+		segments — the number of circumference segments to generate. Default is 12.<br />
+		phiStart — the starting angle in radians. Default is 0.<br />
+		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
+		</div>
+		<div>
+		This creates a LatheBufferGeometry based on the parameters.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 5 - 4
docs/api/extras/geometries/LatheGeometry.html

@@ -17,11 +17,12 @@
 
 		<h2>Example</h2>
 
+		<iframe src='scenes/geometry-browser.html#LatheGeometry'></iframe>
+
 		<code>
 		var points = [];
 		for ( var i = 0; i < 10; i ++ ) {
-			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 15 + 50, ( i - 5 ) * 2 ) );
-
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
 		}
 		var geometry = new THREE.LatheGeometry( points );
 		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
@@ -37,10 +38,10 @@
 		points — Array of Vector2s.<br />
 		segments — the number of circumference segments to generate. Default is 12.<br />
 		phiStart — the starting angle in radians. Default is 0.<br />
-		phiLength — the radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Default is 2*PI
+		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
 		</div>
 		<div>
-		This creates a LatheGeometry based on the parameters.
+		This creates a LatheBufferGeometry based on the parameters.
 		</div>
 
 

+ 1 - 0
docs/list.js

@@ -200,6 +200,7 @@ var list = {
 			[ "DodecahedronGeometry", "api/extras/geometries/DodecahedronGeometry" ],
 			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
 			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
+			[ "LatheBufferGeometry", "api/extras/geometries/LatheBufferGeometry" ],
 			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
 			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
 			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],

+ 72 - 0
docs/scenes/js/geometry.js

@@ -365,6 +365,78 @@ var guis = {
 
 	},
 
+	LatheBufferGeometry : function() {
+
+		var points = [];
+
+		for ( var i = 0; i < 10; i ++ ) {
+
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+
+		}
+
+		var data = {
+			segments : 12,
+			phiStart : 0,
+			phiLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			var geometry = new THREE.LatheBufferGeometry(
+				points, data.segments, data.phiStart, data.phiLength
+			);
+
+			updateGroupGeometry( mesh, geometry );
+
+		}
+
+		var folder = gui.addFolder( 'THREE.LatheBufferGeometry' );
+
+		folder.add( data, 'segments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
+	LatheGeometry : function() {
+
+		var points = [];
+
+		for ( var i = 0; i < 10; i ++ ) {
+
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+
+		}
+
+		var data = {
+			segments : 12,
+			phiStart : 0,
+			phiLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			var geometry = new THREE.LatheGeometry(
+				points, data.segments, data.phiStart, data.phiLength
+			);
+
+			updateGroupGeometry( mesh, geometry );
+
+		}
+
+		var folder = gui.addFolder( 'THREE.LatheGeometry' );
+
+		folder.add( data, 'segments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	OctahedronGeometry : function() {
 
 		var data = {

+ 156 - 0
src/extras/geometries/LatheBufferGeometry.js

@@ -0,0 +1,156 @@
+/**
+ * @author Mugen87 / https://github.com/Mugen87
+ */
+
+ // points - to create a closed torus, one must use a set of points
+ //    like so: [ a, b, c, d, a ], see first is the same as last.
+ // segments - the number of circumference segments to create
+ // phiStart - the starting radian
+ // phiLength - the radian (0 to 2PI) range of the lathed section
+ //    2PI is a closed lathe, less than 2PI is a portion.
+
+THREE.LatheBufferGeometry = function ( points, segments, phiStart, phiLength ) {
+
+	THREE.BufferGeometry.call( this );
+
+	this.type = 'LatheBufferGeometry';
+
+	this.parameters = {
+		points: points,
+		segments: segments,
+		phiStart: phiStart,
+		phiLength: phiLength
+	};
+
+	segments = Math.floor( segments ) || 12;
+	phiStart = phiStart || 0;
+	phiLength = phiLength || Math.PI * 2;
+
+	// clamp phiLength so it's in range of [ 0, 2PI ]
+	phiLength = THREE.Math.clamp( phiLength, 0, Math.PI * 2 );
+
+	// these are used to calculate buffer length
+	var vertexCount = ( segments + 1 ) * points.length;
+	var indexCount = segments * points.length * 2 * 3;
+
+	// buffers
+	var indices = new THREE.BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );
+	var vertices = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
+	var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );
+
+	// helper variables
+	var index = 0, indexOffset = 0, base;
+	var inversePointLength = 1.0 / ( points.length - 1 );
+	var inverseSegments = 1.0 / segments;
+	var vertex = new THREE.Vector3();
+	var uv = new THREE.Vector2();
+	var i, j;
+
+	// generate vertices and uvs
+
+	for ( i = 0; i <= segments; i ++ ) {
+
+		var phi = phiStart + i * inverseSegments * phiLength;
+
+		var sin = Math.sin( phi );
+		var cos = Math.cos( phi );
+
+		for ( j = 0; j <= ( points.length - 1 ); j ++ ) {
+
+			// vertex
+			vertex.x = points[ j ].x * sin;
+			vertex.y = points[ j ].y;
+			vertex.z = points[ j ].x * cos;
+			vertices.setXYZ( index, vertex.x, vertex.y, vertex.z );
+
+			// uv
+			uv.x = i / segments;
+			uv.y = j / ( points.length - 1 );
+			uvs.setXY( index, uv.x, uv.y );
+
+			// increase index
+			index ++;
+
+		}
+
+	}
+
+	// generate indices
+
+	for ( i = 0; i < segments; i ++ ) {
+
+		for ( j = 0; j < ( points.length - 1 ); j ++ ) {
+
+			base = j + i * points.length;
+
+			// indices
+			var a = base;
+			var b = base + points.length;
+			var c = base + points.length + 1;
+			var d = base + 1;
+
+			// face one
+			indices.setX( indexOffset, a ); indexOffset++;
+			indices.setX( indexOffset, b ); indexOffset++;
+			indices.setX( indexOffset, d ); indexOffset++;
+
+			// face two
+			indices.setX( indexOffset, b ); indexOffset++;
+			indices.setX( indexOffset, c ); indexOffset++;
+			indices.setX( indexOffset, d ); indexOffset++;
+
+		}
+
+	}
+
+	// build geometry
+
+	this.setIndex( indices );
+	this.addAttribute( 'position', vertices );
+	this.addAttribute( 'uv', uvs );
+
+	// generate normals
+
+	this.computeVertexNormals();
+
+	// if the geometry is closed, we need to merge the first and last normal of a vertex row
+	// because the corresponding vertices are identical (but still have different UVs).
+
+	if( phiLength === Math.PI * 2 ) {
+
+		var normals = this.attributes.normal.array;
+		var n1 = new THREE.Vector3();
+		var n2 = new THREE.Vector3();
+		var n = new THREE.Vector3();
+
+		// this is the buffer offset for the last line of vertices
+		base = segments * points.length * 3;
+
+		for( i = 0, j = 0; i < points.length; i ++, j += 3 ) {
+
+			// select the normal of the vertex in the first line
+			n1.x = normals[ j + 0 ];
+			n1.y = normals[ j + 1 ];
+			n1.z = normals[ j + 2 ];
+
+			// select the normal of the vertex in the last line
+			n2.x = normals[ base + j + 0 ];
+			n2.y = normals[ base + j + 1 ];
+			n2.z = normals[ base + j + 2 ];
+
+			// merge normals
+			n.addVectors( n1, n2 ).normalize();
+
+			// assign the new values to both normals
+			normals[ j + 0 ] = normals[ base + j + 0 ] = n.x;
+			normals[ j + 1 ] = normals[ base + j + 1 ] = n.y;
+			normals[ j + 2 ] = normals[ base + j + 2 ] = n.z;
+
+		} // next row
+
+	}
+
+};
+
+THREE.LatheBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+THREE.LatheBufferGeometry.prototype.constructor = THREE.LatheBufferGeometry;

+ 3 - 76
src/extras/geometries/LatheGeometry.js

@@ -8,8 +8,8 @@
 //    like so: [ a, b, c, d, a ], see first is the same as last.
 // segments - the number of circumference segments to create
 // phiStart - the starting radian
-// phiLength - the radian (0 to 2*PI) range of the lathed section
-//    2*pi is a closed lathe, less than 2PI is a portion.
+// phiLength - the radian (0 to 2PI) range of the lathed section
+//    2PI is a closed lathe, less than 2PI is a portion.
 
 THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) {
 
@@ -24,81 +24,8 @@ THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) {
 		phiLength: phiLength
 	};
 
-	segments = segments || 12;
-	phiStart = phiStart || 0;
-	phiLength = phiLength || 2 * Math.PI;
-
-	var inversePointLength = 1.0 / ( points.length - 1 );
-	var inverseSegments = 1.0 / segments;
-
-	for ( var i = 0, il = segments; i <= il; i ++ ) {
-
-		var phi = phiStart + i * inverseSegments * phiLength;
-
-		var sin = Math.sin( phi );
-		var cos = Math.cos( phi );
-
-		for ( var j = 0, jl = points.length; j < jl; j ++ ) {
-
-			var point = points[ j ];
-
-			var vertex = new THREE.Vector3();
-
-			vertex.x = point.x * sin;
-			vertex.y = point.y;
-			vertex.z = point.x * cos;
-
-			this.vertices.push( vertex );
-
-		}
-
-	}
-
-	var np = points.length;
-
-	for ( var i = 0, il = segments; i < il; i ++ ) {
-
-		for ( var j = 0, jl = points.length - 1; j < jl; j ++ ) {
-
-			var base = j + np * i;
-			var a = base;
-			var b = base + np;
-			var c = base + 1 + np;
-			var d = base + 1;
-
-			var u0 = i * inverseSegments;
-			var v0 = j * inversePointLength;
-			var u1 = u0 + inverseSegments;
-			var v1 = v0 + inversePointLength;
-
-			this.faces.push( new THREE.Face3( a, b, d ) );
-
-			this.faceVertexUvs[ 0 ].push( [
-
-				new THREE.Vector2( u0, v0 ),
-				new THREE.Vector2( u1, v0 ),
-				new THREE.Vector2( u0, v1 )
-
-			] );
-
-			this.faces.push( new THREE.Face3( b, c, d ) );
-
-			this.faceVertexUvs[ 0 ].push( [
-
-				new THREE.Vector2( u1, v0 ),
-				new THREE.Vector2( u1, v1 ),
-				new THREE.Vector2( u0, v1 )
-
-			] );
-
-
-		}
-
-	}
-
+	this.fromBufferGeometry( new THREE.LatheBufferGeometry( points, segments, phiStart, phiLength ) );
 	this.mergeVertices();
-	this.computeFaceNormals();
-	this.computeVertexNormals();
 
 };
 

+ 1 - 0
utils/build/includes/extras.json

@@ -28,6 +28,7 @@
 	"src/extras/geometries/EdgesGeometry.js",
 	"src/extras/geometries/ExtrudeGeometry.js",
 	"src/extras/geometries/ShapeGeometry.js",
+	"src/extras/geometries/LatheBufferGeometry.js",
 	"src/extras/geometries/LatheGeometry.js",
 	"src/extras/geometries/PlaneGeometry.js",
 	"src/extras/geometries/PlaneBufferGeometry.js",