Mercurial > cortex
comparison org/skin.org @ 37:eeba17a4bd54
cleaning up the touch code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 03 Nov 2011 09:52:34 -0700 |
parents | 97703c7f020e |
children | 2ce7400825c2 |
comparison
equal
deleted
inserted
replaced
36:91090f8a4414 | 37:eeba17a4bd54 |
---|---|
1 #+title: SKIN! | 1 #+title: Simulated Sense of Touch |
2 #+author: Robert McIntyre | 2 #+author: Robert McIntyre |
3 #+email: rlm@mit.edu | 3 #+email: rlm@mit.edu |
4 #+description: Simulating touch in JMonkeyEngine | 4 #+description: Simulated touch for AI research using JMonkeyEngine and clojure. |
5 #+keywords: simulation, tactile sense, jMonkeyEngine3, clojure | |
5 #+SETUPFILE: ../../aurellem/org/setup.org | 6 #+SETUPFILE: ../../aurellem/org/setup.org |
6 #+INCLUDE: ../../aurellem/org/level-0.org | 7 #+INCLUDE: ../../aurellem/org/level-0.org |
7 #+babel: :mkdirp yes :noweb yes | 8 |
8 | 9 * Touch |
9 let's see what checkboxes look like: | 10 |
10 | 11 My creatures need to be able to feel their environments. The idea here |
11 * Skin! | 12 is to thousands of small /touch receptors/ along the geometries which |
13 make up the creature's body. The number of touch receptors in a given | |
14 area is determined by how complicated that area is, as determined by | |
15 the total number of triangles in that region. This way, complicated | |
16 regions like the hands/face, etc. get more touch receptors than | |
17 simpler areas of the body. | |
12 | 18 |
13 #+srcname: skin-main | 19 #+srcname: skin-main |
14 #+begin_src clojure | 20 #+begin_src clojure |
15 (ns body.skin) | 21 (ns cortex.touch |
16 (use 'cortex.world) | 22 "Simulate the sense of touch in jMonkeyEngine3. Enables any Geometry |
17 (use 'cortex.import) | 23 to be outfitted with touch sensors with density proportional to the |
18 (use 'clojure.contrib.def) | 24 density of triangles along the surface of the Geometry. Enables a |
19 (cortex.import/mega-import-jme3) | 25 Geometry to know what parts of itself are touching nearby objects." |
20 (rlm.rlm-commands/help) | 26 {:author "Robert McIntyre"} |
21 | 27 (:use (cortex world util)) |
22 (import java.util.logging.Level) | 28 (:import com.jme3.scene.Geometry) |
23 (import java.util.logging.Logger) | 29 (:import com.jme3.collision.CollisionResult) |
24 (use 'hello.brick-wall) | 30 (:import com.jme3.math Triangle Vector3f Ray)) |
25 | 31 |
26 (defn triangles [#^Geometry geom] | 32 (defn triangles |
33 "Return a sequence of all the Triangles which compose a given | |
34 Geometry." | |
35 [#^Geometry geom] | |
27 (let | 36 (let |
28 [mesh (.getMesh geom) | 37 [mesh (.getMesh geom) |
29 triangles (transient [])] | 38 triangles (transient [])] |
30 (dorun | 39 (dorun |
31 (for [n (range (.getTriangleCount mesh))] | 40 (for [n (range (.getTriangleCount mesh))] |
32 (let [tri (Triangle.)] | 41 (let [tri (Triangle.)] |
33 (.getTriangle mesh n tri) | 42 (.getTriangle mesh n tri) |
34 (.calculateNormal tri) | 43 ;; (.calculateNormal tri) |
35 (.calculateCenter tri) | 44 ;; (.calculateCenter tri) |
36 (conj! triangles tri)))) | 45 (conj! triangles tri)))) |
37 (persistent! triangles))) | 46 (persistent! triangles))) |
38 | 47 |
39 (defn get-ray-origin | 48 (defn get-ray-origin |
49 "Return the origin which a Ray would have to have to be in the exact | |
50 center of a particular Triangle in the Geometry in World | |
51 Coordinates." | |
40 [geom tri] | 52 [geom tri] |
41 (let [new (Vector3f.)] | 53 (let [new (Vector3f.)] |
42 (.calculateCenter tri) | 54 (.calculateCenter tri) |
43 (.localToWorld geom (.getCenter tri) new) | 55 (.localToWorld geom (.getCenter tri) new) new)) |
44 new)) | |
45 | 56 |
46 (defn get-ray-direction | 57 (defn get-ray-direction |
58 "Return the direction which a Ray would have to have to be in the | |
59 exact center of a particular Triangle in the Geometry, pointing | |
60 normal to the Triangle, in coordinates relative to the center of the | |
61 Triangle." | |
47 [geom tri] | 62 [geom tri] |
48 (let [n+c (Vector3f.)] | 63 (let [n+c (Vector3f.)] |
49 (.calculateNormal tri) | 64 (.calculateNormal tri) |
50 (.calculateCenter tri) | 65 (.calculateCenter tri) |
51 (.localToWorld geom (.add (.getCenter tri) (.getNormal tri)) n+c) | 66 (.localToWorld |
52 (.subtract n+c (get-ray-origin geom tri)) | 67 geom |
53 )) | 68 (.add (.getCenter tri) (.getNormal tri)) n+c) |
69 (.subtract n+c (get-ray-origin geom tri)))) | |
70 | |
71 (defn normal-rays | |
72 "For each Triangle which comprises the Geometry, returns a Ray which | |
73 is centered on that Triangle, points outward in a normal direction, | |
74 and extends for =limit= distance." | |
75 [limit #^Geometry geom] | |
76 (vec | |
77 (map | |
78 (fn [tri] | |
79 (doto | |
80 (Ray. (get-ray-origin geom tri) | |
81 (get-ray-direction geom tri)) | |
82 (.setLimit limit))) | |
83 (triangles geom)))) | |
84 | |
85 (defn touch-percieve | |
86 "Augment a Geometry with the sense of touch. Returns a sequence of | |
87 non-negative integers, one for each triangle, with the value of the | |
88 integer describing how many objects a ray of length =limit=, normal | |
89 to the triangle and originating from its center, encountered. The | |
90 Geometry itself is not counted among the results." | |
91 [limit geom node] | |
92 (let [normals (normal-rays limit geom)] | |
93 (doall | |
94 (for [ray normals] | |
95 (do | |
96 (let [results (CollisionResults.)] | |
97 (.collideWith node ray results) | |
98 (let [touch-objects | |
99 (set (filter #(not (= geom %)) | |
100 (map #(.getGeometry %) results)))] | |
101 (count touch-objects)))))))) | |
102 #+end_src | |
103 | |
104 | |
105 * Example | |
106 | |
107 #+begin_src clojure | |
108 | |
54 | 109 |
55 (defn ray-origin-debug | 110 (defn ray-origin-debug |
56 [ray color] | 111 [ray color] |
57 (make-shape | 112 (make-shape |
58 (assoc base-shape | 113 (assoc base-shape |
79 | 134 |
80 | 135 |
81 (defn contact-color [contacts] | 136 (defn contact-color [contacts] |
82 (case contacts | 137 (case contacts |
83 0 ColorRGBA/Gray | 138 0 ColorRGBA/Gray |
84 1 ColorRGBA/Blue | 139 1 ColorRGBA/Red |
85 2 ColorRGBA/Green | 140 2 ColorRGBA/Green |
86 3 ColorRGBA/Yellow | 141 3 ColorRGBA/Yellow |
87 4 ColorRGBA/Orange | 142 4 ColorRGBA/Orange |
88 5 ColorRGBA/Red | 143 5 ColorRGBA/Red |
89 6 ColorRGBA/Magenta | 144 6 ColorRGBA/Magenta |
90 7 ColorRGBA/Pink | 145 7 ColorRGBA/Pink |
91 8 ColorRGBA/White)) | 146 8 ColorRGBA/White)) |
92 | |
93 (defn normal-rays | |
94 "returns rays" | |
95 [limit #^Geometry geom] | |
96 (vec | |
97 (map | |
98 (fn [tri] | |
99 (doto | |
100 (Ray. (get-ray-origin geom tri) | |
101 (get-ray-direction geom tri)) | |
102 (.setLimit limit))) | |
103 (triangles geom)))) | |
104 | 147 |
105 (defn update-ray-debug [node ray contacts] | 148 (defn update-ray-debug [node ray contacts] |
106 (let [origin (.getChild node 0)] | 149 (let [origin (.getChild node 0)] |
107 (.setLocalTranslation origin (.getOrigin ray)) | 150 (.setLocalTranslation origin (.getOrigin ray)) |
108 (.setColor (.getMaterial origin) "Color" (contact-color contacts)))) | 151 (.setColor (.getMaterial origin) "Color" (contact-color contacts)))) |
128 (dorun | 171 (dorun |
129 (for [n (range (count touch-data))] | 172 (for [n (range (count touch-data))] |
130 (update-ray-debug | 173 (update-ray-debug |
131 (.getChild debug-node n) (nth rays n) (nth touch-data n)))))) | 174 (.getChild debug-node n) (nth rays n) (nth touch-data n)))))) |
132 | 175 |
133 (defn touch-percieve [limit geom node] | 176 |
134 (let [normals (normal-rays limit geom)] | |
135 | |
136 (doall | |
137 (for [ray normals] | |
138 (do | |
139 (let [results (CollisionResults.)] | |
140 (.collideWith node ray results) | |
141 (let [touch-objects (set (filter #(not (= geom %)) | |
142 (map #(.getGeometry %) results)))] | |
143 ;;(dorun (map #(println-repl (.getName %)) touch-objects)) | |
144 (count touch-objects)))))))) | |
145 | 177 |
146 (defn no-logging [] | 178 (defn no-logging [] |
147 (.setLevel (Logger/getLogger "com.jme3") Level/OFF)) | 179 (.setLevel (Logger/getLogger "com.jme3") Level/OFF)) |
148 | 180 |
149 (defn set-accuracy [world new-accuracy] | 181 (defn set-accuracy [world new-accuracy] |
225 (manage-ray-debug-node debug-node b touch-data sensitivity) | 257 (manage-ray-debug-node debug-node b touch-data sensitivity) |
226 ) | 258 ) |
227 (Thread/sleep 10) | 259 (Thread/sleep 10) |
228 )))) | 260 )))) |
229 | 261 |
262 | |
230 #+end_src | 263 #+end_src |
231 | |
232 #+results: skin-main | |
233 : #'body.skin/test-skin | |
234 | |
235 | |
236 | 264 |
237 | 265 |
238 | 266 |
239 | 267 |
240 | 268 |
241 * COMMENT code generation | 269 * COMMENT code generation |
242 #+begin_src clojure :tangle ../src/body/skin.clj :noweb yes | 270 #+begin_src clojure :tangle ../src/cortex/touch.clj :noweb yes |
243 <<skin-main>> | 271 <<skin-main>> |
244 #+end_src | 272 #+end_src |
245 | 273 |
246 | 274 |
247 | 275 |