WebGLObjects.js 5.8 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
	var geometries = new THREE.WebGLGeometries( gl, properties, info );
10

M
Mr.doob 已提交
11 12
	//

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

		var object = event.target;

		object.traverse( function ( child ) {

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

		} );

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

	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;

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

	}

	//

	this.objects = objects;
46

M
Mr.doob 已提交
47 48
	this.init = function ( object ) {

49
		var objectProperties = properties.get( object );
50

51
		if ( objectProperties.__webglInit === undefined ) {
52

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

			object.addEventListener( 'removed', onObjectRemoved );

		}

61
		if ( objectProperties.__webglActive === undefined ) {
M
Mr.doob 已提交
62

63
			objectProperties.__webglActive = true;
M
Mr.doob 已提交
64

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

67 68 69 70 71
				objects[ object.id ] = {
					id: object.id,
					object: object,
					z: 0
				};
M
Mr.doob 已提交
72

73
			}
M
Mr.doob 已提交
74

75
		}
M
Mr.doob 已提交
76

77
	};
M
Mr.doob 已提交
78

79
	function update( object ) {
80 81

		// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.
M
Mr.doob 已提交
82

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

85
		if ( object.geometry instanceof THREE.Geometry ) {
86

87
			geometry.updateFromObject( object );
88 89

		}
90

91
		var attributes = geometry.attributes;
M
Mr.doob 已提交
92

93
		for ( var name in attributes ) {
M
Mr.doob 已提交
94

M
Mr.doob 已提交
95
			updateAttribute( attributes[ name ] );
M
Mr.doob 已提交
96

97
		}
98

99 100 101 102
		// morph targets

		var morphAttributes = geometry.morphAttributes;

103
		for ( var name in morphAttributes ) {
104

105 106 107 108
			var array = morphAttributes[ name ];

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

M
Mr.doob 已提交
109
				updateAttribute( array[ i ] );
110 111

			}
112 113 114

		}

115 116
		return geometry;

117
	}
M
Mr.doob 已提交
118

M
Mr.doob 已提交
119
	function updateAttribute( attribute ) {
120

M
Mr.doob 已提交
121 122 123 124 125 126 127 128 129 130 131
		var bufferType;

		if ( attribute instanceof THREE.IndexBufferAttribute ) {

			bufferType = gl.ELEMENT_ARRAY_BUFFER;

		} else {

			bufferType = gl.ARRAY_BUFFER;

		}
M
Mr.doob 已提交
132

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

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

137
		if ( attributeProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
138

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

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

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

D
dubejf 已提交
145
		}
M
Mr.doob 已提交
146

D
dubejf 已提交
147
	}
M
Mr.doob 已提交
148

149
	function createBuffer( attributeProperties, data, bufferType ) {
M
Mr.doob 已提交
150

D
dubejf 已提交
151 152
		attributeProperties.__webglBuffer = gl.createBuffer();
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
153

D
dubejf 已提交
154
		var usage = gl.STATIC_DRAW;
M
Mr.doob 已提交
155

D
dubejf 已提交
156 157 158
		if ( data instanceof THREE.DynamicBufferAttribute
			 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
			 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
M
Mr.doob 已提交
159

D
dubejf 已提交
160
			usage = gl.DYNAMIC_DRAW;
M
Mr.doob 已提交
161

D
dubejf 已提交
162
		}
M
Mr.doob 已提交
163

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

166
		attributeProperties.version = data.version;
M
Mr.doob 已提交
167

D
dubejf 已提交
168
	}
M
Mr.doob 已提交
169

170
	function updateBuffer( attributeProperties, data, bufferType ) {
171

D
dubejf 已提交
172
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
173

G
gero3 已提交
174 175 176
		if ( data.updateRange === undefined || data.updateRange.count === - 1 ) {

			// Not using update ranges
M
Mr.doob 已提交
177

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

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

M
Mr.doob 已提交
182
			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 已提交
183 184 185 186 187

		} else {

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

D
dubejf 已提交
189 190 191
			data.updateRange.count = 0; // reset range

		}
192

193
		attributeProperties.version = data.version;
D
dubejf 已提交
194 195

	}
M
Mr.doob 已提交
196

197
	function getAttributeBuffer( attribute ) {
198

199 200
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
201
			return properties.get( attribute.data ).__webglBuffer;
202 203 204

		}

205
		return properties.get( attribute ).__webglBuffer;
206

207 208 209 210
	}

	function getWireframeAttribute( geometry ) {

211
		var property = properties.get( geometry );
212

213 214 215
		if ( property.wireframe !== undefined ) {

			return property.wireframe;
216 217 218 219 220

		}

		var indices = [];

221 222
		var attributes = geometry.attributes;

223 224 225 226 227 228 229 230 231 232
		var index = attributes.index;
		var position = attributes.position;

		console.time( 'wireframe' );

		if ( index !== undefined ) {

			var edges = {};
			var array = index.array;

233
			for ( var i = 0, l = array.length; i < l; i += 3 ) {
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248

				var a = array[ i + 0 ];
				var b = array[ i + 1 ];
				var c = array[ i + 2 ];

				if ( checkEdge( edges, a, b ) ) indices.push( a, b );
				if ( checkEdge( edges, b, c ) ) indices.push( b, c );
				if ( checkEdge( edges, c, a ) ) indices.push( c, a );

			}

		} else {

			var array = position.array;

249
			for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
250 251 252 253 254 255 256 257 258 259 260 261 262

				var a = i + 0;
				var b = i + 1;
				var c = i + 2;

				indices.push( a, b, b, c, c, a );

			}

		}

		console.timeEnd( 'wireframe' );

M
Mr.doob 已提交
263
		var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
M
Mr.doob 已提交
264
		var attribute = new THREE.IndexBufferAttribute( new TypeArray( indices ), 1 );
265

M
Mr.doob 已提交
266
		updateAttribute( attribute );
267

268
		property.wireframe = attribute;
269 270 271 272 273 274 275

		return attribute;

	}

	function checkEdge( edges, a, b ) {

M
Mr.doob 已提交
276
		var hash = a < b ? a + '_' + b : b + '_' + a;
277

M
Mr.doob 已提交
278 279 280
		if ( edges.hasOwnProperty( hash ) ) return false;

		edges[ hash ] = 1;
281 282 283 284 285 286 287

		return true;

	}

	this.getAttributeBuffer = getAttributeBuffer;
	this.getWireframeAttribute = getWireframeAttribute;
288

289 290
	this.update = update;

M
Mr.doob 已提交
291 292 293 294 295 296
	this.clear = function () {

		objects = {};

	};

M
Mr.doob 已提交
297
};