comparison 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
comparison
equal deleted inserted replaced
122:b591da250afc 123:91773e8ec50f
653 (map #(vector (.getWidth %) (.getHeight %)) 653 (map #(vector (.getWidth %) (.getHeight %))
654 (vals (retina-sensor-image eye)))] 654 (vals (retina-sensor-image eye)))]
655 [(apply max (map first dimensions)) 655 [(apply max (map first dimensions))
656 (apply max (map second dimensions))])) 656 (apply max (map second dimensions))]))
657 657
658
659 (defn creature-eyes 658 (defn creature-eyes
660 "The eye nodes which are children of the \"eyes\" node in the 659 "The eye nodes which are children of the \"eyes\" node in the
661 creature." 660 creature."
662 [#^Node creature] 661 [#^Node creature]
663 (if-let [eye-node (.getChild creature "eyes")] 662 (if-let [eye-node (.getChild creature "eyes")]
664 (seq (.getChildren eye-node)) 663 (seq (.getChildren eye-node))
665 (do (println-repl "could not find eyes node") []))) 664 (do (println-repl "could not find eyes node") [])))
666 665
667 666 ;; Here's how vision will work.
668 ;; Here's how vision will work. 667
669 668 ;; Make the continuation in scene-processor take FrameBuffer,
670 ;; Make the continuation in scene-processor take FrameBuffer, 669 ;; byte-buffer, BufferedImage already sized to the correct
671 ;; byte-buffer, BufferedImage already sized to the correct 670 ;; dimensions. the continuation will decide wether to "mix" them
672 ;; dimensions. the continuation will decide wether to "mix" them 671 ;; into the BufferedImage, lazily ignore them, or mix them halfway
673 ;; into the BufferedImage, lazily ignore them, or mix them halfway 672 ;; and call c/graphics card routines.
674 ;; and call c/graphics card routines. 673
675 674 ;; (vision creature) will take an optional :skip argument which will
676 ;; (vision creature) will take an optional :skip argument which will 675 ;; inform the continuations in scene processor to skip the given
677 ;; inform the continuations in scene processor to skip the given 676 ;; number of cycles; 0 means that no cycles will be skipped.
678 ;; number of cycles; 0 means that no cycles will be skipped. 677
679 678 ;; (vision creature) will return [init-functions sensor-functions].
680 ;; (vision creature) will return [init-functions sensor-functions]. 679 ;; The init-functions are each single-arg functions that take the
681 ;; The init-functions are each single-arg functions that take the 680 ;; world and register the cameras and must each be called before the
682 ;; world and register the cameras and must each be called before the 681 ;; corresponding sensor-functions. Each init-function returns the
683 ;; corresponding sensor-functions. Each init-function returns the 682 ;; viewport for that eye which can be manipulated, saved, etc. Each
684 ;; viewport for that eye which can be manipulated, saved, etc. Each 683 ;; sensor-function is a thunk and will return data in the same
685 ;; sensor-function is a thunk and will return data in the same 684 ;; format as the tactile-sensor functions; the structure is
686 ;; format as the tactile-sensor functions; the structure is 685 ;; [topology, sensor-data]. Internally, these sensor-functions
687 ;; [topology, sensor-data]. Internally, these sensor-functions 686 ;; maintain a reference to sensor-data which is periodically updated
688 ;; maintain a reference to sensor-data which is periodically updated 687 ;; by the continuation function established by its init-function.
689 ;; by the continuation function established by its init-function. 688 ;; They can be queried every cycle, but their information may not
690 ;; They can be queried every cycle, but their information may not 689 ;; necessairly be different every cycle.
691 ;; necessairly be different every cycle. 690
692 691 ;; Each eye in the creature in blender will work the same way as
693 ;; Each eye in the creature in blender will work the same way as 692 ;; joints -- a zero dimensional object with no geometry whose local
694 ;; joints -- a one dimensional object with no geometry whose local 693 ;; coordinate system determines the orientation of the resulting
695 ;; coordinate system determines the orientation of the resulting 694 ;; eye. All eyes will have a parent named "eyes" just as all joints
696 ;; eye. All eyes will have a parent named "eyes" just as all joints 695 ;; have a parent named "joints". The resulting camera will be a
697 ;; have a parent named "joints". The resulting camera will be a 696 ;; ChaseCamera or a CameraNode bound to the geo that is closest to
698 ;; ChaseCamera or a CameraNode bound to the geo that is closest to 697 ;; the eye marker. The eye marker will contain the metadata for the
699 ;; the eye marker. The eye marker will contain the metadata for the 698 ;; eye, and will be moved by it's bound geometry. The dimensions of
700 ;; eye, and will be moved by it's bound geometry. The dimensions of 699 ;; the eye's camera are equal to the dimensions of the eye's "UV"
701 ;; the eye's camera are equal to the dimensions of the eye's "UV" 700 ;; map.
702 ;; map. 701
703 702
704 (defn eye-target 703 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705 "The closest object in creature to eye." 704
705 ;; Ears work the same way as vision.
706
707 ;; (hearing creature) will return [init-functions
708 ;; sensor-functions]. The init functions each take the world and
709 ;; register a SoundProcessor that does foureier transforms on the
710 ;; incommong sound data, making it available to each sensor function.
711
712 (defn creature-ears
713 "The ear nodes which are children of the \"ears\" node in the
714 creature."
715 [#^Node creature]
716 (if-let [ear-node (.getChild creature "ears")]
717 (seq (.getChildren ear-node))
718 (do (println-repl "could not find ears node") [])))
719
720 (defn closest-node
721 "The closest object in creature to the given node."
706 [#^Node creature #^Node eye] 722 [#^Node creature #^Node eye]
707 (loop [radius (float 0.01)] 723 (loop [radius (float 0.01)]
708 (let [results (CollisionResults.)] 724 (let [results (CollisionResults.)]
709 (.collideWith 725 (.collideWith
710 creature 726 creature
713 results) 729 results)
714 (if-let [target (first results)] 730 (if-let [target (first results)]
715 (.getGeometry target) 731 (.getGeometry target)
716 (recur (float (* 2 radius))))))) 732 (recur (float (* 2 radius)))))))
717 733
718 (defn bind-camera 734 (defn bind-sense
719 "Bind the camera to the Spatial such that it will maintain its 735 "Bind the sense to the Spatial such that it will maintain its
720 current position relative to the Spatial no matter how the spatial 736 current position relative to the Spatial no matter how the spatial
721 moves." 737 moves. 'sense can be either a Camera or Listener object."
722 [#^Spatial obj #^Camera cam] 738 [#^Spatial obj sense]
723 (let [cam-offset (.subtract (.getLocation cam) 739 (let [sense-offset (.subtract (.getLocation sense)
724 (.getWorldTranslation obj)) 740 (.getWorldTranslation obj))
725 initial-cam-rotation (Quaternion. (.getRotation cam)) 741 initial-sense-rotation (Quaternion. (.getRotation sense))
726 base-anti-rotation (.inverse (.getWorldRotation obj))] 742 base-anti-rotation (.inverse (.getWorldRotation obj))]
727 (.addControl 743 (.addControl
728 obj 744 obj
729 (proxy [AbstractControl] [] 745 (proxy [AbstractControl] []
730 (controlUpdate [tpf] 746 (controlUpdate [tpf]
731 (let [total-rotation 747 (let [total-rotation
732 (.mult base-anti-rotation (.getWorldRotation obj))] 748 (.mult base-anti-rotation (.getWorldRotation obj))]
733 (.setLocation cam 749 (.setLocation sense
734 (.add 750 (.add
735 (.mult total-rotation cam-offset) 751 (.mult total-rotation sense-offset)
736 (.getWorldTranslation obj))) 752 (.getWorldTranslation obj)))
737 (.setRotation cam 753 (.setRotation sense
738 (.mult total-rotation initial-cam-rotation)))) 754 (.mult total-rotation initial-sense-rotation))))
739 (controlRender [_ _]))))) 755 (controlRender [_ _])))))
740 756
757
758 (defn update-listener-velocity
759 "Update the listener's velocity every update loop."
760 [#^Spatial obj #^Listener lis]
761 (let [old-position (atom (.getLocation lis))]
762 (.addControl
763 obj
764 (proxy [AbstractControl] []
765 (controlUpdate [tpf]
766 (let [new-position (.getLocation lis)]
767 (.setVelocity
768 lis
769 (.mult (.subtract new-position @old-position)
770 (float (/ tpf))))
771 (reset! old-position new-position)))
772 (controlRender [_ _])))))
773
774 (import com.aurellem.capture.audio.AudioSendRenderer)
775
776 (defn attach-ear
777 [#^Application world #^Node creature #^Spatial ear continuation]
778 (let [target (closest-node creature ear)
779 lis (Listener.)
780 audio-renderer (.getAudioRenderer world)
781 sp (sound-processor continuation)]
782 (println-repl "audio-renderer is " audio-renderer)
783 (.setLocation lis (.getWorldTranslation ear))
784 (.setRotation lis (.getWorldRotation ear))
785 (bind-sense target lis)
786 (update-listener-velocity target lis)
787 (.addListener audio-renderer lis)
788 (.registerSoundProcessor audio-renderer lis sp)))
789
790 (defn enable-hearing
791 [#^Node creature #^Spatial ear]
792 (let [hearing-data (atom [])]
793 [(fn [world]
794 (attach-ear world creature ear
795 (fn [data]
796 (reset! hearing-data (vec data)))))
797 [(fn []
798 (let [data @hearing-data
799 topology
800 (vec (map #(vector % 0) (range 0 (count data))))
801 scaled-data
802 (vec
803 (map
804 #(rem (int (* 255 (/ (+ 1 %) 2))) 256)
805 data))]
806 (println-repl (take 10 scaled-data))
807 [topology scaled-data]))
808 ]]))
809
810 (defn hearing
811 [#^Node creature]
812 (reduce
813 (fn [[init-a senses-a]
814 [init-b senses-b]]
815 [(conj init-a init-b)
816 (into senses-a senses-b)])
817 [[][]]
818 (for [ear (creature-ears creature)]
819 (enable-hearing creature ear))))
741 820
742 (defn attach-eye 821 (defn attach-eye
743 "Attach a Camera to the appropiate area and return the Camera." 822 "Attach a Camera to the appropiate area and return the Camera."
744 [#^Node creature #^Spatial eye] 823 [#^Node creature #^Spatial eye]
745 824 (let [target (closest-node creature eye)
746 (let [target (eye-target creature eye)
747 [cam-width cam-height] (eye-dimensions eye) 825 [cam-width cam-height] (eye-dimensions eye)
748 cam (Camera. cam-width cam-height)] 826 cam (Camera. cam-width cam-height)]
749 (.setLocation cam (.getWorldTranslation eye)) 827 (.setLocation cam (.getWorldTranslation eye))
750 (.setRotation cam (.getWorldRotation eye)) 828 (.setRotation cam (.getWorldRotation eye))
751 (.setFrustumPerspective 829 (.setFrustumPerspective
752 cam 45 (/ (.getWidth cam) (.getHeight cam)) 830 cam 45 (/ (.getWidth cam) (.getHeight cam))
753 1 1000) 831 1 1000)
754 832 (bind-sense target cam)
755 (bind-camera target cam)
756 cam)) 833 cam))
757
758 834
759 (def presets 835 (def presets
760 {:all 0xFFFFFF 836 {:all 0xFFFFFF
761 :red 0xFF0000 837 :red 0xFF0000
762 :blue 0x0000FF 838 :blue 0x0000FF
763 :green 0x00FF00}) 839 :green 0x00FF00})
764 840
765
766
767 (defn enable-vision 841 (defn enable-vision
768 "return [init-function sensor-functions] for a particular eye" 842 "return [init-function sensor-functions] for a particular eye"
769 [#^Node creature #^Spatial eye & {skip :skip :or {skip 0}}] 843 [#^Node creature #^Spatial eye & {skip :skip :or {skip 0}}]
770 (let [retinal-map (retina-sensor-image eye) 844 (let [retinal-map (retina-sensor-image eye)
771 vision-image (atom nil) 845 camera (attach-eye creature eye)
772 camera (attach-eye creature eye)] 846 vision-image
773 [ 847 (atom
774 (fn [world] 848 (BufferedImage. (.getWidth camera)
775 (add-eye 849 (.getHeight camera)
776 world camera 850 BufferedImage/TYPE_BYTE_BINARY))]
777 (let [counter (atom 0)] 851 [(fn [world]
778 (fn [r fb bb bi] 852 (add-eye
779 (if (zero? (rem (swap! counter inc) (inc skip))) 853 world camera
780 (reset! vision-image (BufferedImage! r fb bb bi))))))) 854 (let [counter (atom 0)]
781 (vec 855 (fn [r fb bb bi]
782 (map 856 (if (zero? (rem (swap! counter inc) (inc skip)))
783 (fn [[key image]] 857 (reset! vision-image (BufferedImage! r fb bb bi)))))))
784 (let [whites (white-coordinates image) 858 (vec
785 topology (vec (collapse whites)) 859 (map
786 mask (presets key)] 860 (fn [[key image]]
787 (fn [] 861 (let [whites (white-coordinates image)
788 (vector 862 topology (vec (collapse whites))
789 topology 863 mask (presets key)]
790 (vec 864 (fn []
791 (for [[x y] whites] 865 (vector
792 (bit-and 866 topology
793 mask (.getRGB @vision-image x y)))))))) 867 (vec
794 retinal-map)) 868 (for [[x y] whites]
795 ])) 869 (bit-and
870 mask (.getRGB @vision-image x y))))))))
871 retinal-map))]))
796 872
797 (defn vision 873 (defn vision
798 [#^Node creature & {skip :skip :or {skip 0}}] 874 [#^Node creature & {skip :skip :or {skip 0}}]
799
800 (reduce 875 (reduce
801 (fn [[init-a senses-a] 876 (fn [[init-a senses-a]
802 [init-b senses-b]] 877 [init-b senses-b]]
803 [(conj init-a init-b) 878 [(conj init-a init-b)
804 (into senses-a senses-b)]) 879 (into senses-a senses-b)])
825 [[coords sensor-data]] 900 [[coords sensor-data]]
826 (let [image (points->image coords)] 901 (let [image (points->image coords)]
827 (dorun 902 (dorun
828 (for [i (range (count coords))] 903 (for [i (range (count coords))]
829 (.setRGB image ((coords i) 0) ((coords i) 1) 904 (.setRGB image ((coords i) 0) ((coords i) 1)
830 ({0 -16777216 905 ({0 0x000000
831 1 -1} (sensor-data i))))) 906 1 0xFFFFFF} (sensor-data i)))))
832 (vi image))))) 907 (vi image)))))
833 908
834 (defn debug-vision-window 909 (defn debug-vision-window
835 "creates function that offers a debug view of sensor data" 910 "creates function that offers a debug view of sensor data"
836 [] 911 []
842 (for [i (range (count coords))] 917 (for [i (range (count coords))]
843 (.setRGB image ((coords i) 0) ((coords i) 1) 918 (.setRGB image ((coords i) 0) ((coords i) 1)
844 (sensor-data i)))) 919 (sensor-data i))))
845 (vi image))))) 920 (vi image)))))
846 921
922 (defn debug-hearing-window
923 "view audio data"
924 [height]
925 (let [vi (view-image)]
926 (fn [[coords sensor-data]]
927 (let [image (BufferedImage. (count coords) height
928 BufferedImage/TYPE_INT_RGB)]
929 (dorun
930 (for [x (range (count coords))]
931 (dorun
932 (for [y (range height)]
933 (let [raw-sensor (sensor-data x)]
934 (.setRGB image x y
935 (+ raw-sensor
936 (bit-shift-left raw-sensor 8)
937 (bit-shift-left raw-sensor 16))))))))
938 (vi image)))))
939
940
941
847 ;;(defn test-touch [world creature] 942 ;;(defn test-touch [world creature]
943
944
945
946
848 947
849 948
850 (defn test-creature [thing] 949 (defn test-creature [thing]
851 (let [x-axis 950 (let [x-axis
852 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red) 951 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)
858 touch-nerves (touch creature) 957 touch-nerves (touch creature)
859 touch-debug-windows (map (fn [_] (debug-window)) touch-nerves) 958 touch-debug-windows (map (fn [_] (debug-window)) touch-nerves)
860 [init-vision-fns vision-data] (vision creature) 959 [init-vision-fns vision-data] (vision creature)
861 vision-debug (map (fn [_] (debug-vision-window)) vision-data) 960 vision-debug (map (fn [_] (debug-vision-window)) vision-data)
862 me (sphere 0.5 :color ColorRGBA/Blue :physical? false) 961 me (sphere 0.5 :color ColorRGBA/Blue :physical? false)
962 [init-hearing-fns hearing-senses] (hearing creature)
963 hearing-windows (map (fn [_] (debug-hearing-window 50))
964 hearing-senses)
965 bang (AudioNode. (asset-manager)
966 "Sounds/dream.wav" false)
967 ;; dream
968
863 ] 969 ]
864 (world 970 (world
865 (nodify [creature 971 (nodify [creature
866 (box 10 2 10 :position (Vector3f. 0 -9 0) 972 (box 10 2 10 :position (Vector3f. 0 -9 0)
867 :color ColorRGBA/Gray :mass 0) 973 :color ColorRGBA/Gray :mass 0)
868 x-axis y-axis z-axis 974 x-axis y-axis z-axis
869 me 975 me
870 ]) 976 ])
871 standard-debug-controls 977 (merge standard-debug-controls
978 {"key-return"
979 (fn [_ value]
980 (if value
981 (do
982 (println-repl "play-sound")
983 (.play bang))))})
872 (fn [world] 984 (fn [world]
873 (light-up-everything world) 985 (light-up-everything world)
874 (enable-debug world) 986 (enable-debug world)
875 (dorun (map #(% world) init-vision-fns)) 987 (dorun (map #(% world) init-vision-fns))
988 (dorun (map #(% world) init-hearing-fns))
876 989
877 (add-eye world 990 (add-eye world
878 (attach-eye creature (test-eye)) 991 (attach-eye creature (test-eye))
879 (comp (view-image) BufferedImage!)) 992 (comp (view-image) BufferedImage!))
880 993
887 ;;(set-gravity world (Vector3f. 0 0 0)) 1000 ;;(set-gravity world (Vector3f. 0 0 0))
888 ) 1001 )
889 (fn [world tpf] 1002 (fn [world tpf]
890 ;;(dorun 1003 ;;(dorun
891 ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world)))) 1004 ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world))))
892 1005
1006
1007
893 (dorun 1008 (dorun
894 (map #(%1 (%2 (.getRootNode world))) 1009 (map #(%1 (%2 (.getRootNode world)))
895 touch-debug-windows touch-nerves)) 1010 touch-debug-windows touch-nerves))
1011
896 (dorun 1012 (dorun
897 (map #(%1 (%2)) 1013 (map #(%1 (%2))
898 vision-debug vision-data)) 1014 vision-debug vision-data))
899 1015 (dorun
1016 (map #(%1 (%2)) hearing-windows hearing-senses))
1017
1018
900 ;;(println-repl (vision-data)) 1019 ;;(println-repl (vision-data))
901 (.setLocalTranslation me (.getLocation (.getCamera world))) 1020 (.setLocalTranslation me (.getLocation (.getCamera world)))
902 1021
903 1022
904 ) 1023 )
993 (let 1112 (let
994 [cam (doto (.clone (.getCamera world)) 1113 [cam (doto (.clone (.getCamera world))
995 (.setLocation camera-pos) 1114 (.setLocation camera-pos)
996 (.lookAt Vector3f/ZERO 1115 (.lookAt Vector3f/ZERO
997 Vector3f/UNIT_X))] 1116 Vector3f/UNIT_X))]
998 (bind-camera rock cam) 1117 (bind-sense rock cam)
999 1118
1000 (.setTimer world (RatchetTimer. 60)) 1119 (.setTimer world (RatchetTimer. 60))
1001 (add-eye world cam (comp (view-image) BufferedImage!)) 1120 (add-eye world cam (comp (view-image) BufferedImage!))
1002 (add-eye world (.getCamera world) no-op)) 1121 (add-eye world (.getCamera world) no-op))
1003 ) 1122 )
1004 (fn [_ _] (println-repl rot))))) 1123 (fn [_ _] (println-repl rot)))))
1005 1124
1125
1006 1126
1007 #+end_src 1127 #+end_src
1008 1128
1009 #+results: body-1 1129 #+results: body-1
1010 : #'cortex.silly/test-creature 1130 : #'cortex.silly/test-creature