/** * @author mrdoob / http://mrdoob.com/ */ import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute'; import { BufferGeometry } from '../../core/BufferGeometry'; import { arrayMax } from '../../utils'; function WebGLGeometries( gl, attributes, infoMemory ) {//threejs中管理网格对象的方法 var geometries = {}; var wireframeAttributes = {}; function onGeometryDispose( event ) {//删除几何对象的方法 var geometry = event.target; var buffergeometry = geometries[ geometry.id ];//得到当前的buffergeometry对象 if ( buffergeometry.index !== null ) { attributes.remove( buffergeometry.index ); } for ( var name in buffergeometry.attributes ) { attributes.remove( buffergeometry.attributes[ name ] );//删除此对象的缓冲区属性 // (比如顶点坐标缓冲、纹理坐标缓冲、顶点索引等) } geometry.removeEventListener( 'dispose', onGeometryDispose );//移除删除用的监听方法 delete geometries[ geometry.id ];//释放此对象占用的内存 // TODO Remove duplicate code //删除几何体在网格模式下的对象,套路(每一个对象分别有正常模式和网格模式下的数据) var attribute = wireframeAttributes[ geometry.id ]; if ( attribute ) { attributes.remove( attribute ); delete wireframeAttributes[ geometry.id ]; } attribute = wireframeAttributes[ buffergeometry.id ]; if ( attribute ) { attributes.remove( attribute ); delete wireframeAttributes[ buffergeometry.id ]; } // infoMemory.geometries --; } function get( object, geometry ) { var buffergeometry = geometries[ geometry.id ];//得到当前的buffergeometry对象 if ( buffergeometry ) return buffergeometry; geometry.addEventListener( 'dispose', onGeometryDispose );//添加删除几何对象的监听 if ( geometry.isBufferGeometry ) {//geometry分为geometry和BufferGeometry两种类型, // BufferGeometry占用更少的内存,效率更高 buffergeometry = geometry; } else if ( geometry.isGeometry ) { if ( geometry._bufferGeometry === undefined ) {//如果当前对象中 没有BufferGeometry对象 geometry._bufferGeometry = new BufferGeometry().setFromObject( object );//直接从网格对象中进行转换 } buffergeometry = geometry._bufferGeometry; } geometries[ geometry.id ] = buffergeometry; infoMemory.geometries ++; return buffergeometry;//从geometry中获取BufferGeometry } function update( geometry ) { var index = geometry.index; var geometryAttributes = geometry.attributes; if ( index !== null ) { attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );//更新几何对象的索引缓冲 } for ( var name in geometryAttributes ) { attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );//更新几何对象的其他缓冲 } // morph targets var morphAttributes = geometry.morphAttributes;//几何体做变形时的属性 for ( var name in morphAttributes ) { var array = morphAttributes[ name ]; for ( var i = 0, l = array.length; i < l; i ++ ) { attributes.update( array[ i ], gl.ARRAY_BUFFER );//更新几何体做变形时的属性 } } } function getWireframeAttribute( geometry ) {//网格状态下,网格对象的棱角直接使用线段进行绘制(平常模式下是三角形), //所以其索引必须进行适当地变换 var attribute = wireframeAttributes[ geometry.id ]; if ( attribute ) return attribute; var indices = []; var geometryIndex = geometry.index; var geometryAttributes = geometry.attributes; // console.time( 'wireframe' ); if ( geometryIndex !== null ) { var array = geometryIndex.array; for ( var i = 0, l = array.length; i < l; i += 3 ) { var a = array[ i + 0 ]; var b = array[ i + 1 ]; var c = array[ i + 2 ]; indices.push( a, b, b, c, c, a ); } } else { var array = geometryAttributes.position.array; for ( var i = 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' ); attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );//更新其索引值 wireframeAttributes[ geometry.id ] = attribute; return attribute; } return { get: get, update: update, getWireframeAttribute: getWireframeAttribute }; } export { WebGLGeometries };