Browse Source

Merge pull request #6394 from benaadams/geometries

SphereBufferGeometry
Ricardo Cabello 10 years ago
parent
commit
04101b7c16

+ 1 - 1
examples/js/SkyShader.js

@@ -251,7 +251,7 @@ THREE.Sky = function () {
 		side: THREE.BackSide
 	} );
 
-	var skyGeo = new THREE.SphereGeometry( 450000, 32, 15 );
+	var skyGeo = new THREE.SphereBufferGeometry( 450000, 32, 15 );
 	var skyMesh = new THREE.Mesh( skyGeo, skyMat );
 
 

+ 4 - 4
examples/webgl_camera.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<title>three.js webgl - cameras</title>
@@ -103,14 +103,14 @@
 				//
 
 				mesh = new THREE.Line(
-					new THREE.WireframeGeometry( new THREE.SphereGeometry( 100, 16, 8 ) ),
+					new THREE.WireframeGeometry( new THREE.SphereBufferGeometry( 100, 16, 8 ) ),
 					new THREE.LineBasicMaterial( { color: 0xffffff } ),
 					THREE.LinePieces
 				);
 				scene.add( mesh );
 
 				var mesh2 = new THREE.Line(
-					new THREE.WireframeGeometry( new THREE.SphereGeometry( 50, 16, 8 ) ),
+					new THREE.WireframeGeometry( new THREE.SphereBufferGeometry( 50, 16, 8 ) ),
 					new THREE.LineBasicMaterial( { color: 0x00ff00 } ),
 					THREE.LinePieces
 				);
@@ -118,7 +118,7 @@
 				mesh.add( mesh2 );
 
 				var mesh3 = new THREE.Line(
-					new THREE.WireframeGeometry( new THREE.SphereGeometry( 5, 16, 8 ) ),
+					new THREE.WireframeGeometry( new THREE.SphereBufferGeometry( 5, 16, 8 ) ),
 					new THREE.LineBasicMaterial( { color: 0x0000ff } ),
 					THREE.LinePieces
 				);

+ 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

+ 2 - 2
examples/webgl_shaders_sky.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<title>three.js webgl - shaders - sky sun shader</title>
@@ -75,7 +75,7 @@
 
 
 				// Add Sun Helper
-				sunSphere = new THREE.Mesh( new THREE.SphereGeometry( 20000, 30, 30 ),
+				sunSphere = new THREE.Mesh( new THREE.SphereBufferGeometry( 20000, 30, 30 ),
 					new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: false }));
 				sunSphere.position.y = -700000;
 				sunSphere.visible = true;

