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

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

	var objects = {};
	var objectsImmediate = [];

10 11
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
12
	var geometries = new THREE.WebGLGeometries( gl, info );
13

M
Mr.doob 已提交
14 15
	//

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

		var object = event.target;

		object.traverse( function ( child ) {

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

		} );

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

	function removeObject( object ) {

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

			delete objects[ object.id ];

		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {

			removeInstances( objectsImmediate, object );

		}

		delete object._modelViewMatrix;
		delete object._normalMatrix;

46
		webGLProps.delete( object );
M
Mr.doob 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

	}

	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;
	this.objectsImmediate = objectsImmediate;

69 70
	this.geometries = geometries;

M
Mr.doob 已提交
71 72
	this.init = function ( object ) {

73
		var objectWebglProperties = webGLProps.get( object );
74

75
		if ( objectWebglProperties.__webglInit === undefined ) {
76

77
			objectWebglProperties.__webglInit = true;
M
Mr.doob 已提交
78 79 80 81 82 83 84
			object._modelViewMatrix = new THREE.Matrix4();
			object._normalMatrix = new THREE.Matrix3();

			object.addEventListener( 'removed', onObjectRemoved );

		}

85
		if ( objectWebglProperties.__webglActive === undefined ) {
M
Mr.doob 已提交
86

87
			objectWebglProperties.__webglActive = true;
M
Mr.doob 已提交
88

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

91 92 93 94 95
				objects[ object.id ] = {
					id: object.id,
					object: object,
					z: 0
				};
M
Mr.doob 已提交
96

97
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
M
Mr.doob 已提交
98

99 100 101 102 103 104 105
				objectsImmediate.push( {
					id: null,
					object: object,
					opaque: null,
					transparent: null,
					z: 0
				} );
M
Mr.doob 已提交
106

107
			}
M
Mr.doob 已提交
108

109
		}
M
Mr.doob 已提交
110

111
	};
M
Mr.doob 已提交
112

113 114 115 116 117 118
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

M
Mr.doob 已提交
119
	function updateObject( object ) {
M
Mr.doob 已提交
120

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

123
		if ( object.geometry.dynamic === true ) {
124

125
			geometry.updateFromObject( object );
126 127

		}
128

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		// 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 ) {

164
				var uniforms = material.program.getUniforms();
165

166 167 168
				if ( uniforms.morphTargetInfluences !== null ) {

					gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );
169 170 171 172 173 174 175 176 177 178 179

				}

			} else {

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

			}

		}

180
		//
M
Mr.doob 已提交
181

182
		var attributes = geometry.attributes;
M
Mr.doob 已提交
183

184
		for ( var name in attributes ) {
M
Mr.doob 已提交
185

186
			var attribute = attributes[ name ];
M
Mr.doob 已提交
187

188
			var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
189

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

192
			var attributeWebGLProperties = webGLProps.get( data );
193 194

			if ( attributeWebGLProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
195

196 197
				attributeWebGLProperties.__webglBuffer = gl.createBuffer();
				gl.bindBuffer( bufferType, attributeWebGLProperties.__webglBuffer );
M
Mr.doob 已提交
198

199
				var usage = gl.STATIC_DRAW;
M
Mr.doob 已提交
200

201 202 203
				if ( data instanceof THREE.DynamicBufferAttribute
						 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
						 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
M
Mr.doob 已提交
204

205
					usage = gl.DYNAMIC_DRAW;
M
Mr.doob 已提交
206

207
				}
M
Mr.doob 已提交
208

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

211
				data.needsUpdate = false;
M
Mr.doob 已提交
212

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

215
				gl.bindBuffer( bufferType, attributeWebGLProperties.__webglBuffer );
M
Mr.doob 已提交
216

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

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

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

223
					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 已提交
224

225
				} else {
M
Mr.doob 已提交
226

227 228
					gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
									 data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
M
Mr.doob 已提交
229

230
					data.updateRange.count = 0; // reset range
M
Mr.doob 已提交
231 232 233

				}

234 235
				data.needsUpdate = false;

M
Mr.doob 已提交
236 237 238 239 240 241
			}

		}

	};

242
	// returns the webgl buffer for a specified attribute
243 244
	this.getAttributeBuffer = function ( attribute ) {

245 246 247 248 249 250 251
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

			return webGLProps.get( attribute.data ).__webglBuffer

		}

		return webGLProps.get( attribute ).__webglBuffer;
252

253 254
	}

B
Ben Adams 已提交
255 256 257 258 259 260 261 262
	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 已提交
263
				updateObject( object );
B
Ben Adams 已提交
264 265

			}
266

B
Ben Adams 已提交
267
		}
268 269

	};
B
Ben Adams 已提交
270

M
Mr.doob 已提交
271
};