diff org/test-creature.org @ 156:e8df6e76c3e5

refactored touch
author Robert McIntyre <rlm@mit.edu>
date Fri, 03 Feb 2012 06:15:34 -0700
parents 95bf55614211
children 84c67be00abe
line wrap: on
line diff
     1.1 --- a/org/test-creature.org	Fri Feb 03 06:04:30 2012 -0700
     1.2 +++ b/org/test-creature.org	Fri Feb 03 06:15:34 2012 -0700
     1.3 @@ -77,18 +77,6 @@
     1.4               (.getZ in)
     1.5               (- (.getY in))))
     1.6  
     1.7 -(defn world-to-local
     1.8 -   "Convert the world coordinates into coordinates relative to the 
     1.9 -   object (i.e. local coordinates), taking into account the rotation
    1.10 -   of object."
    1.11 -   [#^Spatial object world-coordinate]
    1.12 -   (.worldToLocal object world-coordinate nil))
    1.13 -
    1.14 -(defn local-to-world
    1.15 -   "Convert the local coordinates into coordinates into world relative
    1.16 -    coordinates" 
    1.17 -   [#^Spatial object local-coordinate]
    1.18 -   (.localToWorld object local-coordinate nil))
    1.19  
    1.20  (defmulti joint-dispatch
    1.21    "Translate blender pseudo-joints into real JME joints."
    1.22 @@ -245,8 +233,6 @@
    1.23  
    1.24  (def worm "Models/creature1/try-again.blend")
    1.25  
    1.26 -(def touch "Models/creature1/touch.blend")
    1.27 -
    1.28  (defn worm-model [] (load-blender-model worm))
    1.29  
    1.30  (defn x-ray [#^ColorRGBA color]
    1.31 @@ -263,237 +249,6 @@
    1.32  
    1.33  (import ij.ImagePlus)
    1.34  
    1.35 -;; Every Mesh has many triangles, each with its own index.
    1.36 -;; Every vertex has its own index as well.
    1.37 -
    1.38 -(defn tactile-sensor-image
    1.39 -  "Return the touch-sensor distribution image in BufferedImage format,
    1.40 -   or nil if it does not exist."
    1.41 -  [#^Geometry obj]
    1.42 -  (if-let [image-path (meta-data obj "touch")]
    1.43 -    (ImageToAwt/convert
    1.44 -     (.getImage
    1.45 -      (.loadTexture
    1.46 -       (asset-manager)
    1.47 -       image-path))
    1.48 -    false false 0)))
    1.49 -     
    1.50 -
    1.51 -
    1.52 -(defn triangle
    1.53 -  "Get the triangle specified by triangle-index from the mesh within
    1.54 -  bounds."
    1.55 -  [#^Mesh mesh triangle-index]
    1.56 -  (let [scratch (Triangle.)]
    1.57 -    (.getTriangle mesh triangle-index scratch)
    1.58 -    scratch))
    1.59 -
    1.60 -(defn triangle-vertex-indices
    1.61 -  "Get the triangle vertex indices of a given triangle from a given
    1.62 -   mesh."
    1.63 -  [#^Mesh mesh triangle-index]
    1.64 -  (let [indices (int-array 3)]
    1.65 -    (.getTriangle mesh triangle-index indices)
    1.66 -    (vec indices)))
    1.67 -
    1.68 -(defn vertex-UV-coord
    1.69 -  "Get the uv-coordinates of the vertex named by vertex-index"
    1.70 -  [#^Mesh mesh vertex-index]
    1.71 -  (let [UV-buffer
    1.72 -        (.getData
    1.73 -         (.getBuffer
    1.74 -          mesh
    1.75 -          VertexBuffer$Type/TexCoord))]
    1.76 -    [(.get UV-buffer (* vertex-index 2))
    1.77 -     (.get UV-buffer (+ 1 (* vertex-index 2)))]))
    1.78 -
    1.79 -(defn triangle-UV-coord
    1.80 -  "Get the uv-cooridnates of the triangle's verticies."
    1.81 -  [#^Mesh mesh width height triangle-index]
    1.82 -  (map (fn [[u v]] (vector (* width u) (* height v)))
    1.83 -       (map (partial vertex-UV-coord mesh)
    1.84 -            (triangle-vertex-indices mesh triangle-index))))
    1.85 -  
    1.86 -(defn same-side?
    1.87 -  "Given the points p1 and p2 and the reference point ref, is point p
    1.88 -  on the same side of the line that goes through p1 and p2 as ref is?" 
    1.89 -  [p1 p2 ref p]
    1.90 -  (<=
    1.91 -   0
    1.92 -   (.dot 
    1.93 -    (.cross (.subtract p2 p1) (.subtract p p1))
    1.94 -    (.cross (.subtract p2 p1) (.subtract ref p1)))))
    1.95 -
    1.96 -(defn triangle-seq [#^Triangle tri]
    1.97 -  [(.get1 tri) (.get2 tri) (.get3 tri)])
    1.98 -
    1.99 -(defn vector3f-seq [#^Vector3f v]
   1.100 -  [(.getX v) (.getY v) (.getZ v)])
   1.101 -
   1.102 -(defn inside-triangle?
   1.103 -  "Is the point inside the triangle?"
   1.104 -  {:author "Dylan Holmes"}
   1.105 -  [#^Triangle tri #^Vector3f p]
   1.106 -  (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]
   1.107 -    (and
   1.108 -     (same-side? vert-1 vert-2 vert-3 p)
   1.109 -     (same-side? vert-2 vert-3 vert-1 p)
   1.110 -     (same-side? vert-3 vert-1 vert-2 p))))
   1.111 -
   1.112 -(defn triangle->matrix4f
   1.113 -  "Converts the triangle into a 4x4 matrix: The first three columns
   1.114 -   contain the vertices of the triangle; the last contains the unit
   1.115 -   normal of the triangle. The bottom row is filled with 1s."
   1.116 -  [#^Triangle t]
   1.117 -  (let [mat (Matrix4f.)
   1.118 -        [vert-1 vert-2 vert-3]
   1.119 -        ((comp vec map) #(.get t %) (range 3))
   1.120 -        unit-normal (do (.calculateNormal t)(.getNormal t))
   1.121 -        vertices [vert-1 vert-2 vert-3 unit-normal]]
   1.122 -    (dorun 
   1.123 -     (for [row (range 4) col (range 3)]
   1.124 -       (do
   1.125 -         (.set mat col row (.get (vertices row)col))
   1.126 -         (.set mat 3 row 1))))
   1.127 -    mat))
   1.128 -
   1.129 -(defn triangle-transformation
   1.130 -  "Returns the affine transformation that converts each vertex in the
   1.131 -   first triangle into the corresponding vertex in the second
   1.132 -   triangle."
   1.133 -  [#^Triangle tri-1 #^Triangle tri-2]
   1.134 -  (.mult 
   1.135 -   (triangle->matrix4f tri-2)
   1.136 -   (.invert (triangle->matrix4f tri-1))))
   1.137 -
   1.138 -(defn point->vector2f [[u v]]
   1.139 -  (Vector2f. u v))
   1.140 -
   1.141 -(defn vector2f->vector3f [v]
   1.142 -  (Vector3f. (.getX v) (.getY v) 0))
   1.143 -
   1.144 -(defn map-triangle [f #^Triangle tri]
   1.145 -  (Triangle.
   1.146 -   (f 0 (.get1 tri))
   1.147 -   (f 1 (.get2 tri))
   1.148 -   (f 2 (.get3 tri))))
   1.149 -
   1.150 -(defn points->triangle
   1.151 -  "Convert a list of points into a triangle."
   1.152 -  [points]
   1.153 -  (apply #(Triangle. %1 %2 %3)
   1.154 -         (map (fn [point]
   1.155 -                (let [point (vec point)]
   1.156 -                  (Vector3f. (get point 0 0)
   1.157 -                             (get point 1 0)
   1.158 -                             (get point 2 0))))
   1.159 -              (take 3 points))))
   1.160 -
   1.161 -(defn convex-bounds
   1.162 -  ;;dylan
   1.163 -  "Returns the smallest square containing the given
   1.164 -vertices, as a vector of integers [left top width height]."
   1.165 - ;; "Dimensions of the smallest integer bounding square of the list of
   1.166 - ;;  2D verticies in the form: [x y width height]."
   1.167 -  [uv-verts]
   1.168 -  (let [xs (map first uv-verts)
   1.169 -        ys (map second uv-verts)
   1.170 -        x0 (Math/floor (apply min xs))
   1.171 -        y0 (Math/floor (apply min ys))
   1.172 -        x1 (Math/ceil (apply max xs))
   1.173 -        y1 (Math/ceil (apply max ys))]
   1.174 -    [x0 y0 (- x1 x0) (- y1 y0)]))
   1.175 -
   1.176 -(defn sensors-in-triangle
   1.177 -  ;;dylan
   1.178 -  "Locate the touch sensors in the triangle, returning a map of their UV and geometry-relative coordinates."
   1.179 -  ;;"Find the locations of the touch sensors within a triangle in both
   1.180 -  ;; UV and gemoetry relative coordinates."
   1.181 -  [image mesh tri-index]
   1.182 -  (let [width (.getWidth image)
   1.183 -        height (.getHeight image)
   1.184 -        UV-vertex-coords (triangle-UV-coord mesh width height tri-index)
   1.185 -        bounds (convex-bounds UV-vertex-coords)
   1.186 -        
   1.187 -        cutout-triangle (points->triangle UV-vertex-coords)
   1.188 -        UV-sensor-coords
   1.189 -        (filter (comp (partial inside-triangle? cutout-triangle)
   1.190 -                      (fn [[u v]] (Vector3f. u v 0)))
   1.191 -                (white-coordinates image bounds))
   1.192 -        UV->geometry (triangle-transformation
   1.193 -                      cutout-triangle
   1.194 -                      (triangle mesh tri-index))
   1.195 -        geometry-sensor-coords
   1.196 -        (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0)))
   1.197 -             UV-sensor-coords)]
   1.198 -  {:UV UV-sensor-coords :geometry geometry-sensor-coords}))
   1.199 -
   1.200 -(defn-memo locate-feelers
   1.201 -  "Search the geometry's tactile UV image for touch sensors, returning
   1.202 -  their positions in geometry-relative coordinates."
   1.203 -  [#^Geometry geo]
   1.204 -  (let [mesh (.getMesh geo)
   1.205 -        num-triangles (.getTriangleCount mesh)]
   1.206 -    (if-let [image (tactile-sensor-image geo)]
   1.207 -      (map
   1.208 -       (partial sensors-in-triangle image mesh)
   1.209 -       (range num-triangles))
   1.210 -      (repeat (.getTriangleCount mesh) {:UV nil :geometry nil}))))
   1.211 -
   1.212 -(use 'clojure.contrib.def)
   1.213 -
   1.214 -(defn-memo touch-topology [#^Gemoetry geo]
   1.215 -  (vec (collapse (reduce concat (map :UV (locate-feelers geo))))))
   1.216 -
   1.217 -(defn-memo feeler-coordinates [#^Geometry geo]
   1.218 -  (vec (map :geometry (locate-feelers geo))))
   1.219 -
   1.220 -(defn enable-touch [#^Geometry geo]
   1.221 -  (let [feeler-coords (feeler-coordinates geo)
   1.222 -        tris (triangles geo)
   1.223 -        limit 0.1
   1.224 -        ;;results (CollisionResults.)
   1.225 -        ]
   1.226 -    (if (empty? (touch-topology geo))
   1.227 -      nil
   1.228 -      (fn [node]
   1.229 -        (let [sensor-origins 
   1.230 -              (map
   1.231 -               #(map (partial local-to-world geo) %)
   1.232 -               feeler-coords)
   1.233 -              triangle-normals 
   1.234 -              (map (partial get-ray-direction geo)
   1.235 -                   tris)
   1.236 -              rays
   1.237 -              (flatten
   1.238 -               (map (fn [origins norm]
   1.239 -                      (map #(doto (Ray. % norm)
   1.240 -                              (.setLimit limit)) origins))
   1.241 -                    sensor-origins triangle-normals))]
   1.242 -          (vector
   1.243 -           (touch-topology geo)
   1.244 -           (vec
   1.245 -            (for [ray rays]
   1.246 -              (do
   1.247 -                (let [results (CollisionResults.)]
   1.248 -                  (.collideWith node ray results)
   1.249 -                  (let [touch-objects
   1.250 -                        (filter #(not (= geo (.getGeometry %)))
   1.251 -                                results)]
   1.252 -                    (- 255
   1.253 -                       (if (empty? touch-objects) 255
   1.254 -                           (rem 
   1.255 -                            (int
   1.256 -                             (* 255 (/ (.getDistance
   1.257 -                                        (first touch-objects)) limit)))
   1.258 -                            256))))))))))))))
   1.259 -                         
   1.260 -  
   1.261 -(defn touch [#^Node pieces]
   1.262 -  (filter (comp not nil?)
   1.263 -          (map enable-touch
   1.264 -               (filter #(isa? (class %) Geometry)
   1.265 -                       (node-seq pieces)))))
   1.266  
   1.267  
   1.268  (defn test-eye  []