view org/sense-util.org @ 181:0f1c7921d967

removed blender.org; got rid of magic constant in sense-utils.
author Robert McIntyre <rlm@mit.edu>
date Sat, 04 Feb 2012 07:31:08 -0700
parents 9e6a30b8c99a
children f2552d61e8df
line wrap: on
line source
1 #+title: General sense/effector utilities
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description: sensory utilities
5 #+keywords: simulation, jMonkeyEngine3, clojure, simulated senses
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
10 #+name: sense-util
11 #+begin_src clojure
12 (ns cortex.sense)
13 (cortex.import/mega-import-jme3)
14 (import ij.process.ImageProcessor)
15 (import java.awt.image.BufferedImage)
16 (use 'cortex.util)
17 (use 'cortex.world)
18 (import jme3tools.converters.ImageToAwt)
20 (defn meta-data
21 "Get the meta-data for a node created with blender."
22 [blender-node key]
23 (if-let [data (.getUserData blender-node "properties")]
24 (.findValue data key)
25 nil))
27 (defn closest-node
28 "Return the object in creature which is closest to the given node."
29 ;;dylan"The closest object in creature to the given node."
30 [#^Node creature #^Node eye]
31 (loop [radius (float 0.01)]
32 (let [results (CollisionResults.)]
33 (.collideWith
34 creature
35 (BoundingBox. (.getWorldTranslation eye)
36 radius radius radius)
37 results)
38 (if-let [target (first results)]
39 (.getGeometry target)
40 (recur (float (* 2 radius)))))))
42 (defn bind-sense
43 "Bind the sense to the Spatial such that it will maintain its
44 current position relative to the Spatial no matter how the spatial
45 moves. 'sense can be either a Camera or Listener object."
46 [#^Spatial obj sense]
47 (let [sense-offset (.subtract (.getLocation sense)
48 (.getWorldTranslation obj))
49 initial-sense-rotation (Quaternion. (.getRotation sense))
50 base-anti-rotation (.inverse (.getWorldRotation obj))]
51 (.addControl
52 obj
53 (proxy [AbstractControl] []
54 (controlUpdate [tpf]
55 (let [total-rotation
56 (.mult base-anti-rotation (.getWorldRotation obj))]
57 (.setLocation
58 sense
59 (.add
60 (.mult total-rotation sense-offset)
61 (.getWorldTranslation obj)))
62 (.setRotation
63 sense
64 (.mult total-rotation initial-sense-rotation))))
65 (controlRender [_ _])))))
67 (def white 0xFFFFFF)
69 (defn white? [rgb]
70 (= (bit-and white rgb) white))
72 (defn filter-pixels
73 "List the coordinates of all pixels matching pred, within the bounds
74 provided. Bounds -> [x0 y0 width height]"
75 {:author "Dylan Holmes"}
76 ([pred #^BufferedImage image]
77 (filter-pixels pred image [0 0 (.getWidth image) (.getHeight image)]))
78 ([pred #^BufferedImage image [x0 y0 width height]]
79 ((fn accumulate [x y matches]
80 (cond
81 (>= y (+ height y0)) matches
82 (>= x (+ width x0)) (recur 0 (inc y) matches)
83 (pred (.getRGB image x y))
84 (recur (inc x) y (conj matches [x y]))
85 :else (recur (inc x) y matches)))
86 x0 y0 [])))
88 (defn white-coordinates
89 "Coordinates of all the white pixels in a subset of the image."
90 ([#^BufferedImage image bounds]
91 (filter-pixels white? image bounds))
92 ([#^BufferedImage image]
93 (filter-pixels white? image)))
95 (defn points->image
96 "Take a sparse collection of points and visuliaze it as a
97 BufferedImage."
98 [points]
99 (if (empty? points)
100 (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY)
101 (let [xs (vec (map first points))
102 ys (vec (map second points))
103 x0 (apply min xs)
104 y0 (apply min ys)
105 width (- (apply max xs) x0)
106 height (- (apply max ys) y0)
107 image (BufferedImage. (inc width) (inc height)
108 BufferedImage/TYPE_INT_RGB)]
109 (dorun
110 (for [x (range (.getWidth image))
111 y (range (.getHeight image))]
112 (.setRGB image x y 0xFF0000)))
113 (dorun
114 (for [index (range (count points))]
115 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1)))
116 image)))
118 (defn average [coll]
119 (/ (reduce + coll) (count coll)))
121 (defn collapse-1d
122 "One dimensional analogue of collapse"
123 [center line]
124 (let [length (count line)
125 num-above (count (filter (partial < center) line))
126 num-below (- length num-above)]
127 (range (- center num-below)
128 (+ center num-above))))
130 (defn collapse
131 "Take a set of pairs of integers and collapse them into a
132 contigous bitmap."
133 [points]
134 (if (empty? points) []
135 (let
136 [num-points (count points)
137 center (vector
138 (int (average (map first points)))
139 (int (average (map first points))))
140 flattened
141 (reduce
142 concat
143 (map
144 (fn [column]
145 (map vector
146 (map first column)
147 (collapse-1d (second center)
148 (map second column))))
149 (partition-by first (sort-by first points))))
150 squeezed
151 (reduce
152 concat
153 (map
154 (fn [row]
155 (map vector
156 (collapse-1d (first center)
157 (map first row))
158 (map second row)))
159 (partition-by second (sort-by second flattened))))
160 relocate
161 (let [min-x (apply min (map first squeezed))
162 min-y (apply min (map second squeezed))]
163 (map (fn [[x y]]
164 [(- x min-x)
165 (- y min-y)])
166 squeezed))]
167 relocate)))
169 (defn world-to-local
170 "Convert the world coordinates into coordinates relative to the
171 object (i.e. local coordinates), taking into account the rotation
172 of object."
173 [#^Spatial object world-coordinate]
174 (.worldToLocal object world-coordinate nil))
176 (defn local-to-world
177 "Convert the local coordinates into coordinates into world relative
178 coordinates"
179 [#^Spatial object local-coordinate]
180 (.localToWorld object local-coordinate nil))
183 (defn sense-nodes [parent-name]
184 (fn [#^Node creature]
185 (if-let [sense-node (.getChild creature parent-name)]
186 (seq (.getChildren sense-node))
187 (do (println-repl "could not find" parent-name "node") []))))
189 (defn load-image
190 "Load an image as a BufferedImage using the asset-manager system."
191 [asset-relative-path]
192 (ImageToAwt/convert
193 (.getImage (.loadTexture (asset-manager) asset-relative-path))
194 false false 0))
196 (defn jme-to-blender
197 "Convert from JME coordinates to Blender coordinates"
198 [#^Vector3f in]
199 (Vector3f. (.getX in)
200 (- (.getZ in))
201 (.getY in)))
203 (defn blender-to-jme
204 "Convert from Blender coordinates to JME coordinates"
205 [#^Vector3f in]
206 (Vector3f. (.getX in)
207 (.getZ in)
208 (- (.getY in))))
209 #+end_src
211 #+results: sense-util
212 : #'cortex.sense/meta-data
216 * COMMENT generate source
217 #+begin_src clojure :tangle ../src/cortex/sense.clj
218 <<sense-util>>
219 #+end_src