comparison org/sense.org @ 200:7eb966144dad

finished video for sense.org, now with subtitles!
author Robert McIntyre <rlm@mit.edu>
date Mon, 06 Feb 2012 08:26:20 -0700
parents 305439cec54d
children 1c915cc1118b
comparison
equal deleted inserted replaced
199:305439cec54d 200:7eb966144dad
217 relocated))) 217 relocated)))
218 #+end_src 218 #+end_src
219 * Viewing Sense Data 219 * Viewing Sense Data
220 220
221 It's vital to /see/ the sense data to make sure that everything is 221 It's vital to /see/ the sense data to make sure that everything is
222 behaving as it should. =(view-sense)= is here so that each sense can 222 behaving as it should. =(view-sense)= and its helper, =(view-image)=
223 define its own way of turning sense-data into pictures, while the 223 are here so that each sense can define its own way of turning
224 actual rendering of said pictures stays in one central place. 224 sense-data into pictures, while the actual rendering of said pictures
225 =(points->image)= helps senses generate a base image onto which they 225 stays in one central place. =(points->image)= helps senses generate a
226 can overlay actual sense data. 226 base image onto which they can overlay actual sense data.
227 227
228 #+name: view-senses 228 #+name: view-senses
229 #+begin_src clojure 229 #+begin_src clojure
230 (in-ns 'cortex.sense) 230 (in-ns 'cortex.sense)
231
232 (defn points->image
233 "Take a collection of points and visuliaze it as a BufferedImage."
234 [points]
235 (if (empty? points)
236 (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY)
237 (let [xs (vec (map first points))
238 ys (vec (map second points))
239 x0 (apply min xs)
240 y0 (apply min ys)
241 width (- (apply max xs) x0)
242 height (- (apply max ys) y0)
243 image (BufferedImage. (inc width) (inc height)
244 BufferedImage/TYPE_INT_RGB)]
245 (dorun
246 (for [x (range (.getWidth image))
247 y (range (.getHeight image))]
248 (.setRGB image x y 0xFF0000)))
249 (dorun
250 (for [index (range (count points))]
251 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1)))
252 image)))
253 231
254 (defn view-image 232 (defn view-image
255 "Initailizes a JPanel on which you may draw a BufferedImage. 233 "Initailizes a JPanel on which you may draw a BufferedImage.
256 Returns a function that accepts a BufferedImage and draws it to the 234 Returns a function that accepts a BufferedImage and draws it to the
257 JPanel. If given a directory it will save the images as png files 235 JPanel. If given a directory it will save the images as png files
301 (map 279 (map
302 (fn [display datum] 280 (fn [display datum]
303 (display (sense-display-kernel datum))) 281 (display (sense-display-kernel datum)))
304 @windows data))))) 282 @windows data)))))
305 283
284 (defn points->image
285 "Take a collection of points and visuliaze it as a BufferedImage."
286 [points]
287 (if (empty? points)
288 (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY)
289 (let [xs (vec (map first points))
290 ys (vec (map second points))
291 x0 (apply min xs)
292 y0 (apply min ys)
293 width (- (apply max xs) x0)
294 height (- (apply max ys) y0)
295 image (BufferedImage. (inc width) (inc height)
296 BufferedImage/TYPE_INT_RGB)]
297 (dorun
298 (for [x (range (.getWidth image))
299 y (range (.getHeight image))]
300 (.setRGB image x y 0xFF0000)))
301 (dorun
302 (for [index (range (count points))]
303 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1)))
304 image)))
305
306 (defn gray 306 (defn gray
307 "Create a gray RGB pixel with R, G, and B set to num. num must be 307 "Create a gray RGB pixel with R, G, and B set to num. num must be
308 between 0 and 255." 308 between 0 and 255."
309 [num] 309 [num]
310 (+ num 310 (+ num
375 (defn local-to-world 375 (defn local-to-world
376 "Convert the local coordinates into world relative coordinates" 376 "Convert the local coordinates into world relative coordinates"
377 [#^Spatial object local-coordinate] 377 [#^Spatial object local-coordinate]
378 (.localToWorld object local-coordinate nil)) 378 (.localToWorld object local-coordinate nil))
379 #+end_src 379 #+end_src
380
381 ** Sense Binding
380 382
381 =(bind-sense)= binds either a Camera or a Listener object to any 383 =(bind-sense)= binds either a Camera or a Listener object to any
382 object so that they will follow that object no matter how it 384 object so that they will follow that object no matter how it
383 moves. It is used to create both eyes and ears. 385 moves. It is used to create both eyes and ears.
384 386
408 sense 410 sense
409 (.mult total-rotation initial-sense-rotation)))) 411 (.mult total-rotation initial-sense-rotation))))
410 (controlRender [_ _]))))) 412 (controlRender [_ _])))))
411 #+end_src 413 #+end_src
412 414
413 Here is some example code which shows a camera bound to a blue 415 Here is some example code which shows how a camera bound to a blue box
414 box as it is buffeted by white cannonballs. 416 with =(bind-sense)= moves as the box is buffeted by white cannonballs.
415 417
416 #+name: test 418 #+name: test
417 #+begin_src clojure 419 #+begin_src clojure
418 (ns cortex.test.sense 420 (ns cortex.test.sense
419 (:use (cortex world util sense vision)) 421 (:use (cortex world util sense vision))
452 BufferedImage!)) 454 BufferedImage!))
453 (add-camera! world (.getCamera world) no-op))) 455 (add-camera! world (.getCamera world) no-op)))
454 no-op))) 456 no-op)))
455 #+end_src 457 #+end_src
456 458
457 ** Demo Video
458
459 #+begin_html 459 #+begin_html
460 <video controls="controls" width="755"> 460 <video controls="controls" width="755">
461 <source src="../video/bind-sense.ogg" type="video/ogg" 461 <source src="../video/bind-sense.ogg" type="video/ogg"
462 preload="none" poster="../images/aurellem-1280x480.png" /> 462 preload="none" poster="../images/aurellem-1280x480.png" />
463 </video> 463 </video>
464 464
465 #+end_html 465 #+end_html
466 466
467 note to self: the video was created with the following commands: 467 With this, eyes are easy --- you just bind the camera closer to the
468 468 desired object, and set it to look outward instead of inward as it
469 469 does in the video.
470
471 (nb : the video was created with the following commands)
472
473 *** Combine Frames with ImageMagick
470 #+begin_src clojure :results silent 474 #+begin_src clojure :results silent
471 (in-ns 'user) 475 (in-ns 'user)
472 (import java.io.File) 476 (import java.io.File)
473 (use 'clojure.contrib.shell-out) 477 (use 'clojure.contrib.shell-out)
474
475 (let 478 (let
476 [idx (atom -1) 479 [idx (atom -1)
477 left (rest 480 left (rest
478 (sort 481 (sort
479 (file-seq (File. "/home/r/proj/cortex/render/bind-sense0/")))) 482 (file-seq (File. "/home/r/proj/cortex/render/bind-sense0/"))))
480 right (rest 483 right (rest
481 (sort 484 (sort
482 (file-seq (File. "/home/r/proj/cortex/render/bind-sense1/"))))] 485 (file-seq
486 (File. "/home/r/proj/cortex/render/bind-sense1/"))))
487 sub (rest
488 (sort
489 (file-seq
490 (File. "/home/r/proj/cortex/render/bind-senseB/"))))
491 sub* (concat sub (repeat 1000 (last sub)))]
483 (dorun 492 (dorun
484 (map 493 (map
485 (fn [im-1 im-2] 494 (fn [im-1 im-2 sub]
486 (println idx)
487 (sh "convert" (.getCanonicalPath im-1) 495 (sh "convert" (.getCanonicalPath im-1)
488 (.getCanonicalPath im-2) "+append" 496 (.getCanonicalPath im-2) "+append"
497 (.getCanonicalPath sub) "-append"
489 (.getCanonicalPath 498 (.getCanonicalPath
490 (File. "/home/r/proj/cortex/render/bind-sense/" 499 (File. "/home/r/proj/cortex/render/bind-sense/"
491 (format "%07d.png" (swap! idx inc)))))) 500 (format "%07d.png" (swap! idx inc))))))
492 left right))) 501 left right sub*)))
493 #+end_src 502 #+end_src
503
504 *** Encode Frames with ffmpeg
494 505
495 #+begin_src sh :results silent 506 #+begin_src sh :results silent
496 cd /home/r/proj/cortex/render/ 507 cd /home/r/proj/cortex/render/
497 cp ../images/aurellem-1280x480.png bind-sense/0000000.png
498 ffmpeg -r 60 -b 9000k -i bind-sense/%07d.png bind-sense.ogg 508 ffmpeg -r 60 -b 9000k -i bind-sense/%07d.png bind-sense.ogg
499 #+end_src 509 #+end_src
500
501
502 510
503 * Bookkeeping 511 * Bookkeeping
504 Here is the header for this namespace, included for completness. 512 Here is the header for this namespace, included for completness.
505 #+name: header 513 #+name: header
506 #+begin_src clojure 514 #+begin_src clojure
518 (:import com.jme3.scene.control.AbstractControl) 526 (:import com.jme3.scene.control.AbstractControl)
519 (:import (com.jme3.math Quaternion Vector3f)) 527 (:import (com.jme3.math Quaternion Vector3f))
520 (:import javax.imageio.ImageIO) 528 (:import javax.imageio.ImageIO)
521 (:import java.io.File) 529 (:import java.io.File)
522 (:import (javax.swing JPanel JFrame SwingUtilities))) 530 (:import (javax.swing JPanel JFrame SwingUtilities)))
523
524 #+end_src 531 #+end_src
525 532
526 * Source Listing 533 * Source Listing
527 Full source: [[../src/cortex/sense.clj][sense.clj]] 534 Full source: [[../src/cortex/sense.clj][sense.clj]]
528 535