changeset 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
files assets/Models/creature1/tip.png assets/Models/creature1/try-again.blend org/test-creature.org
diffstat 3 files changed, 255 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
     1.1 Binary file assets/Models/creature1/tip.png has changed
     2.1 Binary file assets/Models/creature1/try-again.blend has changed
     3.1 --- a/org/test-creature.org	Sun Jan 08 06:11:58 2012 -0700
     3.2 +++ b/org/test-creature.org	Mon Jan 09 06:02:06 2012 -0700
     3.3 @@ -307,22 +307,13 @@
     3.4     )))
     3.5  
     3.6  
     3.7 -(def colorful (.getChild (worm-model) "worm-21"))
     3.8 -
     3.9 -(def im-data
    3.10 -  (let [sink (byte-array 3145727)
    3.11 -        data (.getData (.getImage texture) 0)]
    3.12 -    (.rewind data)
    3.13 -    (.get data sink)
    3.14 -    (vec (seq sink))))
    3.15 -
    3.16 +(defn colorful []
    3.17 +  (.getChild (worm-model) "worm-21"))
    3.18  
    3.19  (import jme3tools.converters.ImageToAwt)
    3.20  
    3.21  (import ij.ImagePlus)
    3.22  
    3.23 -
    3.24 -
    3.25  (defn triangle-indices
    3.26    "Get the triangle vertex indices of a given triangle from a given
    3.27     mesh."
    3.28 @@ -339,19 +330,15 @@
    3.29           (.getBuffer
    3.30            mesh
    3.31            VertexBuffer$Type/TexCoord))]
    3.32 -    [(.get UV-buffer (* vertex-index 2))
    3.33 -     (.get UV-buffer (+ 1 (* vertex-index 2)))]))
    3.34 +    (Vector2f.
    3.35 +     (.get UV-buffer (* vertex-index 2))
    3.36 +     (.get UV-buffer (+ 1 (* vertex-index 2))))))
    3.37  
    3.38 -(defn touch-receptor-image [#^Geometry obj]
    3.39 -  
    3.40 -
    3.41 -
    3.42 -;; yay there's a converter!
    3.43 -
    3.44 -(defn uv-image []
    3.45 +(defn touch-receptor-image
    3.46 +  "Return the touch-sensor distribution image in ImagePlus format."
    3.47 +  [#^Geometry obj]
    3.48    (let
    3.49 -      [colorful (.getChild (worm-model) "worm-21")
    3.50 -       mat (.getMaterial colorful)
    3.51 +      [mat (.getMaterial obj)
    3.52         texture
    3.53         (.getTextureValue
    3.54          (.getTextureParam
    3.55 @@ -362,11 +349,257 @@
    3.56          "UV-map"
    3.57          (ImageToAwt/convert im false false 0))))
    3.58  
    3.59 +
    3.60 +(import ij.process.ImageProcessor)
    3.61 +(import java.awt.image.BufferedImage)
    3.62 +
    3.63 +(defprotocol Frame
    3.64 +  (frame [this]))
    3.65 +
    3.66 +(extend-type BufferedImage
    3.67 +  Frame
    3.68 +  (frame [image]
    3.69 +    (merge  
    3.70 +     (apply
    3.71 +      hash-map 
    3.72 +      (interleave 
    3.73 +       (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]
    3.74 +                (vector x y)))
    3.75 +       (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]
    3.76 +                (let [data (.getRGB image x y)] 
    3.77 +                  (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)
    3.78 +                            :g (bit-shift-right (bit-and 0x00ff00 data) 8)
    3.79 +                            :b (bit-and 0x0000ff data)))))))
    3.80 +     {:width  (.getWidth image) :height (.getHeight image)})))
    3.81 +
    3.82 +
    3.83 +(extend-type ImagePlus
    3.84 +  Frame
    3.85 +  (frame [image+]
    3.86 +    (frame (.getBufferedImage image+))))
    3.87 +
    3.88 +(defn rgb->int [r g b]
    3.89 +  (+ (bit-shift-left r 16)
    3.90 +     (bit-shift-left g 8)
    3.91 +     b))
    3.92 +     
    3.93 +  
    3.94 +
    3.95 +(defn filter-pixels
    3.96 +  "List the coordinates of all pixels matching pred."
    3.97 +  [pred #^ImageProcessor ip]
    3.98 +  (let
    3.99 +      [width (.getWidth ip)
   3.100 +       height (.getHeight ip)]
   3.101 +    ((fn accumulate [x y matches]
   3.102 +       (cond
   3.103 +        (>= y height) matches
   3.104 +        (>= x width) (recur 0 (inc y) matches)
   3.105 +        (pred (.getPixel ip x y))
   3.106 +        (recur (inc x) y (conj matches (Vector2f. x y)))
   3.107 +        :else (recur (inc x) y matches)))
   3.108 +     0 0 [])))
   3.109 +
   3.110 +
   3.111 +
   3.112 +
   3.113 +
   3.114 +(defn filter-pixels*
   3.115 +  [pred #^ImageProcessor ip]
   3.116 +  (let
   3.117 +      [width (.getWidth ip)
   3.118 +       height (.getHeight ip)
   3.119 +       coords (ref [])
   3.120 +       process 
   3.121 +       (fn [[start end]]
   3.122 +         (loop [i start]
   3.123 +           (if (<= i end)
   3.124 +             (do 
   3.125 +               (let [column (rem i height)
   3.126 +                     row (unchecked-divide i width)]
   3.127 +                 (if (pred (.getPixel ip row column))
   3.128 +                   (dosync (ref-set
   3.129 +                            coords
   3.130 +                            (conj @coords (Vector2f. column row)))))
   3.131 +        
   3.132 +               (recur (inc i)))))))
   3.133 +       ]
   3.134 +
   3.135 +       
   3.136 +    (dorun 
   3.137 +     (pmap process (partition
   3.138 +                    2
   3.139 +                    (conj (vec (range 0 (* width height) 100))
   3.140 +                          (* width height)))))
   3.141 +    @coords))
   3.142 +
   3.143 +
   3.144 +
   3.145 +(comment
   3.146 +  ((->
   3.147 +    f
   3.148 +    (partial x)
   3.149 +    (partial y)
   3.150 +    (partial z))))
   3.151 +
   3.152 +(defn filter-pixels**
   3.153 +  [pred #^ImageProcessor ip]
   3.154 +  (let [width (.getWidth ip)
   3.155 +        height (.getHeight ip)]
   3.156 +    ((fn f [x1 x2 y1 y2]
   3.157 +       (println x1)
   3.158 +         (if
   3.159 +             (and
   3.160 +              (= x1 (dec x2))
   3.161 +              (= y1 (dec y2)))
   3.162 +           (if (pred (.getPixel ip x1 y1))
   3.163 +             [[x1 y1]]
   3.164 +             [])
   3.165 +           (let
   3.166 +               [xm (+ x1 (/ (- x2 x1) 2))
   3.167 +                ym (+ y1 (/ (- y2 y1) 2))]
   3.168 +           (apply concat
   3.169 +           (pvalues
   3.170 +            ;;(f x1 xm y1 ym)
   3.171 +            ;;(f xm x2 y1 ym)
   3.172 +            ;;(f x1 xm ym y2)
   3.173 +            (f xm x2 ym y2))))))
   3.174 +       0 width 0 height)))
   3.175 +    
   3.176 +
   3.177 +
   3.178 +
   3.179 +  
   3.180 +       
   3.181 +
   3.182 +
   3.183 +(defn white-coordinates*
   3.184 +  [#^ImageProcessor ip]
   3.185 +  (filter-pixels** #(== % -1) ip))
   3.186 +  
   3.187 +
   3.188 +(defn white-coordinates
   3.189 +  "List the coordinates of all the white pixels in an image."
   3.190 +  [#^ImageProcessor ip]
   3.191 +  (let [height (.getHeight ip)
   3.192 +        width  (.getWidth  ip)
   3.193 +        coords (transient [])]
   3.194 +    (dorun 
   3.195 +     (for [x (range width)
   3.196 +           y (range height)]
   3.197 +       (let [pixel (.getPixel ip x y)]
   3.198 +         (if (= pixel -1)
   3.199 +           (conj! coords (Vector2f. x y))))))
   3.200 +    (persistent! coords)))
   3.201 +                                    
   3.202 +        
   3.203 +
   3.204 +
   3.205 +
   3.206 +    
   3.207 +  
   3.208 +
   3.209 +(def white {:r 255, :g 255, :b 255})
   3.210 +(def black {:r 0,   :g 0,   :b 0})
   3.211 +
   3.212 +
   3.213 +(defn same-side? [p1 p2 ref p]
   3.214 +  (<=
   3.215 +   0
   3.216 +   (.dot 
   3.217 +    (.cross (.subtract p2 p1) (.subtract p p1))
   3.218 +    (.cross (.subtract p2 p1) (.subtract ref p1)))))
   3.219 +
   3.220 +(defn inside-triangle?
   3.221 +  [vert-1 vert-2 vert-3 p]
   3.222 +   (and
   3.223 +    (same-side? vert-1 vert-2 vert-3 p)
   3.224 +    (same-side? vert-2 vert-3 vert-1 p)
   3.225 +    (same-side? vert-3 vert-1 vert-2 p)))
   3.226 +
   3.227 +
   3.228 +(defn white? [color]
   3.229 +  (and 
   3.230 +   (= (:r color) 255)
   3.231 +   (= (:b color) 255)
   3.232 +   (= (:g color) 255)))
   3.233 +                        
   3.234 +
   3.235  ;; for each triangle in the mesh,
   3.236  ;; get the normal to the triangle,
   3.237  ;; look at the UV touch map, restricted to that triangle,
   3.238  ;; get the positions of those touch sensors in geometry-relative
   3.239  ;; coordinates.
   3.240 +(defn tactile-coords [#^Geometry obj]
   3.241 +  (let [mesh (.getMesh obj)
   3.242 +        num-triangles (.getTriangleCount mesh)
   3.243 +        num-verticies (.getVertexCount mesh)
   3.244 +        uv-coord (partial uv-coord mesh)
   3.245 +        triangle-indices (partial triangle-indices mesh)
   3.246 +        receptors (touch-receptor-image obj)
   3.247 +        ]
   3.248 +    (map
   3.249 +     (fn [[tri-1 tri-2 tri-3]]
   3.250 +       (let [width (.getWidth receptors)
   3.251 +             height (.getHeight receptors)
   3.252 +             uv-1 (uv-coord tri-1)
   3.253 +             uv-2 (uv-coord tri-2)
   3.254 +             uv-3 (uv-coord tri-3)
   3.255 +             x-coords (map #(.getX %) [uv-1 uv-2 uv-3])
   3.256 +             y-coords (map #(.getY %) [uv-1 uv-2 uv-3])
   3.257 +             max-x (Math/ceil (* width (apply max x-coords)))
   3.258 +             min-x (Math/floor (* width (apply min x-coords)))
   3.259 +             max-y (Math/ceil (* height (apply max y-coords)))
   3.260 +             min-y (Math/floor (* height (apply min y-coords)))
   3.261 +
   3.262 +             image-1 (Vector2f. (* width (.getX uv-1))
   3.263 +                                (* height (.getY uv-1)))
   3.264 +             image-2 (Vector2f. (* width (.getX uv-2))
   3.265 +                                (* height (.getY uv-2)))
   3.266 +             image-3 (Vector2f. (* width (.getX uv-3))
   3.267 +                                (* height (.getY uv-3)))
   3.268 +             left-corner
   3.269 +             (Vector2f. min-x min-y)
   3.270 +             
   3.271 +             ]
   3.272 +
   3.273 +         (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y))
   3.274 +         (let [processor  (.crop (.getProcessor receptors))
   3.275 +               image (frame (.getBufferedImage processor))]
   3.276 +           (with-meta
   3.277 +             (filter-keys
   3.278 +              (fn [[x y]]
   3.279 +                (inside-triangle?
   3.280 +                 (.subtract image-1 left-corner)
   3.281 +                 (.subtract image-2 left-corner)
   3.282 +                 (.subtract image-3 left-corner)
   3.283 +                 (Vector2f. x y)))
   3.284 +              
   3.285 +              
   3.286 +              (filter-vals white? image))
   3.287 +             {:image
   3.288 +              (comment
   3.289 +                (.getBufferedImage
   3.290 +                 (doto processor
   3.291 +                   (.flipVertical))))
   3.292 +               }
   3.293 +           ))
   3.294 +         )) (map triangle-indices (range num-triangles)))))
   3.295 +    
   3.296 +
   3.297 +
   3.298 +
   3.299 +
   3.300 +
   3.301 +    
   3.302 +(defn all-names []
   3.303 +  (concat 
   3.304 +   (re-split #"\n" (slurp (file-str
   3.305 +                           "/home/r/proj/names/dist.female.first")))
   3.306 +   (re-split #"\n" (slurp (file-str
   3.307 +                           "/home/r/proj/names/dist.male.first")))
   3.308 +   (re-split #"\n" (slurp (file-str
   3.309 +                           "/home/r/proj/names/dist.all.last")))))
   3.310  
   3.311  
   3.312  
   3.313 @@ -382,9 +615,6 @@
   3.314    Lulzable
   3.315    (load-lulz [this] (println "the lulz have arrived!")))
   3.316  
   3.317 -(defn 
   3.318 -
   3.319 -
   3.320  
   3.321  (defn world-setup [joint]
   3.322    (let [joint-position (Vector3f. 0 0 0)