changeset 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
files assets/Models/creature1/try-again.blend org/test-creature.org
diffstat 2 files changed, 205 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
     1.1 Binary file assets/Models/creature1/try-again.blend has changed
     2.1 --- a/org/test-creature.org	Sun Jan 22 04:53:58 2012 -0700
     2.2 +++ b/org/test-creature.org	Mon Jan 23 03:41:26 2012 -0700
     2.3 @@ -655,7 +655,6 @@
     2.4      [(apply max (map first dimensions))
     2.5       (apply max (map second dimensions))]))
     2.6  
     2.7 -
     2.8  (defn creature-eyes
     2.9    "The eye nodes which are children of the \"eyes\" node in the
    2.10    creature."
    2.11 @@ -664,45 +663,62 @@
    2.12      (seq (.getChildren eye-node))
    2.13      (do (println-repl "could not find eyes node") [])))
    2.14  
    2.15 +;; Here's how vision will work.
    2.16  
    2.17 -  ;; Here's how vision will work.
    2.18 +;; Make the continuation in scene-processor take FrameBuffer,
    2.19 +;; byte-buffer, BufferedImage already sized to the correct
    2.20 +;; dimensions. the continuation will decide wether to "mix" them
    2.21 +;; into the BufferedImage, lazily ignore them, or mix them halfway
    2.22 +;; and call c/graphics card routines.
    2.23  
    2.24 -  ;; Make the continuation in scene-processor take FrameBuffer,
    2.25 -  ;; byte-buffer, BufferedImage already sized to the correct
    2.26 -  ;; dimensions. the continuation will decide wether to "mix" them
    2.27 -  ;; into the BufferedImage, lazily ignore them, or mix them halfway
    2.28 -  ;; and call c/graphics card routines.
    2.29 -  
    2.30 -  ;; (vision creature) will take an optional :skip argument which will
    2.31 -  ;; inform the continuations in scene processor to skip the given
    2.32 -  ;; number of cycles; 0 means that no cycles will be skipped.
    2.33 +;; (vision creature) will take an optional :skip argument which will
    2.34 +;; inform the continuations in scene processor to skip the given
    2.35 +;; number of cycles; 0 means that no cycles will be skipped.
    2.36  
    2.37 -  ;; (vision creature) will return [init-functions sensor-functions].
    2.38 -  ;; The init-functions are each single-arg functions that take the
    2.39 -  ;; world and register the cameras and must each be called before the
    2.40 -  ;; corresponding sensor-functions.  Each init-function returns the
    2.41 -  ;; viewport for that eye which can be manipulated, saved, etc. Each
    2.42 -  ;; sensor-function is a thunk and will return data in the same
    2.43 -  ;; format as the tactile-sensor functions; the structure is
    2.44 -  ;; [topology, sensor-data]. Internally, these sensor-functions
    2.45 -  ;; maintain a reference to sensor-data which is periodically updated
    2.46 -  ;; by the continuation function established by its init-function.
    2.47 -  ;; They can be queried every cycle, but their information may not
    2.48 -  ;; necessairly be different every cycle.
    2.49 +;; (vision creature) will return [init-functions sensor-functions].
    2.50 +;; The init-functions are each single-arg functions that take the
    2.51 +;; world and register the cameras and must each be called before the
    2.52 +;; corresponding sensor-functions.  Each init-function returns the
    2.53 +;; viewport for that eye which can be manipulated, saved, etc. Each
    2.54 +;; sensor-function is a thunk and will return data in the same
    2.55 +;; format as the tactile-sensor functions; the structure is
    2.56 +;; [topology, sensor-data]. Internally, these sensor-functions
    2.57 +;; maintain a reference to sensor-data which is periodically updated
    2.58 +;; by the continuation function established by its init-function.
    2.59 +;; They can be queried every cycle, but their information may not
    2.60 +;; necessairly be different every cycle.
    2.61  
    2.62 -  ;; Each eye in the creature in blender will work the same way as
    2.63 -  ;; joints -- a one dimensional object with no geometry whose local
    2.64 -  ;; coordinate system determines the orientation of the resulting
    2.65 -  ;; eye. All eyes will have a parent named "eyes" just as all joints
    2.66 -  ;; have a parent named "joints". The resulting camera will be a
    2.67 -  ;; ChaseCamera or a CameraNode bound to the geo that is closest to
    2.68 -  ;; the eye marker. The eye marker will contain the metadata for the
    2.69 -  ;; eye, and will be moved by it's bound geometry. The dimensions of
    2.70 -  ;; the eye's camera are equal to the dimensions of the eye's "UV"
    2.71 -  ;; map. 
    2.72 +;; Each eye in the creature in blender will work the same way as
    2.73 +;; joints -- a zero dimensional object with no geometry whose local
    2.74 +;; coordinate system determines the orientation of the resulting
    2.75 +;; eye. All eyes will have a parent named "eyes" just as all joints
    2.76 +;; have a parent named "joints". The resulting camera will be a
    2.77 +;; ChaseCamera or a CameraNode bound to the geo that is closest to
    2.78 +;; the eye marker. The eye marker will contain the metadata for the
    2.79 +;; eye, and will be moved by it's bound geometry. The dimensions of
    2.80 +;; the eye's camera are equal to the dimensions of the eye's "UV"
    2.81 +;; map.
    2.82  
    2.83 -(defn eye-target
    2.84 -  "The closest object in creature to eye."
    2.85 +
    2.86 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    2.87 +
    2.88 +;; Ears work the same way as vision.
    2.89 +
    2.90 +;; (hearing creature) will return [init-functions
    2.91 +;; sensor-functions]. The init functions each take the world and
    2.92 +;; register a SoundProcessor that does foureier transforms on the
    2.93 +;; incommong sound data, making it available to each sensor function.
    2.94 +
    2.95 +(defn creature-ears
    2.96 +  "The ear nodes which are children of the \"ears\" node in the
    2.97 +  creature."
    2.98 +  [#^Node creature]
    2.99 +  (if-let [ear-node (.getChild creature "ears")]
   2.100 +    (seq (.getChildren ear-node))
   2.101 +    (do (println-repl "could not find ears node") [])))
   2.102 +
   2.103 +(defn closest-node
   2.104 +  "The closest object in creature to the given node."
   2.105    [#^Node creature #^Node eye]
   2.106    (loop [radius (float 0.01)]
   2.107      (let [results (CollisionResults.)]
   2.108 @@ -715,14 +731,14 @@
   2.109          (.getGeometry target)
   2.110          (recur (float (* 2 radius)))))))
   2.111  
   2.112 -(defn bind-camera
   2.113 -  "Bind the camera to the Spatial such that it will maintain its
   2.114 +(defn bind-sense
   2.115 +  "Bind the sense to the Spatial such that it will maintain its
   2.116     current position relative to the Spatial no matter how the spatial
   2.117 -   moves."
   2.118 -  [#^Spatial obj #^Camera cam]
   2.119 -  (let [cam-offset (.subtract (.getLocation cam)
   2.120 -                              (.getWorldTranslation obj))
   2.121 -        initial-cam-rotation (Quaternion. (.getRotation cam))
   2.122 +   moves. 'sense can be either a Camera or Listener object."
   2.123 +  [#^Spatial obj sense]
   2.124 +  (let [sense-offset (.subtract (.getLocation sense)
   2.125 +                                (.getWorldTranslation obj))
   2.126 +        initial-sense-rotation (Quaternion. (.getRotation sense))
   2.127          base-anti-rotation (.inverse (.getWorldRotation obj))]
   2.128      (.addControl
   2.129       obj
   2.130 @@ -730,20 +746,82 @@
   2.131         (controlUpdate [tpf]
   2.132           (let [total-rotation
   2.133                 (.mult base-anti-rotation (.getWorldRotation obj))]
   2.134 -           (.setLocation cam
   2.135 +           (.setLocation sense
   2.136                           (.add
   2.137 -                          (.mult total-rotation cam-offset)
   2.138 +                          (.mult total-rotation sense-offset)
   2.139                            (.getWorldTranslation obj)))
   2.140 -           (.setRotation cam
   2.141 -                         (.mult total-rotation initial-cam-rotation))))
   2.142 +           (.setRotation sense
   2.143 +                         (.mult total-rotation initial-sense-rotation))))
   2.144         (controlRender [_ _])))))
   2.145  
   2.146  
   2.147 +(defn update-listener-velocity
   2.148 +  "Update the listener's velocity every update loop."
   2.149 +  [#^Spatial obj #^Listener lis]
   2.150 +  (let [old-position (atom (.getLocation lis))]
   2.151 +    (.addControl
   2.152 +     obj
   2.153 +     (proxy [AbstractControl] []
   2.154 +       (controlUpdate [tpf]
   2.155 +         (let [new-position (.getLocation lis)]
   2.156 +           (.setVelocity
   2.157 +            lis 
   2.158 +            (.mult (.subtract new-position @old-position)
   2.159 +                   (float (/ tpf))))
   2.160 +           (reset! old-position new-position)))
   2.161 +       (controlRender [_ _])))))
   2.162 +
   2.163 +(import com.aurellem.capture.audio.AudioSendRenderer)
   2.164 +
   2.165 +(defn attach-ear
   2.166 +  [#^Application world #^Node creature #^Spatial ear continuation]
   2.167 +  (let [target (closest-node creature ear)
   2.168 +        lis (Listener.)
   2.169 +        audio-renderer (.getAudioRenderer world)
   2.170 +        sp (sound-processor continuation)]
   2.171 +    (println-repl "audio-renderer is " audio-renderer)
   2.172 +    (.setLocation lis (.getWorldTranslation ear))
   2.173 +    (.setRotation lis (.getWorldRotation ear))
   2.174 +    (bind-sense target lis)
   2.175 +    (update-listener-velocity target lis)
   2.176 +    (.addListener audio-renderer lis)
   2.177 +    (.registerSoundProcessor audio-renderer lis sp)))
   2.178 +
   2.179 +(defn enable-hearing
   2.180 +  [#^Node creature #^Spatial ear]
   2.181 +  (let [hearing-data (atom [])]
   2.182 +    [(fn [world]
   2.183 +       (attach-ear world creature ear
   2.184 +                   (fn [data]
   2.185 +                     (reset! hearing-data (vec data)))))
   2.186 +     [(fn []
   2.187 +        (let [data @hearing-data
   2.188 +              topology              
   2.189 +              (vec (map #(vector % 0) (range 0 (count data))))
   2.190 +              scaled-data
   2.191 +              (vec
   2.192 +               (map
   2.193 +                #(rem (int (* 255 (/ (+ 1 %) 2)))  256)
   2.194 +                   data))]
   2.195 +          (println-repl (take 10 scaled-data))
   2.196 +          [topology scaled-data]))
   2.197 +        ]]))
   2.198 +
   2.199 +(defn hearing
   2.200 +  [#^Node creature]
   2.201 +  (reduce
   2.202 +   (fn [[init-a senses-a]
   2.203 +        [init-b senses-b]]
   2.204 +     [(conj init-a init-b)
   2.205 +      (into senses-a senses-b)])
   2.206 +   [[][]]      
   2.207 +   (for [ear (creature-ears creature)]
   2.208 +     (enable-hearing creature ear))))
   2.209 +
   2.210  (defn attach-eye
   2.211    "Attach a Camera to the appropiate area and return the Camera."
   2.212    [#^Node creature #^Spatial eye]
   2.213 -
   2.214 -  (let [target (eye-target creature eye)
   2.215 +  (let [target (closest-node creature eye)
   2.216          [cam-width cam-height] (eye-dimensions eye)
   2.217          cam (Camera. cam-width cam-height)]
   2.218      (.setLocation cam (.getWorldTranslation eye))
   2.219 @@ -751,52 +829,49 @@
   2.220      (.setFrustumPerspective
   2.221       cam 45 (/ (.getWidth cam) (.getHeight cam))
   2.222       1 1000)
   2.223 -                                            
   2.224 -    (bind-camera target cam)
   2.225 +    (bind-sense target cam)
   2.226      cam))
   2.227  
   2.228 -
   2.229  (def presets
   2.230    {:all    0xFFFFFF
   2.231     :red    0xFF0000
   2.232     :blue   0x0000FF
   2.233     :green  0x00FF00})
   2.234  
   2.235 -
   2.236 -
   2.237  (defn enable-vision
   2.238    "return [init-function sensor-functions] for a particular eye"
   2.239    [#^Node creature #^Spatial eye & {skip :skip :or {skip 0}}]
   2.240    (let [retinal-map (retina-sensor-image eye)
   2.241 -        vision-image (atom nil)
   2.242 -        camera (attach-eye creature eye)]
   2.243 -    [
   2.244 -    (fn [world]
   2.245 -      (add-eye
   2.246 -       world camera
   2.247 -       (let [counter  (atom 0)]
   2.248 -         (fn [r fb bb bi]
   2.249 -           (if (zero? (rem (swap! counter inc) (inc skip)))
   2.250 -             (reset! vision-image (BufferedImage! r fb bb bi)))))))
   2.251 -    (vec
   2.252 -     (map
   2.253 -      (fn [[key image]]
   2.254 -        (let [whites (white-coordinates image)
   2.255 -              topology (vec (collapse whites))
   2.256 -              mask (presets key)]
   2.257 -          (fn []
   2.258 -            (vector
   2.259 -             topology
   2.260 -             (vec 
   2.261 -              (for [[x y] whites]
   2.262 -                (bit-and
   2.263 -                 mask (.getRGB @vision-image x y))))))))
   2.264 -        retinal-map))
   2.265 -    ]))
   2.266 +        camera (attach-eye creature eye)
   2.267 +        vision-image
   2.268 +        (atom
   2.269 +         (BufferedImage. (.getWidth camera)
   2.270 +                         (.getHeight camera)
   2.271 +                         BufferedImage/TYPE_BYTE_BINARY))]
   2.272 +    [(fn [world]
   2.273 +       (add-eye
   2.274 +        world camera
   2.275 +        (let [counter  (atom 0)]
   2.276 +          (fn [r fb bb bi]
   2.277 +            (if (zero? (rem (swap! counter inc) (inc skip)))
   2.278 +              (reset! vision-image (BufferedImage! r fb bb bi)))))))
   2.279 +     (vec
   2.280 +      (map
   2.281 +       (fn [[key image]]
   2.282 +         (let [whites (white-coordinates image)
   2.283 +               topology (vec (collapse whites))
   2.284 +               mask (presets key)]
   2.285 +           (fn []
   2.286 +             (vector
   2.287 +              topology
   2.288 +              (vec 
   2.289 +               (for [[x y] whites]
   2.290 +                 (bit-and
   2.291 +                  mask (.getRGB @vision-image x y))))))))
   2.292 +       retinal-map))]))
   2.293  
   2.294  (defn vision
   2.295    [#^Node creature & {skip :skip :or {skip 0}}]
   2.296 -
   2.297    (reduce
   2.298     (fn [[init-a senses-a]
   2.299          [init-b senses-b]]
   2.300 @@ -827,8 +902,8 @@
   2.301          (dorun
   2.302           (for [i (range (count coords))]
   2.303             (.setRGB image ((coords i) 0) ((coords i) 1)
   2.304 -                    ({0 -16777216
   2.305 -                      1 -1} (sensor-data i)))))
   2.306 +                    ({0 0x000000
   2.307 +                      1 0xFFFFFF} (sensor-data i)))))
   2.308          (vi image)))))
   2.309  
   2.310  (defn debug-vision-window
   2.311 @@ -844,9 +919,33 @@
   2.312                     (sensor-data i))))
   2.313          (vi image)))))
   2.314  
   2.315 +(defn debug-hearing-window
   2.316 +  "view audio data"
   2.317 +  [height]
   2.318 +  (let [vi (view-image)]
   2.319 +    (fn [[coords sensor-data]]
   2.320 +      (let [image (BufferedImage. (count coords) height
   2.321 +                                  BufferedImage/TYPE_INT_RGB)]
   2.322 +        (dorun
   2.323 +         (for [x (range (count coords))]
   2.324 +           (dorun
   2.325 +            (for [y (range height)]
   2.326 +              (let [raw-sensor (sensor-data x)]
   2.327 +                (.setRGB image x y
   2.328 +                         (+ raw-sensor
   2.329 +                            (bit-shift-left raw-sensor 8)
   2.330 +                            (bit-shift-left raw-sensor 16))))))))
   2.331 +        (vi image)))))
   2.332 +        
   2.333 +         
   2.334 +
   2.335  ;;(defn test-touch [world creature]
   2.336  
   2.337  
   2.338 +
   2.339 +
   2.340 +
   2.341 +
   2.342  (defn test-creature [thing]
   2.343    (let [x-axis
   2.344          (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)
   2.345 @@ -860,6 +959,13 @@
   2.346          [init-vision-fns vision-data] (vision creature)
   2.347          vision-debug (map (fn [_] (debug-vision-window)) vision-data)
   2.348          me (sphere 0.5 :color ColorRGBA/Blue :physical? false)
   2.349 +        [init-hearing-fns hearing-senses] (hearing creature)
   2.350 +        hearing-windows (map (fn [_] (debug-hearing-window 50))
   2.351 +                             hearing-senses)
   2.352 +        bang (AudioNode. (asset-manager)
   2.353 +                         "Sounds/dream.wav" false)
   2.354 +        ;; dream
   2.355 +
   2.356          ]
   2.357    (world
   2.358     (nodify [creature
   2.359 @@ -868,11 +974,18 @@
   2.360              x-axis y-axis z-axis
   2.361              me
   2.362              ])
   2.363 -   standard-debug-controls
   2.364 +   (merge standard-debug-controls
   2.365 +          {"key-return"
   2.366 +           (fn [_ value]
   2.367 +             (if value
   2.368 +               (do
   2.369 +                 (println-repl "play-sound")
   2.370 +                 (.play bang))))})
   2.371     (fn [world]
   2.372       (light-up-everything world)
   2.373       (enable-debug world)
   2.374       (dorun (map #(% world) init-vision-fns))
   2.375 +     (dorun (map #(% world) init-hearing-fns))
   2.376       
   2.377       (add-eye world
   2.378                (attach-eye creature (test-eye))
   2.379 @@ -889,14 +1002,20 @@
   2.380     (fn [world tpf]
   2.381       ;;(dorun 
   2.382       ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world))))
   2.383 -    
   2.384 +     
   2.385 +
   2.386 +     
   2.387       (dorun
   2.388        (map #(%1 (%2 (.getRootNode world)))
   2.389             touch-debug-windows touch-nerves))
   2.390 +     
   2.391       (dorun
   2.392        (map #(%1 (%2))
   2.393             vision-debug vision-data))
   2.394 -
   2.395 +     (dorun
   2.396 +      (map #(%1 (%2)) hearing-windows hearing-senses))
   2.397 +     
   2.398 +     
   2.399       ;;(println-repl (vision-data))
   2.400       (.setLocalTranslation me (.getLocation (.getCamera world)))
   2.401       
   2.402 @@ -995,7 +1114,7 @@
   2.403                            (.setLocation camera-pos)
   2.404                            (.lookAt Vector3f/ZERO
   2.405                                     Vector3f/UNIT_X))]
   2.406 -                 (bind-camera rock cam)
   2.407 +                 (bind-sense rock cam)
   2.408                   
   2.409                   (.setTimer world (RatchetTimer. 60))
   2.410                   (add-eye world cam (comp (view-image) BufferedImage!))
   2.411 @@ -1004,6 +1123,7 @@
   2.412               (fn [_ _] (println-repl rot)))))
   2.413         
   2.414  
   2.415 +
   2.416  #+end_src
   2.417  
   2.418  #+results: body-1