diff --git a/BloubWorld/.gitignore b/BloubWorld/.gitignore index bd50a48..724e152 100644 --- a/BloubWorld/.gitignore +++ b/BloubWorld/.gitignore @@ -13,6 +13,7 @@ exportbloubs genbloubs movebloubs mergebloubs +listbloubs essai core diff --git a/BloubWorld/Makefile b/BloubWorld/Makefile index bfc8204..03a4d92 100644 --- a/BloubWorld/Makefile +++ b/BloubWorld/Makefile @@ -1,6 +1,7 @@ all: genbloubs movebloubs exportbloubs mergebloubs \ + listbloubs \ essai # ------------------------------------------------------------ @@ -10,8 +11,8 @@ OBJS = bloubspace.o povstuff.o mathstuff.o # ------------------------------------------------------------ -essai: essai.f90 Makefile mathstuff.o - gfortran $(GFOPT) $< mathstuff.o -o $@ +essai: essai.f90 Makefile $(OBJS) + gfortran $(GFOPT) $< $(OBJS) -o $@ # ------------------------------------------------------------ @@ -46,6 +47,9 @@ genbloubs: genbloubs.f90 Makefile $(OBJS) movebloubs: movebloubs.f90 Makefile $(OBJS) gfortran $(GFOPT) $< $(OBJS) -o $@ +listbloubs: listbloubs.f90 Makefile $(OBJS) + gfortran $(GFOPT) $< $(OBJS) -o $@ + exportbloubs: exportbloubs.f90 Makefile $(OBJS) gfortran $(GFOPT) $< $(OBJS) -o $@ diff --git a/BloubWorld/README.md b/BloubWorld/README.md index 1f0b406..d840abe 100644 --- a/BloubWorld/README.md +++ b/BloubWorld/README.md @@ -6,15 +6,17 @@ Le BloubWorld (que l'on appelle aussi BloubSpace) est un espace borné dans lequel se déplacent des **bloubs**, lesquels sont des sortes de particule munie de certaines propriétés (age, grosseur, vitesses, etc...). -Lesquelles évoluent en fonction du temps. +Lesquelles valeurs peuvent évoluer en fonction du temps. ## Description d'un bloub +Attention cette description n'est qu'un exemple ! + ``` type t_bloubs character(8) :: nick logical :: alive - integer :: num + integer :: state real :: px, py, pz real :: vx, vy, vz real :: radius @@ -67,14 +69,18 @@ Sortie sur `stdout` de certaines propriétes des bloubs, qui seront reprise par un (ou des) scripts écrits en `awk`, afin de générer ce qu'il faut pour les différents moteurs de rendu. -Bon, pour le moment, il n'y a que POVray :) +Bon, pour le moment, il n'y a que POVray, mais Gnuplot arrivera en second. ### mergebloubs -Alors, celui-ci, il n'est pas vraiment au point. +Alors, celui-ci, il n'est pas vraiment au point. Il faut tout ré-écrire +et faire gaffe à l'explosion quadratique. ## TODO - Concevoir un système de _bouding box_ facile à utiliser - Réfléchir à une politique de vieillissement des bloubs +- le `merge` de deux bloubs est-il un acte politique ? + + diff --git a/BloubWorld/WS/boundinboxes.dat b/BloubWorld/WS/boundinboxes.dat new file mode 100644 index 0000000..512b626 --- /dev/null +++ b/BloubWorld/WS/boundinboxes.dat @@ -0,0 +1 @@ +cube -0.35 -0.5 -0.5 5.0 5.0 5.0 \ No newline at end of file diff --git a/BloubWorld/bloubspace.f90 b/BloubWorld/bloubspace.f90 index 2132c89..135c1a6 100644 --- a/BloubWorld/bloubspace.f90 +++ b/BloubWorld/bloubspace.f90 @@ -11,35 +11,139 @@ module bloubspace type t_bloubs character(8) :: nick logical :: alive + integer :: state integer :: num ! ??? real :: px, py, pz real :: vx, vy, vz real :: radius - integer :: age + integer :: age, agemax end type t_bloubs + type t_boundingbox + character(8) :: id + real :: xm, ym, zm + real :: xp, yp, zp + end type t_boundingbox + contains ! ----------------------------------------- + ! ---------------------------------------------------------------- + + subroutine load_boundingbox(infile, where, name) + character(*), intent(in) :: infile + type(t_boundingbox), intent (out) :: where + character(8), intent(in) :: name + + integer :: fd, errcode + character(200) :: message + + print *, "try to load ", infile + + ! put some default values + where%id = "default" + where%xm = -5.0 ; where%ym = -5.0 ; where%zm = -5.0 + where%xp = 5.0 ; where%yp = 5.0 ; where%zp = 5.0 + + ! and now, try to read the file + open (newunit=fd, file=trim(infile), & + status='old', action='read', & + iostat=errcode, iomsg=message) + if (errcode .NE. 0) then + stop 'OPEN ERROR ' // message + endif + + do + read(unit=fd, iostat=errcode, iomsg=message, & + fmt='(A,6F8.3)') where + if (errcode .NE. 0) then + ! print *, "errcode ", errcode + print *, "message: ", message + exit + endif + enddo + + close(fd) + + end subroutine load_boundingbox + + ! ---------------------------------------------------------------- + subroutine random_pv (blb) - type(t_bloubs), intent (inout) :: blb + type(t_bloubs), intent (out) :: blb - blb%px = 1.35 * (rand() - 0.50) - blb%py = 0.50 + (rand() * 0.50) - blb%pz = 1.90 * (rand() - 0.50) + blb%px = 4.33 * (rand() - 0.50) + blb%py = 3.33 * (rand() - 0.50) + blb%pz = 4.51 * (rand() - 0.50) - blb%vx = (rand() - 0.5) / 2.500 - blb%vy = (rand() - 0.1) / 4.000 - blb%vz = (rand() - 0.5) / 2.500 + blb%vx = (rand()) / 2.000 + blb%vy = (rand()) / 2.900 + blb%vz = (rand()) / 2.000 - blb%alive = .TRUE. + blb%state = 0 + blb%alive = .TRUE. + blb%age = 0 + blb%agemax = 500 end subroutine ! ---------------------------------------------------------------- ! Load a blbs file into an array of bloubs + subroutine spit_bloubs_to_file (fname, blbarray, towrite) + character(*), intent(in) :: fname + type(t_bloubs), dimension(:) :: blbarray + integer, intent(in) :: towrite + + write (0, '(" spiting", (I6), "bloubs to", (A), "file")') & + towrite, trim(fname) + + STOP ' : NOT IMPLEMENTED' + + end subroutine ! ---------------------------------------------------------------- ! Dump an array of bloubs to a blbs file. + ! + subroutine slurp_bloubs_file_in_array (infile, blbarray, nbread) + character(*), intent(in) :: infile + type(t_bloubs), dimension(:), intent(out) :: blbarray + integer, intent(out) :: nbread + character(200) :: chaine + integer :: input, errcode, idx + type(t_bloubs) :: bloub + + write(0, '(" slurping from file [", (A), "]")') trim(infile) + + open( newunit=input, & + file=trim(infile), form='unformatted', & + iostat=errcode, iomsg=chaine, & + action='read', status='old') + if (0 .ne. errcode) then + write(0, '(" errcode ", I8, 2X, A)') errcode, chaine + STOP " : CAN'T OPEN FILE " // trim(infile) + endif + ! write(0, '((A, I3))') " slurping from unit ", input + + nbread = 0 + idx = 1; + do + read (unit=input, iostat=errcode, iomsg=chaine) bloub + if (0 .ne. errcode) then + ! may be we got an EOF ? + ! write(0, '(" got errcode on read ", (I8,1X,A))') errcode, chaine + exit + endif + nbread = nbread + 1 + ! print *, bloub%nick, bloub%radius + if (bloub%alive) then + blbarray(idx) = bloub + idx = idx + 1 + endif + enddo + + close(input) ! no error checking ? + + write(0, '(" read ", (I8), " bloubs")') nbread + end subroutine ! ---------------------------------------------------------------- ! Display a bloub content to stderr @@ -52,7 +156,7 @@ module bloubspace if (blb%alive) then life = "alive" else - life = "dead" + life = "dead " endif write (0, '(4X, A)') '+--------------- ' // message // " -------" write (0, '(4X,A3,A8,2X,I6,4X,A5,4X,I5)') '| ', & @@ -76,37 +180,42 @@ module bloubspace end subroutine ! ---------------------------------------------------------------- + ! + ! detection des collisions avec les parois de la boite + ! laquelle boite gagnerais beaucoup a etre parametrable. + ! subroutine bound_a_blob (blb) type(t_bloubs), intent (inout) :: blb - if (5.0 .lt. blb%px) then + if ( 5.0 .lt. (blb%px + blb%radius)) then blb%vx = -1.0 * blb%vx blb%px = 5.0 blb%age = blb%age + 1 endif - if (-5.0 .gt. blb%px) then + if (-5.0 .gt. (blb%px + blb%radius)) then blb%vx = -1.0 * blb%vx blb%px = -5.0 blb%age = blb%age + 1 endif - if (0.0 .gt. blb%py) then + ! vertical axe + if (-4.99 .gt. (blb%py + blb%radius)) then blb%vy = -1.0 * blb%vy - blb%py = 0.0 + blb%py = blb%radius blb%age = blb%age + 1 endif - if (4.99 .lt. blb%py) then !! + if ( 4.99 .lt. (blb%py + blb%radius)) then ! overshoot ? blb%vy = -1.0 * blb%vy blb%age = blb%age + 1 - blb%py = 4.99 !! + blb%py = 5.0 - blb%radius !! endif - if (5.0 .lt. blb%pz) then + if ( 5.0 .lt. (blb%pz + blb%radius)) then blb%vz = -1.0 * blb%vz blb%age = blb%age + 1 blb%pz = 5.0 endif - if (-5.0 .gt. blb%pz) then + if (-5.0 .gt. (blb%pz + blb%radius)) then blb%vz = -1.0 * blb%vz blb%age = blb%age + 1 blb%pz = -5.0 @@ -134,7 +243,14 @@ module bloubspace subroutine green_soylent (blb) type(t_bloubs), intent (inout) :: blb - if (blb%age .gt. 8) then + + if (blb%age .gt. 18) then + blb%alive = .FALSE. + endif + + ! this is juste a molly-guard, don't worry + ! + if (blb%radius .GT. 2.0) then blb%alive = .FALSE. endif end subroutine diff --git a/BloubWorld/essai.f90 b/BloubWorld/essai.f90 index da7bd89..9eee578 100644 --- a/BloubWorld/essai.f90 +++ b/BloubWorld/essai.f90 @@ -1,19 +1,39 @@ program essai + use bloubspace use mathstuff implicit none - integer :: foo + type(t_boundingbox) :: bbox + + call load_boundingbox("WS/boundinboxes.dat", bbox, "cube ") + + print *, bbox + + + ! call test_random(20) + + + STOP ': BECAUSE JOB IS DONE' + +! -------------------------------------------------------------- + contains + +subroutine test_random(nbre) + integer, intent(in) :: nbre + integer :: foo, bar real :: quux double precision :: somme - call init_random_seed() + call init_random_seed() ! in module 'mathstuff' somme = 0.0 - - do foo=1, 5 + do foo=1, nbre quux = rand() somme = somme + quux - print *, foo, quux, somme/foo + bar = mod(irand(), 7) + print *, foo, quux, somme/foo, bar enddo +end subroutine test_random +! -------------------------------------------------------------- -end program \ No newline at end of file +end program diff --git a/BloubWorld/genbloubs.f90 b/BloubWorld/genbloubs.f90 index 459fab4..335de8f 100644 --- a/BloubWorld/genbloubs.f90 +++ b/BloubWorld/genbloubs.f90 @@ -18,22 +18,20 @@ program genbloubs call getarg(2, str) read(str,*) nbbloubs - write (0, '(A,I6,A)') & + write (0, '(A,I8,A)') & "*** generating ", nbbloubs, " bloubs to "//trim(filename) - ! print *, "generating ", nbbloubs, "bloubs to ", filename - - open(newunit=idu, file=trim(filename), form='unformatted', & + open(newunit=idu, file=trim(filename), & + form='unformatted', & + access="sequential", & action='write', status='replace') do i = 1, nbbloubs bloub%nick = 'noname ' bloub%num = i + 41 - bloub%alive = .TRUE. call random_pv(bloub) - bloub%radius = 0.025 - bloub%age = 0 + bloub%radius = 0.035 + (0.03*rand()) write(idu) bloub ! no error control ? diff --git a/BloubWorld/listbloubs.f90 b/BloubWorld/listbloubs.f90 new file mode 100644 index 0000000..ac6bf87 --- /dev/null +++ b/BloubWorld/listbloubs.f90 @@ -0,0 +1,45 @@ +program movebloubs + + use bloubspace + implicit none + + integer, parameter :: NB_MAX_BLOUBS = 200000 + +! -------------------------------------------------------------- + character(200) :: infile + integer :: errcode, i + integer :: nbgot + type(t_bloubs), dimension(:), allocatable :: bloubs + + i = IARGC() + if (i .ne. 1) then + STOP ": BAD ARG ON COMMAND LINE" + endif + call getarg(1, infile) + + write (0, '(A)') & + "*** listing bloubs from "//trim(infile) + + allocate (bloubs(NB_MAX_BLOUBS), stat=errcode) + if (0 .NE. errcode) then + STOP " : NO ENOUGH MEMORY" + endif + do i = 1, NB_MAX_BLOUBS + bloubs(i)%alive = .FALSE. + enddo + + call slurp_bloubs_file_in_array(trim(infile), bloubs, nbgot) + write(0, '(A,I6,1X,A)') "slurped ", nbgot, "bloubs" + + do i=1,nbgot + write(6, '(A8, 1X, 1L, 1X, I2, 3X, F8.3, 3X, 3F8.3, 3X, 3F8.3)') & + bloubs(i)%nick, bloubs(i)%alive, & + bloubs(i)%state, & + bloubs(i)%radius, & + bloubs(i)%px, bloubs(i)%py, bloubs(i)%pz, & + bloubs(i)%vx, bloubs(i)%vy, bloubs(i)%vz + enddo + +end program + +! \o_ \ No newline at end of file diff --git a/BloubWorld/mathstuff.f90 b/BloubWorld/mathstuff.f90 index 67d49c6..a6edafd 100644 --- a/BloubWorld/mathstuff.f90 +++ b/BloubWorld/mathstuff.f90 @@ -5,21 +5,23 @@ module mathstuff ! ---------------------------------------------------------------- ! really quick'n'dirty hack - ! not working yet... + ! not really tested yet... subroutine init_random_seed() integer, dimension(3) :: tarray - integer :: t3 + integer :: t3, foo real :: dummy call itime(tarray) t3 = 3600*tarray(1) + 60*tarray(2) + tarray(3) - write(0, '(A,3I3,A,I6)') "sranding: ", tarray, " --> ", t3 + ! write(0, '(A,3I3,A,I6)') "sranding: ", tarray, " --> ", t3 call srand(t3) ! after initializing the random generator engine, ! you MUST use it for initializing the initializer - dummy = rand() + do foo=1, tarray(1)+5 + dummy = rand() + enddo end subroutine diff --git a/BloubWorld/movebloubs.f90 b/BloubWorld/movebloubs.f90 index 4021b4a..adf2810 100644 --- a/BloubWorld/movebloubs.f90 +++ b/BloubWorld/movebloubs.f90 @@ -42,6 +42,8 @@ program movebloubs STOP " : CAN'T OPEN " // trim(outfile) // "FOR WRITE" endif + ! write(0, '("Units: ", 2I5)') inu, outu + bx = 0.0; by = 0.0; bz = 0.0 compteur = 0 killed = 0 @@ -53,18 +55,20 @@ program movebloubs exit endif - ! moving and boundingboxing - call move_bloub (bloub, 0.14) + ! moving, morphing and boundingboxing + call move_bloub (bloub, 0.185) call bound_a_blob (bloub) - if (bloub%radius .GT. 0.052) then - bloub%radius = bloub%radius * 0.985 + if (bloub%radius .GT. 0.0151) then + bloub%radius = bloub%radius * 0.9970 endif + call green_soylent (bloub) if (.NOT. bloub%alive) then ! write(0, '(A)') " KILL!" killed = killed + 1 - cycle + ! cycle ! ??? endif + ! calcul du barycentre bx = bx + dble(bloub%px) by = by + dble(bloub%py) @@ -83,11 +87,11 @@ program movebloubs ! ok, we have read all the bloubs in the input file ! insert some fancy conditional here - if (compteur .LT. 1600) then + if (compteur .LT. 3000) then rnd = rand() - write (0, '(A,1X,F5.3)') "try to add bloubs, rnd is", rnd - if (rnd .LT. 0.02) then - call add_more_bloubs(outu, 12, 0.210) + write (0, '(A,1X,F9.6)') "try to add bloubs, rnd is", rnd + if (rnd .LT. 0.0450) then + call add_more_bloubs(outu, 24, 0.0990) endif endif @@ -105,22 +109,23 @@ program movebloubs ! -------------------------------------------------------------- contains - subroutine add_more_bloubs(un, nbre, wtf) + subroutine add_more_bloubs(un, nbre, rayon) integer, intent(in) :: un, nbre - real, intent(in) :: wtf + real, intent(in) :: rayon type(t_bloubs) :: bloub - integer :: foo + integer :: foo, count - write(0, '(A,I4,1X,A)') "adding", nbre, "bloubs" + count = nbre+mod(irand(), 7) + write(0, '(A,I4,1X,A)') "adding", count, "bloubs" - do foo=1, nbre + do foo=1, count bloub%nick = 'newbie ' call random_pv(bloub) - bloub%radius = wtf + bloub%radius = rayon + (0.15*rand()) bloub%age = 1 bloub%alive = .TRUE. - ! call display_bloub (bloub, "new bloub") + bloub%num = mod(irand(), 42) write(un) bloub ! no error control ? enddo diff --git a/BloubWorld/runme.sh b/BloubWorld/runme.sh index e3ec7ef..6250cca 100755 --- a/BloubWorld/runme.sh +++ b/BloubWorld/runme.sh @@ -7,15 +7,15 @@ INCFILE="WS/bloubs.inc" TMPPNG="/dev/shm/bloubs7.png" -POVOPT="+Q9 +a -v -d -W1024 -H768 -WT2" -DDIR="frames" +POVOPT="+Q9 +a -v -d -W1600 -H1200 -WT2" +DDIR="frames/a" LOGERR="log.error" # --- put the work file in ramdisk BLBS_IN="/dev/shm/in.blbs" BLBS_OUT="/dev/shm/out.blbs" -NBIMG=1800 +NBIMG=3000 make all err=$? @@ -30,9 +30,9 @@ printf "\n#declare NbImg = %d;\n" $NBIMG > WS/nbimg.inc # first, we have to make a seminal buch of bloubs # --> this function need to be parametrizable # -./genbloubs ${BLBS_IN} 15 +./genbloubs ${BLBS_IN} 3000 -for idx in $(seq 0 $NBIMG) +for idx in $(seq 0 $((NBIMG-1)) ) do echo "======== run passe $idx =========" @@ -43,45 +43,41 @@ do if [ 0 -ne $? ] ; then tail -15 $LOGERR sleep 30 - else - grep "Trace Time" $LOGERR fi td=$(date +'%F %R:%S') hi=$(printf "#%05d" $idx) - count=$(head -1 "WS/log.nb_bloubs") + count=$(tail -1 "WS/log.nb_bloubs") PNG=$(printf "%s/%05d.png" ${DDIR} $idx) convert ${TMPPNG} \ -font Courier-Bold \ - -pointsize 16 \ - -fill Orange \ - -gravity south-east \ - -annotate +15+10 "$td" \ - -gravity south-west \ - -annotate +15+10 "$hi" \ + -pointsize 24 \ -fill Yellow \ - -pointsize 32 \ + -gravity south-east \ + -annotate +25+5 "$td" \ + -gravity south-west \ + -annotate +25+5 "$hi" \ + -fill Yellow \ + -pointsize 48 \ -gravity north-east \ - -annotate +15+10 "$count" \ + -annotate +25+5 "$count" \ + -gravity north-west \ + -annotate +25+5 "BloubWorld" \ $PNG echo $PNG '[done]' ./movebloubs ${BLBS_IN} ${BLBS_OUT} + # ./mergebloubs ${BLBS_OUT} ${BLBS_IN} mv ${BLBS_OUT} ${BLBS_IN} echo - sleep 15 - done rm $LOGERR -# XXX convert -delay 10 -resize 50% -colors 192 \ -# XXX $DDIR/????[0]*.png foo.gif - nice ./encode.sh diff --git a/BloubWorld/scene.pov b/BloubWorld/scene.pov index 47a4e91..fd5ecfa 100644 --- a/BloubWorld/scene.pov +++ b/BloubWorld/scene.pov @@ -11,6 +11,8 @@ global_settings { #include "colors.inc" + + #include "WS/nbimg.inc" #declare NormClock = clock / NbImg; @@ -31,15 +33,15 @@ object { object { union { - plane { <1, 0, 0>, -23 } - plane { <1, 0, 0>, 23 } + plane { <1, 0, 0>, -32 } + plane { <1, 0, 0>, 32 } plane { <0, 1, 0>, -23 } plane { <0, 1, 0>, 23 } plane { <0, 0, 1>, 50 } texture { - pigment { color srgb <0.195, 0.144, 0.111> } - finish { phong 0.18 metallic 0.35 reflection 0.35 } + pigment { color srgb <0.125, 0.144, 0.111> } + finish { phong 0.18 metallic 0.25 reflection 0.35 } } } } @@ -54,7 +56,7 @@ object { { merge { cylinder { <0, BV, 0>, <0, -BV, 0>, BR } - cylinder { <0, 0.012, 0>, <0, -0.012, 0>, BR*3 } + cylinder { <0, 0.012, 0>, <0, -0.012, 0>, BR*4 } } } diff --git a/BloubWorld/toinc.awk b/BloubWorld/toinc.awk index 6404fb5..e11f1b6 100644 --- a/BloubWorld/toinc.awk +++ b/BloubWorld/toinc.awk @@ -5,17 +5,22 @@ BEGIN { count = 0 + bx = by = bz = 0.0 print "// GENERATED FILE, DON'T TOUCH IT !" print "#declare Bloubs = object\n{" print "union\t{" } { - if ($5 > 6) color = "Turquoise" - else color = "Sienna" - + age = $5 + if (age < 2) color = "Orange" + else if (age > 8) color = "Gray70" + else color = "Sienna" + bx += $1 + by += $2 + bz += $3 pigment = "pigment { color " color " }" - printf "\t\tsphere { <%f, %f, %f>, %f %s }\n", \ + printf "\tsphere { <%f, %f, %f>, %f %s }\n", \ $1, $2, $3, $4, pigment count++ } @@ -23,4 +28,7 @@ BEGIN { END { print "\t} // end of union\n}\n" print "#declare Nb_Bloubs = ", count, ";\n" + print "#declare Bary_X = ", bx/count, ";"; + print "#declare Bary_Y = ", by/count, ";"; + print "#declare Bary_Z = ", bz/count, ";"; }