diff org/eyes.org @ 23:cab2da252494

split off the rest of cortex.org
author Robert McIntyre <rlm@mit.edu>
date Sun, 23 Oct 2011 23:54:26 -0700
parents
children e965675ec4d0
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/org/eyes.org	Sun Oct 23 23:54:26 2011 -0700
     1.3 @@ -0,0 +1,243 @@
     1.4 +#+title: Eyes
     1.5 +#+author: Robert McIntyre
     1.6 +#+email: rlm@mit.edu
     1.7 +#+description: Simulating senses for AI research using JMonkeyEngine3
     1.8 +#+SETUPFILE: ../../aurellem/org/setup.org
     1.9 +#+INCLUDE: ../../aurellem/org/level-0.org
    1.10 +#+babel: :mkdirp yes :noweb yes :exports both
    1.11 +
    1.12 +
    1.13 +
    1.14 +** Eyes
    1.15 +
    1.16 +Ultimately I want to make creatures with eyes. Each eye can be
    1.17 +independely moved and should see its own version of the world
    1.18 +depending on where it is.
    1.19 +#+srcname: eyes
    1.20 +#+begin_src clojure 
    1.21 +(ns body.eye)
    1.22 +(use 'cortex.world)
    1.23 +(use 'cortex.import)
    1.24 +(use 'clojure.contrib.def)
    1.25 +(cortex.import/mega-import-jme3)
    1.26 +(rlm.rlm-commands/help)
    1.27 +(import java.nio.ByteBuffer)
    1.28 +(import java.awt.image.BufferedImage)
    1.29 +(import java.awt.Color)
    1.30 +(import java.awt.Dimension)
    1.31 +(import java.awt.Graphics)
    1.32 +(import java.awt.Graphics2D)
    1.33 +(import java.awt.event.WindowAdapter)
    1.34 +(import java.awt.event.WindowEvent)
    1.35 +(import java.awt.image.BufferedImage)
    1.36 +(import java.nio.ByteBuffer)
    1.37 +(import javax.swing.JFrame)
    1.38 +(import javax.swing.JPanel)
    1.39 +(import javax.swing.SwingUtilities)
    1.40 +(import javax.swing.ImageIcon)
    1.41 +(import javax.swing.JOptionPane)
    1.42 +(import java.awt.image.ImageObserver)
    1.43 +
    1.44 +
    1.45 +
    1.46 +(defn scene-processor
    1.47 +  "deals with converting FrameBuffers to BufferedImages so
    1.48 +   that the continuation function can be defined only in terms
    1.49 +   of what it does with BufferedImages"
    1.50 +  [continuation]
    1.51 +  (let [byte-buffer (atom nil)
    1.52 +	renderer (atom nil)
    1.53 +	image (atom nil)]
    1.54 +  (proxy [SceneProcessor] []
    1.55 +    (initialize
    1.56 +     [renderManager viewPort]
    1.57 +     (let [cam (.getCamera viewPort)
    1.58 +	   width (.getWidth cam)
    1.59 +	   height (.getHeight cam)]
    1.60 +       (reset! renderer (.getRenderer renderManager))
    1.61 +       (reset! byte-buffer
    1.62 +	     (BufferUtils/createByteBuffer
    1.63 +	      (* width height 4)))
    1.64 +       (reset! image (BufferedImage. width height
    1.65 +				     BufferedImage/TYPE_4BYTE_ABGR))))
    1.66 +    (isInitialized [] (not (nil? @byte-buffer)))
    1.67 +    (reshape [_ _ _])
    1.68 +    (preFrame [_])
    1.69 +    (postQueue [_])
    1.70 +    (postFrame
    1.71 +     [#^FrameBuffer fb]
    1.72 +     (.clear @byte-buffer)
    1.73 +     (.readFrameBuffer @renderer fb @byte-buffer)
    1.74 +     (Screenshots/convertScreenShot @byte-buffer @image)
    1.75 +     (continuation @image))
    1.76 +    (cleanup []))))
    1.77 +    
    1.78 +(defn add-eye
    1.79 +  "Add an eye to the world, and call continuation on
    1.80 +   every frame produced"
    1.81 +  [world camera continuation]
    1.82 +  (let [width (.getWidth camera)
    1.83 +	height (.getHeight camera)
    1.84 +	render-manager (.getRenderManager world)
    1.85 +	viewport (.createMainView render-manager "eye-view" camera)]
    1.86 +    (doto viewport
    1.87 +      (.setBackgroundColor ColorRGBA/Black)
    1.88 +      (.setClearFlags true true true)
    1.89 +      (.addProcessor (scene-processor continuation))
    1.90 +      (.attachScene (.getRootNode world)))))
    1.91 +
    1.92 +(defn make-display-frame [display width height]
    1.93 +  (SwingUtilities/invokeLater
    1.94 +   (fn []
    1.95 +     (.setPreferredSize display (Dimension. width height))
    1.96 +     (doto (JFrame. "Eye Camera!")
    1.97 +       (-> (.getContentPane) (.add display))
    1.98 +       (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
    1.99 +       (.pack)
   1.100 +       (.setLocationRelativeTo nil)
   1.101 +       (.setResizable false)
   1.102 +       (.setVisible true)))))
   1.103 +	   
   1.104 +(defn image-monitor [#^BufferedImage image]
   1.105 +  (proxy [JPanel] []
   1.106 +    (paintComponent 
   1.107 +     [g]
   1.108 +     (proxy-super paintComponent g)
   1.109 +     (locking image
   1.110 +       (.drawImage g image 0 0
   1.111 +		   (proxy [ImageObserver]
   1.112 +		       []
   1.113 +		     (imageUpdate
   1.114 +		      []
   1.115 +		      (proxy-super imageUpdate))))))))
   1.116 +
   1.117 +(defn movie-image []
   1.118 +  (let [setup
   1.119 +	(runonce
   1.120 +	 (fn [#^BufferedImage image]
   1.121 +	   (let [width (.getWidth image)
   1.122 +		 height (.getHeight image)
   1.123 +		 display (image-monitor image)
   1.124 +		 frame (make-display-frame display width height)]
   1.125 +	     display)))]
   1.126 +    (fn [#^BufferedImage image]
   1.127 +      (.repaint (setup image)))))
   1.128 +	     
   1.129 +
   1.130 +(defn observer
   1.131 +  "place thy eye!"
   1.132 +  [world camera]
   1.133 +  (let [eye camera
   1.134 +	width (.getWidth eye)
   1.135 +	height (.getHeight eye)]
   1.136 +    (no-exceptions
   1.137 +     (add-eye
   1.138 +      world
   1.139 +      eye
   1.140 +      (movie-image)))))
   1.141 +#+end_src
   1.142 +
   1.143 +#+srcname: test-vision
   1.144 +#+begin_src clojure
   1.145 +
   1.146 +(ns test.vision)
   1.147 +(use 'cortex.world)
   1.148 +(use 'cortex.import)
   1.149 +(use 'clojure.contrib.def)
   1.150 +(use 'body.eye)
   1.151 +(cortex.import/mega-import-jme3)
   1.152 +(rlm.rlm-commands/help)
   1.153 +(import java.nio.ByteBuffer)
   1.154 +(import java.awt.image.BufferedImage)
   1.155 +(import java.awt.Color)
   1.156 +(import java.awt.Dimension)
   1.157 +(import java.awt.Graphics)
   1.158 +(import java.awt.Graphics2D)
   1.159 +(import java.awt.event.WindowAdapter)
   1.160 +(import java.awt.event.WindowEvent)
   1.161 +(import java.awt.image.BufferedImage)
   1.162 +(import java.nio.ByteBuffer)
   1.163 +(import javax.swing.JFrame)
   1.164 +(import javax.swing.JPanel)
   1.165 +(import javax.swing.SwingUtilities)
   1.166 +(import javax.swing.ImageIcon)
   1.167 +(import javax.swing.JOptionPane)
   1.168 +(import java.awt.image.ImageObserver)
   1.169 +
   1.170 +
   1.171 +(def width 200)
   1.172 +(def height 200)
   1.173 +
   1.174 +(defn camera []
   1.175 +  (doto (Camera. width height)
   1.176 +    (.setFrustumPerspective 45 1 1 1000)
   1.177 +    (.setLocation (Vector3f. -3 0 -5))
   1.178 +    (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))
   1.179 +
   1.180 +(defn camera2 []
   1.181 +  (doto (Camera. width height)
   1.182 +    (.setFrustumPerspective 45 1 1 1000)
   1.183 +    (.setLocation (Vector3f. 3 0 -5))
   1.184 +    (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))
   1.185 +
   1.186 +(defn setup-fn [world]
   1.187 +  (let [eye (camera)
   1.188 +	width (.getWidth eye)
   1.189 +	height (.getHeight eye)]
   1.190 +    (no-exceptions
   1.191 +     (add-eye
   1.192 +      world
   1.193 +      eye
   1.194 +      (runonce visual))
   1.195 +     (add-eye
   1.196 +      world
   1.197 +      (camera2)
   1.198 +      (runonce visual)))))
   1.199 +
   1.200 +(defn spider-eye [position]
   1.201 +  (doto (Camera. 200 200 )
   1.202 +    (.setFrustumPerspective 45 1 1 1000)
   1.203 +    (.setLocation position)
   1.204 +    (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))
   1.205 +  
   1.206 +(defn setup-fn* [world]
   1.207 +  (let [eye (camera)
   1.208 +	width (.getWidth eye)
   1.209 +	height (.getHeight eye)]
   1.210 +    ;;(.setClearFlags (.getViewPort world) true true true)
   1.211 +    (observer world (.getCamera world))
   1.212 +    (observer world (spider-eye (Vector3f.  3  0 -5)))
   1.213 +    ;;(observer world (spider-eye (Vector3f.  0  0 -5)))
   1.214 +    ;; (observer world (spider-eye (Vector3f. -3  0 -5)))
   1.215 +    ;; (observer world (spider-eye (Vector3f.  0  3 -5)))
   1.216 +    ;; (observer world (spider-eye (Vector3f.  0 -3 -5)))
   1.217 +    ;; (observer world (spider-eye (Vector3f.  3  3 -5)))
   1.218 +    ;; (observer world (spider-eye (Vector3f. -3  3 -5)))
   1.219 +    ;; (observer world (spider-eye (Vector3f.  3 -3 -5)))
   1.220 +    ;; (observer world (spider-eye (Vector3f. -3 -3 -5)))
   1.221 +
   1.222 +    )
   1.223 +  world)
   1.224 +
   1.225 +(defn test-world []
   1.226 +  (let [thing (box 1 1 1 :physical? false)]
   1.227 +    (world
   1.228 +     (doto (Node.)
   1.229 +       (.attachChild thing))
   1.230 +     {}
   1.231 +     setup-fn
   1.232 +     (fn [world tpf]
   1.233 +       (.rotate thing (* tpf 0.2) 0 0)
   1.234 +       ))))
   1.235 +
   1.236 +
   1.237 +#+end_src
   1.238 +
   1.239 +
   1.240 +#+results: eyes
   1.241 +: #'body.eye/test-world
   1.242 +
   1.243 +Note the use of continuation passing style for connecting the eye to a
   1.244 +function to process the output. The example code will create two
   1.245 +videos of the same rotating cube from different angles, sutiable for
   1.246 +stereoscopic vision.