Mercurial > cortex
view org/integration.org @ 302:7e3938f40c52
added winston letter, corrected source listing for integration
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 17 Feb 2012 13:03:58 -0700 |
parents | 4203c2140b95 |
children | 7e7f8d6d9ec5 |
line wrap: on
line source
1 #+title:2 #+author: Robert McIntyre3 #+email: rlm@mit.edu4 #+description:5 #+keywords: simulation, jMonkeyEngine3, clojure6 #+SETUPFILE: ../../aurellem/org/setup.org7 #+INCLUDE: ../../aurellem/org/level-0.org9 * Integration11 This is the ultimate test which features all of the senses that I've12 made so far. The blender file for the creature serves as an example of13 a fully equipped creature in terms of senses. You can find it [[../assets/Models/test-creature/hand.blend][here]].16 #+begin_html17 <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 <p>Simulated Senses in a Virtual Environment</p>23 </div>24 #+end_html26 * Generating the Video28 #+name: integration29 #+begin_src clojure30 (ns cortex.test.integration31 "let's play!"32 {:author "Robert McIntyre"}33 (:use (cortex world util body sense34 hearing touch vision proprioception movement))35 (:import (com.jme3.math ColorRGBA Vector3f))36 (:import java.io.File)37 (:import com.jme3.audio.AudioNode)38 (:import com.aurellem.capture.RatchetTimer))40 (dorun (cortex.import/mega-import-jme3))41 (rlm.rlm-commands/help)43 (def hand "Models/test-creature/hand.blend")45 (def output-base (File. "/home/r/proj/cortex/render/hand"))46 #+end_src48 For this demonstration I have to manually drive the muscles of the49 hand. I do this by creating a little mini-language to describe50 simulated muscle contraction.52 #+name: integration-253 #+begin_src clojure54 (defn motor-control-program55 "Create a function which will execute the motor script"56 [muscle-positions57 script]58 (let [current-frame (atom -1)59 keyed-script (group-by first script)60 current-forces (atom {}) ]61 (fn [effectors]62 (let [indexed-effectors (vec effectors)]63 (dorun64 (for [[_ part force] (keyed-script (swap! current-frame inc))]65 (swap! current-forces (fn [m] (assoc m part force)))))66 (doall (map (fn [effector power]67 (effector (int power)))68 effectors69 (map #(@current-forces % 0) muscle-positions)))))))71 (def muscle-positions72 [:pointer-2-e73 :pointer-2-f74 :thumb-175 :thumb-176 :pointer-1-e77 :pointer-1-f78 :thumb-2-e79 :thumb-2-f80 :middle-1-e81 :middle-1-f82 :pointer-3-f83 :pointer-3-e84 :middle-2-e85 :middle-2-f86 :middle-3-f87 :middle-3-e88 :pinky-2-e89 :pinky-2-f90 :pinky-3-f91 :pinky-3-e92 :ring-3-e93 :ring-3-f94 :ring-2-f95 :ring-2-e96 :ring-1-e97 :ring-1-f98 :thumb-1-e99 :thumb-1-f100 :pinky-1-f101 :pinky-1-e])103 (def full 9001)106 ;; Coreography:108 ;; Let the hand fall palm-up110 ;; it curls its phalanges, starting with the pinky.112 ;; it lets its phalanges fall back down.114 ;; block falls down onto the hand, accompanied by a sound. The block115 ;; can be seen by the hand's eye.117 ;; hand FORCEFULLY catapults the block so that it hits the camera.120 ;; the systax here is [keyframe body-part force]121 (def move-fingers122 [[300 :pinky-3-f 50]123 [320 :pinky-2-f 80]124 [340 :pinky-1-f 100]126 [310 :ring-3-f 100]127 [330 :ring-2-f 120]128 [350 :ring-1-f 140]130 [330 :middle-3-f 120]131 [340 :middle-2-f 120]132 [360 :middle-1-f 30]134 [350 :pointer-3-f 120]135 [360 :pointer-2-f 120]136 [380 :pointer-1-f 30]138 [800 :pinky-3-f 0]139 [800 :pinky-2-f 0]140 [800 :pinky-1-f 0]142 [800 :ring-3-f 0]143 [800 :ring-2-f 0]144 [800 :ring-1-f 0]146 [800 :middle-3-f 0]147 [800 :middle-2-f 0]148 [800 :middle-1-f 0]150 [800 :pointer-3-f 0]151 [800 :pointer-2-f 0]152 [800 :pointer-1-f 0]155 [800 :pinky-3-e 50]156 [800 :pinky-2-e 80]157 [800 :pinky-1-e 100]159 [800 :ring-3-e 100]160 [800 :ring-2-e 120]161 [800 :ring-1-e 140]163 [800 :middle-3-e 120]164 [800 :middle-2-e 120]165 [800 :middle-1-e 30]167 [800 :pointer-3-e 120]168 [800 :pointer-2-e 120]169 [800 :pointer-1-e 30]171 [870 :pinky-3-e 0]172 [870 :pinky-2-e 0]173 [870 :pinky-1-e 0]175 [870 :ring-3-e 0]176 [870 :ring-2-e 0]177 [870 :ring-1-e 0]179 [870 :middle-3-e 0]180 [870 :middle-2-e 0]181 [870 :middle-1-e 0]183 [870 :pointer-3-e 0]184 [870 :pointer-2-e 0]185 [870 :pointer-1-e 0]187 [1500 :pointer-1-f full]188 [1500 :pointer-2-f full]189 [1500 :pointer-3-f full]191 [1500 :middle-1-f full]192 [1500 :middle-2-f full]193 [1500 :middle-3-f full]195 [1510 :pointer-1-f 0]196 [1510 :pointer-2-f 0]197 [1510 :pointer-3-f 0]199 [1510 :middle-1-f 0]200 [1510 :middle-2-f 0]201 [1510 :middle-3-f 0]202 ])204 (defn gen-summon-ball [debug?]205 (let [wait (atom 1100)]206 (fn [world]207 (if (= 0 (swap! wait dec))208 (let [brick209 (box 0.8 0.8 0.8 :mass 0.05210 :position (Vector3f. -0.5 0 0.5)211 :color (ColorRGBA/Red))212 bell (AudioNode. (asset-manager)213 "Sounds/pure.wav" false)]214 (.play bell)215 (if debug?216 (.addControl217 brick218 (proxy [AbstractControl] []219 (controlUpdate [tpf]220 (println-repl (.getWorldTranslation brick)))221 (controlRender [_ _]))))222 (add-element world brick))))))224 (import com.aurellem.capture.Capture)226 (defn test-everything!227 ([] (test-everything! false))228 ([record?]229 (let [me (sphere 0.5 :color ColorRGBA/Blue :physical? false)231 base (File. "/home/r/proj/cortex/render/hand")234 creature (doto (load-blender-model hand)235 (body!))237 summon-ball (gen-summon-ball false)238 ;;;;;;;;;;;; Sensors/Effectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;239 touch (touch! creature)240 touch-display (view-touch)242 vision (vision! creature)243 vision-display (view-vision)245 hearing (hearing! creature)246 hearing-display (view-hearing)248 prop (proprioception! creature)249 prop-display (view-proprioception)251 control-script (motor-control-program252 muscle-positions move-fingers)253 muscles (movement! creature)254 muscle-display (view-movement)255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;257 fix-display (gen-fix-display)]258 (world259 (nodify [creature260 (box 10 2 10 :position (Vector3f. 0 -9 0)261 :color ColorRGBA/Gray :mass 0)262 me])263 standard-debug-controls265 (fn [world]266 (.setTimer world (RatchetTimer. 60))267 (position-camera268 world (Vector3f. -0.13217318, 5.816415, -5.3089414)269 (Quaternion. 0.55685693, 0.0042774677, -0.0028673497, 0.83059245))271 (light-up-everything world)272 (enable-debug world)273 (add-camera! world274 (add-eye! creature275 (.getChild276 (.getChild creature "eyes") "eye"))277 (comp (view-image) BufferedImage!))279 (if record?280 (Capture/captureVideo281 world (File. base "main")))282 (if record?283 (Capture/captureAudio284 world (File. base "main.wav"))))285 (fn [world tpf]286 (prop-display287 (prop)288 (if record? (File. base "proprio")))289 (touch-display290 (map #(% (.getRootNode world)) touch)291 (if record? (File. base "touch")))292 (vision-display293 (map #(% world) vision)294 (if record? (File. base "vision")))295 (hearing-display296 (map #(% world) hearing)297 (if record? (File. base "hearing")))298 (muscle-display299 (control-script muscles)300 (if record? (File. base "muscle")))302 (summon-ball world)304 (.setLocalTranslation me (.getLocation (.getCamera world)))305 (fix-display world))))))306 #+end_src308 ** ImageMagick / ffmpeg310 Just a bunch of calls to imagemagick to arrange the data that311 =test-everything!= produces.313 #+name: magick-8314 #+begin_src clojure315 (ns cortex.video.magick8316 (:import java.io.File)317 (:use clojure.contrib.shell-out))319 (comment320 ;; list of touch targets321 0 middle-11322 1 middle-21323 2 middle-31324 3 pinky-11325 4 pinky-21326 5 pinky-31327 6 pointer-11328 7 pointer-21329 8 pointer-31330 9 ring-11331 10 ring-21332 11 ring-31333 12 thumb-11334 13 thumb-2.0011337 ;; list of vision targets338 0 :all339 1 :green340 2 :blue341 3 :red343 ;; list of proprio targets344 0 middle-11 -> middle-21345 1 middle-21 -> middle-31346 2 thumb-11 -> thumb-2.0011347 3 pointer-11 -> pointer-21348 4 pointer-21 -> pointer-31349 5 ring-21 -> ring-31350 6 ring-11 -> ring-21351 7 pinky-21 -> pinky-31352 8 pinky-11 -> pinky-21353 9 middle-11 -> palm1354 10 pinky-11 -> palm1355 11 palm1 -> pointer-11356 12 palm1 -> ring-11357 13 palm1 -> thumb-11360 ;; list of muscle targets361 0 :pointer-2-e362 1 :pointer-2-f363 2 :thumb-1364 3 :thumb-1365 4 :pointer-1-e366 5 :pointer-1-f367 6 :thumb-2-e368 7 :thumb-2-f369 8 :middle-1-e370 9 :middle-1-f371 10 :pointer-3-f372 11 :pointer-3-e373 12 :middle-2-e374 13 :middle-2-f375 14 :middle-3-f376 15 :middle-3-e377 16 :pinky-2-e378 17 :pinky-2-f379 18 :pinky-3-f380 19 :pinky-3-e381 20 :ring-3-e382 21 :ring-3-f383 22 :ring-2-f384 23 :ring-2-e385 24 :ring-1-e386 25 :ring-1-f387 26 :thumb-1-e388 27 :thumb-1-f389 28 :pinky-1-f390 29 :pinky-1-e391 )393 (def base (File. "/home/r/proj/cortex/render/hand"))395 (defn prepare-muscle [muscle]396 ["(" muscle "-rotate" "90" "-scale" "15x60!" ")"])398 (defn prepare-touch [touch]399 ["(" touch "-rotate" "180" ")"])401 (defn generate-top-finger [tip-flexor tip-extensor tip402 joint-2-3403 mid-flexor mid-extensor mid404 joint-1-2]405 ["("406 "-size" "113x357" "xc:transparent"407 (prepare-muscle tip-flexor) "-geometry" "+0+7" "-composite"408 (prepare-muscle tip-extensor) "-geometry" "+98+7" "-composite"409 (prepare-touch tip) "-geometry" "+18+0" "-composite"411 joint-2-3 "-geometry" "+32+79" "-composite"413 (prepare-muscle mid-flexor) "-geometry" "+19+131" "-composite"414 (prepare-muscle mid-extensor) "-geometry" "+80+131" "-composite"415 (prepare-touch mid) "-geometry" "+39+133" "-composite"417 joint-1-2 "-geometry" "+32+193" "-composite"418 ")"])420 (defn file-names [#^File dir]421 (map #(.getCanonicalPath %) (next (sort (file-seq dir)))))423 (defn file-groups [& paths]424 (apply (partial map list )425 (map (comp file-names #(File. base %))426 paths)))428 (defn pinky []429 (file-groups430 "muscle/18"431 "muscle/19"432 "touch/5"433 "proprio/7"435 "muscle/17"436 "muscle/16"437 "touch/4"438 "proprio/8"440 "muscle/28"441 "muscle/29"442 "touch/3"443 "proprio/10"))445 (defn ring []446 (file-groups447 "muscle/21"448 "muscle/20"449 "touch/11"450 "proprio/5"452 "muscle/22"453 "muscle/23"454 "touch/10"455 "proprio/6"457 "muscle/25"458 "muscle/24"459 "touch/9"460 "proprio/12"))462 (defn middle []463 (file-groups464 "muscle/14"465 "muscle/15"466 "touch/2"467 "proprio/1"469 "muscle/13"470 "muscle/12"471 "touch/1"472 "proprio/0"474 "muscle/9"475 "muscle/8"476 "touch/0"477 "proprio/9"))479 (defn pointer []480 (file-groups481 "muscle/10"482 "muscle/11"483 "touch/8"484 "proprio/4"486 "muscle/1"487 "muscle/0"488 "touch/7"489 "proprio/3"491 "muscle/5"492 "muscle/4"493 "touch/6"494 "proprio/11"))496 (defn thumb []497 (file-groups498 "muscle/7"499 "muscle/6"500 "touch/13"501 "proprio/2"503 "muscle/27"504 "muscle/26"505 "muscle/3"506 "muscle/2"507 "touch/12"508 "proprio/13"))510 (defn generate-finger511 [tip-flexor tip-extensor tip512 joint-2-3513 mid-flexor mid-extensor mid514 joint-1-2515 base-flexor base-extensor base516 joint-palm-1]517 ["("518 "-size" "113x357" "xc:transparent"519 (generate-top-finger520 tip-flexor tip-extensor tip521 joint-2-3522 mid-flexor mid-extensor mid523 joint-1-2) "-geometry" "+0+0" "-composite"524 (prepare-muscle base-flexor) "-geometry" "+19+245" "-composite"525 (prepare-muscle base-extensor) "-geometry" "+80+245" "-composite"526 (prepare-touch base) "-geometry" "+39+247" "-composite"527 joint-palm-1 "-geometry" "+32+307" "-composite"528 ")"])530 (defn generate-thumb531 [tip-flexor tip-extensor tip532 joint-1-2533 mid-flexor mid-extensor mid-flexor-2 mid-extensor-2 mid534 joint-palm-1]535 ["("536 "-size" "113x357" "xc:transparent"537 (generate-top-finger538 tip-flexor tip-extensor tip539 joint-1-2540 mid-flexor mid-extensor mid541 joint-palm-1) "-geometry" "+0+0" "-composite"542 (prepare-muscle mid-flexor-2) "-geometry" "+2+131" "-composite"543 (prepare-muscle mid-extensor-2) "-geometry" "+100+131" "-composite"544 ")"])546 (defn generate-hand547 [pinky-pieces548 ring-pieces549 middle-pieces550 pointer-pieces551 thumb-pieces]552 ["("553 "-size" "688x769" "xc:transparent"554 (apply generate-finger pinky-pieces)555 "-geometry" "+0+195" "-composite"556 (apply generate-finger ring-pieces)557 "-geometry" "+111+100" "-composite"558 (apply generate-finger middle-pieces)559 "-geometry" "+228+0" "-composite"560 "(" (apply generate-thumb thumb-pieces) "-background" "#00000000"561 "-rotate" "45" ")"562 "-geometry" "+300+420" "-composite"563 (apply generate-finger pointer-pieces)564 "-geometry" "+350+96" "-composite"565 ")"])567 (defn generate-vision568 [all green blue red]569 ["("570 "-size" "204x192" "xc:transparent"571 all "-geometry" "+0+0" "-composite"572 green "-geometry" "+113+0" "-composite"573 blue "-geometry" "+0+105" "-composite"574 red "-geometry" "+113+105" "-composite"575 ")"])577 (def test-muscle (File. base "muscle/0/0000000.png"))578 (def test-proprio (File. base "proprio/0/0000000.png"))579 (def test-tip (File. base "touch/2/0000000.png"))580 (def test-mid (File. base "touch/0/0000000.png"))581 (def test-vision (File. base "vision/0/0000000.png"))582 (def test-hearing (File. base "hearing/0/0000000.png"))583 (def test-main (File. base "main/0000000.png"))585 (def test-target (File. base "output.png"))587 (def background (File. base "background.png"))589 (use 'clojure.contrib.shell-out)591 (defn vision []592 (file-groups593 "vision/0"594 "vision/1"595 "vision/2"596 "vision/3"))598 (defn hearing []599 (file-names (File. base "hearing/0")))601 (defn main []602 (file-names (File. base "main")))604 (defn targets [dest max]605 (map606 (comp #(.getCanonicalPath %)607 #(File. (str base dest (format "%07d.png" %))))608 (range max)))611 (defn final-image [main [all red green blue] hearing612 pinky ring middle pointer thumb target]613 (println target)614 (apply615 sh616 (flatten617 ["convert"618 (.getCanonicalPath background)620 (generate-hand pinky ring middle pointer thumb)621 "-geometry" "+809+22" "-composite"623 (generate-vision all red green blue)624 "-geometry" "+974+599" "-composite"626 hearing627 "-geometry" "+784+819" "-composite"629 main630 "-geometry" "+78+202" "-composite"632 target])))634 (defn combine-files []635 (dorun636 (pmap final-image637 (main)638 (vision)639 (hearing)640 (pinky)641 (ring)642 (middle)643 (pointer)644 (thumb)645 (targets "/out/" (count (main))))))647 (defn subtitles []648 (file-names (File. base "subs")))650 (defn outs []651 (file-names (File. base "out")))654 (defn mix-subtitles []655 (let [subs (subtitles)656 targets (targets "/out-subs/" (count subs))657 overlay (.getCanonicalPath (File. base "output.png"))]658 (dorun659 (pmap660 (fn [sub target]661 (sh662 "convert"663 overlay664 sub "-geometry" "+0+0" "-composite"665 target))666 subs targets))))668 (defn out-subtitles []669 (file-names (File. base "out-subs")))672 (defn insert-subtitles []673 (let [subtitles (out-subtitles)674 outs (outs)675 targets (targets676 "/final/"677 (+ (count outs) (count subtitles)))]678 (dorun679 (pmap680 #(sh "cp" %1 %2)681 (concat subtitles outs) targets))))683 (defn generate-final []684 (combine-files)685 (mix-subtitles)686 (insert-subtitles))687 #+end_src689 #+begin_src sh :results silent690 cd /home/r/proj/cortex/render/hand692 sox --ignore-length main.wav main-delayed.wav delay 24694 mogrify -resize 755x final/*696 ffmpeg -r 60 -i final/%07d.png -i main-delayed.wav -b:a 128k \697 -b:v 9000k -c:a libvorbis -c:v libtheora hand.ogg698 #+end_src701 * Source Listing702 - [[../src/cortex/test/integration.clj][cortex.test.integration]]703 - [[../src/cortex/video/magick8.clj][cortex.video.magick8]]704 - [[../assets/Models/subtitles/hand.blend][subtitles/hand.blend]]705 #+html: <ul> <li> <a href="../org/integration.org">This org file</a> </li> </ul>706 - [[http://hg.bortreb.com ][source-repository]]709 * COMMENT purgatory710 #+begin_src clojure711 (defn bullet-trans* []712 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red713 :position (Vector3f. 5 0 0)714 :mass 90)715 obj-b (sphere 0.5 :color ColorRGBA/Blue716 :position (Vector3f. -5 0 0)717 :mass 0)718 control-a (.getControl obj-a RigidBodyControl)719 control-b (.getControl obj-b RigidBodyControl)720 move-up? (atom nil)721 move-down? (atom nil)722 move-left? (atom nil)723 move-right? (atom nil)724 roll-left? (atom nil)725 roll-right? (atom nil)726 force 100727 swivel728 (.toRotationMatrix729 (doto (Quaternion.)730 (.fromAngleAxis (/ Math/PI 2)731 Vector3f/UNIT_X)))732 x-move733 (doto (Matrix3f.)734 (.fromStartEndVectors Vector3f/UNIT_X735 (.normalize (Vector3f. 1 1 0))))737 timer (atom 0)]738 (doto739 (ConeJoint.740 control-a control-b741 (Vector3f. -8 0 0)742 (Vector3f. 2 0 0)743 ;;swivel swivel744 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY745 x-move Matrix3f/IDENTITY746 )747 (.setCollisionBetweenLinkedBodys false)748 (.setLimit (* 1 (/ Math/PI 4)) ;; twist749 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane750 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane751 (world (nodify752 [obj-a obj-b])753 (merge standard-debug-controls754 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))755 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))756 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))757 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))758 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))759 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})761 (fn [world]762 (enable-debug world)763 (set-gravity world Vector3f/ZERO)764 )766 (fn [world _]768 (if @move-up?769 (.applyForce control-a770 (Vector3f. force 0 0)771 (Vector3f. 0 0 0)))772 (if @move-down?773 (.applyForce control-a774 (Vector3f. (- force) 0 0)775 (Vector3f. 0 0 0)))776 (if @move-left?777 (.applyForce control-a778 (Vector3f. 0 force 0)779 (Vector3f. 0 0 0)))780 (if @move-right?781 (.applyForce control-a782 (Vector3f. 0 (- force) 0)783 (Vector3f. 0 0 0)))785 (if @roll-left?786 (.applyForce control-a787 (Vector3f. 0 0 force)788 (Vector3f. 0 0 0)))789 (if @roll-right?790 (.applyForce control-a791 (Vector3f. 0 0 (- force))792 (Vector3f. 0 0 0)))794 (if (zero? (rem (swap! timer inc) 100))795 (.attachChild796 (.getRootNode world)797 (sphere 0.05 :color ColorRGBA/Yellow798 :physical? false :position799 (.getWorldTranslation obj-a)))))800 )801 ))803 (defn test-joint [joint]804 (let [[origin top bottom floor] (world-setup joint)805 control (.getControl top RigidBodyControl)806 move-up? (atom false)807 move-down? (atom false)808 move-left? (atom false)809 move-right? (atom false)810 roll-left? (atom false)811 roll-right? (atom false)812 timer (atom 0)]814 (world815 (nodify [top bottom floor origin])816 (merge standard-debug-controls817 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))818 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))819 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))820 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))821 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))822 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})824 (fn [world]825 (light-up-everything world)826 (enable-debug world)827 (set-gravity world (Vector3f. 0 0 0))828 )830 (fn [world _]831 (if (zero? (rem (swap! timer inc) 100))832 (do833 ;; (println-repl @timer)834 (.attachChild (.getRootNode world)835 (sphere 0.05 :color ColorRGBA/Yellow836 :position (.getWorldTranslation top)837 :physical? false))838 (.attachChild (.getRootNode world)839 (sphere 0.05 :color ColorRGBA/LightGray840 :position (.getWorldTranslation bottom)841 :physical? false))))843 (if @move-up?844 (.applyTorque control845 (.mult (.getPhysicsRotation control)846 (Vector3f. 0 0 10))))847 (if @move-down?848 (.applyTorque control849 (.mult (.getPhysicsRotation control)850 (Vector3f. 0 0 -10))))851 (if @move-left?852 (.applyTorque control853 (.mult (.getPhysicsRotation control)854 (Vector3f. 0 10 0))))855 (if @move-right?856 (.applyTorque control857 (.mult (.getPhysicsRotation control)858 (Vector3f. 0 -10 0))))859 (if @roll-left?860 (.applyTorque control861 (.mult (.getPhysicsRotation control)862 (Vector3f. -1 0 0))))863 (if @roll-right?864 (.applyTorque control865 (.mult (.getPhysicsRotation control)866 (Vector3f. 1 0 0))))))))867 #+end_src870 * COMMENT generate source871 #+begin_src clojure :tangle ../src/cortex/test/integration.clj872 <<integration>>873 <<integration-2>>874 #+end_src876 #+begin_src clojure :tangle ../src/cortex/video/magick8.clj877 <<magick-8>>878 #+end_src