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>>