Browse Source

SphereBufferGeometry

Ben Adams 10 years ago
parent
commit
723d3f4019

+ 4 - 4
examples/webgl_materials2.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<title>three.js webgl - materials</title>
@@ -76,8 +76,8 @@
 
 				// Spheres geometry
 
-				var geometry_smooth = new THREE.SphereGeometry( 70, 32, 16 );
-				var geometry_flat = new THREE.SphereGeometry( 70, 32, 16 );
+				var geometry_smooth = new THREE.SphereBufferGeometry( 70, 32, 16 );
+				var geometry_flat = new THREE.SphereBufferGeometry( 70, 32, 16 );
 
 				objects = [];
 
@@ -100,7 +100,7 @@
 
 				}
 
-				particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
+				particleLight = new THREE.Mesh( new THREE.SphereBufferGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
 				scene.add( particleLight );
 
 				// Lights

+ 111 - 0
src/extras/geometries/SphereBufferGeometry.js

@@ -0,0 +1,111 @@
+/**
+ * @author benaadams / https://twitter.com/ben_a_adams
+ * based on THREE.SphereGeometry
+ */
+
+THREE.SphereBufferGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
+
+	THREE.BufferGeometry.call( this );
+
+	this.type = 'SphereBufferGeometry';
+
+	this.parameters = {
+		radius: radius,
+		widthSegments: widthSegments,
+		heightSegments: heightSegments,
+		phiStart: phiStart,
+		phiLength: phiLength,
+		thetaStart: thetaStart,
+		thetaLength: thetaLength 
+	};
+
+	radius = radius || 50;
+
+	widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
+	heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
+
+	phiStart = phiStart !== undefined ? phiStart : 0;
+	phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
+
+	thetaStart = thetaStart !== undefined ? thetaStart : 0;
+	thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
+
+	var stride = ( 3 + 3 + 2 );
+	var vertexBuffer = new THREE.InterleavedBuffer( new Float32Array( ( ( widthSegments + 1 ) * ( heightSegments + 1 ) ) * stride ), stride );
+
+	var positions = new THREE.InterleavedBufferAttribute( vertexBuffer, 3, 0 );
+	this.addAttribute( 'position', positions );
+	var normals = new THREE.InterleavedBufferAttribute( vertexBuffer, 3, 3 );
+	this.addAttribute( 'normal', normals );
+	var uvs = new THREE.InterleavedBufferAttribute( vertexBuffer, 2, 6 );
+	this.addAttribute( 'uv', uvs );
+
+	var x, y, u, v, px, py, px, index = 0, vertices = [], normal = new THREE.Vector3();
+
+	for ( y = 0; y <= heightSegments; y ++ ) {
+
+		var verticesRow = [];
+
+		v = y / heightSegments;
+
+		for ( x = 0; x <= widthSegments; x ++ ) {
+
+			u = x / widthSegments;
+
+			px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
+			py = radius * Math.cos( thetaStart + v * thetaLength );
+			pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
+
+			normal.set( px, py, pz ).normalize();
+
+			positions.setXYZ( index, px, py, pz );
+			normals.setXYZ( index, normal.x, normal.y, normal.z );
+			uvs.setXY( index, u, 1 - v );
+
+			verticesRow.push( index );
+
+			index++;
+
+		}
+
+		vertices.push( verticesRow );
+
+	}
+
+	var indices = [];
+	
+	for ( y = 0, ul = heightSegments - 1; y < ul; y++ ) {
+
+		for ( x = 0; x < widthSegments; x++ ) {
+
+			var v1 = vertices[y][x + 1];
+			var v2 = vertices[y][x];
+			var v3 = vertices[y + 1][x];
+			var v4 = vertices[y + 1][x + 1];
+
+			if ( y !== 0 ) indices.push( v1, v2, v4 );
+			indices.push( v2, v3, v4 );
+
+		}
+	}
+
+	y = heightSegments;
+
+	for ( x = 0; x < widthSegments; x++ ) {
+
+		var v2 = vertices[y][x];
+		var v3 = vertices[y - 1][x];
+		var v4 = vertices[y - 1][x + 1];
+
+		indices.push( v2, v4, v3 );
+
+	}
+
+	this.addAttribute( 'index', new THREE.BufferAttribute( new Uint16Array( indices ), 1 ) );
+
+	this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
+
+};
+
+THREE.SphereBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+THREE.SphereBufferGeometry.prototype.constructor = THREE.SphereBufferGeometry;

+ 2 - 0
src/extras/geometries/SphereGeometry.js

@@ -4,6 +4,8 @@
 
 THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
 
+	THREE.log( 'THREE.SphereGeometry: Consider using THREE.SphereBufferGeometry for lower memory footprint.' );
+
 	THREE.Geometry.call( this );
 
 	this.type = 'SphereGeometry';

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

@@ -36,6 +36,7 @@
 	"src/extras/geometries/PlaneBufferGeometry.js",
 	"src/extras/geometries/RingGeometry.js",
 	"src/extras/geometries/SphereGeometry.js",
+	"src/extras/geometries/SphereBufferGeometry.js",
 	"src/extras/geometries/TextGeometry.js",
 	"src/extras/geometries/TorusGeometry.js",
 	"src/extras/geometries/TorusKnotGeometry.js",