import Kernel from './Kernel' ; import { Drawable , Pickable , PickListener } from './Definitions.d' ; import Camera from './Camera' ; import Line from './math/Line' ; class GraphicGroup < T extends Drawable > implements Drawable { id : number ; parent : GraphicGroup < T > ; children : T [ ] ; visible : boolean = true ; constructor ( ) { this . id = ++ Kernel . idCounter ; this . children = [ ] ; } add ( g , first = false ) { if ( first ) { this . children . unshift ( g ) ; } else { this . children . push ( g ) ; } g . parent = this ; } remove ( g ) { const index = this . findChildIndex ( g ) ; if ( index >= 0 ) { this . children . splice ( index , 1 ) ; return true ; } return false ; } clear ( ) { var i = 0 , length = this . children . length , g = null ; for ( ; i < length ; i ++ ) { g = this . children [ i ] ; g . destroy ( ) ; } this . children = [ ] ; } destroy ( ) { this . parent = null ; this . clear ( ) ; } findChildIndex ( child ) { const count = this . children . length ; for ( let i = 0 ; i < count ; i ++ ) { const g = this . children [ i ] ; if ( child === g ) { return i ; } } return - 1 ; } findChildById ( graphicId ) { var i = 0 , length = this . children . length , g = null ; for ( ; i < length ; i ++ ) { g = this . children [ i ] ; if ( g . id === graphicId ) { return { index : i , graphic : g } ; } } return null ; } shouldDraw ( ) { return this . visible && this . children . length > 0 ; } moveChildToLastPosition ( child ) { const index = this . findChildIndex ( child ) ; this . children . splice ( index , 1 ) ; this . children . push ( child ) ; } draw ( camera ) { if ( this . shouldDraw ( ) ) { this . onBeforeDraw ( ) ; this . onDraw ( camera ) ; this . onAfterDraw ( ) ; } } protected onBeforeDraw ( ) { } protected onDraw ( camera ) { this . children . forEach ( function ( g ) { if ( g . shouldDraw ( camera ) ) { g . draw ( camera ) ; } } ) ; } protected onAfterDraw ( ) { } } ; export class PickableGraphicGroup < T extends Drawable & Pickable > extends GraphicGroup < T > { private pickListener : PickListener = null ; pickByLocalLine ( localLine , emitListener = false ) { const count = this . children . length ; for ( let i = count - 1 ; i >= 0 ; i -- ) { const child = this . children [ i ] ; if ( child . ifIntersectLocalLine ( localLine ) ) { if ( emitListener ) { this . onPick ( child ) ; } return child ; } } return null ; } pickByWorldLine ( worldLine , emitListener = false ) { const count = this . children . length ; for ( let i = count - 1 ; i >= 0 ; i -- ) { const child = this . children [ i ] ; if ( child . ifIntersectWorldLine ( worldLine ) ) { if ( emitListener ) { this . onPick ( child ) ; } return child ; } } return null ; } private onPick ( target ) { this . moveChildToLastPosition ( target ) ; if ( this . pickListener ) { this . pickListener ( target ) ; } } hasPickListener ( ) { return ! ! this . pickListener ; } setPickListener ( listener ) { this . pickListener = listener ; } } export default GraphicGroup ;