Mercurial > cortex
view org/integration.org @ 380:2d0afb231081
spellcheck
author | rlm |
---|---|
date | Wed, 10 Apr 2013 16:49:05 -0400 |
parents | 2c7fbcbd5ebb |
children | 4c37d39a3cf6 |
line wrap: on
line source
1 #+title: Integration2 #+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 <br> <a href="http://youtu.be/ZgkWFIoHNuU"> YouTube </a>23 <p>Simulated Senses in a Virtual Environment</p>24 </div>25 #+end_html27 * Generating the Video29 #+name: integration30 #+begin_src clojure31 (ns cortex.test.integration32 "let's play!"33 {:author "Robert McIntyre"}34 (:use (cortex world util import body sense35 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_src49 For this demonstration I have to manually drive the muscles of the50 hand. I do this by creating a little mini-language to describe52 simulated muscle contraction.53 #+name: integration-254 #+begin_src clojure55 (defn motor-control-program56 "Create a function which will execute the motor script"57 [muscle-positions58 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 (dorun65 (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 effectors70 (map #(@current-forces % 0) muscle-positions)))))))72 (def muscle-positions73 [:pointer-2-e74 :pointer-2-f75 :thumb-176 :thumb-177 :pointer-1-e78 :pointer-1-f79 :thumb-2-e80 :thumb-2-f81 :middle-1-e82 :middle-1-f83 :pointer-3-f84 :pointer-3-e85 :middle-2-e86 :middle-2-f87 :middle-3-f88 :middle-3-e89 :pinky-2-e90 :pinky-2-f91 :pinky-3-f92 :pinky-3-e93 :ring-3-e94 :ring-3-f95 :ring-2-f96 :ring-2-e97 :ring-1-e98 :ring-1-f99 :thumb-1-e100 :thumb-1-f101 :pinky-1-f102 :pinky-1-e])104 (def full 9001)107 ;; Choreography:109 ;; Let the hand fall palm-up111 ;; 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 block116 ;; 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-fingers123 [[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 [brick210 (box 0.8 0.8 0.8 :mass 0.05211 :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 (.addControl218 brick219 (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-everything!228 ([] (test-everything! false))229 ([record?]230 (let [me (sphere 0.5 :color ColorRGBA/Blue :physical? false)232 base (File. "/home/r/proj/cortex/render/hand")235 creature (doto (load-blender-model hand)236 (body!))238 summon-ball (gen-summon-ball false)239 ;;;;;;;;;;;; Sensors/Effectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;240 touch (touch! creature)241 touch-display (view-touch)243 vision (vision! creature)244 vision-display (view-vision)246 hearing (hearing! creature)247 hearing-display (view-hearing)249 prop (proprioception! creature)250 prop-display (view-proprioception)252 control-script (motor-control-program253 muscle-positions move-fingers)254 muscles (movement! creature)255 muscle-display (view-movement)256 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;258 fix-display (gen-fix-display)]259 (world260 (nodify [creature261 (box 10 2 10 :position (Vector3f. 0 -9 0)262 :color ColorRGBA/Gray :mass 0)263 me])264 standard-debug-controls266 (fn [world]267 (.setTimer world (RatchetTimer. 60))268 (position-camera269 world (Vector3f. -0.13217318, 5.816415, -5.3089414)270 (Quaternion. 0.55685693, 0.0042774677, -0.0028673497, 0.83059245))272 (light-up-everything world)273 (enable-debug world)274 (add-camera! world275 (add-eye! creature276 (.getChild277 (.getChild creature "eyes") "eye"))278 (comp (view-image) BufferedImage!))280 (if record?281 (Capture/captureVideo282 world (File. base "main")))283 (if record?284 (Capture/captureAudio285 world (File. base "main.wav"))))286 (fn [world tpf]287 (prop-display288 (prop)289 (if record? (File. base "proprio")))290 (touch-display291 (map #(% (.getRootNode world)) touch)292 (if record? (File. base "touch")))293 (vision-display294 (map #(% world) vision)295 (if record? (File. base "vision")))296 (hearing-display297 (map #(% world) hearing)298 (if record? (File. base "hearing")))299 (muscle-display300 (control-script muscles)301 (if record? (File. base "muscle")))303 (summon-ball world)305 (.setLocalTranslation me (.getLocation (.getCamera world)))306 (fix-display world))))))307 #+end_src309 ** ImageMagick / ffmpeg311 Just a bunch of calls to imagemagick to arrange the data that312 =test-everything!= produces.314 #+name: magick-8315 #+begin_src clojure316 (ns cortex.video.magick8317 (:import java.io.File)318 (:use clojure.java.shell))320 (comment321 ;; list of touch targets322 0 middle-11323 1 middle-21324 2 middle-31325 3 pinky-11326 4 pinky-21327 5 pinky-31328 6 pointer-11329 7 pointer-21330 8 pointer-31331 9 ring-11332 10 ring-21333 11 ring-31334 12 thumb-11335 13 thumb-2.0011338 ;; list of vision targets339 0 :all340 1 :green341 2 :blue342 3 :red344 ;; list of proprio targets345 0 middle-11 -> middle-21346 1 middle-21 -> middle-31347 2 thumb-11 -> thumb-2.0011348 3 pointer-11 -> pointer-21349 4 pointer-21 -> pointer-31350 5 ring-21 -> ring-31351 6 ring-11 -> ring-21352 7 pinky-21 -> pinky-31353 8 pinky-11 -> pinky-21354 9 middle-11 -> palm1355 10 pinky-11 -> palm1356 11 palm1 -> pointer-11357 12 palm1 -> ring-11358 13 palm1 -> thumb-11361 ;; list of muscle targets362 0 :pointer-2-e363 1 :pointer-2-f364 2 :thumb-1365 3 :thumb-1366 4 :pointer-1-e367 5 :pointer-1-f368 6 :thumb-2-e369 7 :thumb-2-f370 8 :middle-1-e371 9 :middle-1-f372 10 :pointer-3-f373 11 :pointer-3-e374 12 :middle-2-e375 13 :middle-2-f376 14 :middle-3-f377 15 :middle-3-e378 16 :pinky-2-e379 17 :pinky-2-f380 18 :pinky-3-f381 19 :pinky-3-e382 20 :ring-3-e383 21 :ring-3-f384 22 :ring-2-f385 23 :ring-2-e386 24 :ring-1-e387 25 :ring-1-f388 26 :thumb-1-e389 27 :thumb-1-f390 28 :pinky-1-f391 29 :pinky-1-e392 )394 (def base (File. "/home/r/proj/cortex/render/hand"))396 (defn prepare-muscle [muscle]397 ["(" muscle "-rotate" "90" "-scale" "15x60!" ")"])399 (defn prepare-touch [touch]400 ["(" touch "-rotate" "180" ")"])402 (defn generate-top-finger [tip-flexor tip-extensor tip403 joint-2-3404 mid-flexor mid-extensor mid405 joint-1-2]406 ["("407 "-size" "113x357" "xc:transparent"408 (prepare-muscle tip-flexor) "-geometry" "+0+7" "-composite"409 (prepare-muscle tip-extensor) "-geometry" "+98+7" "-composite"410 (prepare-touch tip) "-geometry" "+18+0" "-composite"412 joint-2-3 "-geometry" "+32+79" "-composite"414 (prepare-muscle mid-flexor) "-geometry" "+19+131" "-composite"415 (prepare-muscle mid-extensor) "-geometry" "+80+131" "-composite"416 (prepare-touch mid) "-geometry" "+39+133" "-composite"418 joint-1-2 "-geometry" "+32+193" "-composite"419 ")"])421 (defn file-names [#^File dir]422 (map #(.getCanonicalPath %) (next (sort (file-seq dir)))))424 (defn file-groups [& paths]425 (apply (partial map list )426 (map (comp file-names #(File. base %))427 paths)))429 (defn pinky []430 (file-groups431 "muscle/18"432 "muscle/19"433 "touch/5"434 "proprio/7"436 "muscle/17"437 "muscle/16"438 "touch/4"439 "proprio/8"441 "muscle/28"442 "muscle/29"443 "touch/3"444 "proprio/10"))446 (defn ring []447 (file-groups448 "muscle/21"449 "muscle/20"450 "touch/11"451 "proprio/5"453 "muscle/22"454 "muscle/23"455 "touch/10"456 "proprio/6"458 "muscle/25"459 "muscle/24"460 "touch/9"461 "proprio/12"))463 (defn middle []464 (file-groups465 "muscle/14"466 "muscle/15"467 "touch/2"468 "proprio/1"470 "muscle/13"471 "muscle/12"472 "touch/1"473 "proprio/0"475 "muscle/9"476 "muscle/8"477 "touch/0"478 "proprio/9"))480 (defn pointer []481 (file-groups482 "muscle/10"483 "muscle/11"484 "touch/8"485 "proprio/4"487 "muscle/1"488 "muscle/0"489 "touch/7"490 "proprio/3"492 "muscle/5"493 "muscle/4"494 "touch/6"495 "proprio/11"))497 (defn thumb []498 (file-groups499 "muscle/7"500 "muscle/6"501 "touch/13"502 "proprio/2"504 "muscle/27"505 "muscle/26"506 "muscle/3"507 "muscle/2"508 "touch/12"509 "proprio/13"))511 (defn generate-finger512 [tip-flexor tip-extensor tip513 joint-2-3514 mid-flexor mid-extensor mid515 joint-1-2516 base-flexor base-extensor base517 joint-palm-1]518 ["("519 "-size" "113x357" "xc:transparent"520 (generate-top-finger521 tip-flexor tip-extensor tip522 joint-2-3523 mid-flexor mid-extensor mid524 joint-1-2) "-geometry" "+0+0" "-composite"525 (prepare-muscle base-flexor) "-geometry" "+19+245" "-composite"526 (prepare-muscle base-extensor) "-geometry" "+80+245" "-composite"527 (prepare-touch base) "-geometry" "+39+247" "-composite"528 joint-palm-1 "-geometry" "+32+307" "-composite"529 ")"])531 (defn generate-thumb532 [tip-flexor tip-extensor tip533 joint-1-2534 mid-flexor mid-extensor mid-flexor-2 mid-extensor-2 mid535 joint-palm-1]536 ["("537 "-size" "113x357" "xc:transparent"538 (generate-top-finger539 tip-flexor tip-extensor tip540 joint-1-2541 mid-flexor mid-extensor mid542 joint-palm-1) "-geometry" "+0+0" "-composite"543 (prepare-muscle mid-flexor-2) "-geometry" "+2+131" "-composite"544 (prepare-muscle mid-extensor-2) "-geometry" "+100+131" "-composite"545 ")"])547 (defn generate-hand548 [pinky-pieces549 ring-pieces550 middle-pieces551 pointer-pieces552 thumb-pieces]553 ["("554 "-size" "688x769" "xc:transparent"555 (apply generate-finger pinky-pieces)556 "-geometry" "+0+195" "-composite"557 (apply generate-finger ring-pieces)558 "-geometry" "+111+100" "-composite"559 (apply generate-finger middle-pieces)560 "-geometry" "+228+0" "-composite"561 "(" (apply generate-thumb thumb-pieces) "-background" "#00000000"562 "-rotate" "45" ")"563 "-geometry" "+300+420" "-composite"564 (apply generate-finger pointer-pieces)565 "-geometry" "+350+96" "-composite"566 ")"])568 (defn generate-vision569 [all green blue red]570 ["("571 "-size" "204x192" "xc:transparent"572 all "-geometry" "+0+0" "-composite"573 green "-geometry" "+113+0" "-composite"574 blue "-geometry" "+0+105" "-composite"575 red "-geometry" "+113+105" "-composite"576 ")"])578 (def test-muscle (File. base "muscle/0/0000000.png"))579 (def test-proprio (File. base "proprio/0/0000000.png"))580 (def test-tip (File. base "touch/2/0000000.png"))581 (def test-mid (File. base "touch/0/0000000.png"))582 (def test-vision (File. base "vision/0/0000000.png"))583 (def test-hearing (File. base "hearing/0/0000000.png"))584 (def test-main (File. base "main/0000000.png"))586 (def test-target (File. base "output.png"))588 (def background (File. base "background.png"))590 (use 'clojure.java.shell)592 (defn vision []593 (file-groups594 "vision/0"595 "vision/1"596 "vision/2"597 "vision/3"))599 (defn hearing []600 (file-names (File. base "hearing/0")))602 (defn main []603 (file-names (File. base "main")))605 (defn targets [dest max]606 (map607 (comp #(.getCanonicalPath %)608 #(File. (str base dest (format "%07d.png" %))))609 (range max)))612 (defn final-image [main [all red green blue] hearing613 pinky ring middle pointer thumb target]614 (println target)615 (apply616 sh617 (flatten618 ["convert"619 (.getCanonicalPath background)621 (generate-hand pinky ring middle pointer thumb)622 "-geometry" "+809+22" "-composite"624 (generate-vision all red green blue)625 "-geometry" "+974+599" "-composite"627 hearing628 "-geometry" "+784+819" "-composite"630 main631 "-geometry" "+78+202" "-composite"633 target])))635 (defn combine-files []636 (dorun637 (pmap final-image638 (main)639 (vision)640 (hearing)641 (pinky)642 (ring)643 (middle)644 (pointer)645 (thumb)646 (targets "/out/" (count (main))))))648 (defn subtitles []649 (file-names (File. base "subs")))651 (defn outs []652 (file-names (File. base "out")))655 (defn mix-subtitles []656 (let [subs (subtitles)657 targets (targets "/out-subs/" (count subs))658 overlay (.getCanonicalPath (File. base "output.png"))]659 (dorun660 (pmap661 (fn [sub target]662 (sh663 "convert"664 overlay665 sub "-geometry" "+0+0" "-composite"666 target))667 subs targets))))669 (defn out-subtitles []670 (file-names (File. base "out-subs")))673 (defn insert-subtitles []674 (let [subtitles (out-subtitles)675 outs (outs)676 targets (targets677 "/final/"678 (+ (count outs) (count subtitles)))]679 (dorun680 (pmap681 #(sh "cp" %1 %2)682 (concat subtitles outs) targets))))684 (defn generate-final []685 (combine-files)686 (mix-subtitles)687 (insert-subtitles))688 #+end_src690 #+begin_src sh :results silent691 cd /home/r/proj/cortex/render/hand693 sox --ignore-length main.wav main-delayed.wav delay 24695 mogrify -resize 755x final/*696 #+end_src698 #+begin_src sh :results silent699 cd /home/r/proj/cortex/render/hand701 ffmpeg -r 60 -i final/%07d.png -i main-delayed.wav -b:a 128k \702 -b:v 9000k -c:a libvorbis -c:v libtheora hand.ogg703 #+end_src705 * Source Listing706 - [[../src/cortex/test/integration.clj][cortex.test.integration]]707 - [[../src/cortex/video/magick8.clj][cortex.video.magick8]]708 - [[../assets/Models/subtitles/hand.blend][subtitles/hand.blend]]709 #+html: <ul> <li> <a href="../org/integration.org">This org file</a> </li> </ul>710 - [[http://hg.bortreb.com ][source-repository]]713 * COMMENT purgatory714 #+begin_src clojure715 (defn bullet-trans* []716 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red717 :position (Vector3f. 5 0 0)718 :mass 90)719 obj-b (sphere 0.5 :color ColorRGBA/Blue720 :position (Vector3f. -5 0 0)721 :mass 0)722 control-a (.getControl obj-a RigidBodyControl)723 control-b (.getControl obj-b RigidBodyControl)724 move-up? (atom nil)725 move-down? (atom nil)726 move-left? (atom nil)727 move-right? (atom nil)728 roll-left? (atom nil)729 roll-right? (atom nil)730 force 100731 swivel732 (.toRotationMatrix733 (doto (Quaternion.)734 (.fromAngleAxis (/ Math/PI 2)735 Vector3f/UNIT_X)))736 x-move737 (doto (Matrix3f.)738 (.fromStartEndVectors Vector3f/UNIT_X739 (.normalize (Vector3f. 1 1 0))))741 timer (atom 0)]742 (doto743 (ConeJoint.744 control-a control-b745 (Vector3f. -8 0 0)746 (Vector3f. 2 0 0)747 ;;swivel swivel748 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY749 x-move Matrix3f/IDENTITY750 )751 (.setCollisionBetweenLinkedBodys false)752 (.setLimit (* 1 (/ Math/PI 4)) ;; twist753 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane754 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane755 (world (nodify756 [obj-a obj-b])757 (merge standard-debug-controls758 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))759 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))760 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))761 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))762 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))763 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})765 (fn [world]766 (enable-debug world)767 (set-gravity world Vector3f/ZERO)768 )770 (fn [world _]772 (if @move-up?773 (.applyForce control-a774 (Vector3f. force 0 0)775 (Vector3f. 0 0 0)))776 (if @move-down?777 (.applyForce control-a778 (Vector3f. (- force) 0 0)779 (Vector3f. 0 0 0)))780 (if @move-left?781 (.applyForce control-a782 (Vector3f. 0 force 0)783 (Vector3f. 0 0 0)))784 (if @move-right?785 (.applyForce control-a786 (Vector3f. 0 (- force) 0)787 (Vector3f. 0 0 0)))789 (if @roll-left?790 (.applyForce control-a791 (Vector3f. 0 0 force)792 (Vector3f. 0 0 0)))793 (if @roll-right?794 (.applyForce control-a795 (Vector3f. 0 0 (- force))796 (Vector3f. 0 0 0)))798 (if (zero? (rem (swap! timer inc) 100))799 (.attachChild800 (.getRootNode world)801 (sphere 0.05 :color ColorRGBA/Yellow802 :physical? false :position803 (.getWorldTranslation obj-a)))))804 )805 ))807 (defn test-joint [joint]808 (let [[origin top bottom floor] (world-setup joint)809 control (.getControl top RigidBodyControl)810 move-up? (atom false)811 move-down? (atom false)812 move-left? (atom false)813 move-right? (atom false)814 roll-left? (atom false)815 roll-right? (atom false)816 timer (atom 0)]818 (world819 (nodify [top bottom floor origin])820 (merge standard-debug-controls821 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))822 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))823 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))824 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))825 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))826 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})828 (fn [world]829 (light-up-everything world)830 (enable-debug world)831 (set-gravity world (Vector3f. 0 0 0))832 )834 (fn [world _]835 (if (zero? (rem (swap! timer inc) 100))836 (do837 ;; (println-repl @timer)838 (.attachChild (.getRootNode world)839 (sphere 0.05 :color ColorRGBA/Yellow840 :position (.getWorldTranslation top)841 :physical? false))842 (.attachChild (.getRootNode world)843 (sphere 0.05 :color ColorRGBA/LightGray844 :position (.getWorldTranslation bottom)845 :physical? false))))847 (if @move-up?848 (.applyTorque control849 (.mult (.getPhysicsRotation control)850 (Vector3f. 0 0 10))))851 (if @move-down?852 (.applyTorque control853 (.mult (.getPhysicsRotation control)854 (Vector3f. 0 0 -10))))855 (if @move-left?856 (.applyTorque control857 (.mult (.getPhysicsRotation control)858 (Vector3f. 0 10 0))))859 (if @move-right?860 (.applyTorque control861 (.mult (.getPhysicsRotation control)862 (Vector3f. 0 -10 0))))863 (if @roll-left?864 (.applyTorque control865 (.mult (.getPhysicsRotation control)866 (Vector3f. -1 0 0))))867 (if @roll-right?868 (.applyTorque control869 (.mult (.getPhysicsRotation control)870 (Vector3f. 1 0 0))))))))871 #+end_src875 * COMMENT generate source876 #+begin_src clojure :tangle ../src/cortex/test/integration.clj877 <<integration>>878 <<integration-2>>879 #+end_src881 #+begin_src clojure :tangle ../src/cortex/video/magick8.clj882 <<magick-8>>883 #+end_src