WebGLObjects.js 5.7 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
		var bufferType = name === 'index' ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
M
Mr.doob 已提交
122

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

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

127
		if ( attributeProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
128

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

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

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

D
dubejf 已提交
135
		}
M
Mr.doob 已提交
136

D
dubejf 已提交
137
	}
M
Mr.doob 已提交
138

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

D
dubejf 已提交
141 142
		attributeProperties.__webglBuffer = gl.createBuffer();
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
143

D
dubejf 已提交
144
		var usage = gl.STATIC_DRAW;
M
Mr.doob 已提交
145

D
dubejf 已提交
146 147 148
		if ( data instanceof THREE.DynamicBufferAttribute
			 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
			 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
M
Mr.doob 已提交
149

D
dubejf 已提交
150
			usage = gl.DYNAMIC_DRAW;
M
Mr.doob 已提交
151

D
dubejf 已提交
152
		}
M
Mr.doob 已提交
153

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

156
		attributeProperties.version = data.version;
M
Mr.doob 已提交
157

D
dubejf 已提交
158
	}
M
Mr.doob 已提交
159

160
	function updateBuffer( attributeProperties, data, bufferType ) {
161

D
dubejf 已提交
162
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
163

G
gero3 已提交
164 165 166
		if ( data.updateRange === undefined || data.updateRange.count === - 1 ) {

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

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

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

M
Mr.doob 已提交
172
			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 已提交
173 174 175 176 177

		} else {

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

D
dubejf 已提交
179 180 181
			data.updateRange.count = 0; // reset range

		}
182

183
		attributeProperties.version = data.version;
D
dubejf 已提交
184 185

	}
M
Mr.doob 已提交
186

187
	function getAttributeBuffer( attribute ) {
188

189 190
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
191
			return properties.get( attribute.data ).__webglBuffer;
192 193 194

		}

195
		return properties.get( attribute ).__webglBuffer;
196

197 198 199 200
	}

	function getWireframeAttribute( geometry ) {

201
		if ( geometry._wireframe !== undefined ) {
202

203
			return geometry._wireframe;
204 205 206 207 208

		}

		var indices = [];

209 210
		var attributes = geometry.attributes;

211 212 213 214 215 216 217 218 219 220
		var index = attributes.index;
		var position = attributes.position;

		console.time( 'wireframe' );

		if ( index !== undefined ) {

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

221
			for ( var i = 0, l = array.length; i < l; i += 3 ) {
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

				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;

237
			for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
238 239 240 241 242 243 244 245 246 247 248 249 250

				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 已提交
251
		var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
252 253
		var attribute = new THREE.BufferAttribute( new TypeArray( indices ), 1 );

254
		updateAttribute( attribute, 'index' );
255

256
		geometry._wireframe = attribute;
257 258 259 260 261 262 263

		return attribute;

	}

	function checkEdge( edges, a, b ) {

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

M
Mr.doob 已提交
266 267 268
		if ( edges.hasOwnProperty( hash ) ) return false;

		edges[ hash ] = 1;
269 270 271 272 273 274 275

		return true;

	}

	this.getAttributeBuffer = getAttributeBuffer;
	this.getWireframeAttribute = getWireframeAttribute;
276

277 278 279
	this.update = update;
	this.updateAttribute = updateAttribute;

M
Mr.doob 已提交
280 281 282 283 284 285
	this.clear = function () {

		objects = {};

	};

M
Mr.doob 已提交
286
};