Mercurial > cortex
comparison org/touch.org @ 178:6fba17a74a57
refactored touch
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 04 Feb 2012 07:05:54 -0700 |
parents | 5af4ebe72b97 |
children | 11bd5f0625ad |
comparison
equal
deleted
inserted
replaced
177:5af4ebe72b97 | 178:6fba17a74a57 |
---|---|
3 #+email: rlm@mit.edu | 3 #+email: rlm@mit.edu |
4 #+description: Simulated touch for AI research using JMonkeyEngine and clojure. | 4 #+description: Simulated touch for AI research using JMonkeyEngine and clojure. |
5 #+keywords: simulation, tactile sense, jMonkeyEngine3, clojure | 5 #+keywords: simulation, tactile sense, jMonkeyEngine3, clojure |
6 #+SETUPFILE: ../../aurellem/org/setup.org | 6 #+SETUPFILE: ../../aurellem/org/setup.org |
7 #+INCLUDE: ../../aurellem/org/level-0.org | 7 #+INCLUDE: ../../aurellem/org/level-0.org |
8 | |
9 | 8 |
10 * Touch | 9 * Touch |
11 | 10 |
12 My creatures need to be able to feel their environments. The idea here | 11 My creatures need to be able to feel their environments. The idea here |
13 is to create thousands of small /touch receptors/ along the geometries | 12 is to create thousands of small /touch receptors/ along the geometries |
24 to be outfitted with touch sensors with density proportional to the | 23 to be outfitted with touch sensors with density proportional to the |
25 density of triangles along the surface of the Geometry. Enables a | 24 density of triangles along the surface of the Geometry. Enables a |
26 Geometry to know what parts of itself are touching nearby objects." | 25 Geometry to know what parts of itself are touching nearby objects." |
27 {:author "Robert McIntyre"} | 26 {:author "Robert McIntyre"} |
28 (:use (cortex world util sense)) | 27 (:use (cortex world util sense)) |
28 (:use clojure.contrib.def) | |
29 (:import com.jme3.scene.Geometry) | 29 (:import com.jme3.scene.Geometry) |
30 (:import com.jme3.collision.CollisionResults) | 30 (:import com.jme3.collision.CollisionResults) |
31 (:import jme3tools.converters.ImageToAwt) | 31 (:import jme3tools.converters.ImageToAwt) |
32 (:import (com.jme3.math Triangle Vector3f Ray))) | 32 (:import (com.jme3.math Triangle Vector3f Ray))) |
33 | 33 |
34 (use 'clojure.contrib.def) | |
35 (cortex.import/mega-import-jme3) | 34 (cortex.import/mega-import-jme3) |
36 | 35 |
37 (defn triangles | 36 (defn triangles |
38 "Return a sequence of all the Triangles which compose a given | 37 "Return a sequence of all the Triangles which compose a given |
39 Geometry." | 38 Geometry." |
73 (.subtract n+c (get-ray-origin geom tri)))) | 72 (.subtract n+c (get-ray-origin geom tri)))) |
74 | 73 |
75 ;; Every Mesh has many triangles, each with its own index. | 74 ;; Every Mesh has many triangles, each with its own index. |
76 ;; Every vertex has its own index as well. | 75 ;; Every vertex has its own index as well. |
77 | 76 |
78 (defn tactile-sensor-image | 77 (defn tactile-sensor-profile |
79 "Return the touch-sensor distribution image in BufferedImage format, | 78 "Return the touch-sensor distribution image in BufferedImage format, |
80 or nil if it does not exist." | 79 or nil if it does not exist." |
81 [#^Geometry obj] | 80 [#^Geometry obj] |
82 (if-let [image-path (meta-data obj "touch")] | 81 (if-let [image-path (meta-data obj "touch")] |
83 (ImageToAwt/convert | 82 (load-image image-path))) |
84 (.getImage | |
85 (.loadTexture | |
86 (asset-manager) | |
87 image-path)) | |
88 false false 0))) | |
89 | |
90 | |
91 | 83 |
92 (defn triangle | 84 (defn triangle |
93 "Get the triangle specified by triangle-index from the mesh within | 85 "Get the triangle specified by triangle-index from the mesh within |
94 bounds." | 86 bounds." |
95 [#^Mesh mesh triangle-index] | 87 [#^Mesh mesh triangle-index] |
197 (get point 1 0) | 189 (get point 1 0) |
198 (get point 2 0)))) | 190 (get point 2 0)))) |
199 (take 3 points)))) | 191 (take 3 points)))) |
200 | 192 |
201 (defn convex-bounds | 193 (defn convex-bounds |
202 ;;dylan | 194 "Returns the smallest square containing the given vertices, as a |
203 "Returns the smallest square containing the given | 195 vector of integers [left top width height]." |
204 vertices, as a vector of integers [left top width height]." | |
205 ;; "Dimensions of the smallest integer bounding square of the list of | |
206 ;; 2D verticies in the form: [x y width height]." | |
207 [uv-verts] | 196 [uv-verts] |
208 (let [xs (map first uv-verts) | 197 (let [xs (map first uv-verts) |
209 ys (map second uv-verts) | 198 ys (map second uv-verts) |
210 x0 (Math/floor (apply min xs)) | 199 x0 (Math/floor (apply min xs)) |
211 y0 (Math/floor (apply min ys)) | 200 y0 (Math/floor (apply min ys)) |
212 x1 (Math/ceil (apply max xs)) | 201 x1 (Math/ceil (apply max xs)) |
213 y1 (Math/ceil (apply max ys))] | 202 y1 (Math/ceil (apply max ys))] |
214 [x0 y0 (- x1 x0) (- y1 y0)])) | 203 [x0 y0 (- x1 x0) (- y1 y0)])) |
215 | 204 |
216 (defn sensors-in-triangle | 205 (defn sensors-in-triangle |
217 ;;dylan | 206 "Locate the touch sensors in the triangle, returning a map of their |
218 "Locate the touch sensors in the triangle, returning a map of their UV and geometry-relative coordinates." | 207 UV and geometry-relative coordinates." |
219 ;;"Find the locations of the touch sensors within a triangle in both | |
220 ;; UV and gemoetry relative coordinates." | |
221 [image mesh tri-index] | 208 [image mesh tri-index] |
222 (let [width (.getWidth image) | 209 (let [width (.getWidth image) |
223 height (.getHeight image) | 210 height (.getHeight image) |
224 UV-vertex-coords (triangle-UV-coord mesh width height tri-index) | 211 UV-vertex-coords (triangle-UV-coord mesh width height tri-index) |
225 bounds (convex-bounds UV-vertex-coords) | 212 bounds (convex-bounds UV-vertex-coords) |
236 (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0))) | 223 (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0))) |
237 UV-sensor-coords)] | 224 UV-sensor-coords)] |
238 {:UV UV-sensor-coords :geometry geometry-sensor-coords})) | 225 {:UV UV-sensor-coords :geometry geometry-sensor-coords})) |
239 | 226 |
240 (defn-memo locate-feelers | 227 (defn-memo locate-feelers |
241 "Search the geometry's tactile UV image for touch sensors, returning | 228 "Search the geometry's tactile UV profile for touch sensors, |
242 their positions in geometry-relative coordinates." | 229 returning their positions in geometry-relative coordinates." |
243 [#^Geometry geo] | 230 [#^Geometry geo] |
244 (let [mesh (.getMesh geo) | 231 (let [mesh (.getMesh geo) |
245 num-triangles (.getTriangleCount mesh)] | 232 num-triangles (.getTriangleCount mesh)] |
246 (if-let [image (tactile-sensor-image geo)] | 233 (if-let [image (tactile-sensor-profile geo)] |
247 (map | 234 (map |
248 (partial sensors-in-triangle image mesh) | 235 (partial sensors-in-triangle image mesh) |
249 (range num-triangles)) | 236 (range num-triangles)) |
250 (repeat (.getTriangleCount mesh) {:UV nil :geometry nil})))) | 237 (repeat (.getTriangleCount mesh) {:UV nil :geometry nil})))) |
251 | 238 |
252 (defn-memo touch-topology [#^Gemoetry geo] | 239 (defn-memo touch-topology |
240 "Return a sequence of vectors of the form [x y] describing the | |
241 \"topology\" of the tactile sensors. Points that are close together | |
242 in the touch-topology are generally close together in the simulation." | |
243 [#^Gemoetry geo] | |
253 (vec (collapse (reduce concat (map :UV (locate-feelers geo)))))) | 244 (vec (collapse (reduce concat (map :UV (locate-feelers geo)))))) |
254 | 245 |
255 (defn-memo feeler-coordinates [#^Geometry geo] | 246 (defn-memo feeler-coordinates |
247 "The location of the touch sensors in world-space coordinates." | |
248 [#^Geometry geo] | |
256 (vec (map :geometry (locate-feelers geo)))) | 249 (vec (map :geometry (locate-feelers geo)))) |
257 | 250 |
258 (defn enable-touch [#^Geometry geo] | 251 (defn touch-fn |
252 "Returns a function which returns tactile sensory data when called | |
253 inside a running simulation." | |
254 [#^Geometry geo] | |
259 (let [feeler-coords (feeler-coordinates geo) | 255 (let [feeler-coords (feeler-coordinates geo) |
260 tris (triangles geo) | 256 tris (triangles geo) |
261 limit 0.1 | 257 limit 0.1 |
262 ;;results (CollisionResults.) | 258 ;;results (CollisionResults.) |
263 ] | 259 ] |
292 (rem | 288 (rem |
293 (int | 289 (int |
294 (* 255 (/ (.getDistance | 290 (* 255 (/ (.getDistance |
295 (first touch-objects)) limit))) | 291 (first touch-objects)) limit))) |
296 256)))))))))))))) | 292 256)))))))))))))) |
297 | |
298 | 293 |
299 (defn touch [#^Node pieces] | 294 (defn touch! |
300 (filter (comp not nil?) | 295 "Endow the creature with the sense of touch. Returns a sequence of |
301 (map enable-touch | 296 functions, one for each body part with a tactile-sensor-proile, |
302 (filter #(isa? (class %) Geometry) | 297 each of which when called returns sensory data for that body part." |
303 (node-seq pieces))))) | 298 [#^Node creature] |
299 (filter | |
300 (comp not nil?) | |
301 (map touch-fn | |
302 (filter #(isa? (class %) Geometry) | |
303 (node-seq creature))))) | |
304 | 304 |
305 | 305 |
306 #+end_src | 306 #+end_src |
307 | 307 |
308 | 308 |