| |
| |
| |
|
|
| function painterSortStable( a, b ) { |
|
|
| if ( a.groupOrder !== b.groupOrder ) { |
|
|
| return a.groupOrder - b.groupOrder; |
|
|
| } else if ( a.renderOrder !== b.renderOrder ) { |
|
|
| return a.renderOrder - b.renderOrder; |
|
|
| } else if ( a.program !== b.program ) { |
|
|
| return a.program.id - b.program.id; |
|
|
| } else if ( a.material.id !== b.material.id ) { |
|
|
| return a.material.id - b.material.id; |
|
|
| } else if ( a.z !== b.z ) { |
|
|
| return a.z - b.z; |
|
|
| } else { |
|
|
| return a.id - b.id; |
|
|
| } |
|
|
| } |
|
|
| function reversePainterSortStable( a, b ) { |
|
|
| if ( a.groupOrder !== b.groupOrder ) { |
|
|
| return a.groupOrder - b.groupOrder; |
|
|
| } else if ( a.renderOrder !== b.renderOrder ) { |
|
|
| return a.renderOrder - b.renderOrder; |
|
|
| } else if ( a.z !== b.z ) { |
|
|
| return b.z - a.z; |
|
|
| } else { |
|
|
| return a.id - b.id; |
|
|
| } |
|
|
| } |
|
|
|
|
| function WebGLRenderList() { |
|
|
| var renderItems = []; |
| var renderItemsIndex = 0; |
|
|
| var opaque = []; |
| var transparent = []; |
|
|
| var defaultProgram = { id: - 1 }; |
|
|
| function init() { |
|
|
| renderItemsIndex = 0; |
|
|
| opaque.length = 0; |
| transparent.length = 0; |
|
|
| } |
|
|
| function getNextRenderItem( object, geometry, material, groupOrder, z, group ) { |
|
|
| var renderItem = renderItems[ renderItemsIndex ]; |
|
|
| if ( renderItem === undefined ) { |
|
|
| renderItem = { |
| id: object.id, |
| object: object, |
| geometry: geometry, |
| material: material, |
| program: material.program || defaultProgram, |
| groupOrder: groupOrder, |
| renderOrder: object.renderOrder, |
| z: z, |
| group: group |
| }; |
|
|
| renderItems[ renderItemsIndex ] = renderItem; |
|
|
| } else { |
|
|
| renderItem.id = object.id; |
| renderItem.object = object; |
| renderItem.geometry = geometry; |
| renderItem.material = material; |
| renderItem.program = material.program || defaultProgram; |
| renderItem.groupOrder = groupOrder; |
| renderItem.renderOrder = object.renderOrder; |
| renderItem.z = z; |
| renderItem.group = group; |
|
|
| } |
|
|
| renderItemsIndex ++; |
|
|
| return renderItem; |
|
|
| } |
|
|
| function push( object, geometry, material, groupOrder, z, group ) { |
|
|
| var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); |
|
|
| ( material.transparent === true ? transparent : opaque ).push( renderItem ); |
|
|
| } |
|
|
| function unshift( object, geometry, material, groupOrder, z, group ) { |
|
|
| var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); |
|
|
| ( material.transparent === true ? transparent : opaque ).unshift( renderItem ); |
|
|
| } |
|
|
| function sort() { |
|
|
| if ( opaque.length > 1 ) opaque.sort( painterSortStable ); |
| if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); |
|
|
| } |
|
|
| return { |
| opaque: opaque, |
| transparent: transparent, |
|
|
| init: init, |
| push: push, |
| unshift: unshift, |
|
|
| sort: sort |
| }; |
|
|
| } |
|
|
| function WebGLRenderLists() { |
|
|
| var lists = {}; |
|
|
| function onSceneDispose( event ) { |
|
|
| var scene = event.target; |
|
|
| scene.removeEventListener( 'dispose', onSceneDispose ); |
|
|
| delete lists[ scene.id ]; |
|
|
| } |
|
|
| function get( scene, camera ) { |
|
|
| var cameras = lists[ scene.id ]; |
| var list; |
| if ( cameras === undefined ) { |
|
|
| list = new WebGLRenderList(); |
| lists[ scene.id ] = {}; |
| lists[ scene.id ][ camera.id ] = list; |
|
|
| scene.addEventListener( 'dispose', onSceneDispose ); |
|
|
| } else { |
|
|
| list = cameras[ camera.id ]; |
| if ( list === undefined ) { |
|
|
| list = new WebGLRenderList(); |
| cameras[ camera.id ] = list; |
|
|
| } |
|
|
| } |
|
|
| return list; |
|
|
| } |
|
|
| function dispose() { |
|
|
| lists = {}; |
|
|
| } |
|
|
| return { |
| get: get, |
| dispose: dispose |
| }; |
|
|
| } |
|
|
|
|
| export { WebGLRenderLists }; |
|
|