# HG changeset patch
# User Robert McIntyre <rlm@mit.edu>
# Date 1329138362 25200
# Node ID 95a9f6f1cb823afd5d2d6040eedfbd9f21a4b2fb
# Parent  267add63b1685c9a003f2437fa770b36b2fff4dd
added touch-cube and fixed some problems with touch which it flushed out

diff -r 267add63b168 -r 95a9f6f1cb82 assets/Models/test-touch/touch-cube.blend
Binary file assets/Models/test-touch/touch-cube.blend has changed
diff -r 267add63b168 -r 95a9f6f1cb82 assets/Models/test-touch/touch-guide.png
Binary file assets/Models/test-touch/touch-guide.png has changed
diff -r 267add63b168 -r 95a9f6f1cb82 assets/Models/test-touch/touch-profile.png
Binary file assets/Models/test-touch/touch-profile.png has changed
diff -r 267add63b168 -r 95a9f6f1cb82 assets/Models/test-touch/touch-profile.xcf
Binary file assets/Models/test-touch/touch-profile.xcf has changed
diff -r 267add63b168 -r 95a9f6f1cb82 images/touch-cube-1.png
Binary file images/touch-cube-1.png has changed
diff -r 267add63b168 -r 95a9f6f1cb82 images/touch-profile.png
Binary file images/touch-profile.png has changed
diff -r 267add63b168 -r 95a9f6f1cb82 org/ideas.org
--- a/org/ideas.org	Sun Feb 12 16:00:31 2012 -0700
+++ b/org/ideas.org	Mon Feb 13 06:06:02 2012 -0700
@@ -75,6 +75,7 @@
  - [ ] fix videos that were encoded wrong, test on InterNet Explorer.
  - [ ] redo videos vision with new collapse code
  - [ ] find a topology that looks good. (maybe nil topology?)
+ - [ ] fix red part of touch cube in video and image
  - [ ] write summary of project for Winston            \
  - [ ] project proposals for Winston                    \
  - [ ] additional senses to be implemented for Winston   |  -- 2 days 
diff -r 267add63b168 -r 95a9f6f1cb82 org/touch.org
--- a/org/touch.org	Sun Feb 12 16:00:31 2012 -0700
+++ b/org/touch.org	Mon Feb 13 06:06:02 2012 -0700
@@ -383,10 +383,13 @@
   ;; Doing everything locally recduces garbage collection by enough to
   ;; be worth it.
   (.mult transform origin (.getOrigin ray))
-  
   (.mult transform tip (.getDirection ray))
-  (.subtractLocal (.getDirection ray) (.getOrigin ray)))
+  (.subtractLocal (.getDirection ray) (.getOrigin ray))
+  (.normalizeLocal (.getDirection ray)))
 
+(import com.jme3.math.FastMath)
+
+ 
 (defn touch-kernel
   "Constructs a function which will return tactile sensory data from
    'geo when called from inside a running simulation"
@@ -397,7 +400,15 @@
           ray-reference-tips (feeler-tips geo profile)
           ray-length (tactile-scale geo)
           current-rays (map (fn [_] (Ray.)) ray-reference-origins)
-          topology (touch-topology geo profile)]
+          topology (touch-topology geo profile)
+          correction (float (* ray-length -0.2))]
+
+      ;; slight tolerance for very close collisions.
+      (dorun
+       (map (fn [origin tip]
+              (.addLocal origin (.mult (.subtract tip origin)
+                                       correction)))
+            ray-reference-origins ray-reference-tips))
       (dorun (map #(.setLimit % ray-length) current-rays))
       (fn [node]
         (let [transform (.getWorldMatrix geo)]
@@ -415,11 +426,20 @@
                   (.collideWith node ray results)
                   (let [touch-objects
                         (filter #(not (= geo (.getGeometry %)))
-                                results)]
+                                results)
+                        limit (.getLimit ray)]
                     [(if (empty? touch-objects)
-                       (.getLimit ray)
-                       (.getDistance (first touch-objects)))
-                     (.getLimit ray)])))))))))))
+                       limit
+                       (let [response
+                             (apply min (map #(.getDistance %)
+                                             touch-objects))]
+                         (FastMath/clamp
+                          (float 
+                           (if (> response limit) 0.0
+                               (+ response correction)))
+                           (float 0.0)
+                           limit)))
+                     limit])))))))))))
 
 (defn touch! 
   "Endow the creature with the sense of touch. Returns a sequence of
@@ -433,8 +453,18 @@
                 (node-seq creature)))))
 #+end_src
 
+#+results: kernel
+: #'cortex.touch/touch!
+
 * Visualizing Touch
 
+Each feeler is represented in the image as a single pixel. The
+grayscale value of each pixel represents how deep the feeler
+represented by that pixel is inside another object.  Black means that
+nothing is touching the feeler, while white means that the feeler is
+completely inside another object, which is presumably flush with the
+surface of the triangle from which the feeler originates.
+
 #+name: visualization
 #+begin_src clojure
 (in-ns 'cortex.touch)
@@ -453,9 +483,80 @@
      (let [image (points->image coords)]
        (dorun
         (for [i (range (count coords))]
-          (.setRGB image ((coords i) 0) ((coords i) 1)
-                   (apply touch->gray (sensor-data i))))) image))))
+          (do
+            (if (= i 500) (println-repl (sensor-data i)))
+
+            (comment
+              (.setRGB image ((coords i) 0) ((coords i) 1)
+                     (apply touch->gray (sensor-data i))))))) 
+       image))))
 #+end_src
+
+#+results: visualization
+: #'cortex.touch/view-touch
+
+* COMMENT Basic Test of Touch
+
+The worm's sense of touch is a bit complicated, so for this basic test
+I'll use a new creature --- a simple cube which has touch sensors
+evenly distributed along each of its sides.
+
+#+begin_src clojure
+(in-ns 'cortex.test.touch)
+
+(defn touch-cube []
+  (load-blender-model "Models/test-touch/touch-cube.blend"))
+#+end_src
+
+#+begin_html
+<br>
+#+end_html
+
+#+begin_html
+<div class="figure">
+<center>
+<video controls="controls" width="500">
+  <source src="../video/touch-cube.ogg" type="video/ogg"
+	  preload="none" poster="../images/aurellem-1280x480.png" />
+</video>
+</center>
+<p>A simple creature with evenly distributed touch sensors.</p>
+</div>
+#+end_html
+
+The tactile-sensor-profile image for this simple creature looks like
+this:
+
+#+attr_html: width=500
+#+caption: The distribution of feelers along the touch-cube. The colors of the faces are irrelevant; only the white pixels specify feelers.
+[[../images/touch-profile.png]]
+
+#+begin_src clojure
+(in-ns 'cortex.test.touch)
+
+(defn test-basic-touch
+  ([] (test-basic-touch false))
+  ([record?]
+     (let [the-cube (doto (touch-cube) (body!))
+           touch (touch! the-cube)
+           touch-display (view-touch)]
+       (world (nodify [the-cube
+                       (box 10 1 10 :position (Vector3f. 0 -10 0)
+                            :color ColorRGBA/Gray :mass 0)])
+
+              standard-debug-controls
+              
+              (fn [world]
+                (speed-up world)
+                (light-up-everything world))
+
+              (fn [world tpf]
+                (touch-display 
+                 (map #(% (.getRootNode world)) touch)))))))
+  
+
+#+end_src
+
 * Adding Touch to the Worm
 
 #+name: test-touch