Mercurial > cortex
diff org/touch.org @ 243:f33fec68f775
touch has been restored, with some very slight speed improvements, and now with much less code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 12 Feb 2012 14:14:57 -0700 |
parents | a7f26a074071 |
children | f23217324f72 |
line wrap: on
line diff
1.1 --- a/org/touch.org Sun Feb 12 13:48:28 2012 -0700 1.2 +++ b/org/touch.org Sun Feb 12 14:14:57 2012 -0700 1.3 @@ -77,15 +77,7 @@ 1.4 1.5 1.6 * Skin Creation 1.7 -* TODO get the actual lengths for each hair 1.8 - 1.9 -#+begin_src clojure 1.10 -pixel-triangles 1.11 - xyz-triangles 1.12 - conversions (map triangles->affine-transform pixel-triangles 1.13 - xyz-triangles) 1.14 - 1.15 -#+end_src 1.16 +* TODO get the actual lengths for each feeler 1.17 1.18 1.19 =(touch-kernel)= generates the functions which implement the sense of 1.20 @@ -119,14 +111,6 @@ 1.21 - Generate some sort of topology for the sensors. 1.22 =(touch-topology)= 1.23 1.24 -#+begin_src clojure 1.25 - 1.26 - 1.27 - 1.28 - 1.29 -#+end_src 1.30 - 1.31 - 1.32 1.33 #+name: kernel 1.34 #+begin_src clojure 1.35 @@ -134,77 +118,38 @@ 1.36 1.37 (declare touch-topology feelers set-ray) 1.38 1.39 -(defn set-ray [#^Ray ray #^Matrix4f transform 1.40 - #^Vector3f origin #^Vector3f tip 1.41 - length] 1.42 - (.setOrigin ray (.mult transform origin)) 1.43 - (.setDirection ray (.subtract 1.44 - (.mult transform tip) 1.45 - (.getOrigin ray))) 1.46 - (.setLimit ray length) 1.47 - ray) 1.48 - 1.49 +(defn set-ray [#^Ray ray #^Matrix4f transform #^Vector3f origin 1.50 + #^Vector3f tip length] 1.51 + ;; Doing everything locally recduces garbage collection by enough to 1.52 + ;; be worth it. 1.53 + (.mult transform origin (.getOrigin ray)) 1.54 + 1.55 + (.mult transform tip (.getDirection ray)) 1.56 + (.subtractLocal (.getDirection ray) (.getOrigin ray)) 1.57 + (.setLimit ray length)) 1.58 1.59 (defn touch-kernel 1.60 "Constructs a function which will return tactile sensory data from 1.61 'geo when called from inside a running simulation" 1.62 [#^Geometry geo] 1.63 - (let [profile (tactile-sensor-profile geo) 1.64 - ray-reference-origins (feeler-origins geo profile) 1.65 - ray-reference-tips (feeler-tips geo profile) 1.66 - ray-lengths (repeat 9000 0.1) 1.67 - current-rays (map (fn [] (Ray.)) ray-reference-origins) 1.68 - topology (touch-topology geo profile)] 1.69 - (if (empty? ray-reference-origins) nil 1.70 - (fn [node] 1.71 - (let [transform (.getWorldMatrix geo)] 1.72 - (dorun 1.73 - (map (fn [ray ref-origin ref-tip length] 1.74 - (set-ray ray transform ref-origin ref-tip length)) 1.75 - current-rays ray-reference-origins 1.76 - ray-reference-tips ray-lengths)) 1.77 - (vector 1.78 - topology 1.79 - (vec 1.80 - (for [ray current-rays] 1.81 - (do 1.82 - (let [results (CollisionResults.)] 1.83 - (.collideWith node ray results) 1.84 - (let [touch-objects 1.85 - (filter #(not (= geo (.getGeometry %))) 1.86 - results)] 1.87 - [(if (empty? touch-objects) 1.88 - (.getLimit ray) 1.89 - (.getDistance (first touch-objects))) 1.90 - (.getLimit ray)]))))))))))) 1.91 - 1.92 -(defn touch-kernel* 1.93 - "Returns a function which returns tactile sensory data when called 1.94 - inside a running simulation." 1.95 - [#^Geometry geo] 1.96 - (let [feeler-coords (feeler-coordinates geo) 1.97 - tris (triangles geo) 1.98 - limit (tactile-scale geo)] 1.99 - (if (empty? (touch-topology geo)) 1.100 - nil 1.101 + (if-let 1.102 + [profile (tactile-sensor-profile geo)] 1.103 + (let [ray-reference-origins (feeler-origins geo profile) 1.104 + ray-reference-tips (feeler-tips geo profile) 1.105 + ray-lengths (repeat 9000 0.1) 1.106 + current-rays (map (fn [_] (Ray.)) ray-reference-origins) 1.107 + topology (touch-topology geo profile)] 1.108 (fn [node] 1.109 - (let [sensor-origins 1.110 - (map 1.111 - #(map (partial local-to-world geo) %) 1.112 - feeler-coords) 1.113 - triangle-normals 1.114 - (map (partial get-ray-direction geo) 1.115 - tris) 1.116 - rays 1.117 - (flatten 1.118 - (map (fn [origins norm] 1.119 - (map #(doto (Ray. % norm) 1.120 - (.setLimit limit)) origins)) 1.121 - sensor-origins triangle-normals))] 1.122 + (let [transform (.getWorldMatrix geo)] 1.123 + (dorun 1.124 + (map (fn [ray ref-origin ref-tip length] 1.125 + (set-ray ray transform ref-origin ref-tip length)) 1.126 + current-rays ray-reference-origins 1.127 + ray-reference-tips ray-lengths)) 1.128 (vector 1.129 - (touch-topology geo) 1.130 + topology 1.131 (vec 1.132 - (for [ray rays] 1.133 + (for [ray current-rays] 1.134 (do 1.135 (let [results (CollisionResults.)] 1.136 (.collideWith node ray results) 1.137 @@ -212,8 +157,9 @@ 1.138 (filter #(not (= geo (.getGeometry %))) 1.139 results)] 1.140 [(if (empty? touch-objects) 1.141 - limit (.getDistance (first touch-objects))) 1.142 - limit]))))))))))) 1.143 + (.getLimit ray) 1.144 + (.getDistance (first touch-objects))) 1.145 + (.getLimit ray)]))))))))))) 1.146 1.147 (defn touch! 1.148 "Endow the creature with the sense of touch. Returns a sequence of 1.149 @@ -227,6 +173,9 @@ 1.150 (node-seq creature))))) 1.151 #+end_src 1.152 1.153 +#+results: kernel 1.154 +: #'cortex.touch/touch! 1.155 + 1.156 * Sensor Related Functions 1.157 1.158 These functions analyze the touch-sensor-profile image convert the 1.159 @@ -279,59 +228,9 @@ 1.160 1.161 1.162 (defn touch-topology [#^Geometry geo image] 1.163 - (collapse (feeler-pixel-coords geo image))) 1.164 - 1.165 - 1.166 -(defn sensors-in-triangle 1.167 - "Locate the touch sensors in the triangle, returning a map of their 1.168 - UV and geometry-relative coordinates." 1.169 - [image mesh tri-index] 1.170 - (let [width (.getWidth image) 1.171 - height (.getHeight image) 1.172 - UV-vertex-coords (triangle-UV-coord mesh width height tri-index) 1.173 - bounds (convex-bounds UV-vertex-coords) 1.174 - 1.175 - cutout-triangle (points->triangle UV-vertex-coords) 1.176 - UV-sensor-coords 1.177 - (filter (comp (partial inside-triangle? cutout-triangle) 1.178 - (fn [[u v]] (Vector3f. u v 0))) 1.179 - (white-coordinates image bounds)) 1.180 - UV->geometry (triangle-transformation 1.181 - cutout-triangle 1.182 - (mesh-triangle mesh tri-index)) 1.183 - geometry-sensor-coords 1.184 - (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0))) 1.185 - UV-sensor-coords)] 1.186 - {:UV UV-sensor-coords :geometry geometry-sensor-coords})) 1.187 - 1.188 -(defn-memo locate-feelers 1.189 - "Search the geometry's tactile UV profile for touch sensors, 1.190 - returning their positions in geometry-relative coordinates." 1.191 - [#^Geometry geo] 1.192 - (let [mesh (.getMesh geo) 1.193 - num-triangles (.getTriangleCount mesh)] 1.194 - (if-let [image (tactile-sensor-profile geo)] 1.195 - (map 1.196 - (partial sensors-in-triangle image mesh) 1.197 - (range num-triangles)) 1.198 - (repeat (.getTriangleCount mesh) {:UV nil :geometry nil})))) 1.199 - 1.200 -(defn-memo touch-topology 1.201 - "Return a sequence of vectors of the form [x y] describing the 1.202 - \"topology\" of the tactile sensors. Points that are close together 1.203 - in the touch-topology are generally close together in the simulation." 1.204 - [#^Gemoetry geo] 1.205 - (vec (collapse (reduce concat (map :UV (locate-feelers geo)))))) 1.206 - 1.207 -(defn-memo feeler-coordinates 1.208 - "The location of the touch sensors in world-space coordinates." 1.209 - [#^Geometry geo] 1.210 - (vec (map :geometry (locate-feelers geo)))) 1.211 + (collapse (reduce concat (feeler-pixel-coords geo image)))) 1.212 #+end_src 1.213 1.214 - 1.215 - 1.216 - 1.217 * Visualizing Touch 1.218 #+name: visualization 1.219 #+begin_src clojure 1.220 @@ -457,6 +356,8 @@ 1.221 1.222 #+name: triangles-3 1.223 #+begin_src clojure 1.224 +(in-ns 'cortex.touch) 1.225 + 1.226 (defn triangle->matrix4f 1.227 "Converts the triangle into a 4x4 matrix: The first three columns 1.228 contain the vertices of the triangle; the last contains the unit 1.229 @@ -492,32 +393,6 @@ 1.230 functions make this easy. If these classes implemented =Iterable= then 1.231 this code would not be necessary. Hopefully they will in the future. 1.232 1.233 -#+name: triangles-2 1.234 -#+begin_src clojure 1.235 -(defn point->vector2f [[u v]] 1.236 - (Vector2f. u v)) 1.237 - 1.238 -(defn vector2f->vector3f [v] 1.239 - (Vector3f. (.getX v) (.getY v) 0)) 1.240 - 1.241 -(defn map-triangle [f #^Triangle tri] 1.242 - (Triangle. 1.243 - (f 0 (.get1 tri)) 1.244 - (f 1 (.get2 tri)) 1.245 - (f 2 (.get3 tri)))) 1.246 - 1.247 -(defn points->triangle 1.248 - "Convert a list of points into a triangle." 1.249 - [points] 1.250 - (apply #(Triangle. %1 %2 %3) 1.251 - (map (fn [point] 1.252 - (let [point (vec point)] 1.253 - (Vector3f. (get point 0 0) 1.254 - (get point 1 0) 1.255 - (get point 2 0)))) 1.256 - (take 3 points)))) 1.257 -#+end_src 1.258 - 1.259 1.260 * Triangle Boundaries 1.261 1.262 @@ -563,39 +438,11 @@ 1.263 (same-side? vert-3 vert-1 vert-2 p)))) 1.264 #+end_src 1.265 1.266 -#+results: triangles-4 1.267 -: #'cortex.touch/inside-triangle? 1.268 - 1.269 - 1.270 * Physics Collision Objects 1.271 1.272 The "hairs" are actually =Rays= which extend from a point on a 1.273 =Triangle= in the =Mesh= normal to the =Triangle's= surface. 1.274 1.275 -#+name: rays 1.276 -#+begin_src clojure 1.277 -(defn get-ray-origin 1.278 - "Return the origin which a Ray would have to have to be in the exact 1.279 - center of a particular Triangle in the Geometry in World 1.280 - Coordinates." 1.281 - [geom tri] 1.282 - (let [new (Vector3f.)] 1.283 - (.calculateCenter tri) 1.284 - (.localToWorld geom (.getCenter tri) new) new)) 1.285 - 1.286 -(defn get-ray-direction 1.287 - "Return the direction which a Ray would have to have to be to point 1.288 - normal to the Triangle, in coordinates relative to the center of the 1.289 - Triangle." 1.290 - [geom tri] 1.291 - (let [n+c (Vector3f.)] 1.292 - (.calculateNormal tri) 1.293 - (.calculateCenter tri) 1.294 - (.localToWorld 1.295 - geom 1.296 - (.add (.getCenter tri) (.getNormal tri)) n+c) 1.297 - (.subtract n+c (get-ray-origin geom tri)))) 1.298 -#+end_src 1.299 * Headers 1.300 1.301 #+name: touch-header 1.302 @@ -636,7 +483,12 @@ 1.303 (light-up-everything world)) 1.304 1.305 (fn [world tpf] 1.306 - (touch-display (map #(% (.getRootNode world)) touch)))))) 1.307 + 1.308 + 1.309 + (dorun (map #(% (.getRootNode world)) touch)) 1.310 + 1.311 + 1.312 + )))) 1.313 #+end_src 1.314 * Source Listing 1.315 * Next 1.316 @@ -647,11 +499,9 @@ 1.317 <<touch-header>> 1.318 <<meta-data>> 1.319 <<triangles-1>> 1.320 -<<triangles-2>> 1.321 <<triangles-3>> 1.322 <<triangles-4>> 1.323 <<sensors>> 1.324 -<<rays>> 1.325 <<kernel>> 1.326 <<visualization>> 1.327 #+end_src