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)