diff --git a/examples/webgl_materials2.html b/examples/webgl_materials2.html index 6870eed32b9c8..7b5f716bd126e 100644 --- a/examples/webgl_materials2.html +++ b/examples/webgl_materials2.html @@ -1,4 +1,4 @@ - + three.js webgl - materials @@ -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 diff --git a/src/extras/geometries/SphereBufferGeometry.js b/src/extras/geometries/SphereBufferGeometry.js new file mode 100644 index 0000000000000..72a2dc48c72d8 --- /dev/null +++ b/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; \ No newline at end of file diff --git a/src/extras/geometries/SphereGeometry.js b/src/extras/geometries/SphereGeometry.js index 9fcb2afdda53c..b57354bed2624 100644 --- a/src/extras/geometries/SphereGeometry.js +++ b/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'; diff --git a/utils/build/includes/extras.json b/utils/build/includes/extras.json index c92201e71682c..b6aa372be7d85 100644 --- a/utils/build/includes/extras.json +++ b/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",