187 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			187 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import { LightsNode } from '../../nodes/Nodes.js'; | ||
|  | 
 | ||
|  | 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.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; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | class RenderList { | ||
|  | 
 | ||
|  | 	constructor() { | ||
|  | 
 | ||
|  | 		this.renderItems = []; | ||
|  | 		this.renderItemsIndex = 0; | ||
|  | 
 | ||
|  | 		this.opaque = []; | ||
|  | 		this.transparent = []; | ||
|  | 
 | ||
|  | 		this.lightsNode = new LightsNode( [] ); | ||
|  | 		this.lightsArray = []; | ||
|  | 
 | ||
|  | 		this.occlusionQueryCount = 0; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	begin() { | ||
|  | 
 | ||
|  | 		this.renderItemsIndex = 0; | ||
|  | 
 | ||
|  | 		this.opaque.length = 0; | ||
|  | 		this.transparent.length = 0; | ||
|  | 		this.lightsArray.length = 0; | ||
|  | 
 | ||
|  | 		this.occlusionQueryCount = 0; | ||
|  | 
 | ||
|  | 		return this; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	getNextRenderItem( object, geometry, material, groupOrder, z, group ) { | ||
|  | 
 | ||
|  | 		let renderItem = this.renderItems[ this.renderItemsIndex ]; | ||
|  | 
 | ||
|  | 		if ( renderItem === undefined ) { | ||
|  | 
 | ||
|  | 			renderItem = { | ||
|  | 				id: object.id, | ||
|  | 				object: object, | ||
|  | 				geometry: geometry, | ||
|  | 				material: material, | ||
|  | 				groupOrder: groupOrder, | ||
|  | 				renderOrder: object.renderOrder, | ||
|  | 				z: z, | ||
|  | 				group: group | ||
|  | 			}; | ||
|  | 
 | ||
|  | 			this.renderItems[ this.renderItemsIndex ] = renderItem; | ||
|  | 
 | ||
|  | 		} else { | ||
|  | 
 | ||
|  | 			renderItem.id = object.id; | ||
|  | 			renderItem.object = object; | ||
|  | 			renderItem.geometry = geometry; | ||
|  | 			renderItem.material = material; | ||
|  | 			renderItem.groupOrder = groupOrder; | ||
|  | 			renderItem.renderOrder = object.renderOrder; | ||
|  | 			renderItem.z = z; | ||
|  | 			renderItem.group = group; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		this.renderItemsIndex ++; | ||
|  | 
 | ||
|  | 		return renderItem; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	push( object, geometry, material, groupOrder, z, group ) { | ||
|  | 
 | ||
|  | 		const renderItem = this.getNextRenderItem( object, geometry, material, groupOrder, z, group ); | ||
|  | 
 | ||
|  | 		if ( object.occlusionTest === true ) this.occlusionQueryCount ++; | ||
|  | 
 | ||
|  | 		( material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque ).push( renderItem ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	unshift( object, geometry, material, groupOrder, z, group ) { | ||
|  | 
 | ||
|  | 		const renderItem = this.getNextRenderItem( object, geometry, material, groupOrder, z, group ); | ||
|  | 
 | ||
|  | 		( material.transparent === true ? this.transparent : this.opaque ).unshift( renderItem ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	pushLight( light ) { | ||
|  | 
 | ||
|  | 		this.lightsArray.push( light ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	getLightsNode() { | ||
|  | 
 | ||
|  | 		return this.lightsNode.fromLights( this.lightsArray ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	sort( customOpaqueSort, customTransparentSort ) { | ||
|  | 
 | ||
|  | 		if ( this.opaque.length > 1 ) this.opaque.sort( customOpaqueSort || painterSortStable ); | ||
|  | 		if ( this.transparent.length > 1 ) this.transparent.sort( customTransparentSort || reversePainterSortStable ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	finish() { | ||
|  | 
 | ||
|  | 		// update lights
 | ||
|  | 
 | ||
|  | 		this.lightsNode.fromLights( this.lightsArray ); | ||
|  | 
 | ||
|  | 		// Clear references from inactive renderItems in the list
 | ||
|  | 
 | ||
|  | 		for ( let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i ++ ) { | ||
|  | 
 | ||
|  | 			const renderItem = this.renderItems[ i ]; | ||
|  | 
 | ||
|  | 			if ( renderItem.id === null ) break; | ||
|  | 
 | ||
|  | 			renderItem.id = null; | ||
|  | 			renderItem.object = null; | ||
|  | 			renderItem.geometry = null; | ||
|  | 			renderItem.material = null; | ||
|  | 			renderItem.groupOrder = null; | ||
|  | 			renderItem.renderOrder = null; | ||
|  | 			renderItem.z = null; | ||
|  | 			renderItem.group = null; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default RenderList; |