Mercurial > cortex
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. |