Mercurial > cortex
diff org/test-creature.org @ 91:2bcc7636cfea
faster touch creation code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 09 Jan 2012 06:02:06 -0700 |
parents | 6d7c17c847a3 |
children | e70ec4bba96b |
line wrap: on
line diff
1.1 --- a/org/test-creature.org Sun Jan 08 06:11:58 2012 -0700 1.2 +++ b/org/test-creature.org Mon Jan 09 06:02:06 2012 -0700 1.3 @@ -307,22 +307,13 @@ 1.4 ))) 1.5 1.6 1.7 -(def colorful (.getChild (worm-model) "worm-21")) 1.8 - 1.9 -(def im-data 1.10 - (let [sink (byte-array 3145727) 1.11 - data (.getData (.getImage texture) 0)] 1.12 - (.rewind data) 1.13 - (.get data sink) 1.14 - (vec (seq sink)))) 1.15 - 1.16 +(defn colorful [] 1.17 + (.getChild (worm-model) "worm-21")) 1.18 1.19 (import jme3tools.converters.ImageToAwt) 1.20 1.21 (import ij.ImagePlus) 1.22 1.23 - 1.24 - 1.25 (defn triangle-indices 1.26 "Get the triangle vertex indices of a given triangle from a given 1.27 mesh." 1.28 @@ -339,19 +330,15 @@ 1.29 (.getBuffer 1.30 mesh 1.31 VertexBuffer$Type/TexCoord))] 1.32 - [(.get UV-buffer (* vertex-index 2)) 1.33 - (.get UV-buffer (+ 1 (* vertex-index 2)))])) 1.34 + (Vector2f. 1.35 + (.get UV-buffer (* vertex-index 2)) 1.36 + (.get UV-buffer (+ 1 (* vertex-index 2)))))) 1.37 1.38 -(defn touch-receptor-image [#^Geometry obj] 1.39 - 1.40 - 1.41 - 1.42 -;; yay there's a converter! 1.43 - 1.44 -(defn uv-image [] 1.45 +(defn touch-receptor-image 1.46 + "Return the touch-sensor distribution image in ImagePlus format." 1.47 + [#^Geometry obj] 1.48 (let 1.49 - [colorful (.getChild (worm-model) "worm-21") 1.50 - mat (.getMaterial colorful) 1.51 + [mat (.getMaterial obj) 1.52 texture 1.53 (.getTextureValue 1.54 (.getTextureParam 1.55 @@ -362,11 +349,257 @@ 1.56 "UV-map" 1.57 (ImageToAwt/convert im false false 0)))) 1.58 1.59 + 1.60 +(import ij.process.ImageProcessor) 1.61 +(import java.awt.image.BufferedImage) 1.62 + 1.63 +(defprotocol Frame 1.64 + (frame [this])) 1.65 + 1.66 +(extend-type BufferedImage 1.67 + Frame 1.68 + (frame [image] 1.69 + (merge 1.70 + (apply 1.71 + hash-map 1.72 + (interleave 1.73 + (doall (for [x (range (.getWidth image)) y (range (.getHeight image))] 1.74 + (vector x y))) 1.75 + (doall (for [x (range (.getWidth image)) y (range (.getHeight image))] 1.76 + (let [data (.getRGB image x y)] 1.77 + (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16) 1.78 + :g (bit-shift-right (bit-and 0x00ff00 data) 8) 1.79 + :b (bit-and 0x0000ff data))))))) 1.80 + {:width (.getWidth image) :height (.getHeight image)}))) 1.81 + 1.82 + 1.83 +(extend-type ImagePlus 1.84 + Frame 1.85 + (frame [image+] 1.86 + (frame (.getBufferedImage image+)))) 1.87 + 1.88 +(defn rgb->int [r g b] 1.89 + (+ (bit-shift-left r 16) 1.90 + (bit-shift-left g 8) 1.91 + b)) 1.92 + 1.93 + 1.94 + 1.95 +(defn filter-pixels 1.96 + "List the coordinates of all pixels matching pred." 1.97 + [pred #^ImageProcessor ip] 1.98 + (let 1.99 + [width (.getWidth ip) 1.100 + height (.getHeight ip)] 1.101 + ((fn accumulate [x y matches] 1.102 + (cond 1.103 + (>= y height) matches 1.104 + (>= x width) (recur 0 (inc y) matches) 1.105 + (pred (.getPixel ip x y)) 1.106 + (recur (inc x) y (conj matches (Vector2f. x y))) 1.107 + :else (recur (inc x) y matches))) 1.108 + 0 0 []))) 1.109 + 1.110 + 1.111 + 1.112 + 1.113 + 1.114 +(defn filter-pixels* 1.115 + [pred #^ImageProcessor ip] 1.116 + (let 1.117 + [width (.getWidth ip) 1.118 + height (.getHeight ip) 1.119 + coords (ref []) 1.120 + process 1.121 + (fn [[start end]] 1.122 + (loop [i start] 1.123 + (if (<= i end) 1.124 + (do 1.125 + (let [column (rem i height) 1.126 + row (unchecked-divide i width)] 1.127 + (if (pred (.getPixel ip row column)) 1.128 + (dosync (ref-set 1.129 + coords 1.130 + (conj @coords (Vector2f. column row))))) 1.131 + 1.132 + (recur (inc i))))))) 1.133 + ] 1.134 + 1.135 + 1.136 + (dorun 1.137 + (pmap process (partition 1.138 + 2 1.139 + (conj (vec (range 0 (* width height) 100)) 1.140 + (* width height))))) 1.141 + @coords)) 1.142 + 1.143 + 1.144 + 1.145 +(comment 1.146 + ((-> 1.147 + f 1.148 + (partial x) 1.149 + (partial y) 1.150 + (partial z)))) 1.151 + 1.152 +(defn filter-pixels** 1.153 + [pred #^ImageProcessor ip] 1.154 + (let [width (.getWidth ip) 1.155 + height (.getHeight ip)] 1.156 + ((fn f [x1 x2 y1 y2] 1.157 + (println x1) 1.158 + (if 1.159 + (and 1.160 + (= x1 (dec x2)) 1.161 + (= y1 (dec y2))) 1.162 + (if (pred (.getPixel ip x1 y1)) 1.163 + [[x1 y1]] 1.164 + []) 1.165 + (let 1.166 + [xm (+ x1 (/ (- x2 x1) 2)) 1.167 + ym (+ y1 (/ (- y2 y1) 2))] 1.168 + (apply concat 1.169 + (pvalues 1.170 + ;;(f x1 xm y1 ym) 1.171 + ;;(f xm x2 y1 ym) 1.172 + ;;(f x1 xm ym y2) 1.173 + (f xm x2 ym y2)))))) 1.174 + 0 width 0 height))) 1.175 + 1.176 + 1.177 + 1.178 + 1.179 + 1.180 + 1.181 + 1.182 + 1.183 +(defn white-coordinates* 1.184 + [#^ImageProcessor ip] 1.185 + (filter-pixels** #(== % -1) ip)) 1.186 + 1.187 + 1.188 +(defn white-coordinates 1.189 + "List the coordinates of all the white pixels in an image." 1.190 + [#^ImageProcessor ip] 1.191 + (let [height (.getHeight ip) 1.192 + width (.getWidth ip) 1.193 + coords (transient [])] 1.194 + (dorun 1.195 + (for [x (range width) 1.196 + y (range height)] 1.197 + (let [pixel (.getPixel ip x y)] 1.198 + (if (= pixel -1) 1.199 + (conj! coords (Vector2f. x y)))))) 1.200 + (persistent! coords))) 1.201 + 1.202 + 1.203 + 1.204 + 1.205 + 1.206 + 1.207 + 1.208 + 1.209 +(def white {:r 255, :g 255, :b 255}) 1.210 +(def black {:r 0, :g 0, :b 0}) 1.211 + 1.212 + 1.213 +(defn same-side? [p1 p2 ref p] 1.214 + (<= 1.215 + 0 1.216 + (.dot 1.217 + (.cross (.subtract p2 p1) (.subtract p p1)) 1.218 + (.cross (.subtract p2 p1) (.subtract ref p1))))) 1.219 + 1.220 +(defn inside-triangle? 1.221 + [vert-1 vert-2 vert-3 p] 1.222 + (and 1.223 + (same-side? vert-1 vert-2 vert-3 p) 1.224 + (same-side? vert-2 vert-3 vert-1 p) 1.225 + (same-side? vert-3 vert-1 vert-2 p))) 1.226 + 1.227 + 1.228 +(defn white? [color] 1.229 + (and 1.230 + (= (:r color) 255) 1.231 + (= (:b color) 255) 1.232 + (= (:g color) 255))) 1.233 + 1.234 + 1.235 ;; for each triangle in the mesh, 1.236 ;; get the normal to the triangle, 1.237 ;; look at the UV touch map, restricted to that triangle, 1.238 ;; get the positions of those touch sensors in geometry-relative 1.239 ;; coordinates. 1.240 +(defn tactile-coords [#^Geometry obj] 1.241 + (let [mesh (.getMesh obj) 1.242 + num-triangles (.getTriangleCount mesh) 1.243 + num-verticies (.getVertexCount mesh) 1.244 + uv-coord (partial uv-coord mesh) 1.245 + triangle-indices (partial triangle-indices mesh) 1.246 + receptors (touch-receptor-image obj) 1.247 + ] 1.248 + (map 1.249 + (fn [[tri-1 tri-2 tri-3]] 1.250 + (let [width (.getWidth receptors) 1.251 + height (.getHeight receptors) 1.252 + uv-1 (uv-coord tri-1) 1.253 + uv-2 (uv-coord tri-2) 1.254 + uv-3 (uv-coord tri-3) 1.255 + x-coords (map #(.getX %) [uv-1 uv-2 uv-3]) 1.256 + y-coords (map #(.getY %) [uv-1 uv-2 uv-3]) 1.257 + max-x (Math/ceil (* width (apply max x-coords))) 1.258 + min-x (Math/floor (* width (apply min x-coords))) 1.259 + max-y (Math/ceil (* height (apply max y-coords))) 1.260 + min-y (Math/floor (* height (apply min y-coords))) 1.261 + 1.262 + image-1 (Vector2f. (* width (.getX uv-1)) 1.263 + (* height (.getY uv-1))) 1.264 + image-2 (Vector2f. (* width (.getX uv-2)) 1.265 + (* height (.getY uv-2))) 1.266 + image-3 (Vector2f. (* width (.getX uv-3)) 1.267 + (* height (.getY uv-3))) 1.268 + left-corner 1.269 + (Vector2f. min-x min-y) 1.270 + 1.271 + ] 1.272 + 1.273 + (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y)) 1.274 + (let [processor (.crop (.getProcessor receptors)) 1.275 + image (frame (.getBufferedImage processor))] 1.276 + (with-meta 1.277 + (filter-keys 1.278 + (fn [[x y]] 1.279 + (inside-triangle? 1.280 + (.subtract image-1 left-corner) 1.281 + (.subtract image-2 left-corner) 1.282 + (.subtract image-3 left-corner) 1.283 + (Vector2f. x y))) 1.284 + 1.285 + 1.286 + (filter-vals white? image)) 1.287 + {:image 1.288 + (comment 1.289 + (.getBufferedImage 1.290 + (doto processor 1.291 + (.flipVertical)))) 1.292 + } 1.293 + )) 1.294 + )) (map triangle-indices (range num-triangles))))) 1.295 + 1.296 + 1.297 + 1.298 + 1.299 + 1.300 + 1.301 + 1.302 +(defn all-names [] 1.303 + (concat 1.304 + (re-split #"\n" (slurp (file-str 1.305 + "/home/r/proj/names/dist.female.first"))) 1.306 + (re-split #"\n" (slurp (file-str 1.307 + "/home/r/proj/names/dist.male.first"))) 1.308 + (re-split #"\n" (slurp (file-str 1.309 + "/home/r/proj/names/dist.all.last"))))) 1.310 1.311 1.312 1.313 @@ -382,9 +615,6 @@ 1.314 Lulzable 1.315 (load-lulz [this] (println "the lulz have arrived!"))) 1.316 1.317 -(defn 1.318 - 1.319 - 1.320 1.321 (defn world-setup [joint] 1.322 (let [joint-position (Vector3f. 0 0 0)