# HG changeset patch # User Robert McIntyre # Date 1328351399 25200 # Node ID c33a8e5fe7bc3b609e318f56aaa480dd6b3408f2 # Parent 985c7365992362d295a7f3cfc95a406c67ef0266 removed hearing-init-fns requirement, changed names diff -r 985c73659923 -r c33a8e5fe7bc org/ear.org --- a/org/ear.org Sat Feb 04 02:15:32 2012 -0700 +++ b/org/ear.org Sat Feb 04 03:29:59 2012 -0700 @@ -749,13 +749,22 @@ #+include "../../jmeCapture/src/com/aurellem/capture/audio/SoundProcessor.java" src java + +Ears work the same way as vision. + +(hearing creature) will return [init-functions sensor-functions]. The +init functions each take the world and register a SoundProcessor that +does foureier transforms on the incommong sound data, making it +available to each sensor function. + + #+name: ears #+begin_src clojure (ns cortex.hearing "Simulate the sense of hearing in jMonkeyEngine3. Enables multiple - listeners at different positions in the same world. Passes vectors - of floats in the range [-1.0 -- 1.0] in PCM format to any arbitrary - function." + listeners at different positions in the same world. Automatically + reads ear-nodes from specially prepared blender files and + instantiates them in the world as actual ears." {:author "Robert McIntyre"} (:use (cortex world util sense)) (:import java.nio.ByteBuffer) @@ -763,7 +772,8 @@ (:import com.aurellem.capture.audio.SoundProcessor) (:import javax.sound.sampled.AudioFormat)) -(cortex.import/mega-import-jme3) +(cortex.import/mega-import-jme3) +(use 'clojure.contrib.def) (defn sound-processor "Deals with converting ByteBuffers into Vectors of floats so that @@ -783,12 +793,11 @@ (continuation (vec floats)))))) -(defn ears - "Return the children of the creature's \"ears\" node." - [#^Node creature] - (if-let [ear-node (.getChild creature "ears")] - (seq (.getChildren ear-node)) - (do (println-repl "could not find ears node") []))) +(defvar + ^{:arglists '([creature])} + ears + (sense-nodes "ears") + "Return the children of the creature's \"ears\" node.") (defn update-listener-velocity! "Update the listener's velocity every update loop." @@ -808,7 +817,10 @@ (import com.aurellem.capture.audio.AudioSendRenderer) -(defn create-listener! +(defn create-listener! + "Create a Listener centered on the current position of 'ear + which follows the closest physical node in 'creature and + sends sound data to 'continuation." [#^Application world #^Node creature #^Spatial ear continuation] (let [target (closest-node creature ear) lis (Listener.) @@ -822,34 +834,36 @@ (.registerSoundProcessor audio-renderer lis sp))) (defn hearing-fn + "Returns a functon which returns auditory sensory data when called + inside a running simulation." [#^Node creature #^Spatial ear] - (let [hearing-data (atom [])] - [(fn [world] - (create-listener! world creature ear - (fn [data] - (reset! hearing-data (vec data))))) - [(fn [] - (let [data @hearing-data - topology - (vec (map #(vector % 0) (range 0 (count data)))) - scaled-data - (vec - (map - #(rem (int (* 255 (/ (+ 1 %) 2))) 256) - data))] - [topology scaled-data])) - ]])) - + (let [hearing-data (atom []) + register-listener! + (runonce + (fn [#^Application world] + (create-listener! + world creature ear + (fn [data] + (reset! hearing-data (vec data))))))] + (fn [#^Application world] + (register-listener! world) + (let [data @hearing-data + topology + (vec (map #(vector % 0) (range 0 (count data)))) + scaled-data + (vec + (map + #(rem (int (* 255 (/ (+ 1 %) 2))) 256) + data))] + [topology scaled-data])))) + (defn hearing! + "Endow the creature in a particular world with the sense of + hearing. Will return a sequence of functions, one for each ear, + which when called will return the auditory data from that ear." [#^Node creature] - (reduce - (fn [[init-a senses-a] - [init-b senses-b]] - [(conj init-a init-b) - (into senses-a senses-b)]) - [[][]] - (for [ear (ears creature)] - (hearing-fn creature ear)))) + (for [ear (ears creature)] + (hearing-fn creature ear))) #+end_src diff -r 985c73659923 -r c33a8e5fe7bc org/ideas.org --- a/org/ideas.org Sat Feb 04 02:15:32 2012 -0700 +++ b/org/ideas.org Sat Feb 04 03:29:59 2012 -0700 @@ -114,7 +114,13 @@ - [ ] joints! - [ ] touch! - - [ ] hearing! + - [X] hearing! - [ ] vision! - [ ] proprioception! - [ ] movement! + + +;;In the elder days of Art, +;;Builders wrought with greatest care +;;Each minute and unseen part; +;;For the Gods see everywhere. diff -r 985c73659923 -r c33a8e5fe7bc org/sense-util.org --- a/org/sense-util.org Sat Feb 04 02:15:32 2012 -0700 +++ b/org/sense-util.org Sat Feb 04 03:29:59 2012 -0700 @@ -174,6 +174,14 @@ [#^Spatial object local-coordinate] (.localToWorld object local-coordinate nil)) + +(defn sense-nodes [parent-name] + (fn [#^Node creature] + (if-let [sense-node (.getChild creature parent-name)] + (seq (.getChildren sense-node)) + (do (println-repl "could not find" parent-name "node") [])))) + + #+end_src #+results: sense-util diff -r 985c73659923 -r c33a8e5fe7bc org/test-creature.org --- a/org/test-creature.org Sat Feb 04 02:15:32 2012 -0700 +++ b/org/test-creature.org Sat Feb 04 03:29:59 2012 -0700 @@ -184,7 +184,7 @@ [init-vision-fns vision-data] (vision creature) vision-debug (map (fn [_] (debug-vision-window)) vision-data) me (sphere 0.5 :color ColorRGBA/Blue :physical? false) - [init-hearing-fns hearing-senses] (hearing! creature) + hearing-senses (hearing! creature) hearing-windows (map (fn [_] (debug-hearing-window 50)) hearing-senses) bell (AudioNode. (asset-manager) @@ -231,7 +231,7 @@ (light-up-everything world) (enable-debug world) (dorun (map #(% world) init-vision-fns)) - (dorun (map #(% world) init-hearing-fns)) + ;;(dorun (map #(% world) init-hearing-fns)) (add-eye world (attach-eye creature (test-eye)) @@ -259,7 +259,7 @@ (map #(%1 (%2)) vision-debug vision-data)) (dorun - (map #(%1 (%2)) hearing-windows hearing-senses)) + (map #(%1 (%2 world)) hearing-windows hearing-senses)) ;;(println-repl (vision-data)) diff -r 985c73659923 -r c33a8e5fe7bc org/util.org --- a/org/util.org Sat Feb 04 02:15:32 2012 -0700 +++ b/org/util.org Sat Feb 04 03:29:59 2012 -0700 @@ -202,6 +202,19 @@ keeping the keys the same." [f m] (zipmap (keys m) (map f (vals m)))) +(defn runonce + "Decorator. returns a function which will run only once. + Inspired by Halloway's version from Lancet." + {:author "Robert McIntyre"} + [function] + (let [sentinel (Object.) + result (atom sentinel)] + (fn [& args] + (locking sentinel + (if (= @result sentinel) + (reset! result (apply function args)) + @result))))) + #+end_src