Mercurial > cortex
changeset 228:0589c35f04f2
wrote intro for touch.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 11 Feb 2012 18:42:27 -0700 |
parents | 2a7f57e7efdb |
children | 6f1be9525e40 |
files | org/ideas.org org/touch.org |
diffstat | 2 files changed, 230 insertions(+), 172 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/org/ideas.org Sat Feb 11 14:12:17 2012 -0700 1.2 +++ b/org/ideas.org Sat Feb 11 18:42:27 2012 -0700 1.3 @@ -98,6 +98,7 @@ 1.4 - [ ] show sensor maps in AWT display? -- 2 days 1.5 - [ ] add iteraterator constructs to Vector3f, Vector2f, etc. 1.6 - [ ] upgrade to clojure 1.3, replace all defvars with new def 1.7 + - [ ] get Vector3f, Triangle to implement iterable 1.8 1.9 1.10
2.1 --- a/org/touch.org Sat Feb 11 14:12:17 2012 -0700 2.2 +++ b/org/touch.org Sat Feb 11 18:42:27 2012 -0700 2.3 @@ -11,179 +11,34 @@ 2.4 Touch is critical to navigation and spatial reasoning and as such I 2.5 need a simulated version of it to give to my AI creatures. 2.6 2.7 -#+name: skin-main 2.8 +However, touch in my virtual can not exactly correspond to human touch 2.9 +because my creatures are made out of completely rigid segments that 2.10 +don't deform like human skin. 2.11 + 2.12 +Human skin has a wide array of touch sensors, each of which speciliaze 2.13 +in detecting different vibrational modes and pressures. These sensors 2.14 +can integrate a vast expanse of skin (i.e. your entire palm), or a 2.15 +tiny patch of skin at the tip of your finger. The hairs of the skin 2.16 +help detect objects before they even come into contact with the skin 2.17 +proper. 2.18 + 2.19 +Instead of measuring deformation or vibration, I surround each rigid 2.20 +part with a plenitude of hair-like objects which do not interact with 2.21 +the physical world. Physical objects can pass through them with no 2.22 +effect. The hairs are able to measure contact with other objects, and 2.23 +constantly report how much of their extent is covered. So, even though 2.24 +the creature's body parts do not deform, the hairs create a margin 2.25 +around those body parts which achieves a sense of touch which is a 2.26 +hybrid between a human's sense of deformation and sense from hairs. 2.27 + 2.28 +Implementing touch in jMonkeyEngine follows a different techinal route 2.29 +than vision and hearing. Those two senses piggybacked off 2.30 +jMonkeyEngine's 3D audio and video rendering subsystems. To simulate 2.31 +Touch, I use jMonkeyEngine's physics system to execute many small 2.32 +collision detections, one for each "hair". 2.33 + 2.34 +* Sensor Related Functions 2.35 #+begin_src clojure 2.36 -(in-ns 'cortex.touch) 2.37 - 2.38 -(defn triangles 2.39 - "Return a sequence of all the Triangles which compose a given 2.40 - Geometry." 2.41 - [#^Geometry geom] 2.42 - (let 2.43 - [mesh (.getMesh geom) 2.44 - triangles (transient [])] 2.45 - (dorun 2.46 - (for [n (range (.getTriangleCount mesh))] 2.47 - (let [tri (Triangle.)] 2.48 - (.getTriangle mesh n tri) 2.49 - ;; (.calculateNormal tri) 2.50 - ;; (.calculateCenter tri) 2.51 - (conj! triangles tri)))) 2.52 - (persistent! triangles))) 2.53 - 2.54 -(defn get-ray-origin 2.55 - "Return the origin which a Ray would have to have to be in the exact 2.56 - center of a particular Triangle in the Geometry in World 2.57 - Coordinates." 2.58 - [geom tri] 2.59 - (let [new (Vector3f.)] 2.60 - (.calculateCenter tri) 2.61 - (.localToWorld geom (.getCenter tri) new) new)) 2.62 - 2.63 -(defn get-ray-direction 2.64 - "Return the direction which a Ray would have to have to be to point 2.65 - normal to the Triangle, in coordinates relative to the center of the 2.66 - Triangle." 2.67 - [geom tri] 2.68 - (let [n+c (Vector3f.)] 2.69 - (.calculateNormal tri) 2.70 - (.calculateCenter tri) 2.71 - (.localToWorld 2.72 - geom 2.73 - (.add (.getCenter tri) (.getNormal tri)) n+c) 2.74 - (.subtract n+c (get-ray-origin geom tri)))) 2.75 - 2.76 -;; Every Mesh has many triangles, each with its own index. 2.77 -;; Every vertex has its own index as well. 2.78 - 2.79 -(defn tactile-sensor-profile 2.80 - "Return the touch-sensor distribution image in BufferedImage format, 2.81 - or nil if it does not exist." 2.82 - [#^Geometry obj] 2.83 - (if-let [image-path (meta-data obj "touch")] 2.84 - (load-image image-path))) 2.85 - 2.86 -(defn mesh-triangle 2.87 - "Get the triangle specified by triangle-index from the mesh within 2.88 - bounds." 2.89 - [#^Mesh mesh triangle-index] 2.90 - (let [scratch (Triangle.)] 2.91 - (.getTriangle mesh triangle-index scratch) 2.92 - scratch)) 2.93 - 2.94 -(defn triangle-vertex-indices 2.95 - "Get the triangle vertex indices of a given triangle from a given 2.96 - mesh." 2.97 - [#^Mesh mesh triangle-index] 2.98 - (let [indices (int-array 3)] 2.99 - (.getTriangle mesh triangle-index indices) 2.100 - (vec indices))) 2.101 - 2.102 -(defn vertex-UV-coord 2.103 - "Get the UV-coordinates of the vertex named by vertex-index" 2.104 - [#^Mesh mesh vertex-index] 2.105 - (let [UV-buffer 2.106 - (.getData 2.107 - (.getBuffer 2.108 - mesh 2.109 - VertexBuffer$Type/TexCoord))] 2.110 - [(.get UV-buffer (* vertex-index 2)) 2.111 - (.get UV-buffer (+ 1 (* vertex-index 2)))])) 2.112 - 2.113 -(defn triangle-UV-coord 2.114 - "Get the UV-cooridnates of the triangle's verticies." 2.115 - [#^Mesh mesh width height triangle-index] 2.116 - (map (fn [[u v]] (vector (* width u) (* height v))) 2.117 - (map (partial vertex-UV-coord mesh) 2.118 - (triangle-vertex-indices mesh triangle-index)))) 2.119 - 2.120 -(defn same-side? 2.121 - "Given the points p1 and p2 and the reference point ref, is point p 2.122 - on the same side of the line that goes through p1 and p2 as ref is?" 2.123 - [p1 p2 ref p] 2.124 - (<= 2.125 - 0 2.126 - (.dot 2.127 - (.cross (.subtract p2 p1) (.subtract p p1)) 2.128 - (.cross (.subtract p2 p1) (.subtract ref p1))))) 2.129 - 2.130 -(defn triangle-seq [#^Triangle tri] 2.131 - [(.get1 tri) (.get2 tri) (.get3 tri)]) 2.132 - 2.133 -(defn vector3f-seq [#^Vector3f v] 2.134 - [(.getX v) (.getY v) (.getZ v)]) 2.135 - 2.136 -(defn inside-triangle? 2.137 - "Is the point inside the triangle?" 2.138 - {:author "Dylan Holmes"} 2.139 - [#^Triangle tri #^Vector3f p] 2.140 - (let [[vert-1 vert-2 vert-3] (triangle-seq tri)] 2.141 - (and 2.142 - (same-side? vert-1 vert-2 vert-3 p) 2.143 - (same-side? vert-2 vert-3 vert-1 p) 2.144 - (same-side? vert-3 vert-1 vert-2 p)))) 2.145 - 2.146 -(defn triangle->matrix4f 2.147 - "Converts the triangle into a 4x4 matrix: The first three columns 2.148 - contain the vertices of the triangle; the last contains the unit 2.149 - normal of the triangle. The bottom row is filled with 1s." 2.150 - [#^Triangle t] 2.151 - (let [mat (Matrix4f.) 2.152 - [vert-1 vert-2 vert-3] 2.153 - ((comp vec map) #(.get t %) (range 3)) 2.154 - unit-normal (do (.calculateNormal t)(.getNormal t)) 2.155 - vertices [vert-1 vert-2 vert-3 unit-normal]] 2.156 - (dorun 2.157 - (for [row (range 4) col (range 3)] 2.158 - (do 2.159 - (.set mat col row (.get (vertices row)col)) 2.160 - (.set mat 3 row 1)))) 2.161 - mat)) 2.162 - 2.163 -(defn triangle-transformation 2.164 - "Returns the affine transformation that converts each vertex in the 2.165 - first triangle into the corresponding vertex in the second 2.166 - triangle." 2.167 - [#^Triangle tri-1 #^Triangle tri-2] 2.168 - (.mult 2.169 - (triangle->matrix4f tri-2) 2.170 - (.invert (triangle->matrix4f tri-1)))) 2.171 - 2.172 -(defn point->vector2f [[u v]] 2.173 - (Vector2f. u v)) 2.174 - 2.175 -(defn vector2f->vector3f [v] 2.176 - (Vector3f. (.getX v) (.getY v) 0)) 2.177 - 2.178 -(defn map-triangle [f #^Triangle tri] 2.179 - (Triangle. 2.180 - (f 0 (.get1 tri)) 2.181 - (f 1 (.get2 tri)) 2.182 - (f 2 (.get3 tri)))) 2.183 - 2.184 -(defn points->triangle 2.185 - "Convert a list of points into a triangle." 2.186 - [points] 2.187 - (apply #(Triangle. %1 %2 %3) 2.188 - (map (fn [point] 2.189 - (let [point (vec point)] 2.190 - (Vector3f. (get point 0 0) 2.191 - (get point 1 0) 2.192 - (get point 2 0)))) 2.193 - (take 3 points)))) 2.194 - 2.195 -(defn convex-bounds 2.196 - "Returns the smallest square containing the given vertices, as a 2.197 - vector of integers [left top width height]." 2.198 - [uv-verts] 2.199 - (let [xs (map first uv-verts) 2.200 - ys (map second uv-verts) 2.201 - x0 (Math/floor (apply min xs)) 2.202 - y0 (Math/floor (apply min ys)) 2.203 - x1 (Math/ceil (apply max xs)) 2.204 - y1 (Math/ceil (apply max ys))] 2.205 - [x0 y0 (- x1 x0) (- y1 y0)])) 2.206 - 2.207 (defn sensors-in-triangle 2.208 "Locate the touch sensors in the triangle, returning a map of their 2.209 UV and geometry-relative coordinates." 2.210 @@ -229,7 +84,198 @@ 2.211 "The location of the touch sensors in world-space coordinates." 2.212 [#^Geometry geo] 2.213 (vec (map :geometry (locate-feelers geo)))) 2.214 +#+end_src 2.215 2.216 +* Triangle Manipulation Functions 2.217 + 2.218 +#+begin_src clojure 2.219 +(defn triangles 2.220 + "Return a sequence of all the Triangles which compose a given 2.221 + Geometry." 2.222 + [#^Geometry geom] 2.223 + (let 2.224 + [mesh (.getMesh geom) 2.225 + triangles (transient [])] 2.226 + (dorun 2.227 + (for [n (range (.getTriangleCount mesh))] 2.228 + (let [tri (Triangle.)] 2.229 + (.getTriangle mesh n tri) 2.230 + ;; (.calculateNormal tri) 2.231 + ;; (.calculateCenter tri) 2.232 + (conj! triangles tri)))) 2.233 + (persistent! triangles))) 2.234 + 2.235 +(defn mesh-triangle 2.236 + "Get the triangle specified by triangle-index from the mesh within 2.237 + bounds." 2.238 + [#^Mesh mesh triangle-index] 2.239 + (let [scratch (Triangle.)] 2.240 + (.getTriangle mesh triangle-index scratch) 2.241 + scratch)) 2.242 + 2.243 +(defn triangle-vertex-indices 2.244 + "Get the triangle vertex indices of a given triangle from a given 2.245 + mesh." 2.246 + [#^Mesh mesh triangle-index] 2.247 + (let [indices (int-array 3)] 2.248 + (.getTriangle mesh triangle-index indices) 2.249 + (vec indices))) 2.250 + 2.251 +(defn vertex-UV-coord 2.252 + "Get the UV-coordinates of the vertex named by vertex-index" 2.253 + [#^Mesh mesh vertex-index] 2.254 + (let [UV-buffer 2.255 + (.getData 2.256 + (.getBuffer 2.257 + mesh 2.258 + VertexBuffer$Type/TexCoord))] 2.259 + [(.get UV-buffer (* vertex-index 2)) 2.260 + (.get UV-buffer (+ 1 (* vertex-index 2)))])) 2.261 + 2.262 +(defn triangle-UV-coord 2.263 + "Get the UV-cooridnates of the triangle's verticies." 2.264 + [#^Mesh mesh width height triangle-index] 2.265 + (map (fn [[u v]] (vector (* width u) (* height v))) 2.266 + (map (partial vertex-UV-coord mesh) 2.267 + (triangle-vertex-indices mesh triangle-index)))) 2.268 +#+end_src 2.269 + 2.270 +* Schrapnel Conversion Functions 2.271 +#+begin_src clojure 2.272 +(defn triangle-seq [#^Triangle tri] 2.273 + [(.get1 tri) (.get2 tri) (.get3 tri)]) 2.274 + 2.275 +(defn vector3f-seq [#^Vector3f v] 2.276 + [(.getX v) (.getY v) (.getZ v)]) 2.277 + 2.278 +(defn point->vector2f [[u v]] 2.279 + (Vector2f. u v)) 2.280 + 2.281 +(defn vector2f->vector3f [v] 2.282 + (Vector3f. (.getX v) (.getY v) 0)) 2.283 + 2.284 +(defn map-triangle [f #^Triangle tri] 2.285 + (Triangle. 2.286 + (f 0 (.get1 tri)) 2.287 + (f 1 (.get2 tri)) 2.288 + (f 2 (.get3 tri)))) 2.289 + 2.290 +(defn points->triangle 2.291 + "Convert a list of points into a triangle." 2.292 + [points] 2.293 + (apply #(Triangle. %1 %2 %3) 2.294 + (map (fn [point] 2.295 + (let [point (vec point)] 2.296 + (Vector3f. (get point 0 0) 2.297 + (get point 1 0) 2.298 + (get point 2 0)))) 2.299 + (take 3 points)))) 2.300 +#+end_src 2.301 + 2.302 +* Triangle Affine Transforms 2.303 + 2.304 +#+begin_src clojure 2.305 +(defn triangle->matrix4f 2.306 + "Converts the triangle into a 4x4 matrix: The first three columns 2.307 + contain the vertices of the triangle; the last contains the unit 2.308 + normal of the triangle. The bottom row is filled with 1s." 2.309 + [#^Triangle t] 2.310 + (let [mat (Matrix4f.) 2.311 + [vert-1 vert-2 vert-3] 2.312 + ((comp vec map) #(.get t %) (range 3)) 2.313 + unit-normal (do (.calculateNormal t)(.getNormal t)) 2.314 + vertices [vert-1 vert-2 vert-3 unit-normal]] 2.315 + (dorun 2.316 + (for [row (range 4) col (range 3)] 2.317 + (do 2.318 + (.set mat col row (.get (vertices row)col)) 2.319 + (.set mat 3 row 1)))) 2.320 + mat)) 2.321 + 2.322 +(defn triangle-transformation 2.323 + "Returns the affine transformation that converts each vertex in the 2.324 + first triangle into the corresponding vertex in the second 2.325 + triangle." 2.326 + [#^Triangle tri-1 #^Triangle tri-2] 2.327 + (.mult 2.328 + (triangle->matrix4f tri-2) 2.329 + (.invert (triangle->matrix4f tri-1)))) 2.330 +#+end_src 2.331 + 2.332 +* Blender Meta-Data 2.333 + 2.334 +#+begin_src clojure 2.335 +(defn tactile-sensor-profile 2.336 + "Return the touch-sensor distribution image in BufferedImage format, 2.337 + or nil if it does not exist." 2.338 + [#^Geometry obj] 2.339 + (if-let [image-path (meta-data obj "touch")] 2.340 + (load-image image-path))) 2.341 +#+end_src 2.342 + 2.343 +* Physics Collision Objects 2.344 +#+begin_src clojure 2.345 +(defn get-ray-origin 2.346 + "Return the origin which a Ray would have to have to be in the exact 2.347 + center of a particular Triangle in the Geometry in World 2.348 + Coordinates." 2.349 + [geom tri] 2.350 + (let [new (Vector3f.)] 2.351 + (.calculateCenter tri) 2.352 + (.localToWorld geom (.getCenter tri) new) new)) 2.353 + 2.354 +(defn get-ray-direction 2.355 + "Return the direction which a Ray would have to have to be to point 2.356 + normal to the Triangle, in coordinates relative to the center of the 2.357 + Triangle." 2.358 + [geom tri] 2.359 + (let [n+c (Vector3f.)] 2.360 + (.calculateNormal tri) 2.361 + (.calculateCenter tri) 2.362 + (.localToWorld 2.363 + geom 2.364 + (.add (.getCenter tri) (.getNormal tri)) n+c) 2.365 + (.subtract n+c (get-ray-origin geom tri)))) 2.366 +#+end_src 2.367 + 2.368 +* Triangle Boundaries 2.369 +#+begin_src clojure 2.370 +(defn same-side? 2.371 + "Given the points p1 and p2 and the reference point ref, is point p 2.372 + on the same side of the line that goes through p1 and p2 as ref is?" 2.373 + [p1 p2 ref p] 2.374 + (<= 2.375 + 0 2.376 + (.dot 2.377 + (.cross (.subtract p2 p1) (.subtract p p1)) 2.378 + (.cross (.subtract p2 p1) (.subtract ref p1))))) 2.379 + 2.380 +(defn inside-triangle? 2.381 + "Is the point inside the triangle?" 2.382 + {:author "Dylan Holmes"} 2.383 + [#^Triangle tri #^Vector3f p] 2.384 + (let [[vert-1 vert-2 vert-3] (triangle-seq tri)] 2.385 + (and 2.386 + (same-side? vert-1 vert-2 vert-3 p) 2.387 + (same-side? vert-2 vert-3 vert-1 p) 2.388 + (same-side? vert-3 vert-1 vert-2 p)))) 2.389 + 2.390 +(defn convex-bounds 2.391 + "Returns the smallest square containing the given vertices, as a 2.392 + vector of integers [left top width height]." 2.393 + [uv-verts] 2.394 + (let [xs (map first uv-verts) 2.395 + ys (map second uv-verts) 2.396 + x0 (Math/floor (apply min xs)) 2.397 + y0 (Math/floor (apply min ys)) 2.398 + x1 (Math/ceil (apply max xs)) 2.399 + y1 (Math/ceil (apply max ys))] 2.400 + [x0 y0 (- x1 x0) (- y1 y0)])) 2.401 +#+end_src 2.402 + 2.403 +* Skin Creation 2.404 + 2.405 +#+begin_src clojure 2.406 (defn touch-fn 2.407 "Returns a function which returns tactile sensory data when called 2.408 inside a running simulation." 2.409 @@ -283,7 +329,11 @@ 2.410 (map touch-fn 2.411 (filter #(isa? (class %) Geometry) 2.412 (node-seq creature))))) 2.413 +#+end_src 2.414 2.415 +* Visualizing Touch 2.416 + 2.417 +#+begin_src clojure 2.418 (defn view-touch 2.419 "Creates a function which accepts a list of touch sensor-data and 2.420 displays each element to the screen." 2.421 @@ -316,6 +366,13 @@ 2.422 (:import (com.jme3.math Triangle Vector3f Vector2f Ray Matrix4f))) 2.423 #+end_src 2.424 2.425 +;; Every Mesh has many triangles, each with its own index. 2.426 +;; Every vertex has its own index as well. 2.427 + 2.428 +* Source Listing 2.429 +* Next 2.430 + 2.431 + 2.432 * COMMENT Code Generation 2.433 #+begin_src clojure :tangle ../src/cortex/touch.clj 2.434 <<skin-main>>