WebGLObjects.js 5.3 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 );

M
Mr.doob 已提交
11
	var geometries = new THREE.WebGLGeometries( gl, 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

	}

	function removeInstances( objlist, object ) {

		for ( var o = objlist.length - 1; o >= 0; o -- ) {

			if ( objlist[ o ].object === object ) {

				objlist.splice( o, 1 );

			}

		}

	}

	//

	this.objects = objects;

63 64
	this.geometries = geometries;

M
Mr.doob 已提交
65 66
	this.init = function ( object ) {

67
		var objectProperties = properties.get( object );
68

69
		if ( objectProperties.__webglInit === undefined ) {
70

71
			objectProperties.__webglInit = true;
M
Mr.doob 已提交
72 73 74 75 76 77 78
			object._modelViewMatrix = new THREE.Matrix4();
			object._normalMatrix = new THREE.Matrix3();

			object.addEventListener( 'removed', onObjectRemoved );

		}

79
		if ( objectProperties.__webglActive === undefined ) {
M
Mr.doob 已提交
80

81
			objectProperties.__webglActive = true;
M
Mr.doob 已提交
82

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

85 86 87 88 89
				objects[ object.id ] = {
					id: object.id,
					object: object,
					z: 0
				};
M
Mr.doob 已提交
90

91
			}
M
Mr.doob 已提交
92

93
		}
M
Mr.doob 已提交
94

95
	};
M
Mr.doob 已提交
96

97 98 99 100 101 102
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

M
Mr.doob 已提交
103
	function updateObject( object ) {
M
Mr.doob 已提交
104

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

107
		if ( object.geometry.dynamic === true ) {
108

109
			geometry.updateFromObject( object );
110 111

		}
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
		// 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 ) {

148
				var uniforms = material.program.getUniforms();
149

150 151 152
				if ( uniforms.morphTargetInfluences !== null ) {

					gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );
153 154 155 156 157 158 159 160 161 162 163

				}

			} else {

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

			}

		}

164
		//
M
Mr.doob 已提交
165

166
		var attributes = geometry.attributes;
M
Mr.doob 已提交
167

168
		for ( var name in attributes ) {
M
Mr.doob 已提交
169

170
			var attribute = attributes[ name ];
171
			updateAttribute( attribute, name );
M
Mr.doob 已提交
172

173
		}
174

175
	}
M
Mr.doob 已提交
176

177
	function updateAttribute ( attribute, name ) {
178

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

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

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

185
		if ( attributeProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
186

187 188
			attributeProperties.__webglBuffer = gl.createBuffer();
			gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
189

190
			var usage = gl.STATIC_DRAW;
M
Mr.doob 已提交
191

192 193 194
			if ( data instanceof THREE.DynamicBufferAttribute
				 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
				 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
M
Mr.doob 已提交
195

196
				usage = gl.DYNAMIC_DRAW;
M
Mr.doob 已提交
197

198
			}
M
Mr.doob 已提交
199

200
			gl.bufferData( bufferType, data.array, usage );
M
Mr.doob 已提交
201

202
			data.needsUpdate = false;
M
Mr.doob 已提交
203

204
		} else if ( data.needsUpdate === true ) {
M
Mr.doob 已提交
205

206
			gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
207

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

210
				gl.bufferSubData( bufferType, 0, data.array );
M
Mr.doob 已提交
211

212
			} else if ( data.updateRange.count === 0 ) {
M
Mr.doob 已提交
213

214
				console.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
M
Mr.doob 已提交
215

216
			} else {
M
Mr.doob 已提交
217

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

				data.updateRange.count = 0; // reset range
222

M
Mr.doob 已提交
223 224
			}

225 226
			data.needsUpdate = false;

M
Mr.doob 已提交
227 228
		}

229 230 231
	}


M
Mr.doob 已提交
232

233
	// returns the webgl buffer for a specified attribute
234 235
	this.getAttributeBuffer = function ( attribute ) {

236 237
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

238
			return properties.get( attribute.data ).__webglBuffer
239 240 241

		}

242
		return properties.get( attribute ).__webglBuffer;
243

244 245
	}

B
Ben Adams 已提交
246 247 248 249 250 251 252 253
	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 已提交
254
				updateObject( object );
B
Ben Adams 已提交
255 256

			}
257

B
Ben Adams 已提交
258
		}
259 260

	};
B
Ben Adams 已提交
261

M
Mr.doob 已提交
262 263 264 265 266 267
	this.clear = function () {

		objects = {};

	};

M
Mr.doob 已提交
268
};