Mercurial > cortex
diff org/test-creature.org @ 123:91773e8ec50f
got hearing diaplay working
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 23 Jan 2012 03:41:26 -0700 |
parents | b591da250afc |
children | 90154bd674e9 |
line wrap: on
line diff
1.1 --- a/org/test-creature.org Sun Jan 22 04:53:58 2012 -0700 1.2 +++ b/org/test-creature.org Mon Jan 23 03:41:26 2012 -0700 1.3 @@ -655,7 +655,6 @@ 1.4 [(apply max (map first dimensions)) 1.5 (apply max (map second dimensions))])) 1.6 1.7 - 1.8 (defn creature-eyes 1.9 "The eye nodes which are children of the \"eyes\" node in the 1.10 creature." 1.11 @@ -664,45 +663,62 @@ 1.12 (seq (.getChildren eye-node)) 1.13 (do (println-repl "could not find eyes node") []))) 1.14 1.15 +;; Here's how vision will work. 1.16 1.17 - ;; Here's how vision will work. 1.18 +;; Make the continuation in scene-processor take FrameBuffer, 1.19 +;; byte-buffer, BufferedImage already sized to the correct 1.20 +;; dimensions. the continuation will decide wether to "mix" them 1.21 +;; into the BufferedImage, lazily ignore them, or mix them halfway 1.22 +;; and call c/graphics card routines. 1.23 1.24 - ;; Make the continuation in scene-processor take FrameBuffer, 1.25 - ;; byte-buffer, BufferedImage already sized to the correct 1.26 - ;; dimensions. the continuation will decide wether to "mix" them 1.27 - ;; into the BufferedImage, lazily ignore them, or mix them halfway 1.28 - ;; and call c/graphics card routines. 1.29 - 1.30 - ;; (vision creature) will take an optional :skip argument which will 1.31 - ;; inform the continuations in scene processor to skip the given 1.32 - ;; number of cycles; 0 means that no cycles will be skipped. 1.33 +;; (vision creature) will take an optional :skip argument which will 1.34 +;; inform the continuations in scene processor to skip the given 1.35 +;; number of cycles; 0 means that no cycles will be skipped. 1.36 1.37 - ;; (vision creature) will return [init-functions sensor-functions]. 1.38 - ;; The init-functions are each single-arg functions that take the 1.39 - ;; world and register the cameras and must each be called before the 1.40 - ;; corresponding sensor-functions. Each init-function returns the 1.41 - ;; viewport for that eye which can be manipulated, saved, etc. Each 1.42 - ;; sensor-function is a thunk and will return data in the same 1.43 - ;; format as the tactile-sensor functions; the structure is 1.44 - ;; [topology, sensor-data]. Internally, these sensor-functions 1.45 - ;; maintain a reference to sensor-data which is periodically updated 1.46 - ;; by the continuation function established by its init-function. 1.47 - ;; They can be queried every cycle, but their information may not 1.48 - ;; necessairly be different every cycle. 1.49 +;; (vision creature) will return [init-functions sensor-functions]. 1.50 +;; The init-functions are each single-arg functions that take the 1.51 +;; world and register the cameras and must each be called before the 1.52 +;; corresponding sensor-functions. Each init-function returns the 1.53 +;; viewport for that eye which can be manipulated, saved, etc. Each 1.54 +;; sensor-function is a thunk and will return data in the same 1.55 +;; format as the tactile-sensor functions; the structure is 1.56 +;; [topology, sensor-data]. Internally, these sensor-functions 1.57 +;; maintain a reference to sensor-data which is periodically updated 1.58 +;; by the continuation function established by its init-function. 1.59 +;; They can be queried every cycle, but their information may not 1.60 +;; necessairly be different every cycle. 1.61 1.62 - ;; Each eye in the creature in blender will work the same way as 1.63 - ;; joints -- a one dimensional object with no geometry whose local 1.64 - ;; coordinate system determines the orientation of the resulting 1.65 - ;; eye. All eyes will have a parent named "eyes" just as all joints 1.66 - ;; have a parent named "joints". The resulting camera will be a 1.67 - ;; ChaseCamera or a CameraNode bound to the geo that is closest to 1.68 - ;; the eye marker. The eye marker will contain the metadata for the 1.69 - ;; eye, and will be moved by it's bound geometry. The dimensions of 1.70 - ;; the eye's camera are equal to the dimensions of the eye's "UV" 1.71 - ;; map. 1.72 +;; Each eye in the creature in blender will work the same way as 1.73 +;; joints -- a zero dimensional object with no geometry whose local 1.74 +;; coordinate system determines the orientation of the resulting 1.75 +;; eye. All eyes will have a parent named "eyes" just as all joints 1.76 +;; have a parent named "joints". The resulting camera will be a 1.77 +;; ChaseCamera or a CameraNode bound to the geo that is closest to 1.78 +;; the eye marker. The eye marker will contain the metadata for the 1.79 +;; eye, and will be moved by it's bound geometry. The dimensions of 1.80 +;; the eye's camera are equal to the dimensions of the eye's "UV" 1.81 +;; map. 1.82 1.83 -(defn eye-target 1.84 - "The closest object in creature to eye." 1.85 + 1.86 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.87 + 1.88 +;; Ears work the same way as vision. 1.89 + 1.90 +;; (hearing creature) will return [init-functions 1.91 +;; sensor-functions]. The init functions each take the world and 1.92 +;; register a SoundProcessor that does foureier transforms on the 1.93 +;; incommong sound data, making it available to each sensor function. 1.94 + 1.95 +(defn creature-ears 1.96 + "The ear nodes which are children of the \"ears\" node in the 1.97 + creature." 1.98 + [#^Node creature] 1.99 + (if-let [ear-node (.getChild creature "ears")] 1.100 + (seq (.getChildren ear-node)) 1.101 + (do (println-repl "could not find ears node") []))) 1.102 + 1.103 +(defn closest-node 1.104 + "The closest object in creature to the given node." 1.105 [#^Node creature #^Node eye] 1.106 (loop [radius (float 0.01)] 1.107 (let [results (CollisionResults.)] 1.108 @@ -715,14 +731,14 @@ 1.109 (.getGeometry target) 1.110 (recur (float (* 2 radius))))))) 1.111 1.112 -(defn bind-camera 1.113 - "Bind the camera to the Spatial such that it will maintain its 1.114 +(defn bind-sense 1.115 + "Bind the sense to the Spatial such that it will maintain its 1.116 current position relative to the Spatial no matter how the spatial 1.117 - moves." 1.118 - [#^Spatial obj #^Camera cam] 1.119 - (let [cam-offset (.subtract (.getLocation cam) 1.120 - (.getWorldTranslation obj)) 1.121 - initial-cam-rotation (Quaternion. (.getRotation cam)) 1.122 + moves. 'sense can be either a Camera or Listener object." 1.123 + [#^Spatial obj sense] 1.124 + (let [sense-offset (.subtract (.getLocation sense) 1.125 + (.getWorldTranslation obj)) 1.126 + initial-sense-rotation (Quaternion. (.getRotation sense)) 1.127 base-anti-rotation (.inverse (.getWorldRotation obj))] 1.128 (.addControl 1.129 obj 1.130 @@ -730,20 +746,82 @@ 1.131 (controlUpdate [tpf] 1.132 (let [total-rotation 1.133 (.mult base-anti-rotation (.getWorldRotation obj))] 1.134 - (.setLocation cam 1.135 + (.setLocation sense 1.136 (.add 1.137 - (.mult total-rotation cam-offset) 1.138 + (.mult total-rotation sense-offset) 1.139 (.getWorldTranslation obj))) 1.140 - (.setRotation cam 1.141 - (.mult total-rotation initial-cam-rotation)))) 1.142 + (.setRotation sense 1.143 + (.mult total-rotation initial-sense-rotation)))) 1.144 (controlRender [_ _]))))) 1.145 1.146 1.147 +(defn update-listener-velocity 1.148 + "Update the listener's velocity every update loop." 1.149 + [#^Spatial obj #^Listener lis] 1.150 + (let [old-position (atom (.getLocation lis))] 1.151 + (.addControl 1.152 + obj 1.153 + (proxy [AbstractControl] [] 1.154 + (controlUpdate [tpf] 1.155 + (let [new-position (.getLocation lis)] 1.156 + (.setVelocity 1.157 + lis 1.158 + (.mult (.subtract new-position @old-position) 1.159 + (float (/ tpf)))) 1.160 + (reset! old-position new-position))) 1.161 + (controlRender [_ _]))))) 1.162 + 1.163 +(import com.aurellem.capture.audio.AudioSendRenderer) 1.164 + 1.165 +(defn attach-ear 1.166 + [#^Application world #^Node creature #^Spatial ear continuation] 1.167 + (let [target (closest-node creature ear) 1.168 + lis (Listener.) 1.169 + audio-renderer (.getAudioRenderer world) 1.170 + sp (sound-processor continuation)] 1.171 + (println-repl "audio-renderer is " audio-renderer) 1.172 + (.setLocation lis (.getWorldTranslation ear)) 1.173 + (.setRotation lis (.getWorldRotation ear)) 1.174 + (bind-sense target lis) 1.175 + (update-listener-velocity target lis) 1.176 + (.addListener audio-renderer lis) 1.177 + (.registerSoundProcessor audio-renderer lis sp))) 1.178 + 1.179 +(defn enable-hearing 1.180 + [#^Node creature #^Spatial ear] 1.181 + (let [hearing-data (atom [])] 1.182 + [(fn [world] 1.183 + (attach-ear world creature ear 1.184 + (fn [data] 1.185 + (reset! hearing-data (vec data))))) 1.186 + [(fn [] 1.187 + (let [data @hearing-data 1.188 + topology 1.189 + (vec (map #(vector % 0) (range 0 (count data)))) 1.190 + scaled-data 1.191 + (vec 1.192 + (map 1.193 + #(rem (int (* 255 (/ (+ 1 %) 2))) 256) 1.194 + data))] 1.195 + (println-repl (take 10 scaled-data)) 1.196 + [topology scaled-data])) 1.197 + ]])) 1.198 + 1.199 +(defn hearing 1.200 + [#^Node creature] 1.201 + (reduce 1.202 + (fn [[init-a senses-a] 1.203 + [init-b senses-b]] 1.204 + [(conj init-a init-b) 1.205 + (into senses-a senses-b)]) 1.206 + [[][]] 1.207 + (for [ear (creature-ears creature)] 1.208 + (enable-hearing creature ear)))) 1.209 + 1.210 (defn attach-eye 1.211 "Attach a Camera to the appropiate area and return the Camera." 1.212 [#^Node creature #^Spatial eye] 1.213 - 1.214 - (let [target (eye-target creature eye) 1.215 + (let [target (closest-node creature eye) 1.216 [cam-width cam-height] (eye-dimensions eye) 1.217 cam (Camera. cam-width cam-height)] 1.218 (.setLocation cam (.getWorldTranslation eye)) 1.219 @@ -751,52 +829,49 @@ 1.220 (.setFrustumPerspective 1.221 cam 45 (/ (.getWidth cam) (.getHeight cam)) 1.222 1 1000) 1.223 - 1.224 - (bind-camera target cam) 1.225 + (bind-sense target cam) 1.226 cam)) 1.227 1.228 - 1.229 (def presets 1.230 {:all 0xFFFFFF 1.231 :red 0xFF0000 1.232 :blue 0x0000FF 1.233 :green 0x00FF00}) 1.234 1.235 - 1.236 - 1.237 (defn enable-vision 1.238 "return [init-function sensor-functions] for a particular eye" 1.239 [#^Node creature #^Spatial eye & {skip :skip :or {skip 0}}] 1.240 (let [retinal-map (retina-sensor-image eye) 1.241 - vision-image (atom nil) 1.242 - camera (attach-eye creature eye)] 1.243 - [ 1.244 - (fn [world] 1.245 - (add-eye 1.246 - world camera 1.247 - (let [counter (atom 0)] 1.248 - (fn [r fb bb bi] 1.249 - (if (zero? (rem (swap! counter inc) (inc skip))) 1.250 - (reset! vision-image (BufferedImage! r fb bb bi))))))) 1.251 - (vec 1.252 - (map 1.253 - (fn [[key image]] 1.254 - (let [whites (white-coordinates image) 1.255 - topology (vec (collapse whites)) 1.256 - mask (presets key)] 1.257 - (fn [] 1.258 - (vector 1.259 - topology 1.260 - (vec 1.261 - (for [[x y] whites] 1.262 - (bit-and 1.263 - mask (.getRGB @vision-image x y)))))))) 1.264 - retinal-map)) 1.265 - ])) 1.266 + camera (attach-eye creature eye) 1.267 + vision-image 1.268 + (atom 1.269 + (BufferedImage. (.getWidth camera) 1.270 + (.getHeight camera) 1.271 + BufferedImage/TYPE_BYTE_BINARY))] 1.272 + [(fn [world] 1.273 + (add-eye 1.274 + world camera 1.275 + (let [counter (atom 0)] 1.276 + (fn [r fb bb bi] 1.277 + (if (zero? (rem (swap! counter inc) (inc skip))) 1.278 + (reset! vision-image (BufferedImage! r fb bb bi))))))) 1.279 + (vec 1.280 + (map 1.281 + (fn [[key image]] 1.282 + (let [whites (white-coordinates image) 1.283 + topology (vec (collapse whites)) 1.284 + mask (presets key)] 1.285 + (fn [] 1.286 + (vector 1.287 + topology 1.288 + (vec 1.289 + (for [[x y] whites] 1.290 + (bit-and 1.291 + mask (.getRGB @vision-image x y)))))))) 1.292 + retinal-map))])) 1.293 1.294 (defn vision 1.295 [#^Node creature & {skip :skip :or {skip 0}}] 1.296 - 1.297 (reduce 1.298 (fn [[init-a senses-a] 1.299 [init-b senses-b]] 1.300 @@ -827,8 +902,8 @@ 1.301 (dorun 1.302 (for [i (range (count coords))] 1.303 (.setRGB image ((coords i) 0) ((coords i) 1) 1.304 - ({0 -16777216 1.305 - 1 -1} (sensor-data i))))) 1.306 + ({0 0x000000 1.307 + 1 0xFFFFFF} (sensor-data i))))) 1.308 (vi image))))) 1.309 1.310 (defn debug-vision-window 1.311 @@ -844,9 +919,33 @@ 1.312 (sensor-data i)))) 1.313 (vi image))))) 1.314 1.315 +(defn debug-hearing-window 1.316 + "view audio data" 1.317 + [height] 1.318 + (let [vi (view-image)] 1.319 + (fn [[coords sensor-data]] 1.320 + (let [image (BufferedImage. (count coords) height 1.321 + BufferedImage/TYPE_INT_RGB)] 1.322 + (dorun 1.323 + (for [x (range (count coords))] 1.324 + (dorun 1.325 + (for [y (range height)] 1.326 + (let [raw-sensor (sensor-data x)] 1.327 + (.setRGB image x y 1.328 + (+ raw-sensor 1.329 + (bit-shift-left raw-sensor 8) 1.330 + (bit-shift-left raw-sensor 16)))))))) 1.331 + (vi image))))) 1.332 + 1.333 + 1.334 + 1.335 ;;(defn test-touch [world creature] 1.336 1.337 1.338 + 1.339 + 1.340 + 1.341 + 1.342 (defn test-creature [thing] 1.343 (let [x-axis 1.344 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red) 1.345 @@ -860,6 +959,13 @@ 1.346 [init-vision-fns vision-data] (vision creature) 1.347 vision-debug (map (fn [_] (debug-vision-window)) vision-data) 1.348 me (sphere 0.5 :color ColorRGBA/Blue :physical? false) 1.349 + [init-hearing-fns hearing-senses] (hearing creature) 1.350 + hearing-windows (map (fn [_] (debug-hearing-window 50)) 1.351 + hearing-senses) 1.352 + bang (AudioNode. (asset-manager) 1.353 + "Sounds/dream.wav" false) 1.354 + ;; dream 1.355 + 1.356 ] 1.357 (world 1.358 (nodify [creature 1.359 @@ -868,11 +974,18 @@ 1.360 x-axis y-axis z-axis 1.361 me 1.362 ]) 1.363 - standard-debug-controls 1.364 + (merge standard-debug-controls 1.365 + {"key-return" 1.366 + (fn [_ value] 1.367 + (if value 1.368 + (do 1.369 + (println-repl "play-sound") 1.370 + (.play bang))))}) 1.371 (fn [world] 1.372 (light-up-everything world) 1.373 (enable-debug world) 1.374 (dorun (map #(% world) init-vision-fns)) 1.375 + (dorun (map #(% world) init-hearing-fns)) 1.376 1.377 (add-eye world 1.378 (attach-eye creature (test-eye)) 1.379 @@ -889,14 +1002,20 @@ 1.380 (fn [world tpf] 1.381 ;;(dorun 1.382 ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world)))) 1.383 - 1.384 + 1.385 + 1.386 + 1.387 (dorun 1.388 (map #(%1 (%2 (.getRootNode world))) 1.389 touch-debug-windows touch-nerves)) 1.390 + 1.391 (dorun 1.392 (map #(%1 (%2)) 1.393 vision-debug vision-data)) 1.394 - 1.395 + (dorun 1.396 + (map #(%1 (%2)) hearing-windows hearing-senses)) 1.397 + 1.398 + 1.399 ;;(println-repl (vision-data)) 1.400 (.setLocalTranslation me (.getLocation (.getCamera world))) 1.401 1.402 @@ -995,7 +1114,7 @@ 1.403 (.setLocation camera-pos) 1.404 (.lookAt Vector3f/ZERO 1.405 Vector3f/UNIT_X))] 1.406 - (bind-camera rock cam) 1.407 + (bind-sense rock cam) 1.408 1.409 (.setTimer world (RatchetTimer. 60)) 1.410 (add-eye world cam (comp (view-image) BufferedImage!)) 1.411 @@ -1004,6 +1123,7 @@ 1.412 (fn [_ _] (println-repl rot))))) 1.413 1.414 1.415 + 1.416 #+end_src 1.417 1.418 #+results: body-1