Mercurial > cortex
diff org/test-creature.org @ 97:2ff8c7c4e64d
have function for creating touch for a blender creature
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 11 Jan 2012 00:06:33 -0700 |
parents | 4a9096f31017 |
children | 5b23961433e3 |
line wrap: on
line diff
1.1 --- a/org/test-creature.org Tue Jan 10 21:26:41 2012 -0700 1.2 +++ b/org/test-creature.org Wed Jan 11 00:06:33 2012 -0700 1.3 @@ -350,19 +350,22 @@ 1.4 (triangle-indices mesh (.getIndex triangle)))) 1.5 1.6 (defn touch-receptor-image 1.7 - "Return the touch-sensor distribution image in ImagePlus format." 1.8 + "Return the touch-sensor distribution image in ImagePlus format, or 1.9 + nil if it does not exist." 1.10 [#^Geometry obj] 1.11 - (let 1.12 - [mat (.getMaterial obj) 1.13 - texture 1.14 - (.getTextureValue 1.15 - (.getTextureParam 1.16 - mat 1.17 - MaterialHelper/TEXTURE_TYPE_DIFFUSE)) 1.18 - im (.getImage texture)] 1.19 - (ImagePlus. 1.20 - "UV-map" 1.21 - (ImageToAwt/convert im false false 0)))) 1.22 + (let [mat (.getMaterial obj)] 1.23 + (if-let [texture-param 1.24 + (.getTextureParam 1.25 + mat 1.26 + MaterialHelper/TEXTURE_TYPE_DIFFUSE)] 1.27 + (let 1.28 + [texture 1.29 + (.getTextureValue texture-param) 1.30 + im (.getImage texture)] 1.31 + (ImagePlus. 1.32 + "UV-map" 1.33 + (ImageToAwt/convert im false false 0)))))) 1.34 + 1.35 1.36 1.37 (import ij.process.ImageProcessor) 1.38 @@ -533,200 +536,84 @@ 1.39 ])) 1.40 1.41 1.42 -(defn locate-tactile-sensors 1.43 +(defn locate-feelers 1.44 "Search the geometry's tactile UV image for touch sensors, returning 1.45 their positions in geometry-relative coordinates." 1.46 [#^Geometry geo] 1.47 - (let [mesh (.getMesh geo) 1.48 + (if-let [image (touch-receptor-image geo)] 1.49 + (let [mesh (.getMesh geo) 1.50 + tris (triangles geo) 1.51 + 1.52 + 1.53 + width (.getWidth image) 1.54 + height (.getHeight image) 1.55 + 1.56 + ;; for each triangle 1.57 + sensor-coords 1.58 + (fn [tri] 1.59 + ;; translate triangle to uv-pixel-space 1.60 + (let [uv-tri 1.61 + (pixel-triangle mesh tri width height) 1.62 + bounds (vec (triangle-bounds uv-tri))] 1.63 + 1.64 + ;; get that part of the picture 1.65 + 1.66 + (apply #(.setRoi image %1 %2 %3 %4) bounds) 1.67 + (let [cutout (.crop (.getProcessor image)) 1.68 + ;; extract white pixels inside triangle 1.69 + cutout-tri 1.70 + (map-triangle 1.71 + (fn [_ v] 1.72 + (.subtract 1.73 + v 1.74 + (Vector3f. (bounds 0) (bounds 1) (float 0)))) 1.75 + uv-tri) 1.76 + whites (filter (partial inside-triangle? cutout-tri) 1.77 + (map vector2f->vector3f 1.78 + (white-coordinates cutout))) 1.79 + ;; translate pixel coordinates to world-space 1.80 + transform (triangle-transformation cutout-tri tri)] 1.81 + (map #(.mult transform %) whites))))] 1.82 + (vec (map sensor-coords tris))) 1.83 + (repeat (count (triangles geo)) []))) 1.84 + 1.85 +(defn enable-touch [#^Geometry geo] 1.86 + (let [feeler-coords (locate-feelers geo) 1.87 tris (triangles geo) 1.88 - 1.89 - image (touch-receptor-image geo) 1.90 - width (.getWidth image) 1.91 - height (.getHeight image) 1.92 - 1.93 + limit 0.1] 1.94 + (fn [node] 1.95 + (let [sensor-origins 1.96 + (map 1.97 + #(map (partial local-to-world geo) %) 1.98 + feeler-coords) 1.99 + triangle-normals 1.100 + (map (partial get-ray-direction geo) 1.101 + tris) 1.102 + rays 1.103 + (flatten 1.104 + (map (fn [origins norm] 1.105 + (map #(doto (Ray. % norm) 1.106 + (.setLimit limit)) origins)) 1.107 + sensor-origins triangle-normals))] 1.108 + (for [ray rays] 1.109 + (do 1.110 + (let [results (CollisionResults.)] 1.111 + (.collideWith node ray results) 1.112 + (let [touch-objects 1.113 + (set 1.114 + (filter #(not (= geo %)) 1.115 + (map #(.getGeometry %) results)))] 1.116 + (count touch-objects))))))))) 1.117 1.118 - ;; for each triangle 1.119 - sensor-coords 1.120 - (fn [tri] 1.121 - ;; translate triangle to uv-pixel-space 1.122 - (let [uv-tri 1.123 - (pixel-triangle mesh tri width height) 1.124 - bounds (vec (triangle-bounds uv-tri))] 1.125 - 1.126 - ;; get that part of the picture 1.127 - 1.128 - (apply #(.setRoi image %1 %2 %3 %4) bounds) 1.129 - (let [cutout (.crop (.getProcessor image)) 1.130 - ;; extract white pixels inside triangle 1.131 - cutout-tri 1.132 - (map-triangle 1.133 - (fn [_ v] 1.134 - (.subtract 1.135 - v 1.136 - (Vector3f. (bounds 0) (bounds 1) (float 0)))) 1.137 - uv-tri) 1.138 - whites (filter (partial inside-triangle? cutout-tri) 1.139 - (map vector2f->vector3f 1.140 - (white-coordinates cutout))) 1.141 - ;; translate pixel coordinates to world-space 1.142 - transform (triangle-transformation cutout-tri tri)] 1.143 - (map #(.mult transform %) whites))))] 1.144 - 1.145 - 1.146 +(defn touch [#^Node pieces] 1.147 + (let [touch-components 1.148 + (map enable-touch 1.149 + (filter #(isa? (class %) Geometry) 1.150 + (node-seq pieces)))] 1.151 + (fn [node] 1.152 + (reduce into [] (map #(% node) touch-components))))) 1.153 1.154 - (vec (map sensor-coords tris)))) 1.155 - 1.156 -(defn locate-tactile-sensors* 1.157 - "Search the geometry's tactile UV image for touch sensors, returning 1.158 - their positions in geometry-relative coordinates." 1.159 - [#^Geometry geo] 1.160 - (let [uv-image (touch-receptor-image geo) 1.161 - width (.getWidth uv-image) 1.162 - height (.getHeight uv-image) 1.163 - 1.164 - mesh (.getMesh geo) 1.165 - mesh-tris (triangles geo) 1.166 - 1.167 - ;; for each triangle 1.168 - sensor-coords 1.169 - (fn [tri] 1.170 - ;; translate triangle to uv-pixel-space 1.171 - (let [uv-tri 1.172 - (rasterize mesh tri width height) 1.173 - bounds (vec (triangle-bounds uv-tri))] 1.174 - 1.175 - ;; get that part of the picture 1.176 - 1.177 - (apply (partial (memfn setRoi) uv-image) bounds) 1.178 - (let [cutout (.crop (.getProcessor uv-image)) 1.179 - ;; extract white pixels inside triangle 1.180 - cutout-tri 1.181 - (map-triangle 1.182 - (fn [_ v] 1.183 - (.subtract 1.184 - v 1.185 - (Vector3f. (bounds 0) (bounds 1) (float 0)))) 1.186 - uv-tri) 1.187 - whites (filter (partial inside-triangle? cutout-tri) 1.188 - (map vector2f->vector3f 1.189 - (white-coordinates cutout))) 1.190 - ;; translate pixel coordinates to world-space 1.191 - transform (triangle-transformation cutout-tri tri)] 1.192 - (map #(.mult transform %) whites))))] 1.193 - 1.194 - 1.195 - 1.196 - (for [mesh-tri mesh-tris] 1.197 - 1.198 - (let [uv-tri (rasterize mesh mesh-tri width height) 1.199 - bounding-box (vec (triangle-bounds uv-tri))] 1.200 - (apply (partial (memfn setRoi) uv-image) bounding-box) 1.201 - 1.202 - 1.203 - 1.204 - 1.205 - )) 1.206 - (vec (map sensor-coords mesh-tris)))) 1.207 - 1.208 - 1.209 - 1.210 -(defn measure-touchies [#^Geometry geo] 1.211 - (let [tactile-sensor-coords (locate-tactile-sensors geo) 1.212 - tris (triangles geo)] 1.213 - (fn [world] 1.214 - (let [sensor-origins (vec 1.215 - (map 1.216 - #(map (partial local-to-world geo) %) 1.217 - tactile-sensor-coords)) 1.218 - triangle-normals (vec 1.219 - (map (partial get-ray-direction geo) 1.220 - tris)) 1.221 - rays (flatten 1.222 - (map 1.223 - (fn [origins normals] 1.224 - (map 1.225 - #(Ray. %1 %2) 1.226 - origins 1.227 - normals)) 1.228 - sensor-origins 1.229 - (map repeat triangle-normals))) 1.230 - 1.231 - 1.232 - ] 1.233 - rays)))) 1.234 - 1.235 - 1.236 - 1.237 - 1.238 - 1.239 - 1.240 - 1.241 - 1.242 - 1.243 - 1.244 - 1.245 - 1.246 - 1.247 - 1.248 - 1.249 - 1.250 - 1.251 - 1.252 - 1.253 -;; for each triangle in the mesh, 1.254 -;; get the normal to the triangle, 1.255 -;; look at the UV touch map, restricted to that triangle, 1.256 -;; get the positions of those touch sensors in geometry-relative 1.257 -;; coordinates. 1.258 -(defn tactile-coords [#^Geometry obj] 1.259 - (let [mesh (.getMesh obj) 1.260 - num-triangles (.getTriangleCount mesh) 1.261 - num-verticies (.getVertexCount mesh) 1.262 - uv-coord (partial uv-coord mesh) 1.263 - triangle-indices (partial triangle-indices mesh) 1.264 - receptors (touch-receptor-image obj) 1.265 - tris (triangles obj) 1.266 - ] 1.267 - (map 1.268 - (fn [[tri-1 tri-2 tri-3]] 1.269 - (let [width (.getWidth receptors) 1.270 - height (.getHeight receptors) 1.271 - uv-1 (uv-coord tri-1) 1.272 - uv-2 (uv-coord tri-2) 1.273 - uv-3 (uv-coord tri-3) 1.274 - x-coords (map #(.getX %) [uv-1 uv-2 uv-3]) 1.275 - y-coords (map #(.getY %) [uv-1 uv-2 uv-3]) 1.276 - max-x (Math/ceil (* width (apply max x-coords))) 1.277 - min-x (Math/floor (* width (apply min x-coords))) 1.278 - max-y (Math/ceil (* height (apply max y-coords))) 1.279 - min-y (Math/floor (* height (apply min y-coords))) 1.280 - 1.281 - image-1 (Vector2f. (* width (.getX uv-1)) 1.282 - (* height (.getY uv-1))) 1.283 - image-2 (Vector2f. (* width (.getX uv-2)) 1.284 - (* height (.getY uv-2))) 1.285 - image-3 (Vector2f. (* width (.getX uv-3)) 1.286 - (* height (.getY uv-3))) 1.287 - left-corner 1.288 - (Vector2f. min-x min-y) 1.289 - ] 1.290 - 1.291 - (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y)) 1.292 - (let [processor (.crop (.getProcessor receptors))] 1.293 - (map 1.294 - #(.add left-corner %) 1.295 - 1.296 - (filter 1.297 - (partial 1.298 - inside-triangle? 1.299 - (.subtract image-1 left-corner) 1.300 - (.subtract image-2 left-corner) 1.301 - (.subtract image-3 left-corner)) 1.302 - (white-coordinates processor)))) 1.303 - )) (map triangle-indices (range num-triangles))))) 1.304 - 1.305 - 1.306 - 1.307 + 1.308 1.309 1.310 1.311 @@ -874,6 +761,101 @@ 1.312 (Vector3f. 1 0 0)))))))) 1.313 1.314 1.315 +(defn locate-feelers* 1.316 + "Search the geometry's tactile UV image for touch sensors, returning 1.317 + their positions in geometry-relative coordinates." 1.318 + [#^Geometry geo] 1.319 + (let [uv-image (touch-receptor-image geo) 1.320 + width (.getWidth uv-image) 1.321 + height (.getHeight uv-image) 1.322 + 1.323 + mesh (.getMesh geo) 1.324 + mesh-tris (triangles geo) 1.325 + 1.326 + ;; for each triangle 1.327 + sensor-coords 1.328 + (fn [tri] 1.329 + ;; translate triangle to uv-pixel-space 1.330 + (let [uv-tri 1.331 + (rasterize mesh tri width height) 1.332 + bounds (vec (triangle-bounds uv-tri))] 1.333 + 1.334 + ;; get that part of the picture 1.335 + 1.336 + (apply (partial (memfn setRoi) uv-image) bounds) 1.337 + (let [cutout (.crop (.getProcessor uv-image)) 1.338 + ;; extract white pixels inside triangle 1.339 + cutout-tri 1.340 + (map-triangle 1.341 + (fn [_ v] 1.342 + (.subtract 1.343 + v 1.344 + (Vector3f. (bounds 0) (bounds 1) (float 0)))) 1.345 + uv-tri) 1.346 + whites (filter (partial inside-triangle? cutout-tri) 1.347 + (map vector2f->vector3f 1.348 + (white-coordinates cutout))) 1.349 + ;; translate pixel coordinates to world-space 1.350 + transform (triangle-transformation cutout-tri tri)] 1.351 + (map #(.mult transform %) whites))))] 1.352 + 1.353 + 1.354 + 1.355 + (for [mesh-tri mesh-tris] 1.356 + 1.357 + (let [uv-tri (rasterize mesh mesh-tri width height) 1.358 + bounding-box (vec (triangle-bounds uv-tri))] 1.359 + (apply (partial (memfn setRoi) uv-image) bounding-box) 1.360 + )) 1.361 + (vec (map sensor-coords mesh-tris)))) 1.362 + 1.363 + 1.364 +(defn tactile-coords [#^Geometry obj] 1.365 + (let [mesh (.getMesh obj) 1.366 + num-triangles (.getTriangleCount mesh) 1.367 + num-verticies (.getVertexCount mesh) 1.368 + uv-coord (partial uv-coord mesh) 1.369 + triangle-indices (partial triangle-indices mesh) 1.370 + receptors (touch-receptor-image obj) 1.371 + tris (triangles obj) 1.372 + ] 1.373 + (map 1.374 + (fn [[tri-1 tri-2 tri-3]] 1.375 + (let [width (.getWidth receptors) 1.376 + height (.getHeight receptors) 1.377 + uv-1 (uv-coord tri-1) 1.378 + uv-2 (uv-coord tri-2) 1.379 + uv-3 (uv-coord tri-3) 1.380 + x-coords (map #(.getX %) [uv-1 uv-2 uv-3]) 1.381 + y-coords (map #(.getY %) [uv-1 uv-2 uv-3]) 1.382 + max-x (Math/ceil (* width (apply max x-coords))) 1.383 + min-x (Math/floor (* width (apply min x-coords))) 1.384 + max-y (Math/ceil (* height (apply max y-coords))) 1.385 + min-y (Math/floor (* height (apply min y-coords))) 1.386 + 1.387 + image-1 (Vector2f. (* width (.getX uv-1)) 1.388 + (* height (.getY uv-1))) 1.389 + image-2 (Vector2f. (* width (.getX uv-2)) 1.390 + (* height (.getY uv-2))) 1.391 + image-3 (Vector2f. (* width (.getX uv-3)) 1.392 + (* height (.getY uv-3))) 1.393 + left-corner 1.394 + (Vector2f. min-x min-y) 1.395 + ] 1.396 + 1.397 + (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y)) 1.398 + (let [processor (.crop (.getProcessor receptors))] 1.399 + (map 1.400 + #(.add left-corner %) 1.401 + 1.402 + (filter 1.403 + (partial 1.404 + inside-triangle? 1.405 + (.subtract image-1 left-corner) 1.406 + (.subtract image-2 left-corner) 1.407 + (.subtract image-3 left-corner)) 1.408 + (white-coordinates processor)))) 1.409 + )) (map triangle-indices (range num-triangles))))) 1.410 1.411 #+end_src 1.412