comparison org/eyes.org @ 112:128fa71ee188

working on retina design
author Robert McIntyre <rlm@mit.edu>
date Thu, 19 Jan 2012 11:29:46 -0700
parents b7a3ba5e879b
children a980462ebe76
comparison
equal deleted inserted replaced
111:61d9c0e8d188 112:128fa71ee188
18 eyes from different positions to observe the same world, and pass 18 eyes from different positions to observe the same world, and pass
19 the observed data to any arbitray function." 19 the observed data to any arbitray function."
20 {:author "Robert McIntyre"} 20 {:author "Robert McIntyre"}
21 (:use cortex.world) 21 (:use cortex.world)
22 (:import com.jme3.post.SceneProcessor) 22 (:import com.jme3.post.SceneProcessor)
23 (:import (com.jme3.util Screenshots BufferUtils)) 23 (:import (com.jme3.util BufferUtils))
24 (:import java.nio.ByteBuffer) 24 (:import java.nio.ByteBuffer)
25 (:import java.awt.image.BufferedImage) 25 (:import java.awt.image.BufferedImage)
26 (:import com.jme3.renderer.ViewPort) 26 (:import com.jme3.renderer.ViewPort)
27 (:import com.jme3.math.ColorRGBA)) 27 (:import com.jme3.math.ColorRGBA))
28 28
29 (defn scene-processor 29 (defn scene-processor
30 "Create a SceneProcessor object which wraps a vision processing 30 "Create a SceneProcessor object which wraps a vision processing
31 continuation function. The SceneProcessor will take care of 31 continuation function. The SceneProcessor will take care of
32 converting the rendered frame to a BufferedImage and passing that 32 converting the rendered frame to a BufferedImage and passing that
33 BufferedImage to the continuation. The continuation should be a 33 BufferedImage to the continuation. The continuation should be a
34 function that takes a BufferedImage." 34 function that takes a ByteBuffer which represents the image."
35 [continuation] 35 [continuation]
36 (let [byte-buffer (atom nil) 36 (let [byte-buffer (atom nil)
37 renderer (atom nil) 37 renderer (atom nil)]
38 image (atom nil)]
39 (proxy [SceneProcessor] [] 38 (proxy [SceneProcessor] []
40 (initialize 39 (initialize
41 [renderManager viewPort] 40 [renderManager viewPort]
42 (let [cam (.getCamera viewPort) 41 (let [cam (.getCamera viewPort)
43 width (.getWidth cam) 42 width (.getWidth cam)
44 height (.getHeight cam)] 43 height (.getHeight cam)]
45 (reset! renderer (.getRenderer renderManager)) 44 (reset! renderer (.getRenderer renderManager))
46 (reset! byte-buffer 45 (reset! byte-buffer
47 (BufferUtils/createByteBuffer 46 (BufferUtils/createByteBuffer
48 (* width height 4))) 47 (* width height 4)))))
49 (reset! image (BufferedImage.
50 width height
51 BufferedImage/TYPE_4BYTE_ABGR))))
52 (isInitialized [] (not (nil? @byte-buffer))) 48 (isInitialized [] (not (nil? @byte-buffer)))
53 (reshape [_ _ _]) 49 (reshape [_ _ _])
54 (preFrame [_]) 50 (preFrame [_])
55 (postQueue [_]) 51 (postQueue [_])
56 (postFrame 52 (postFrame
57 [#^FrameBuffer fb] 53 [#^FrameBuffer fb]
58 (.clear @byte-buffer) 54 (.clear @byte-buffer)
59 (.readFrameBuffer @renderer fb @byte-buffer) 55 ;;(.readFrameBuffer @renderer fb @byte-buffer)
60 (Screenshots/convertScreenShot @byte-buffer @image) 56 (continuation @byte-buffer))
61 (continuation @image))
62 (cleanup [])))) 57 (cleanup []))))
63 58
59 (defn buffer->image! [width height]
60 (let [image (BufferedImage. width height
61 BufferedImage/TYPE_4BYTE_ABGR)]
62 (fn [byte-buffer]
63 (Screenshots/convertScreenShot byte-buffer image)
64 image)))
65
64 (defn add-eye 66 (defn add-eye
65 "Add an eye to the world, calling continuation on every frame 67 "Add an eye to the world, calling continuation on every frame
66 produced." 68 produced."
67 [world camera continuation] 69 [world camera continuation]
68 (let [width (.getWidth camera) 70 (let [width (.getWidth camera)
69 height (.getHeight camera) 71 height (.getHeight camera)
70 render-manager (.getRenderManager world) 72 render-manager (.getRenderManager world)
71 viewport (.createMainView render-manager "eye-view" camera)] 73 viewport (.createMainView render-manager "eye-view" camera)]
72 (doto viewport 74 (doto viewport
73 (.setClearFlags true true true) 75 (.setClearFlags true true true)
74 (.setBackgroundColor ColorRGBA/Gray) 76 (.setBackgroundColor ColorRGBA/Black)
75 (.addProcessor (scene-processor continuation)) 77 (.addProcessor (scene-processor continuation))
76 (.attachScene (.getRootNode world))))) 78 (.attachScene (.getRootNode world)))))
77 #+end_src 79 #+end_src
80
81 #+results: eyes
82 : #'cortex.vision/add-eye
78 83
79 Note the use of continuation passing style for connecting the eye to a 84 Note the use of continuation passing style for connecting the eye to a
80 function to process the output. You can create any number of eyes, and 85 function to process the output. You can create any number of eyes, and
81 each of them will see the world from their own =Camera=. Once every 86 each of them will see the world from their own =Camera=. Once every
82 frame, the rendered image is copied to a =BufferedImage=, and that 87 frame, the rendered image is copied to a =BufferedImage=, and that
94 (:import javax.swing.SwingUtilities) 99 (:import javax.swing.SwingUtilities)
95 (:import java.awt.Dimension) 100 (:import java.awt.Dimension)
96 (:import javax.swing.JFrame) 101 (:import javax.swing.JFrame)
97 (:import com.jme3.math.ColorRGBA) 102 (:import com.jme3.math.ColorRGBA)
98 (:import com.jme3.scene.Node) 103 (:import com.jme3.scene.Node)
99 (:import com.jme3.math.Vector3f)) 104 (:import com.jme3.math.Vector3f)
105 (:import (com.jme3.util Screenshots)))
100 106
101 (defn view-image 107 (defn view-image
102 "Initailizes a JPanel on which you may draw a BufferedImage. 108 "Initailizes a JPanel on which you may draw a BufferedImage.
103 Returns a function that accepts a BufferedImage and draws it to the 109 Returns a function that accepts a BufferedImage and draws it to the
104 JPanel." 110 JPanel."
135 You should see a rotating cube, and two windows, 141 You should see a rotating cube, and two windows,
136 each displaying a different view of the cube." 142 each displaying a different view of the cube."
137 [] 143 []
138 (let [candy 144 (let [candy
139 (box 1 1 1 :physical? false :color ColorRGBA/Blue)] 145 (box 1 1 1 :physical? false :color ColorRGBA/Blue)]
140 (world (doto (Node.) 146 (world
141 (.attachChild candy)) 147 (doto (Node.)
142 {} 148 (.attachChild candy))
143 (fn [world] 149 {}
144 (let [cam (.clone (.getCamera world)) 150 (fn [world]
145 width (.getWidth cam) 151 (let [cam (.clone (.getCamera world))
146 height (.getHeight cam)] 152 width (.getWidth cam)
147 (add-eye world cam (view-image)) 153 height (.getHeight cam)]
148 (add-eye world 154 (add-eye world cam
149 (doto (.clone cam) 155 no-op
150 (.setLocation (Vector3f. -10 0 0)) 156 ;;(comp (view-image) (buffer->image! width height))
151 (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)) 157 )
152 (view-image)) 158 (add-eye world
153 ;; This is here to restore the main view 159 (doto (.clone cam)
154 ;; after the other views have completed processing 160 (.setLocation (Vector3f. -10 0 0))
155 (add-eye world (.getCamera world) no-op))) 161 (.lookAt Vector3f/ZERO Vector3f/UNIT_Y))
156 (fn [world tpf] 162 no-op
157 (.rotate candy (* tpf 0.2) 0 0))))) 163 ;;(comp (view-image) (buffer->image! width height))
164 )
165
166
167 ;; This is here to restore the main view
168 ;; after the other views have completed processing
169 (add-eye world (.getCamera world) no-op)))
170 (fn [world tpf]
171 (.rotate candy (* tpf 0.2) 0 0)))))
158 #+end_src 172 #+end_src
173
174 #+results: test-vision
175 : #'cortex.test.vision/test-two-eyes
159 176
160 The example code will create two videos of the same rotating object 177 The example code will create two videos of the same rotating object
161 from different angles. It can be used both for stereoscopic vision 178 from different angles. It can be used both for stereoscopic vision
162 simulation or for simulating multiple creatures, each with their own 179 simulation or for simulating multiple creatures, each with their own
163 sense of vision. 180 sense of vision.