view org/integration.org @ 535:8a5abd51cd4f

add example / discussion per Winston's request.
author Robert McIntyre <rlm@mit.edu>
date Sun, 27 Apr 2014 20:25:22 -0400
parents ee977613c244
children
line wrap: on
line source
1 #+title: Integration
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description:
5 #+keywords: simulation, jMonkeyEngine3, clojure
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
9 * Integration
11 This is the ultimate test which features all of the senses that I've
12 made so far. The blender file for the creature serves as an example of
13 a fully equipped creature in terms of senses. You can find it [[../assets/Models/test-creature/hand.blend][here]].
16 #+begin_html
17 <div class="figure">
18 <video controls="controls" width="755">
19 <source src="../video/hand.ogg" type="video/ogg"
20 preload="none" poster="../images/aurellem-1280x480.png" />
21 </video>
22 <br> <a href="http://youtu.be/ZgkWFIoHNuU"> YouTube </a>
23 <p>Simulated Senses in a Virtual Environment</p>
24 </div>
25 #+end_html
27 * Generating the Video
29 #+name: integration
30 #+begin_src clojure
31 (ns cortex.test.integration
32 "let's play!"
33 {:author "Robert McIntyre"}
34 (:use (cortex world util import body sense
35 hearing touch vision proprioception movement))
36 (:import (com.jme3.math ColorRGBA Vector3f))
37 (:import java.io.File)
38 (:import com.jme3.audio.AudioNode)
39 (:import com.aurellem.capture.RatchetTimer))
41 (dorun (cortex.import/mega-import-jme3))
42 ;;(rlm.rlm-commands/help)
44 (def hand "Models/test-creature/hand.blend")
46 (def output-base (File. "/home/r/proj/cortex/render/hand"))
47 #+end_src
49 For this demonstration I have to manually drive the muscles of the
50 hand. I do this by creating a little mini-language to describe
51 simulated muscle contraction.
53 #+name: integration-2
54 #+begin_src clojure
55 (defn motor-control-program
56 "Create a function which will execute the motor script"
57 [muscle-positions
58 script]
59 (let [current-frame (atom -1)
60 keyed-script (group-by first script)
61 current-forces (atom {}) ]
62 (fn [effectors]
63 (let [indexed-effectors (vec effectors)]
64 (dorun
65 (for [[_ part force] (keyed-script (swap! current-frame inc))]
66 (swap! current-forces (fn [m] (assoc m part force)))))
67 (doall (map (fn [effector power]
68 (effector (int power)))
69 effectors
70 (map #(@current-forces % 0) muscle-positions)))))))
72 (def muscle-positions
73 [:pointer-2-e
74 :pointer-2-f
75 :thumb-1
76 :thumb-1
77 :pointer-1-e
78 :pointer-1-f
79 :thumb-2-e
80 :thumb-2-f
81 :middle-1-e
82 :middle-1-f
83 :pointer-3-f
84 :pointer-3-e
85 :middle-2-e
86 :middle-2-f
87 :middle-3-f
88 :middle-3-e
89 :pinky-2-e
90 :pinky-2-f
91 :pinky-3-f
92 :pinky-3-e
93 :ring-3-e
94 :ring-3-f
95 :ring-2-f
96 :ring-2-e
97 :ring-1-e
98 :ring-1-f
99 :thumb-1-e
100 :thumb-1-f
101 :pinky-1-f
102 :pinky-1-e])
104 (def full 9001)
107 ;; Choreography:
109 ;; Let the hand fall palm-up
111 ;; it curls its phalanges, starting with the pinky.
113 ;; it lets its phalanges fall back down.
115 ;; block falls down onto the hand, accompanied by a sound. The block
116 ;; can be seen by the hand's eye.
118 ;; hand FORCEFULLY catapults the block so that it hits the camera.
121 ;; the syntax here is [keyframe body-part force]
122 (def move-fingers
123 [[300 :pinky-3-f 50]
124 [320 :pinky-2-f 80]
125 [340 :pinky-1-f 100]
127 [310 :ring-3-f 100]
128 [330 :ring-2-f 120]
129 [350 :ring-1-f 140]
131 [330 :middle-3-f 120]
132 [340 :middle-2-f 120]
133 [360 :middle-1-f 30]
135 [350 :pointer-3-f 120]
136 [360 :pointer-2-f 120]
137 [380 :pointer-1-f 30]
139 [800 :pinky-3-f 0]
140 [800 :pinky-2-f 0]
141 [800 :pinky-1-f 0]
143 [800 :ring-3-f 0]
144 [800 :ring-2-f 0]
145 [800 :ring-1-f 0]
147 [800 :middle-3-f 0]
148 [800 :middle-2-f 0]
149 [800 :middle-1-f 0]
151 [800 :pointer-3-f 0]
152 [800 :pointer-2-f 0]
153 [800 :pointer-1-f 0]
156 [800 :pinky-3-e 50]
157 [800 :pinky-2-e 80]
158 [800 :pinky-1-e 100]
160 [800 :ring-3-e 100]
161 [800 :ring-2-e 120]
162 [800 :ring-1-e 140]
164 [800 :middle-3-e 120]
165 [800 :middle-2-e 120]
166 [800 :middle-1-e 30]
168 [800 :pointer-3-e 120]
169 [800 :pointer-2-e 120]
170 [800 :pointer-1-e 30]
172 [870 :pinky-3-e 0]
173 [870 :pinky-2-e 0]
174 [870 :pinky-1-e 0]
176 [870 :ring-3-e 0]
177 [870 :ring-2-e 0]
178 [870 :ring-1-e 0]
180 [870 :middle-3-e 0]
181 [870 :middle-2-e 0]
182 [870 :middle-1-e 0]
184 [870 :pointer-3-e 0]
185 [870 :pointer-2-e 0]
186 [870 :pointer-1-e 0]
188 [1500 :pointer-1-f full]
189 [1500 :pointer-2-f full]
190 [1500 :pointer-3-f full]
192 [1500 :middle-1-f full]
193 [1500 :middle-2-f full]
194 [1500 :middle-3-f full]
196 [1510 :pointer-1-f 0]
197 [1510 :pointer-2-f 0]
198 [1510 :pointer-3-f 0]
200 [1510 :middle-1-f 0]
201 [1510 :middle-2-f 0]
202 [1510 :middle-3-f 0]
203 ])
205 (defn gen-summon-ball [debug?]
206 (let [wait (atom 1100)]
207 (fn [world]
208 (if (= 0 (swap! wait dec))
209 (let [brick
210 (box 0.8 0.8 0.8 :mass 0.05
211 :position (Vector3f. -0.5 0 0.5)
212 :color (ColorRGBA/Red))
213 bell (AudioNode. (asset-manager)
214 "Sounds/pure.wav" false)]
215 (.play bell)
216 (if debug?
217 (.addControl
218 brick
219 (proxy [AbstractControl] []
220 (controlUpdate [tpf]
221 (println-repl (.getWorldTranslation brick)))
222 (controlRender [_ _]))))
223 (add-element world brick))))))
225 (import com.aurellem.capture.Capture)
227 (defn test-integration
228 "Testing Everything!
230 You will see an articulated hand fall onto the table. It has all
231 senses including:
232 - Vision, 4 channels
233 - Hearing
234 - Touch
235 - Proprioceptoin
236 - Muscle Tension
238 Keys:
239 <space> : fire ball"
240 ([] (test-integration false))
241 ([record?]
242 (let [me (sphere 0.5 :color ColorRGBA/Blue :physical? false)
244 base (File. "/home/r/proj/cortex/render/hand")
247 creature (doto (load-blender-model hand)
248 (body!))
250 summon-ball (gen-summon-ball false)
251 ;;;;;;;;;;;; Sensors/Effectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252 touch (touch! creature)
253 touch-display (view-touch)
255 vision (vision! creature)
256 vision-display (view-vision)
258 hearing (hearing! creature)
259 hearing-display (view-hearing)
261 prop (proprioception! creature)
262 prop-display (view-proprioception)
264 control-script (motor-control-program
265 muscle-positions move-fingers)
266 muscles (movement! creature)
267 muscle-display (view-movement)
268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
270 fix-display (gen-fix-display)]
271 (world
272 (nodify [creature
273 (box 10 2 10 :position (Vector3f. 0 -9 0)
274 :color ColorRGBA/Gray :mass 0)
275 me])
276 standard-debug-controls
278 (fn [world]
279 (.setTimer world (RatchetTimer. 60))
280 (position-camera
281 world (Vector3f. -0.13217318, 5.816415, -5.3089414)
282 (Quaternion. 0.55685693, 0.0042774677, -0.0028673497, 0.83059245))
284 (light-up-everything world)
285 (enable-debug world)
286 (add-camera! world
287 (add-eye! creature
288 (.getChild
289 (.getChild creature "eyes") "eye"))
290 (comp (view-image) BufferedImage!))
292 (if record?
293 (Capture/captureVideo
294 world (File. base "main")))
295 (if record?
296 (Capture/captureAudio
297 world (File. base "main.wav"))))
298 (fn [world tpf]
299 (prop-display
300 (prop)
301 (if record? (File. base "proprio")))
302 (touch-display
303 (map #(% (.getRootNode world)) touch)
304 (if record? (File. base "touch")))
305 (vision-display
306 (map #(% world) vision)
307 (if record? (File. base "vision")))
308 (hearing-display
309 (map #(% world) hearing)
310 (if record? (File. base "hearing")))
311 (muscle-display
312 (control-script muscles)
313 (if record? (File. base "muscle")))
315 (summon-ball world)
317 (.setLocalTranslation me (.getLocation (.getCamera world)))
318 (fix-display world))))))
319 #+end_src
321 ** ImageMagick / ffmpeg
323 Just a bunch of calls to imagemagick to arrange the data that
324 =test-everything!= produces.
326 #+name: magick-8
327 #+begin_src clojure
328 (ns cortex.video.magick8
329 (:import java.io.File)
330 (:use clojure.java.shell))
332 (comment
333 ;; list of touch targets
334 0 middle-11
335 1 middle-21
336 2 middle-31
337 3 pinky-11
338 4 pinky-21
339 5 pinky-31
340 6 pointer-11
341 7 pointer-21
342 8 pointer-31
343 9 ring-11
344 10 ring-21
345 11 ring-31
346 12 thumb-11
347 13 thumb-2.0011
350 ;; list of vision targets
351 0 :all
352 1 :green
353 2 :blue
354 3 :red
356 ;; list of proprio targets
357 0 middle-11 -> middle-21
358 1 middle-21 -> middle-31
359 2 thumb-11 -> thumb-2.0011
360 3 pointer-11 -> pointer-21
361 4 pointer-21 -> pointer-31
362 5 ring-21 -> ring-31
363 6 ring-11 -> ring-21
364 7 pinky-21 -> pinky-31
365 8 pinky-11 -> pinky-21
366 9 middle-11 -> palm1
367 10 pinky-11 -> palm1
368 11 palm1 -> pointer-11
369 12 palm1 -> ring-11
370 13 palm1 -> thumb-11
373 ;; list of muscle targets
374 0 :pointer-2-e
375 1 :pointer-2-f
376 2 :thumb-1
377 3 :thumb-1
378 4 :pointer-1-e
379 5 :pointer-1-f
380 6 :thumb-2-e
381 7 :thumb-2-f
382 8 :middle-1-e
383 9 :middle-1-f
384 10 :pointer-3-f
385 11 :pointer-3-e
386 12 :middle-2-e
387 13 :middle-2-f
388 14 :middle-3-f
389 15 :middle-3-e
390 16 :pinky-2-e
391 17 :pinky-2-f
392 18 :pinky-3-f
393 19 :pinky-3-e
394 20 :ring-3-e
395 21 :ring-3-f
396 22 :ring-2-f
397 23 :ring-2-e
398 24 :ring-1-e
399 25 :ring-1-f
400 26 :thumb-1-e
401 27 :thumb-1-f
402 28 :pinky-1-f
403 29 :pinky-1-e
404 )
406 (def base (File. "/home/r/proj/cortex/render/hand"))
408 (defn prepare-muscle [muscle]
409 ["(" muscle "-rotate" "90" "-scale" "15x60!" ")"])
411 (defn prepare-touch [touch]
412 ["(" touch "-rotate" "180" ")"])
414 (defn generate-top-finger [tip-flexor tip-extensor tip
415 joint-2-3
416 mid-flexor mid-extensor mid
417 joint-1-2]
418 ["("
419 "-size" "113x357" "xc:transparent"
420 (prepare-muscle tip-flexor) "-geometry" "+0+7" "-composite"
421 (prepare-muscle tip-extensor) "-geometry" "+98+7" "-composite"
422 (prepare-touch tip) "-geometry" "+18+0" "-composite"
424 joint-2-3 "-geometry" "+32+79" "-composite"
426 (prepare-muscle mid-flexor) "-geometry" "+19+131" "-composite"
427 (prepare-muscle mid-extensor) "-geometry" "+80+131" "-composite"
428 (prepare-touch mid) "-geometry" "+39+133" "-composite"
430 joint-1-2 "-geometry" "+32+193" "-composite"
431 ")"])
433 (defn file-names [#^File dir]
434 (map #(.getCanonicalPath %) (next (sort (file-seq dir)))))
436 (defn file-groups [& paths]
437 (apply (partial map list )
438 (map (comp file-names #(File. base %))
439 paths)))
441 (defn pinky []
442 (file-groups
443 "muscle/18"
444 "muscle/19"
445 "touch/5"
446 "proprio/7"
448 "muscle/17"
449 "muscle/16"
450 "touch/4"
451 "proprio/8"
453 "muscle/28"
454 "muscle/29"
455 "touch/3"
456 "proprio/10"))
458 (defn ring []
459 (file-groups
460 "muscle/21"
461 "muscle/20"
462 "touch/11"
463 "proprio/5"
465 "muscle/22"
466 "muscle/23"
467 "touch/10"
468 "proprio/6"
470 "muscle/25"
471 "muscle/24"
472 "touch/9"
473 "proprio/12"))
475 (defn middle []
476 (file-groups
477 "muscle/14"
478 "muscle/15"
479 "touch/2"
480 "proprio/1"
482 "muscle/13"
483 "muscle/12"
484 "touch/1"
485 "proprio/0"
487 "muscle/9"
488 "muscle/8"
489 "touch/0"
490 "proprio/9"))
492 (defn pointer []
493 (file-groups
494 "muscle/10"
495 "muscle/11"
496 "touch/8"
497 "proprio/4"
499 "muscle/1"
500 "muscle/0"
501 "touch/7"
502 "proprio/3"
504 "muscle/5"
505 "muscle/4"
506 "touch/6"
507 "proprio/11"))
509 (defn thumb []
510 (file-groups
511 "muscle/7"
512 "muscle/6"
513 "touch/13"
514 "proprio/2"
516 "muscle/27"
517 "muscle/26"
518 "muscle/3"
519 "muscle/2"
520 "touch/12"
521 "proprio/13"))
523 (defn generate-finger
524 [tip-flexor tip-extensor tip
525 joint-2-3
526 mid-flexor mid-extensor mid
527 joint-1-2
528 base-flexor base-extensor base
529 joint-palm-1]
530 ["("
531 "-size" "113x357" "xc:transparent"
532 (generate-top-finger
533 tip-flexor tip-extensor tip
534 joint-2-3
535 mid-flexor mid-extensor mid
536 joint-1-2) "-geometry" "+0+0" "-composite"
537 (prepare-muscle base-flexor) "-geometry" "+19+245" "-composite"
538 (prepare-muscle base-extensor) "-geometry" "+80+245" "-composite"
539 (prepare-touch base) "-geometry" "+39+247" "-composite"
540 joint-palm-1 "-geometry" "+32+307" "-composite"
541 ")"])
543 (defn generate-thumb
544 [tip-flexor tip-extensor tip
545 joint-1-2
546 mid-flexor mid-extensor mid-flexor-2 mid-extensor-2 mid
547 joint-palm-1]
548 ["("
549 "-size" "113x357" "xc:transparent"
550 (generate-top-finger
551 tip-flexor tip-extensor tip
552 joint-1-2
553 mid-flexor mid-extensor mid
554 joint-palm-1) "-geometry" "+0+0" "-composite"
555 (prepare-muscle mid-flexor-2) "-geometry" "+2+131" "-composite"
556 (prepare-muscle mid-extensor-2) "-geometry" "+100+131" "-composite"
557 ")"])
559 (defn generate-hand
560 [pinky-pieces
561 ring-pieces
562 middle-pieces
563 pointer-pieces
564 thumb-pieces]
565 ["("
566 "-size" "688x769" "xc:transparent"
567 (apply generate-finger pinky-pieces)
568 "-geometry" "+0+195" "-composite"
569 (apply generate-finger ring-pieces)
570 "-geometry" "+111+100" "-composite"
571 (apply generate-finger middle-pieces)
572 "-geometry" "+228+0" "-composite"
573 "(" (apply generate-thumb thumb-pieces) "-background" "#00000000"
574 "-rotate" "45" ")"
575 "-geometry" "+300+420" "-composite"
576 (apply generate-finger pointer-pieces)
577 "-geometry" "+350+96" "-composite"
578 ")"])
580 (defn generate-vision
581 [all green blue red]
582 ["("
583 "-size" "204x192" "xc:transparent"
584 all "-geometry" "+0+0" "-composite"
585 green "-geometry" "+113+0" "-composite"
586 blue "-geometry" "+0+105" "-composite"
587 red "-geometry" "+113+105" "-composite"
588 ")"])
590 (def test-muscle (File. base "muscle/0/0000000.png"))
591 (def test-proprio (File. base "proprio/0/0000000.png"))
592 (def test-tip (File. base "touch/2/0000000.png"))
593 (def test-mid (File. base "touch/0/0000000.png"))
594 (def test-vision (File. base "vision/0/0000000.png"))
595 (def test-hearing (File. base "hearing/0/0000000.png"))
596 (def test-main (File. base "main/0000000.png"))
598 (def test-target (File. base "output.png"))
600 (def background (File. base "background.png"))
602 (use 'clojure.java.shell)
604 (defn vision []
605 (file-groups
606 "vision/0"
607 "vision/1"
608 "vision/2"
609 "vision/3"))
611 (defn hearing []
612 (file-names (File. base "hearing/0")))
614 (defn main []
615 (file-names (File. base "main")))
617 (defn targets [dest max]
618 (map
619 (comp #(.getCanonicalPath %)
620 #(File. (str base dest (format "%07d.png" %))))
621 (range max)))
624 (defn final-image [main [all red green blue] hearing
625 pinky ring middle pointer thumb target]
626 (println target)
627 (apply
628 sh
629 (flatten
630 ["convert"
631 (.getCanonicalPath background)
633 (generate-hand pinky ring middle pointer thumb)
634 "-geometry" "+809+22" "-composite"
636 (generate-vision all red green blue)
637 "-geometry" "+974+599" "-composite"
639 hearing
640 "-geometry" "+784+819" "-composite"
642 main
643 "-geometry" "+78+202" "-composite"
645 target])))
647 (defn combine-files []
648 (dorun
649 (pmap final-image
650 (main)
651 (vision)
652 (hearing)
653 (pinky)
654 (ring)
655 (middle)
656 (pointer)
657 (thumb)
658 (targets "/out/" (count (main))))))
660 (defn subtitles []
661 (file-names (File. base "subs")))
663 (defn outs []
664 (file-names (File. base "out")))
667 (defn mix-subtitles []
668 (let [subs (subtitles)
669 targets (targets "/out-subs/" (count subs))
670 overlay (.getCanonicalPath (File. base "output.png"))]
671 (dorun
672 (pmap
673 (fn [sub target]
674 (sh
675 "convert"
676 overlay
677 sub "-geometry" "+0+0" "-composite"
678 target))
679 subs targets))))
681 (defn out-subtitles []
682 (file-names (File. base "out-subs")))
685 (defn insert-subtitles []
686 (let [subtitles (out-subtitles)
687 outs (outs)
688 targets (targets
689 "/final/"
690 (+ (count outs) (count subtitles)))]
691 (dorun
692 (pmap
693 #(sh "cp" %1 %2)
694 (concat subtitles outs) targets))))
696 (defn generate-final []
697 (combine-files)
698 (mix-subtitles)
699 (insert-subtitles))
700 #+end_src
702 #+begin_src sh :results silent
703 cd /home/r/proj/cortex/render/hand
705 sox --ignore-length main.wav main-delayed.wav delay 24
707 mogrify -resize 755x final/*
708 #+end_src
710 #+begin_src sh :results silent
711 cd /home/r/proj/cortex/render/hand
713 ffmpeg -r 60 -i final/%07d.png -i main-delayed.wav -b:a 128k \
714 -b:v 9000k -c:a libvorbis -c:v libtheora hand.ogg
715 #+end_src
717 * Source Listing
718 - [[../src/cortex/test/integration.clj][cortex.test.integration]]
719 - [[../src/cortex/video/magick8.clj][cortex.video.magick8]]
720 - [[../assets/Models/subtitles/hand.blend][subtitles/hand.blend]]
721 #+html: <ul> <li> <a href="../org/integration.org">This org file</a> </li> </ul>
722 - [[http://hg.bortreb.com ][source-repository]]
725 * COMMENT purgatory
726 #+begin_src clojure
727 (defn bullet-trans* []
728 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
729 :position (Vector3f. 5 0 0)
730 :mass 90)
731 obj-b (sphere 0.5 :color ColorRGBA/Blue
732 :position (Vector3f. -5 0 0)
733 :mass 0)
734 control-a (.getControl obj-a RigidBodyControl)
735 control-b (.getControl obj-b RigidBodyControl)
736 move-up? (atom nil)
737 move-down? (atom nil)
738 move-left? (atom nil)
739 move-right? (atom nil)
740 roll-left? (atom nil)
741 roll-right? (atom nil)
742 force 100
743 swivel
744 (.toRotationMatrix
745 (doto (Quaternion.)
746 (.fromAngleAxis (/ Math/PI 2)
747 Vector3f/UNIT_X)))
748 x-move
749 (doto (Matrix3f.)
750 (.fromStartEndVectors Vector3f/UNIT_X
751 (.normalize (Vector3f. 1 1 0))))
753 timer (atom 0)]
754 (doto
755 (ConeJoint.
756 control-a control-b
757 (Vector3f. -8 0 0)
758 (Vector3f. 2 0 0)
759 ;;swivel swivel
760 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
761 x-move Matrix3f/IDENTITY
762 )
763 (.setCollisionBetweenLinkedBodys false)
764 (.setLimit (* 1 (/ Math/PI 4)) ;; twist
765 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
766 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
767 (world (nodify
768 [obj-a obj-b])
769 (merge standard-debug-controls
770 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
771 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
772 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
773 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
774 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
775 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
777 (fn [world]
778 (enable-debug world)
779 (set-gravity world Vector3f/ZERO)
780 )
782 (fn [world _]
784 (if @move-up?
785 (.applyForce control-a
786 (Vector3f. force 0 0)
787 (Vector3f. 0 0 0)))
788 (if @move-down?
789 (.applyForce control-a
790 (Vector3f. (- force) 0 0)
791 (Vector3f. 0 0 0)))
792 (if @move-left?
793 (.applyForce control-a
794 (Vector3f. 0 force 0)
795 (Vector3f. 0 0 0)))
796 (if @move-right?
797 (.applyForce control-a
798 (Vector3f. 0 (- force) 0)
799 (Vector3f. 0 0 0)))
801 (if @roll-left?
802 (.applyForce control-a
803 (Vector3f. 0 0 force)
804 (Vector3f. 0 0 0)))
805 (if @roll-right?
806 (.applyForce control-a
807 (Vector3f. 0 0 (- force))
808 (Vector3f. 0 0 0)))
810 (if (zero? (rem (swap! timer inc) 100))
811 (.attachChild
812 (.getRootNode world)
813 (sphere 0.05 :color ColorRGBA/Yellow
814 :physical? false :position
815 (.getWorldTranslation obj-a)))))
816 )
817 ))
819 (defn test-joint [joint]
820 (let [[origin top bottom floor] (world-setup joint)
821 control (.getControl top RigidBodyControl)
822 move-up? (atom false)
823 move-down? (atom false)
824 move-left? (atom false)
825 move-right? (atom false)
826 roll-left? (atom false)
827 roll-right? (atom false)
828 timer (atom 0)]
830 (world
831 (nodify [top bottom floor origin])
832 (merge standard-debug-controls
833 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
834 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
835 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
836 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
837 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
838 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
840 (fn [world]
841 (light-up-everything world)
842 (enable-debug world)
843 (set-gravity world (Vector3f. 0 0 0))
844 )
846 (fn [world _]
847 (if (zero? (rem (swap! timer inc) 100))
848 (do
849 ;; (println-repl @timer)
850 (.attachChild (.getRootNode world)
851 (sphere 0.05 :color ColorRGBA/Yellow
852 :position (.getWorldTranslation top)
853 :physical? false))
854 (.attachChild (.getRootNode world)
855 (sphere 0.05 :color ColorRGBA/LightGray
856 :position (.getWorldTranslation bottom)
857 :physical? false))))
859 (if @move-up?
860 (.applyTorque control
861 (.mult (.getPhysicsRotation control)
862 (Vector3f. 0 0 10))))
863 (if @move-down?
864 (.applyTorque control
865 (.mult (.getPhysicsRotation control)
866 (Vector3f. 0 0 -10))))
867 (if @move-left?
868 (.applyTorque control
869 (.mult (.getPhysicsRotation control)
870 (Vector3f. 0 10 0))))
871 (if @move-right?
872 (.applyTorque control
873 (.mult (.getPhysicsRotation control)
874 (Vector3f. 0 -10 0))))
875 (if @roll-left?
876 (.applyTorque control
877 (.mult (.getPhysicsRotation control)
878 (Vector3f. -1 0 0))))
879 (if @roll-right?
880 (.applyTorque control
881 (.mult (.getPhysicsRotation control)
882 (Vector3f. 1 0 0))))))))
883 #+end_src
887 * COMMENT generate source
888 #+begin_src clojure :tangle ../src/cortex/test/integration.clj
889 <<integration>>
890 <<integration-2>>
891 #+end_src
893 #+begin_src clojure :tangle ../src/cortex/video/magick8.clj
894 <<magick-8>>
895 #+end_src