158 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Factor
		
	
	
| ! Copyright (C) 2008 Eduardo Cavazos.
 | |
| ! Copyright (C) 2011 Anton Gorenko.
 | |
| ! See http://factorcode.org/license.txt for BSD license.
 | |
| USING: accessors arrays boids.simulation calendar classes kernel
 | |
| literals locals math math.functions math.trig models opengl
 | |
| opengl.demo-support opengl.gl sequences threads ui ui.gadgets
 | |
| ui.gadgets.borders ui.gadgets.buttons ui.gadgets.frames
 | |
| ui.gadgets.grids ui.gadgets.labeled ui.gadgets.labels
 | |
| ui.gadgets.packs ui.gadgets.sliders ui.render ;
 | |
| QUALIFIED-WITH: models.range mr
 | |
| IN: boids
 | |
| 
 | |
| TUPLE: boids-gadget < gadget paused boids behaviours dt ;
 | |
| 
 | |
| CONSTANT: initial-population 100
 | |
| CONSTANT: initial-dt 5
 | |
| 
 | |
| : initial-behaviours ( -- seq )
 | |
|     1.0 75 -0.1 <cohesion>
 | |
|     1.0 40 -0.5 <alignment>
 | |
|     1.0 25 -1.0 <separation>
 | |
|     3array ;
 | |
| 
 | |
| : <boids-gadget> ( -- gadget )
 | |
|     boids-gadget new
 | |
|         t >>clipped?
 | |
|         ${ width height } >>pref-dim
 | |
|         initial-population random-boids >>boids
 | |
|         initial-behaviours >>behaviours
 | |
|         initial-dt >>dt ;
 | |
| 
 | |
| M:  boids-gadget ungraft*
 | |
|     t >>paused drop ;
 | |
| 
 | |
| : vec>deg ( vec -- deg )
 | |
|     first2 rect> arg rad>deg ; inline
 | |
| 
 | |
| : draw-boid ( boid -- )
 | |
|     dup pos>> [
 | |
|         vel>> vec>deg 0 0 1 glRotated
 | |
|         GL_TRIANGLES [
 | |
|             -6.0  4.0 glVertex2f
 | |
|             -6.0 -4.0 glVertex2f
 | |
|             8.0 0.0 glVertex2f
 | |
|          ] do-state
 | |
|     ] with-translation ;
 | |
| 
 | |
| : draw-boids ( boids -- )
 | |
|     0.0 0.0 0.0 0.5 glColor4f
 | |
|     [ draw-boid ] each ;
 | |
| 
 | |
| M: boids-gadget draw-gadget* ( boids-gadget -- )
 | |
|     boids>> draw-boids ;
 | |
| 
 | |
| : iterate-system ( boids-gadget -- )
 | |
|     dup [ boids>> ] [ behaviours>> ] [ dt>> ] tri
 | |
|     simulate >>boids drop ;
 | |
| 
 | |
| :: start-boids-thread ( gadget -- )
 | |
|     [
 | |
|         [ gadget paused>> ]
 | |
|         [
 | |
|             gadget iterate-system
 | |
|             gadget relayout-1
 | |
|             10 milliseconds sleep
 | |
|         ] until
 | |
|     ] in-thread ;
 | |
| 
 | |
| TUPLE: range-observer quot ;
 | |
| 
 | |
| M: range-observer model-changed
 | |
|     [ range-value ] dip quot>> call( value -- ) ;
 | |
| 
 | |
| : connect ( range-model quot -- )
 | |
|     range-observer boa swap add-connection ;
 | |
| 
 | |
| :: behavior-panel ( behavior -- gadget )
 | |
|     2 3 <frame> { 2 4 } >>gap { 0 0 } >>filled-cell
 | |
| 
 | |
|     "weight" <label> { 0 0 } grid-add
 | |
|     behavior weight>> 100 * >fixnum 0 0 200 1 mr:<range>
 | |
|     dup [ 100.0 / behavior weight<< ] connect
 | |
|     horizontal <slider> { 1 0 } grid-add
 | |
| 
 | |
|     "radius" <label> { 0 1 } grid-add
 | |
|     behavior radius>> 0 0 100 1 mr:<range>
 | |
|     dup [ behavior radius<< ] connect
 | |
|     horizontal <slider> { 1 1 } grid-add
 | |
| 
 | |
|     "angle" <label> { 0 2 } grid-add
 | |
|     behavior angle-cos>> acos rad>deg >fixnum 0 0 180 1 mr:<range>
 | |
|     dup [ deg>rad cos behavior angle-cos<< ] connect
 | |
|     horizontal <slider> { 1 2 } grid-add
 | |
| 
 | |
|     behavior class-of name>> <labeled-gadget> ;
 | |
| 
 | |
| :: set-population ( n boids-gadget -- )
 | |
|     boids-gadget [
 | |
|         dup length n - dup 0 >
 | |
|         [ head* ]
 | |
|         [ neg random-boids append ] if
 | |
|     ] change-boids drop ;
 | |
| 
 | |
| : pause-toggle ( boids-gadget -- )
 | |
|     dup paused>> not [ >>paused ] keep
 | |
|     [ drop ] [ start-boids-thread ] if ;
 | |
| 
 | |
| : randomize-boids ( boids-gadget -- )
 | |
|     [ length random-boids ] change-boids drop ;
 | |
| 
 | |
| :: simulation-panel ( boids-gadget -- gadget )
 | |
|     <pile> { 2 2 } >>gap
 | |
| 
 | |
|     2 2 <frame> { 4 4 } >>gap { 0 0 } >>filled-cell
 | |
| 
 | |
|     "population" <label> { 0 0 } grid-add
 | |
|     initial-population 0 0 200 10 mr:<range>
 | |
|     dup [ boids-gadget set-population ] connect
 | |
|     horizontal <slider> { 1 0 } grid-add
 | |
| 
 | |
|     "speed" <label> { 0 1 } grid-add
 | |
|     boids-gadget dt>> 0 1 10 1 mr:<range>
 | |
|     dup [ boids-gadget dt<< ] connect
 | |
|     horizontal <slider> { 1 1 } grid-add
 | |
| 
 | |
|     add-gadget
 | |
| 
 | |
|     <shelf> { 2 2 } >>gap
 | |
|     "pause" [ drop boids-gadget pause-toggle ]
 | |
|     <border-button> add-gadget
 | |
|     "randomize" [ drop boids-gadget randomize-boids ]
 | |
|     <border-button> add-gadget
 | |
| 
 | |
|     add-gadget
 | |
| 
 | |
|     "simulation" <labeled-gadget> ;
 | |
| 
 | |
| :: create-gadgets ( -- gadgets )
 | |
|     <shelf>
 | |
|     <boids-gadget> :> boids-gadget
 | |
|     boids-gadget [ start-boids-thread ] keep
 | |
|     add-gadget
 | |
| 
 | |
|     <pile> { 2 2 } >>gap 1.0 >>fill
 | |
| 
 | |
|     boids-gadget simulation-panel
 | |
|     add-gadget
 | |
| 
 | |
|     boids-gadget behaviours>>
 | |
|     [ behavior-panel add-gadget ] each
 | |
| 
 | |
|     add-gadget
 | |
|     { 2 2 } <border> ;
 | |
| 
 | |
| MAIN-WINDOW: boids { { title "Boids" } }
 | |
|     create-gadgets
 | |
|     >>gadgets ;
 |