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

D
dubejf 已提交
95
			updateAttribute( attributes[ name ], 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 109 110 111
			var array = morphAttributes[ name ];

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

				updateAttribute( array[ i ], i );

			}
112 113 114

		}

115 116
		return geometry;

117
	}
M
Mr.doob 已提交
118

119
	function updateAttribute( attribute, name ) {
120

121 122 123 124 125 126 127 128 129 130 131
		var bufferType;

		if ( name === 'index' || name === 'wireframe' ) {

			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 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
	}

	function getWireframeAttribute( geometry ) {

		var attributes = geometry.attributes;

		if ( attributes.wireframe !== undefined ) {

			return attributes.wireframe;

		}

		var indices = [];

		var index = attributes.index;
		var position = attributes.position;

		console.time( 'wireframe' );

		if ( index !== undefined ) {

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

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

				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;

			for ( var i = 0, j = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {

				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 已提交
261
		var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
262 263 264 265 266 267 268 269 270 271 272 273
		var attribute = new THREE.BufferAttribute( new TypeArray( indices ), 1 );

		updateAttribute( attribute, 'wireframe' );

		geometry.addAttribute( 'wireframe', attribute );

		return attribute;

	}

	function checkEdge( edges, a, b ) {

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

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

		edges[ hash ] = 1;
279 280 281 282 283 284 285

		return true;

	}

	this.getAttributeBuffer = getAttributeBuffer;
	this.getWireframeAttribute = getWireframeAttribute;
286

287 288 289
	this.update = update;
	this.updateAttribute = updateAttribute;

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

		objects = {};

	};

M
Mr.doob 已提交
296
};