Mercurial > cortex
comparison org/body.org @ 63:7f2653ad3199
cleaning
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 29 Nov 2011 02:46:46 -0700 |
parents | 2b9d81017cb7 |
children | ab1fee4280c3 |
comparison
equal
deleted
inserted
replaced
62:2b9d81017cb7 | 63:7f2653ad3199 |
---|---|
3 #+email: rlm@mit.edu | 3 #+email: rlm@mit.edu |
4 #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3. | 4 #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3. |
5 #+SETUPFILE: ../../aurellem/org/setup.org | 5 #+SETUPFILE: ../../aurellem/org/setup.org |
6 #+INCLUDE: ../../aurellem/org/level-0.org | 6 #+INCLUDE: ../../aurellem/org/level-0.org |
7 | 7 |
8 * Body | 8 * COMMENT Body |
9 | 9 |
10 #+srcname: body-main | 10 #+srcname: body-main |
11 #+begin_src clojure | 11 #+begin_src clojure |
12 (ns cortex.body | 12 (ns cortex.body |
13 (use (cortex world util import))) | 13 (use (cortex world util import))) |
14 | 14 |
15 (use 'clojure.contrib.def) | 15 (use 'clojure.contrib.def) |
16 (cortex.import/mega-import-jme3) | 16 (cortex.import/mega-import-jme3) |
17 (rlm.rlm-commands/help) | 17 (rlm.rlm-commands/help) |
18 | 18 |
19 (defn load-blender-model | 19 (defn load-blender-model |
20 "Load a .blend file using an asset folder relative path." | |
20 [^String model] | 21 [^String model] |
21 (.loadModel | 22 (.loadModel |
22 (doto (asset-manager) | 23 (doto (asset-manager) |
23 (.registerLoader BlenderModelLoader (into-array String ["blend"]))) | 24 (.registerLoader BlenderModelLoader (into-array String ["blend"]))) |
24 model)) | 25 model)) |
25 | 26 |
26 (defn skel [node] | |
27 (doto | |
28 (.getSkeleton | |
29 (.getControl node SkeletonControl)) | |
30 ;; this is necessary to force the skeleton to have accurate world | |
31 ;; transforms before it is rendered to the screen. | |
32 (.resetAndUpdate))) | |
33 | |
34 | |
35 (defn green-x-ray [] | |
36 (doto (Material. (asset-manager) | |
37 "Common/MatDefs/Misc/Unshaded.j3md") | |
38 (.setColor "Color" ColorRGBA/Green) | |
39 (-> (.getAdditionalRenderState) | |
40 (.setDepthTest false)))) | |
41 | |
42 | |
43 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
44 | 28 |
45 ;;;;;;;;;;;; eve-style bodies ;;;;;;;; | 29 ;;;;;;;;;;;; eve-style bodies ;;;;;;;; |
46 | 30 |
47 (defn worm [segment-length num-segments interstitial-space radius] | 31 (defn worm-segments |
32 "Create multiple evenly spaced box segments. They're fabulous!" | |
33 [segment-length num-segments interstitial-space radius] | |
48 (letfn [(nth-segment | 34 (letfn [(nth-segment |
49 [n] | 35 [n] |
50 (box segment-length radius radius :mass 0.1 | 36 (box segment-length radius radius :mass 0.1 |
51 :position | 37 :position |
52 (Vector3f. | 38 (Vector3f. |
53 (* 2 n (+ interstitial-space segment-length)) 0 0) | 39 (* 2 n (+ interstitial-space segment-length)) 0 0) |
54 :name (str "worm-segment" n) | 40 :name (str "worm-segment" n) |
55 :color (ColorRGBA/randomColor)))] | 41 :color (ColorRGBA/randomColor)))] |
56 (map nth-segment (range num-segments)))) | 42 (map nth-segment (range num-segments)))) |
57 | 43 |
58 | |
59 (defn connect-at-midpoint | 44 (defn connect-at-midpoint |
45 "Connect two physics objects with a Point2Point joint constraint at | |
46 the point equidistant from both objects' centers." | |
60 [segmentA segmentB] | 47 [segmentA segmentB] |
61 (let [centerA (.getWorldTranslation segmentA) | 48 (let [centerA (.getWorldTranslation segmentA) |
62 centerB (.getWorldTranslation segmentB) | 49 centerB (.getWorldTranslation segmentB) |
63 midpoint (.mult (.add centerA centerB) (float 0.5)) | 50 midpoint (.mult (.add centerA centerB) (float 0.5)) |
64 pivotA (.subtract midpoint centerA) | 51 pivotA (.subtract midpoint centerA) |
65 pivotB (.subtract midpoint centerB) | 52 pivotB (.subtract midpoint centerB) |
53 | |
54 ;; A side-effect of creating a joint registers | |
55 ;; it with both physics objects which in turn | |
56 ;; will register the joint with the physics system | |
57 ;; when the simulation is started. | |
66 joint (Point2PointJoint. | 58 joint (Point2PointJoint. |
67 (.getControl segmentA RigidBodyControl) | 59 (.getControl segmentA RigidBodyControl) |
68 (.getControl segmentB RigidBodyControl) | 60 (.getControl segmentB RigidBodyControl) |
69 pivotA | 61 pivotA |
70 pivotB)] | 62 pivotB)] |
71 segmentB)) | 63 segmentB)) |
72 | 64 |
73 (defn point-worm [] | 65 (defn point-worm [] |
74 (let [segments (worm 0.2 5 0.1 0.1)] | 66 (let [segments (worm-segments 0.2 5 0.1 0.1)] |
75 (dorun (map (partial apply connect-at-midpoint) | 67 (dorun (map (partial apply connect-at-midpoint) |
76 (partition 2 1 segments))) | 68 (partition 2 1 segments))) |
77 (nodify "worm" segments))) | 69 (nodify "worm" segments))) |
78 | 70 |
79 (defn test-worm [] | 71 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
80 (.start | 72 ;;;;;;;;; Proprioception ;;;;;;;;;;;;; |
81 (world | 73 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
82 (doto (Node.) | 74 |
83 ;;(.attachChild (point-worm)) | 75 (declare |
84 (.attachChild (load-blender-model | 76 ;; generate an arbitray (but stable) orthogonal vector |
85 "Models/anim2/joint-worm.blend")) | 77 ;; to a given vector. |
86 | 78 some-orthogonal |
87 (.attachChild (box 10 1 10 | 79 |
88 :position (Vector3f. 0 -2 0) :mass 0 | 80 ;; determine the amount of rotation a quaternion will |
89 :color (ColorRGBA/Gray)))) | 81 ;; cause about a given axis |
90 { | 82 project-quaternion |
91 "key-space" (fire-cannon-ball) | 83 |
92 } | 84 ;; proprioception for a single joint |
93 (fn [world] | 85 joint-proprioception |
94 (enable-debug world) | 86 |
95 (light-up-everything world) | 87 ;; create a function that provides proprioceptive information |
96 ;;(.setTimer world (NanoTimer.)) | 88 ;; about an entire body. |
97 ) | 89 proprioception) |
98 no-op))) | 90 |
99 | 91 (defn some-orthogonal |
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 92 "Generate an arbitray (but stable) orthogonal vector to a given |
101 | 93 vector." |
102 | |
103 ;;;;;;;;; Mortor Control ;;;;;;;;;;;;; | |
104 | |
105 | |
106 ;; surprisingly ehough, terristerial creatures only move by using | |
107 ;; torque applied to their joints. There's not a single straight line | |
108 ;; of force in the human body at all! (a straight line of force would | |
109 ;; correspond to some sort of jet or rocket propulseion) | |
110 | |
111 (defn torque-controls [control] | |
112 (let [torques | |
113 (concat | |
114 (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) | |
115 (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) | |
116 [Vector3f/UNIT_X])] | |
117 (map (fn [torque-axis] | |
118 (fn [torque] | |
119 (.applyTorque | |
120 control | |
121 (.mult (.mult (.getPhysicsRotation control) | |
122 torque-axis) | |
123 (float | |
124 (* (.getMass control) torque)))))) | |
125 torques))) | |
126 | |
127 (defn motor-map | |
128 "Take a creature and generate a function that will enable fine | |
129 grained control over all the creature's limbs." | |
130 [#^Node creature] | |
131 (let [controls (keep #(.getControl % RigidBodyControl) | |
132 (node-seq creature)) | |
133 limb-controls (reduce concat (map torque-controls controls)) | |
134 body-control (partial map #(%1 %2) limb-controls)] | |
135 body-control)) | |
136 | |
137 (defn test-motor-map | |
138 "see how torque works." | |
139 [] | |
140 (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) | |
141 :mass 1 :color ColorRGBA/Green) | |
142 motor-map (motor-map finger)] | |
143 (world | |
144 (nodify [finger | |
145 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
146 :color ColorRGBA/Gray)]) | |
147 standard-debug-controls | |
148 (fn [world] | |
149 (set-gravity world Vector3f/ZERO) | |
150 (light-up-everything world) | |
151 (.setTimer world (NanoTimer.))) | |
152 (fn [_ _] | |
153 (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) | |
154 | |
155 (defn test-torque | |
156 "see how torque works." | |
157 [] | |
158 (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) | |
159 :mass 1 :color ColorRGBA/Green) | |
160 move-left? (atom false) | |
161 move-right? (atom false) | |
162 control (.getControl finger RigidBodyControl)] | |
163 (world | |
164 (nodify [finger | |
165 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
166 :color ColorRGBA/Gray)]) | |
167 (merge standard-debug-controls | |
168 {"key-k" (fn [_ pressed?] (reset! move-left? pressed?)) | |
169 "key-l" (fn [_ pressed?] (reset! move-right? pressed?))}) | |
170 (fn [world] | |
171 (set-gravity world Vector3f/ZERO) | |
172 (light-up-everything world) | |
173 (.setTimer world (NanoTimer.))) | |
174 (fn [_ _] | |
175 (if @move-left? | |
176 (.applyTorque control | |
177 (.mult (.getPhysicsRotation control) | |
178 (Vector3f. -3 20 0)))) | |
179 (if @move-right? | |
180 (.applyTorque control (Vector3f. 0 0 1))))))) | |
181 | |
182 (defn worm-pattern [time] | |
183 [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
184 | |
185 0 0 0 0 0 0 0 0 0 0 0 | |
186 | |
187 (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) | |
188 | |
189 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
191 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
192 | |
193 ]) | |
194 | |
195 ;;;;;;;;;;;;;;;;;; Proprioception ;;;;;;;;;;;;;;;;;;;;;;;; | |
196 | |
197 ;; this is not used as just getting the rotation would be simpler. | |
198 (defn proprioception-senses | |
199 "given a control , create a sequence of thunks that will report the | |
200 rotation of the control's object along the same axes as the motor-control map." | |
201 [control] | |
202 (let [torques | |
203 (concat | |
204 (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) | |
205 (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) | |
206 [Vector3f/UNIT_X])] | |
207 (map (fn [torque-axis] | |
208 (fn [] | |
209 (.getPhysicsRotation control))) | |
210 torques))) | |
211 | |
212 (defn orthogonal-vect | |
213 "Return a vector orthogonal to the current one" | |
214 [vector] | 94 [vector] |
215 (let [x (.getX vector) | 95 (let [x (.getX vector) |
216 y (.getY vector) | 96 y (.getY vector) |
217 z (.getZ vector)] | 97 z (.getZ vector)] |
218 (cond | 98 (cond |
219 (not= x (float 0)) (Vector3f. (- z) 0 x) | 99 (not= x (float 0)) (Vector3f. (- z) 0 x) |
220 (not= y (float 0)) (Vector3f. 0 (- z) y) | 100 (not= y (float 0)) (Vector3f. 0 (- z) y) |
221 (not= z (float 0)) (Vector3f. 0 (- z) y) | 101 (not= z (float 0)) (Vector3f. 0 (- z) y) |
222 true Vector3f/ZERO))) | 102 true Vector3f/ZERO))) |
223 | 103 |
224 ;; from | 104 (defn project-quaternion |
225 ;; http://stackoverflow.com/questions/3684269/ \\ | 105 "From http://stackoverflow.com/questions/3684269/ |
226 ;; component-of-a-quaternion-rotation-around-an-axis | 106 component-of-a-quaternion-rotation-around-an-axis. |
227 (defn rot-about-axis [#^Quaternion q #^Vector3f axis] | 107 |
108 Determine the amount of rotation a quaternion will | |
109 cause about a given axis." | |
110 [#^Quaternion q #^Vector3f axis] | |
228 (let [basis-1 (orthogonal-vect axis) | 111 (let [basis-1 (orthogonal-vect axis) |
229 basis-2 (.cross axis basis-1) | 112 basis-2 (.cross axis basis-1) |
230 rotated (.mult q basis-1) | 113 rotated (.mult q basis-1) |
231 alpha (.dot basis-1 (.project rotated basis-1)) | 114 alpha (.dot basis-1 (.project rotated basis-1)) |
232 beta (.dot basis-2 (.project rotated basis-2))] | 115 beta (.dot basis-2 (.project rotated basis-2))] |
233 (Math/atan2 beta alpha))) | 116 (Math/atan2 beta alpha))) |
234 | 117 |
235 | 118 (defn joint-proprioception |
236 (defn check-rot [a] | 119 "Relative position information for a two-part system connected by a |
237 (rot-about-axis | 120 joint. Gives the pitch, yaw, and roll of the 'B' object relative to |
238 (doto (Quaternion.) | 121 the 'A' object, as determined by the joint." |
239 (.fromAngleAxis | 122 [joint] |
240 (float a) | |
241 (Vector3f. 1 0 0))) (Vector3f. 1 0 0))) | |
242 | |
243 (defn relative-positions [joint] | |
244 (let [object-a (.getUserObject (.getBodyA joint)) | 123 (let [object-a (.getUserObject (.getBodyA joint)) |
245 object-b (.getUserObject (.getBodyB joint)) | 124 object-b (.getUserObject (.getBodyB joint)) |
246 arm-a | 125 arm-a |
247 (.normalize | 126 (.normalize |
248 (.subtract | 127 (.subtract |
271 (rot-about-axis | 150 (rot-about-axis |
272 (.mult | 151 (.mult |
273 (.getLocalRotation object-b) | 152 (.getLocalRotation object-b) |
274 (doto (Quaternion.) | 153 (doto (Quaternion.) |
275 (.fromRotationMatrix rotate-a))) | 154 (.fromRotationMatrix rotate-a))) |
276 arm-b) | 155 arm-b)] |
277 ] | |
278 | |
279 | |
280 | |
281 ;;(println-repl | |
282 ;; "arm-b is " arm-b) | |
283 ;;(println-repl | |
284 ;; "pivot-b is " (.getPivotB joint)) | |
285 ;;(println-repl | |
286 ;; (format "pitch: %1.2f\nyaw: %1.2f\nroll: %1.2f\n" | |
287 ;; pitch yaw roll)) | |
288 [pitch yaw roll])) | 156 [pitch yaw roll])) |
289 | 157 |
290 | 158 (defn proprioception |
291 | 159 "Create a function that provides proprioceptive information about an |
292 | 160 entire body." |
161 [body] | |
162 ;; extract the body's joints | |
163 (let [joints | |
164 (distinct | |
165 (reduce | |
166 concat | |
167 (map #(.getJoints %) | |
168 (keep | |
169 #(.getControl % RigidBodyControl) | |
170 (node-seq body)))))] | |
171 (fn [] | |
172 (map joint-proprioception joints)))) | |
293 | 173 |
294 | 174 |
175 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
176 ;;;;;;;;; Mortor Control ;;;;;;;;;;;;; | |
177 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
178 | |
179 | |
180 ;; surprisingly enough, terristerial creatures only move by using | |
181 ;; torque applied about their joints. There's not a single straight | |
182 ;; line of force in the human body at all! (A straight line of force | |
183 ;; would correspond to some sort of jet or rocket propulseion.) | |
184 | |
185 (defn vector-motor-control | |
186 "Create a function that accepts a sequence of Vector3f objects that | |
187 describe the torque to be applied to each part of the body." | |
188 [body] | |
189 (let [nodes (node-seq body) | |
190 controls (keep #(.getControl % RigidBodyControl) nodes)] | |
191 (fn [torques] | |
192 (map #(.applyTorque %1 %2) | |
193 controls torques)))) | |
194 | |
195 ;; note -- might want to add a lower dimensional, discrete version of | |
196 ;; this if it proves usefull from a x-modal clustering perspective. | |
197 | |
198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
199 | |
200 | |
201 | |
202 (defn worm-pattern [time] | |
203 [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
204 | |
205 0 0 0 0 0 0 0 0 0 0 0 | |
206 | |
207 (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) | |
208 | |
209 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
210 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
211 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
212 | |
213 ]) | |
214 | |
215 (defn worm-pattern [time] | |
216 (let [angle (* Math/PI (/ 4 20)) | |
217 direction (Vector3f. 0 (Math/sin angle) (Math/cos angle))] | |
218 [Vector3f/ZERO | |
219 (.mult | |
220 direction | |
221 (float (* 2 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))))) | |
222 Vector3f/ZERO | |
223 Vector3f/ZERO | |
224 Vector3f/ZERO])) | |
295 | 225 |
296 (defn test-worm-control | 226 (defn test-worm-control |
297 [] | 227 [] |
298 (let [worm (point-worm) | 228 (let [worm (point-worm) |
299 time (atom 0) | 229 time (atom 0) |
300 worm-motor-map (motor-map worm) | 230 worm-motor-map (vector-motor-control worm)] |
301 ;;body-map (proprioception worm) | |
302 debug-segments | |
303 (map | |
304 #(doto | |
305 (make-shape | |
306 (assoc base-shape | |
307 :name "debug-line" | |
308 :physical? false | |
309 :shape | |
310 (com.jme3.scene.shape.Line. | |
311 (.add (.getWorldTranslation %) | |
312 (Vector3f. -0.2 0 0 )) | |
313 (.add (.getWorldTranslation %) | |
314 (Vector3f. 0.2 0 0))))) | |
315 (.setMaterial (green-x-ray))) | |
316 (drop 1 (node-seq worm)))] | |
317 (world | 231 (world |
318 (nodify [worm | 232 (nodify [worm |
319 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | 233 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 |
320 :color ColorRGBA/Gray)]) | 234 :color ColorRGBA/Gray)]) |
321 standard-debug-controls | 235 standard-debug-controls |
322 (fn [world] | 236 (fn [world] |
323 (.attachChild (.getRootNode world) (nodify debug-segments)) | |
324 (enable-debug world) | 237 (enable-debug world) |
325 (light-up-everything world) | 238 (light-up-everything world) |
326 (com.aurellem.capture.Capture/captureVideo | 239 (comment |
327 world | 240 (com.aurellem.capture.Capture/captureVideo |
328 (file-str "/home/r/proj/cortex/tmp/moving-worm"))) | 241 world |
242 (file-str "/home/r/proj/cortex/tmp/moving-worm"))) | |
243 ) | |
329 | 244 |
330 (fn [_ _] | 245 (fn [_ _] |
331 (dorun | |
332 (map | |
333 (fn [worm-segment | |
334 debug-segment] | |
335 (.rotate | |
336 debug-segment | |
337 (Quaternion. (float 0) (float 0.05) (float 0) (float 1)))) | |
338 (drop 1 (node-seq worm)) | |
339 debug-segments)) | |
340 (swap! time inc) | 246 (swap! time inc) |
341 ;;(println-repl (with-out-str (clojure.pprint/pprint (doall (body-map))))) | 247 ;;(Thread/sleep 200) |
342 (Thread/sleep 200) | |
343 (dorun (worm-motor-map | 248 (dorun (worm-motor-map |
344 (worm-pattern @time))))))) | 249 (worm-pattern @time))))))) |
345 | |
346 | 250 |
347 | 251 |
348 | 252 |
349 | 253 |
350 (defn test-prop | 254 (defn test-prop |
426 (relative-positions joint)))))))) | 330 (relative-positions joint)))))))) |
427 | 331 |
428 #+end_src | 332 #+end_src |
429 | 333 |
430 | 334 |
431 * COMMENT failed-clojure-code | 335 * COMMENT code-limbo |
432 #+begin_src clojure | 336 #+begin_src clojure |
433 ;;(.loadModel | 337 ;;(.loadModel |
434 ;; (doto (asset-manager) | 338 ;; (doto (asset-manager) |
435 ;; (.registerLoader BlenderModelLoader (into-array String ["blend"]))) | 339 ;; (.registerLoader BlenderModelLoader (into-array String ["blend"]))) |
436 ;; "Models/person/person.blend") | 340 ;; "Models/person/person.blend") |
757 nodes))))] | 661 nodes))))] |
758 (fn [] | 662 (fn [] |
759 (reduce concat (map relative-positions (list (first joints))))))) | 663 (reduce concat (map relative-positions (list (first joints))))))) |
760 | 664 |
761 | 665 |
666 (defn skel [node] | |
667 (doto | |
668 (.getSkeleton | |
669 (.getControl node SkeletonControl)) | |
670 ;; this is necessary to force the skeleton to have accurate world | |
671 ;; transforms before it is rendered to the screen. | |
672 (.resetAndUpdate))) | |
673 | |
674 (defn green-x-ray [] | |
675 (doto (Material. (asset-manager) | |
676 "Common/MatDefs/Misc/Unshaded.j3md") | |
677 (.setColor "Color" ColorRGBA/Green) | |
678 (-> (.getAdditionalRenderState) | |
679 (.setDepthTest false)))) | |
680 | |
681 (defn test-worm [] | |
682 (.start | |
683 (world | |
684 (doto (Node.) | |
685 ;;(.attachChild (point-worm)) | |
686 (.attachChild (load-blender-model | |
687 "Models/anim2/joint-worm.blend")) | |
688 | |
689 (.attachChild (box 10 1 10 | |
690 :position (Vector3f. 0 -2 0) :mass 0 | |
691 :color (ColorRGBA/Gray)))) | |
692 { | |
693 "key-space" (fire-cannon-ball) | |
694 } | |
695 (fn [world] | |
696 (enable-debug world) | |
697 (light-up-everything world) | |
698 ;;(.setTimer world (NanoTimer.)) | |
699 ) | |
700 no-op))) | |
701 | |
702 | |
703 | |
704 ;; defunct movement stuff | |
705 (defn torque-controls [control] | |
706 (let [torques | |
707 (concat | |
708 (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) | |
709 (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) | |
710 [Vector3f/UNIT_X])] | |
711 (map (fn [torque-axis] | |
712 (fn [torque] | |
713 (.applyTorque | |
714 control | |
715 (.mult (.mult (.getPhysicsRotation control) | |
716 torque-axis) | |
717 (float | |
718 (* (.getMass control) torque)))))) | |
719 torques))) | |
720 | |
721 (defn motor-map | |
722 "Take a creature and generate a function that will enable fine | |
723 grained control over all the creature's limbs." | |
724 [#^Node creature] | |
725 (let [controls (keep #(.getControl % RigidBodyControl) | |
726 (node-seq creature)) | |
727 limb-controls (reduce concat (map torque-controls controls)) | |
728 body-control (partial map #(%1 %2) limb-controls)] | |
729 body-control)) | |
730 | |
731 (defn test-motor-map | |
732 "see how torque works." | |
733 [] | |
734 (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) | |
735 :mass 1 :color ColorRGBA/Green) | |
736 motor-map (motor-map finger)] | |
737 (world | |
738 (nodify [finger | |
739 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
740 :color ColorRGBA/Gray)]) | |
741 standard-debug-controls | |
742 (fn [world] | |
743 (set-gravity world Vector3f/ZERO) | |
744 (light-up-everything world) | |
745 (.setTimer world (NanoTimer.))) | |
746 (fn [_ _] | |
747 (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) | |
748 | |
749 | |
762 #+end_src | 750 #+end_src |
763 | 751 |
764 | 752 |
765 | 753 |
766 | 754 |