Mercurial > cortex
diff org/sense.org @ 199:305439cec54d
added video to sense.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 06 Feb 2012 01:40:22 -0700 |
parents | fc0bf33bded2 |
children | 7eb966144dad |
line wrap: on
line diff
1.1 --- a/org/sense.org Sun Feb 05 14:01:47 2012 -0700 1.2 +++ b/org/sense.org Mon Feb 06 01:40:22 2012 -0700 1.3 @@ -225,24 +225,9 @@ 1.4 =(points->image)= helps senses generate a base image onto which they 1.5 can overlay actual sense data. 1.6 1.7 -#+name view-senses 1.8 +#+name: view-senses 1.9 #+begin_src clojure 1.10 -(defn view-sense 1.11 - "Take a kernel that produces a BufferedImage from some sense data 1.12 - and return a function which takes a list of sense data, uses the 1.13 - kernel to convert to images, and displays those images, each in 1.14 - its own JFrame." 1.15 - [sense-display-kernel] 1.16 - (let [windows (atom [])] 1.17 - (fn [data] 1.18 - (if (> (count data) (count @windows)) 1.19 - (reset! 1.20 - windows (map (fn [_] (view-image)) (range (count data))))) 1.21 - (dorun 1.22 - (map 1.23 - (fn [display datum] 1.24 - (display (sense-display-kernel datum))) 1.25 - @windows data))))) 1.26 +(in-ns 'cortex.sense) 1.27 1.28 (defn points->image 1.29 "Take a collection of points and visuliaze it as a BufferedImage." 1.30 @@ -266,6 +251,58 @@ 1.31 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1))) 1.32 image))) 1.33 1.34 +(defn view-image 1.35 + "Initailizes a JPanel on which you may draw a BufferedImage. 1.36 + Returns a function that accepts a BufferedImage and draws it to the 1.37 + JPanel. If given a directory it will save the images as png files 1.38 + starting at 0000000.png and incrementing from there." 1.39 + ([#^File save] 1.40 + (let [idx (atom -1) 1.41 + image 1.42 + (atom 1.43 + (BufferedImage. 1 1 BufferedImage/TYPE_4BYTE_ABGR)) 1.44 + panel 1.45 + (proxy [JPanel] [] 1.46 + (paint 1.47 + [graphics] 1.48 + (proxy-super paintComponent graphics) 1.49 + (.drawImage graphics @image 0 0 nil))) 1.50 + frame (JFrame. "Display Image")] 1.51 + (SwingUtilities/invokeLater 1.52 + (fn [] 1.53 + (doto frame 1.54 + (-> (.getContentPane) (.add panel)) 1.55 + (.pack) 1.56 + (.setLocationRelativeTo nil) 1.57 + (.setResizable true) 1.58 + (.setVisible true)))) 1.59 + (fn [#^BufferedImage i] 1.60 + (reset! image i) 1.61 + (.setSize frame (+ 8 (.getWidth i)) (+ 28 (.getHeight i))) 1.62 + (.repaint panel 0 0 (.getWidth i) (.getHeight i)) 1.63 + (if save 1.64 + (ImageIO/write 1.65 + i "png" 1.66 + (File. save (format "%07d.png" (swap! idx inc)))))))) 1.67 + ([] (view-image nil))) 1.68 + 1.69 +(defn view-sense 1.70 + "Take a kernel that produces a BufferedImage from some sense data 1.71 + and return a function which takes a list of sense data, uses the 1.72 + kernel to convert to images, and displays those images, each in 1.73 + its own JFrame." 1.74 + [sense-display-kernel] 1.75 + (let [windows (atom [])] 1.76 + (fn [data] 1.77 + (if (> (count data) (count @windows)) 1.78 + (reset! 1.79 + windows (map (fn [_] (view-image)) (range (count data))))) 1.80 + (dorun 1.81 + (map 1.82 + (fn [display datum] 1.83 + (display (sense-display-kernel datum))) 1.84 + @windows data))))) 1.85 + 1.86 (defn gray 1.87 "Create a gray RGB pixel with R, G, and B set to num. num must be 1.88 between 0 and 255." 1.89 @@ -343,8 +380,7 @@ 1.90 1.91 =(bind-sense)= binds either a Camera or a Listener object to any 1.92 object so that they will follow that object no matter how it 1.93 -moves. Here is some example code which shows a camera bound to a blue 1.94 -box as it is buffeted by white cannonballs. 1.95 +moves. It is used to create both eyes and ears. 1.96 1.97 #+name: node-2 1.98 #+begin_src clojure 1.99 @@ -374,11 +410,99 @@ 1.100 (controlRender [_ _]))))) 1.101 #+end_src 1.102 1.103 +Here is some example code which shows a camera bound to a blue 1.104 +box as it is buffeted by white cannonballs. 1.105 + 1.106 +#+name: test 1.107 +#+begin_src clojure 1.108 +(ns cortex.test.sense 1.109 + (:use (cortex world util sense vision)) 1.110 + (:import 1.111 + java.io.File 1.112 + (com.jme3.math Vector3f ColorRGBA) 1.113 + (com.aurellem.capture RatchetTimer Capture))) 1.114 + 1.115 +(defn test-bind-sense 1.116 + "Show a camera that stays in the same relative position to a blue cube." 1.117 + [] 1.118 + (let [camera-pos (Vector3f. 0 30 0) 1.119 + rock (box 1 1 1 :color ColorRGBA/Blue 1.120 + :position (Vector3f. 0 10 0) 1.121 + :mass 30) 1.122 + rot (.getWorldRotation rock) 1.123 + table (box 3 1 10 :color ColorRGBA/Gray :mass 0 1.124 + :position (Vector3f. 0 -3 0))] 1.125 + (world 1.126 + (nodify [rock table]) 1.127 + standard-debug-controls 1.128 + (fn [world] 1.129 + (let 1.130 + [cam (doto (.clone (.getCamera world)) 1.131 + (.setLocation camera-pos) 1.132 + (.lookAt Vector3f/ZERO 1.133 + Vector3f/UNIT_X))] 1.134 + (bind-sense rock cam) 1.135 + (.setTimer world (RatchetTimer. 60)) 1.136 + (Capture/captureVideo 1.137 + world (File. "/home/r/proj/cortex/render/bind-sense0")) 1.138 + (add-camera! 1.139 + world cam 1.140 + (comp (view-image 1.141 + (File. "/home/r/proj/cortex/render/bind-sense1")) 1.142 + BufferedImage!)) 1.143 + (add-camera! world (.getCamera world) no-op))) 1.144 + no-op))) 1.145 +#+end_src 1.146 + 1.147 +** Demo Video 1.148 + 1.149 +#+begin_html 1.150 +<video controls="controls" width="755"> 1.151 + <source src="../video/bind-sense.ogg" type="video/ogg" 1.152 + preload="none" poster="../images/aurellem-1280x480.png" /> 1.153 +</video> 1.154 + 1.155 +#+end_html 1.156 + 1.157 +note to self: the video was created with the following commands: 1.158 + 1.159 + 1.160 +#+begin_src clojure :results silent 1.161 +(in-ns 'user) 1.162 +(import java.io.File) 1.163 +(use 'clojure.contrib.shell-out) 1.164 + 1.165 +(let 1.166 + [idx (atom -1) 1.167 + left (rest 1.168 + (sort 1.169 + (file-seq (File. "/home/r/proj/cortex/render/bind-sense0/")))) 1.170 + right (rest 1.171 + (sort 1.172 + (file-seq (File. "/home/r/proj/cortex/render/bind-sense1/"))))] 1.173 + (dorun 1.174 + (map 1.175 + (fn [im-1 im-2] 1.176 + (println idx) 1.177 + (sh "convert" (.getCanonicalPath im-1) 1.178 + (.getCanonicalPath im-2) "+append" 1.179 + (.getCanonicalPath 1.180 + (File. "/home/r/proj/cortex/render/bind-sense/" 1.181 + (format "%07d.png" (swap! idx inc)))))) 1.182 + left right))) 1.183 +#+end_src 1.184 + 1.185 +#+begin_src sh :results silent 1.186 +cd /home/r/proj/cortex/render/ 1.187 +cp ../images/aurellem-1280x480.png bind-sense/0000000.png 1.188 +ffmpeg -r 60 -b 9000k -i bind-sense/%07d.png bind-sense.ogg 1.189 +#+end_src 1.190 + 1.191 1.192 1.193 * Bookkeeping 1.194 Here is the header for this namespace, included for completness. 1.195 -#+name header 1.196 +#+name: header 1.197 #+begin_src clojure 1.198 (ns cortex.sense 1.199 "Here are functions useful in the construction of two or more 1.200 @@ -392,7 +516,11 @@ 1.201 (:import com.jme3.bounding.BoundingBox) 1.202 (:import (com.jme3.scene Node Spatial)) 1.203 (:import com.jme3.scene.control.AbstractControl) 1.204 - (:import (com.jme3.math Quaternion Vector3f))) 1.205 + (:import (com.jme3.math Quaternion Vector3f)) 1.206 + (:import javax.imageio.ImageIO) 1.207 + (:import java.io.File) 1.208 + (:import (javax.swing JPanel JFrame SwingUtilities))) 1.209 + 1.210 #+end_src 1.211 1.212 * Source Listing 1.213 @@ -410,3 +538,7 @@ 1.214 <<node-2>> 1.215 <<view-senses>> 1.216 #+end_src 1.217 + 1.218 +#+begin_src clojure :tangle ../src/cortex/test/sense.clj 1.219 +<<test>> 1.220 +#+end_src