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