WebGLObjects.js 5.4 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
* @author mrdoob / http://mrdoob.com/
*/

5
THREE.WebGLObjects = function ( gl, properties, info ) {
M
Mr.doob 已提交
6 7 8

	var objects = {};

9 10
	var morphInfluences = new Float32Array( 8 );

11
	var geometries = new THREE.WebGLGeometries( gl, properties, info );
12

M
Mr.doob 已提交
13 14
	//

M
Mr.doob 已提交
15
	function onObjectRemoved( event ) {
M
Mr.doob 已提交
16 17 18 19 20 21 22 23 24 25

		var object = event.target;

		object.traverse( function ( child ) {

			child.removeEventListener( 'remove', onObjectRemoved );
			removeObject( child );

		} );

B
brason 已提交
26
	}
M
Mr.doob 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40

	function removeObject( object ) {

		if ( object instanceof THREE.Mesh ||
			 object instanceof THREE.PointCloud ||
			 object instanceof THREE.Line ) {

			delete objects[ object.id ];

		}

		delete object._modelViewMatrix;
		delete object._normalMatrix;

41
		properties.delete( object );
M
Mr.doob 已提交
42 43 44 45 46 47

	}

	//

	this.objects = objects;
48 49
	this.geometries = geometries;

M
Mr.doob 已提交
50 51
	this.init = function ( object ) {

52
		var objectProperties = properties.get( object );
53

54
		if ( objectProperties.__webglInit === undefined ) {
55

56
			objectProperties.__webglInit = true;
M
Mr.doob 已提交
57 58 59 60 61 62 63
			object._modelViewMatrix = new THREE.Matrix4();
			object._normalMatrix = new THREE.Matrix3();

			object.addEventListener( 'removed', onObjectRemoved );

		}

64
		if ( objectProperties.__webglActive === undefined ) {
M
Mr.doob 已提交
65

66
			objectProperties.__webglActive = true;
M
Mr.doob 已提交
67

68
			if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
M
Mr.doob 已提交
69

70 71 72 73 74
				objects[ object.id ] = {
					id: object.id,
					object: object,
					z: 0
				};
M
Mr.doob 已提交
75

76
			}
M
Mr.doob 已提交
77

78
		}
M
Mr.doob 已提交
79

80
	};
M
Mr.doob 已提交
81

82 83 84 85 86 87
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

M
Mr.doob 已提交
88
	function updateObject( object ) {
M
Mr.doob 已提交
89

90
		var geometry = geometries.get( object );
M
Mr.doob 已提交
91

92
		if ( object.geometry instanceof THREE.Geometry ) {
93

94
			geometry.updateFromObject( object );
95 96

		}
97

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
		// morph targets

		if ( object.morphTargetInfluences !== undefined ) {

			var activeInfluences = [];
			var morphTargetInfluences = object.morphTargetInfluences;

			for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {

				var influence = morphTargetInfluences[ i ];
				activeInfluences.push( [ influence, i ] );

			}

			activeInfluences.sort( numericalSort );

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

				morphInfluences[ i ] = activeInfluences[ i ][ 0 ];

				var attribute = geometry.morphAttributes[ activeInfluences[ i ][ 1 ] ];
				geometry.addAttribute( 'morphTarget' + i, attribute );

			}

			var material = object.material;

			if ( material.program !== undefined ) {

133
				var uniforms = material.program.getUniforms();
134

135 136 137
				if ( uniforms.morphTargetInfluences !== null ) {

					gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );
138 139 140 141 142 143 144 145 146 147 148

				}

			} else {

				console.warn( 'TOFIX: material.program is undefined' );

			}

		}

149
		//
M
Mr.doob 已提交
150

151
		var attributes = geometry.attributes;
M
Mr.doob 已提交
152

153
		for ( var name in attributes ) {
M
Mr.doob 已提交
154

D
dubejf 已提交
155
			updateAttribute( attributes[ name ], name );
M
Mr.doob 已提交
156

157
		}
158

159
	}
M
Mr.doob 已提交
160

161
	function updateAttribute ( attribute, name ) {
162

163
		var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
M
Mr.doob 已提交
164

165
		var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
M
Mr.doob 已提交
166

167
		var attributeProperties = properties.get( data );
M
Mr.doob 已提交
168

169
		if ( attributeProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
170

D
dubejf 已提交
171
			createBuffer( attributeProperties, data, bufferType );
M
Mr.doob 已提交
172

173
		} else if ( attributeProperties.version !== data.version ) {
M
Mr.doob 已提交
174

D
dubejf 已提交
175
			updateBuffer( attributeProperties, data, bufferType );
M
Mr.doob 已提交
176

D
dubejf 已提交
177
		}
M
Mr.doob 已提交
178

D
dubejf 已提交
179
	}
M
Mr.doob 已提交
180

D
dubejf 已提交
181
	function createBuffer ( attributeProperties, data, bufferType ) {
M
Mr.doob 已提交
182

D
dubejf 已提交
183 184
		attributeProperties.__webglBuffer = gl.createBuffer();
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
185

D
dubejf 已提交
186
		var usage = gl.STATIC_DRAW;
M
Mr.doob 已提交
187

D
dubejf 已提交
188 189 190
		if ( data instanceof THREE.DynamicBufferAttribute
			 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
			 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
M
Mr.doob 已提交
191

D
dubejf 已提交
192
			usage = gl.DYNAMIC_DRAW;
M
Mr.doob 已提交
193

D
dubejf 已提交
194
		}
M
Mr.doob 已提交
195

D
dubejf 已提交
196
		gl.bufferData( bufferType, data.array, usage );
M
Mr.doob 已提交
197

198
		attributeProperties.version = data.version;
M
Mr.doob 已提交
199

D
dubejf 已提交
200
	}
M
Mr.doob 已提交
201

D
dubejf 已提交
202
	function updateBuffer ( attributeProperties, data, bufferType ) {
203

D
dubejf 已提交
204
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
205

D
dubejf 已提交
206
		if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
M
Mr.doob 已提交
207

D
dubejf 已提交
208
			gl.bufferSubData( bufferType, 0, data.array );
209

D
dubejf 已提交
210
		} else if ( data.updateRange.count === 0 ) {
M
Mr.doob 已提交
211

M
Mr.doob 已提交
212
			console.error( 'THREE.WebGLObjects.updateBuffer: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
D
dubejf 已提交
213 214 215 216 217

		} else {

			gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
							  data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
218

D
dubejf 已提交
219 220 221
			data.updateRange.count = 0; // reset range

		}
222

223
		attributeProperties.version = data.version;
D
dubejf 已提交
224 225

	}
M
Mr.doob 已提交
226

227
	// returns the webgl buffer for a specified attribute
228 229
	this.getAttributeBuffer = function ( attribute ) {

230 231
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
232
			return properties.get( attribute.data ).__webglBuffer;
233 234 235

		}

236
		return properties.get( attribute ).__webglBuffer;
237

D
dubejf 已提交
238
	};
239

B
Ben Adams 已提交
240 241 242 243 244 245 246 247
	this.update = function ( renderList ) {

		for ( var i = 0, ul = renderList.length; i < ul; i++ ) {

			var object = renderList[i].object;

			if ( object.material.visible !== false ) {

M
Mr.doob 已提交
248
				updateObject( object );
B
Ben Adams 已提交
249 250

			}
251

B
Ben Adams 已提交
252
		}
253 254

	};
B
Ben Adams 已提交
255

M
Mr.doob 已提交
256 257 258 259 260 261
	this.clear = function () {

		objects = {};

	};

M
Mr.doob 已提交
262
};