+ 2 - 2
examples/webgl_test_memory.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<title>three.js - webgl</title>
@@ -72,7 +72,7 @@
 
 			function render() {
 
-				var geometry = new THREE.SphereGeometry( 50, Math.random() * 64, Math.random() * 32 );
+			    var geometry = new THREE.SphereBufferGeometry( 50, Math.random() * 64, Math.random() * 32 );
 
 				var texture = new THREE.Texture( createImage() );
 				texture.needsUpdate = true;

+ 2 - 2
examples/webgl_test_memory2.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<title>three.js - webgl</title>
@@ -73,7 +73,7 @@
 
 				scene = new THREE.Scene();
 
-				geometry = new THREE.SphereGeometry( 15, 64, 32 );
+				geometry = new THREE.SphereBufferGeometry( 15, 64, 32 );
 
 				for ( var i = 0; i < N; i ++ ) {
 

+ 32 - 0
src/core/BufferAttribute.js

@@ -170,6 +170,38 @@ THREE.BufferAttribute.prototype = {
 
 	},
 
+	setW: function ( index, w ) {
+
+		this.array[ index * this.itemSize + 3 ] = w;
+
+		return this;
+
+	},
+
+	getX: function ( index ) {
+
+		return this.array[ index * this.itemSize ];
+
+	},
+
+	getY: function ( index ) {
+
+		return this.array[ index * this.itemSize + 1 ];
+
+	},
+
+	getZ: function ( index ) {
+
+		return this.array[ index * this.itemSize + 2 ];
+
+	},
+
+	getW: function ( index ) {
+
+		return this.array[ index * this.itemSize + 3 ];
+
+	},
+
 	setXY: function ( index, x, y ) {
 
 		index *= this.itemSize;

+ 10 - 10
src/core/BufferGeometry.js

@@ -68,7 +68,7 @@ THREE.BufferGeometry.prototype = {
 
 		if ( position !== undefined ) {
 
-			matrix.applyToVector3Array( position.array );
+			matrix.applyToBuffer( position );
 			position.needsUpdate = true;
 
 		}
@@ -79,7 +79,7 @@ THREE.BufferGeometry.prototype = {
 
 			var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
 
-			normalMatrix.applyToVector3Array( normal.array );
+			normalMatrix.applyToBuffer( normal );
 			normal.needsUpdate = true;
 
 		}
@@ -466,16 +466,16 @@ THREE.BufferGeometry.prototype = {
 
 			}
 
-			var positions = this.attributes.position.array;
+			var positions = this.attributes.position;
 
 			if ( positions ) {
 
 				var bb = this.boundingBox;
 				bb.makeEmpty();
 
-				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
+				for ( var i = 0, il = positions.length / positions.itemSize; i < il; i ++ ) {
 
-					vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+					vector.set( positions.getX( i ), positions.getY( i ), positions.getZ( i ) );
 					bb.expandByPoint( vector );
 
 				}
@@ -512,7 +512,7 @@ THREE.BufferGeometry.prototype = {
 
 			}
 
-			var positions = this.attributes.position.array;
+			var positions = this.attributes.position;
 
 			if ( positions ) {
 
@@ -520,9 +520,9 @@ THREE.BufferGeometry.prototype = {
 
 				var center = this.boundingSphere.center;
 
-				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
+				for ( var i = 0, il = positions.length / positions.itemSize; i < il; i ++ ) {
 
-					vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+					vector.set( positions.getX( i ), positions.getY( i ), positions.getZ( i ) );
 					box.expandByPoint( vector );
 
 				}
@@ -534,9 +534,9 @@ THREE.BufferGeometry.prototype = {
 
 				var maxRadiusSq = 0;
 
-				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
+				for ( var i = 0, il = positions.length / positions.itemSize; i < il; i ++ ) {
 
-					vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+					vector.set( positions.getX( i ), positions.getY( i ), positions.getZ( i ) );
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
 
 				}

+ 32 - 0
src/core/InterleavedBufferAttribute.js

@@ -45,6 +45,38 @@ THREE.InterleavedBufferAttribute.prototype = {
 
 	},
 
+	setW: function ( index, w ) {
+
+		this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
+
+		return this;
+
+	},
+
+	getX: function ( index ) {
+
+		return this.data.array[ index * this.data.stride + this.offset ];
+
+	},
+
+	getY: function ( index ) {
+
+		return this.data.array[ index * this.data.stride + this.offset + 1 ];
+
+	},
+
+	getZ: function ( index ) {
+
+		return this.data.array[ index * this.data.stride + this.offset + 2 ];
+
+	},
+
+	getW: function ( index ) {
+
+		return this.data.array[ index * this.data.stride + this.offset + 3 ];
+
+	},
+
 	setXY: function ( index, x, y ) {
 
 		index = index * this.data.stride + this.offset;

+ 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';

+ 6 - 5
src/extras/geometries/WireframeGeometry.js

@@ -68,7 +68,7 @@ THREE.WireframeGeometry = function ( geometry ) {
 
 		if ( geometry.attributes.index !== undefined ) { // Indexed BufferGeometry
 
-			var vertices = geometry.attributes.position.array;
+			var vertices = geometry.attributes.position;
 			var indices = geometry.attributes.index.array;
 			var drawcalls = geometry.drawcalls;
 			var numEdges = 0;
@@ -120,10 +120,11 @@ THREE.WireframeGeometry = function ( geometry ) {
 				for ( var j = 0; j < 2; j ++ ) {
 
 					var index = 6 * i + 3 * j;
-					var index2 = 3 * edges[ 2 * i + j];
-					coords[ index + 0 ] = vertices[ index2 ];
-					coords[ index + 1 ] = vertices[ index2 + 1 ];
-					coords[ index + 2 ] = vertices[ index2 + 2 ];
+					var index2 = edges[2 * i + j];
+
+					coords[ index + 0 ] = vertices.getX( index2 );
+					coords[ index + 1 ] = vertices.getY( index2 );
+					coords[ index + 2 ] = vertices.getZ( index2 );
 
 				}
 

+ 31 - 2
src/math/Matrix3.js

@@ -84,10 +84,11 @@ THREE.Matrix3.prototype = {
 
 	applyToVector3Array: function () {
 
-		var v1 = new THREE.Vector3();
+		var v1;
 
-		return function ( array, offset, length ) {
+		return function applyToVector3Array( array, offset, length ) {
 
+			if ( v1 === undefined ) v1 = new THREE.Vector3();
 			if ( offset === undefined ) offset = 0;
 			if ( length === undefined ) length = array.length;
 
@@ -111,6 +112,34 @@ THREE.Matrix3.prototype = {
 
 	}(),
 
+	applyToBuffer: function () {
+
+		var v1;
+
+		return function applyToBuffer( buffer, offset, length ) {
+
+			if ( v1 === undefined ) v1 = new THREE.Vector3();
+			if ( offset === undefined ) offset = 0;
+			if ( length === undefined ) length = buffer.length / buffer.itemSize;
+
+			for ( var i = 0, j = offset; i < length; i ++, j ++ ) {
+
+				v1.x = buffer.getX( j );
+				v1.y = buffer.getY( j );
+				v1.z = buffer.getZ( j );
+
+				v1.applyMatrix3( this );
+
+				buffer.setXYZ( v1.x, v1.y, v1.z );
+
+			}
+
+			return array;
+
+		};
+
+	}(),
+
 	multiplyScalar: function ( s ) {
 
 		var te = this.elements;

+ 29 - 1
src/math/Matrix4.js

@@ -469,7 +469,7 @@ THREE.Matrix4.prototype = {
 
 		var v1;
 
-		return function ( array, offset, length ) {
+		return function applyToVector3Array( array, offset, length ) {
 
 			if ( v1 === undefined ) v1 = new THREE.Vector3();
 			if ( offset === undefined ) offset = 0;
@@ -495,6 +495,34 @@ THREE.Matrix4.prototype = {
 
 	}(),
 
+	applyToBuffer: function () {
+
+		var v1;
+
+		return function applyToBuffer( buffer, offset, length ) {
+
+			if ( v1 === undefined ) v1 = new THREE.Vector3();
+			if ( offset === undefined ) offset = 0;
+			if ( length === undefined ) length = buffer.length / buffer.itemSize;
+
+			for ( var i = 0, j = offset; i < length; i ++, j ++ ) {
+
+				v1.x = buffer.getX( j );
+				v1.y = buffer.getY( j );
+				v1.z = buffer.getZ( j );
+
+				v1.applyMatrix4( this );
+
+				buffer.setXYZ( v1.x, v1.y, v1.z );
+
+			}
+
+			return array;
+
+		};
+
+	}(),
+
 	rotateAxis: function ( v ) {
 
 		THREE.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );

+ 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",