rlm@306: #+title: Integration
rlm@73: #+author: Robert McIntyre
rlm@73: #+email: rlm@mit.edu
rlm@73: #+description:
rlm@73: #+keywords: simulation, jMonkeyEngine3, clojure
rlm@73: #+SETUPFILE: ../../aurellem/org/setup.org
rlm@73: #+INCLUDE: ../../aurellem/org/level-0.org
rlm@73:
rlm@302: * Integration
rlm@129:
rlm@281: This is the ultimate test which features all of the senses that I've
rlm@281: made so far. The blender file for the creature serves as an example of
rlm@281: a fully equipped creature in terms of senses. You can find it [[../assets/Models/test-creature/hand.blend][here]].
rlm@73:
rlm@300:
rlm@300: #+begin_html
rlm@300:
rlm@300: #+end_html
rlm@300:
rlm@302: * Generating the Video
rlm@300:
rlm@192: #+name: integration
rlm@73: #+begin_src clojure
rlm@300: (ns cortex.test.integration
rlm@73: "let's play!"
rlm@192: {:author "Robert McIntyre"}
rlm@281: (:use (cortex world util body sense
rlm@281: hearing touch vision proprioception movement))
rlm@192: (:import (com.jme3.math ColorRGBA Vector3f))
rlm@281: (:import java.io.File)
rlm@192: (:import com.jme3.audio.AudioNode)
rlm@192: (:import com.aurellem.capture.RatchetTimer))
rlm@73:
rlm@281: (dorun (cortex.import/mega-import-jme3))
rlm@281: (rlm.rlm-commands/help)
rlm@74:
rlm@281: (def hand "Models/test-creature/hand.blend")
rlm@78:
rlm@281: (def output-base (File. "/home/r/proj/cortex/render/hand"))
rlm@300: #+end_src
rlm@189:
rlm@300: For this demonstration I have to manually drive the muscles of the
rlm@300: hand. I do this by creating a little mini-language to describe
rlm@300: simulated muscle contraction.
rlm@297:
rlm@300: #+name: integration-2
rlm@300: #+begin_src clojure
rlm@296: (defn motor-control-program
rlm@296: "Create a function which will execute the motor script"
rlm@296: [muscle-positions
rlm@296: script]
rlm@296: (let [current-frame (atom -1)
rlm@296: keyed-script (group-by first script)
rlm@296: current-forces (atom {}) ]
rlm@296: (fn [effectors]
rlm@296: (let [indexed-effectors (vec effectors)]
rlm@296: (dorun
rlm@296: (for [[_ part force] (keyed-script (swap! current-frame inc))]
rlm@296: (swap! current-forces (fn [m] (assoc m part force)))))
rlm@296: (doall (map (fn [effector power]
rlm@296: (effector (int power)))
rlm@296: effectors
rlm@296: (map #(@current-forces % 0) muscle-positions)))))))
rlm@296:
rlm@296: (def muscle-positions
rlm@296: [:pointer-2-e
rlm@296: :pointer-2-f
rlm@296: :thumb-1
rlm@296: :thumb-1
rlm@296: :pointer-1-e
rlm@296: :pointer-1-f
rlm@296: :thumb-2-e
rlm@296: :thumb-2-f
rlm@296: :middle-1-e
rlm@296: :middle-1-f
rlm@296: :pointer-3-f
rlm@296: :pointer-3-e
rlm@296: :middle-2-e
rlm@296: :middle-2-f
rlm@296: :middle-3-f
rlm@296: :middle-3-e
rlm@296: :pinky-2-e
rlm@296: :pinky-2-f
rlm@296: :pinky-3-f
rlm@296: :pinky-3-e
rlm@296: :ring-3-e
rlm@296: :ring-3-f
rlm@296: :ring-2-f
rlm@296: :ring-2-e
rlm@296: :ring-1-e
rlm@296: :ring-1-f
rlm@296: :thumb-1-e
rlm@296: :thumb-1-f
rlm@296: :pinky-1-f
rlm@296: :pinky-1-e])
rlm@296:
rlm@296: (def full 9001)
rlm@300:
rlm@300:
rlm@306: ;; Choreography:
rlm@300:
rlm@300: ;; Let the hand fall palm-up
rlm@300:
rlm@300: ;; it curls its phalanges, starting with the pinky.
rlm@300:
rlm@300: ;; it lets its phalanges fall back down.
rlm@300:
rlm@300: ;; block falls down onto the hand, accompanied by a sound. The block
rlm@300: ;; can be seen by the hand's eye.
rlm@300:
rlm@300: ;; hand FORCEFULLY catapults the block so that it hits the camera.
rlm@300:
rlm@300:
rlm@306: ;; the syntax here is [keyframe body-part force]
rlm@300: (def move-fingers
rlm@298: [[300 :pinky-3-f 50]
rlm@298: [320 :pinky-2-f 80]
rlm@298: [340 :pinky-1-f 100]
rlm@297:
rlm@298: [310 :ring-3-f 100]
rlm@298: [330 :ring-2-f 120]
rlm@298: [350 :ring-1-f 140]
rlm@296:
rlm@298: [330 :middle-3-f 120]
rlm@298: [340 :middle-2-f 120]
rlm@298: [360 :middle-1-f 30]
rlm@296:
rlm@298: [350 :pointer-3-f 120]
rlm@298: [360 :pointer-2-f 120]
rlm@298: [380 :pointer-1-f 30]
rlm@296:
rlm@298: [800 :pinky-3-f 0]
rlm@298: [800 :pinky-2-f 0]
rlm@298: [800 :pinky-1-f 0]
rlm@296:
rlm@298: [800 :ring-3-f 0]
rlm@298: [800 :ring-2-f 0]
rlm@298: [800 :ring-1-f 0]
rlm@296:
rlm@298: [800 :middle-3-f 0]
rlm@298: [800 :middle-2-f 0]
rlm@298: [800 :middle-1-f 0]
rlm@296:
rlm@298: [800 :pointer-3-f 0]
rlm@298: [800 :pointer-2-f 0]
rlm@298: [800 :pointer-1-f 0]
rlm@297:
rlm@297:
rlm@298: [800 :pinky-3-e 50]
rlm@298: [800 :pinky-2-e 80]
rlm@298: [800 :pinky-1-e 100]
rlm@297:
rlm@298: [800 :ring-3-e 100]
rlm@298: [800 :ring-2-e 120]
rlm@298: [800 :ring-1-e 140]
rlm@298:
rlm@298: [800 :middle-3-e 120]
rlm@298: [800 :middle-2-e 120]
rlm@298: [800 :middle-1-e 30]
rlm@298:
rlm@298: [800 :pointer-3-e 120]
rlm@298: [800 :pointer-2-e 120]
rlm@298: [800 :pointer-1-e 30]
rlm@298:
rlm@298: [870 :pinky-3-e 0]
rlm@298: [870 :pinky-2-e 0]
rlm@298: [870 :pinky-1-e 0]
rlm@298:
rlm@298: [870 :ring-3-e 0]
rlm@298: [870 :ring-2-e 0]
rlm@298: [870 :ring-1-e 0]
rlm@298:
rlm@298: [870 :middle-3-e 0]
rlm@298: [870 :middle-2-e 0]
rlm@298: [870 :middle-1-e 0]
rlm@298:
rlm@298: [870 :pointer-3-e 0]
rlm@298: [870 :pointer-2-e 0]
rlm@298: [870 :pointer-1-e 0]
rlm@298:
rlm@298: [1500 :pointer-1-f full]
rlm@298: [1500 :pointer-2-f full]
rlm@298: [1500 :pointer-3-f full]
rlm@298:
rlm@298: [1500 :middle-1-f full]
rlm@298: [1500 :middle-2-f full]
rlm@298: [1500 :middle-3-f full]
rlm@298:
rlm@298: [1510 :pointer-1-f 0]
rlm@298: [1510 :pointer-2-f 0]
rlm@298: [1510 :pointer-3-f 0]
rlm@298:
rlm@298: [1510 :middle-1-f 0]
rlm@298: [1510 :middle-2-f 0]
rlm@298: [1510 :middle-3-f 0]
rlm@297: ])
rlm@297:
rlm@298: (defn gen-summon-ball [debug?]
rlm@298: (let [wait (atom 1100)]
rlm@297: (fn [world]
rlm@297: (if (= 0 (swap! wait dec))
rlm@297: (let [brick
rlm@297: (box 0.8 0.8 0.8 :mass 0.05
rlm@298: :position (Vector3f. -0.5 0 0.5)
rlm@298: :color (ColorRGBA/Red))
rlm@298: bell (AudioNode. (asset-manager)
rlm@298: "Sounds/pure.wav" false)]
rlm@298: (.play bell)
rlm@298: (if debug?
rlm@298: (.addControl
rlm@298: brick
rlm@298: (proxy [AbstractControl] []
rlm@298: (controlUpdate [tpf]
rlm@298: (println-repl (.getWorldTranslation brick)))
rlm@298: (controlRender [_ _]))))
rlm@297: (add-element world brick))))))
rlm@295:
rlm@298: (import com.aurellem.capture.Capture)
rlm@298:
rlm@281: (defn test-everything!
rlm@281: ([] (test-everything! false))
rlm@281: ([record?]
rlm@281: (let [me (sphere 0.5 :color ColorRGBA/Blue :physical? false)
rlm@281:
rlm@298: base (File. "/home/r/proj/cortex/render/hand")
rlm@298:
rlm@298:
rlm@281: creature (doto (load-blender-model hand)
rlm@281: (body!))
rlm@297:
rlm@298: summon-ball (gen-summon-ball false)
rlm@192: ;;;;;;;;;;;; Sensors/Effectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@298: touch (touch! creature)
rlm@298: touch-display (view-touch)
rlm@189:
rlm@298: vision (vision! creature)
rlm@298: vision-display (view-vision)
rlm@189:
rlm@298: hearing (hearing! creature)
rlm@298: hearing-display (view-hearing)
rlm@189:
rlm@173: prop (proprioception! creature)
rlm@190: prop-display (view-proprioception)
rlm@148:
rlm@296: control-script (motor-control-program
rlm@300: muscle-positions move-fingers)
rlm@191: muscles (movement! creature)
rlm@281: muscle-display (view-movement)
rlm@281: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@189:
rlm@281: fix-display (gen-fix-display)]
rlm@285: (world
rlm@285: (nodify [creature
rlm@285: (box 10 2 10 :position (Vector3f. 0 -9 0)
rlm@285: :color ColorRGBA/Gray :mass 0)
rlm@285: me])
rlm@298: standard-debug-controls
rlm@298:
rlm@285: (fn [world]
rlm@285: (.setTimer world (RatchetTimer. 60))
rlm@297: (position-camera
rlm@298: world (Vector3f. -0.13217318, 5.816415, -5.3089414)
rlm@298: (Quaternion. 0.55685693, 0.0042774677, -0.0028673497, 0.83059245))
rlm@298:
rlm@285: (light-up-everything world)
rlm@285: (enable-debug world)
rlm@285: (add-camera! world
rlm@285: (add-eye! creature
rlm@285: (.getChild
rlm@285: (.getChild creature "eyes") "eye"))
rlm@285: (comp (view-image) BufferedImage!))
rlm@298:
rlm@298: (if record?
rlm@298: (Capture/captureVideo
rlm@298: world (File. base "main")))
rlm@298: (if record?
rlm@298: (Capture/captureAudio
rlm@298: world (File. base "main.wav"))))
rlm@285: (fn [world tpf]
rlm@298: (prop-display
rlm@298: (prop)
rlm@298: (if record? (File. base "proprio")))
rlm@298: (touch-display
rlm@298: (map #(% (.getRootNode world)) touch)
rlm@298: (if record? (File. base "touch")))
rlm@298: (vision-display
rlm@298: (map #(% world) vision)
rlm@298: (if record? (File. base "vision")))
rlm@298: (hearing-display
rlm@298: (map #(% world) hearing)
rlm@298: (if record? (File. base "hearing")))
rlm@298: (muscle-display
rlm@298: (control-script muscles)
rlm@298: (if record? (File. base "muscle")))
rlm@298:
rlm@297: (summon-ball world)
rlm@298:
rlm@285: (.setLocalTranslation me (.getLocation (.getCamera world)))
rlm@285: (fix-display world))))))
rlm@300: #+end_src
rlm@298:
rlm@302: ** ImageMagick / ffmpeg
rlm@300:
rlm@300: Just a bunch of calls to imagemagick to arrange the data that
rlm@300: =test-everything!= produces.
rlm@300:
rlm@300: #+name: magick-8
rlm@300: #+begin_src clojure
rlm@300: (ns cortex.video.magick8
rlm@300: (:import java.io.File)
rlm@300: (:use clojure.contrib.shell-out))
rlm@298:
rlm@298: (comment
rlm@298: ;; list of touch targets
rlm@298: 0 middle-11
rlm@298: 1 middle-21
rlm@298: 2 middle-31
rlm@298: 3 pinky-11
rlm@298: 4 pinky-21
rlm@298: 5 pinky-31
rlm@298: 6 pointer-11
rlm@298: 7 pointer-21
rlm@298: 8 pointer-31
rlm@298: 9 ring-11
rlm@298: 10 ring-21
rlm@298: 11 ring-31
rlm@298: 12 thumb-11
rlm@298: 13 thumb-2.0011
rlm@298:
rlm@298:
rlm@298: ;; list of vision targets
rlm@298: 0 :all
rlm@298: 1 :green
rlm@298: 2 :blue
rlm@298: 3 :red
rlm@298:
rlm@298: ;; list of proprio targets
rlm@298: 0 middle-11 -> middle-21
rlm@298: 1 middle-21 -> middle-31
rlm@298: 2 thumb-11 -> thumb-2.0011
rlm@298: 3 pointer-11 -> pointer-21
rlm@298: 4 pointer-21 -> pointer-31
rlm@298: 5 ring-21 -> ring-31
rlm@298: 6 ring-11 -> ring-21
rlm@298: 7 pinky-21 -> pinky-31
rlm@298: 8 pinky-11 -> pinky-21
rlm@298: 9 middle-11 -> palm1
rlm@298: 10 pinky-11 -> palm1
rlm@298: 11 palm1 -> pointer-11
rlm@298: 12 palm1 -> ring-11
rlm@298: 13 palm1 -> thumb-11
rlm@298:
rlm@298:
rlm@298: ;; list of muscle targets
rlm@298: 0 :pointer-2-e
rlm@298: 1 :pointer-2-f
rlm@298: 2 :thumb-1
rlm@298: 3 :thumb-1
rlm@298: 4 :pointer-1-e
rlm@298: 5 :pointer-1-f
rlm@298: 6 :thumb-2-e
rlm@298: 7 :thumb-2-f
rlm@298: 8 :middle-1-e
rlm@298: 9 :middle-1-f
rlm@298: 10 :pointer-3-f
rlm@298: 11 :pointer-3-e
rlm@298: 12 :middle-2-e
rlm@298: 13 :middle-2-f
rlm@298: 14 :middle-3-f
rlm@298: 15 :middle-3-e
rlm@298: 16 :pinky-2-e
rlm@298: 17 :pinky-2-f
rlm@298: 18 :pinky-3-f
rlm@298: 19 :pinky-3-e
rlm@298: 20 :ring-3-e
rlm@298: 21 :ring-3-f
rlm@298: 22 :ring-2-f
rlm@298: 23 :ring-2-e
rlm@298: 24 :ring-1-e
rlm@298: 25 :ring-1-f
rlm@298: 26 :thumb-1-e
rlm@298: 27 :thumb-1-f
rlm@298: 28 :pinky-1-f
rlm@298: 29 :pinky-1-e
rlm@298: )
rlm@298:
rlm@298: (def base (File. "/home/r/proj/cortex/render/hand"))
rlm@298:
rlm@298: (defn prepare-muscle [muscle]
rlm@298: ["(" muscle "-rotate" "90" "-scale" "15x60!" ")"])
rlm@298:
rlm@298: (defn prepare-touch [touch]
rlm@298: ["(" touch "-rotate" "180" ")"])
rlm@298:
rlm@298: (defn generate-top-finger [tip-flexor tip-extensor tip
rlm@298: joint-2-3
rlm@298: mid-flexor mid-extensor mid
rlm@298: joint-1-2]
rlm@298: ["("
rlm@298: "-size" "113x357" "xc:transparent"
rlm@298: (prepare-muscle tip-flexor) "-geometry" "+0+7" "-composite"
rlm@298: (prepare-muscle tip-extensor) "-geometry" "+98+7" "-composite"
rlm@298: (prepare-touch tip) "-geometry" "+18+0" "-composite"
rlm@298:
rlm@298: joint-2-3 "-geometry" "+32+79" "-composite"
rlm@298:
rlm@298: (prepare-muscle mid-flexor) "-geometry" "+19+131" "-composite"
rlm@298: (prepare-muscle mid-extensor) "-geometry" "+80+131" "-composite"
rlm@298: (prepare-touch mid) "-geometry" "+39+133" "-composite"
rlm@298:
rlm@298: joint-1-2 "-geometry" "+32+193" "-composite"
rlm@298: ")"])
rlm@298:
rlm@299: (defn file-names [#^File dir]
rlm@299: (map #(.getCanonicalPath %) (next (sort (file-seq dir)))))
rlm@299:
rlm@299: (defn file-groups [& paths]
rlm@299: (apply (partial map list )
rlm@299: (map (comp file-names #(File. base %))
rlm@299: paths)))
rlm@299:
rlm@299: (defn pinky []
rlm@299: (file-groups
rlm@299: "muscle/18"
rlm@299: "muscle/19"
rlm@299: "touch/5"
rlm@299: "proprio/7"
rlm@299:
rlm@299: "muscle/17"
rlm@299: "muscle/16"
rlm@299: "touch/4"
rlm@299: "proprio/8"
rlm@299:
rlm@299: "muscle/28"
rlm@299: "muscle/29"
rlm@299: "touch/3"
rlm@299: "proprio/10"))
rlm@299:
rlm@299: (defn ring []
rlm@299: (file-groups
rlm@299: "muscle/21"
rlm@299: "muscle/20"
rlm@299: "touch/11"
rlm@299: "proprio/5"
rlm@299:
rlm@299: "muscle/22"
rlm@299: "muscle/23"
rlm@299: "touch/10"
rlm@299: "proprio/6"
rlm@299:
rlm@299: "muscle/25"
rlm@299: "muscle/24"
rlm@299: "touch/9"
rlm@299: "proprio/12"))
rlm@299:
rlm@299: (defn middle []
rlm@299: (file-groups
rlm@299: "muscle/14"
rlm@299: "muscle/15"
rlm@299: "touch/2"
rlm@299: "proprio/1"
rlm@299:
rlm@300: "muscle/13"
rlm@299: "muscle/12"
rlm@299: "touch/1"
rlm@299: "proprio/0"
rlm@299:
rlm@300: "muscle/9"
rlm@299: "muscle/8"
rlm@299: "touch/0"
rlm@299: "proprio/9"))
rlm@299:
rlm@299: (defn pointer []
rlm@299: (file-groups
rlm@299: "muscle/10"
rlm@299: "muscle/11"
rlm@299: "touch/8"
rlm@299: "proprio/4"
rlm@299:
rlm@299: "muscle/1"
rlm@299: "muscle/0"
rlm@299: "touch/7"
rlm@299: "proprio/3"
rlm@299:
rlm@299: "muscle/5"
rlm@299: "muscle/4"
rlm@299: "touch/6"
rlm@299: "proprio/11"))
rlm@299:
rlm@299: (defn thumb []
rlm@299: (file-groups
rlm@299: "muscle/7"
rlm@299: "muscle/6"
rlm@299: "touch/13"
rlm@299: "proprio/2"
rlm@299:
rlm@299: "muscle/27"
rlm@299: "muscle/26"
rlm@299: "muscle/3"
rlm@299: "muscle/2"
rlm@299: "touch/12"
rlm@299: "proprio/13"))
rlm@299:
rlm@298: (defn generate-finger
rlm@298: [tip-flexor tip-extensor tip
rlm@298: joint-2-3
rlm@298: mid-flexor mid-extensor mid
rlm@298: joint-1-2
rlm@298: base-flexor base-extensor base
rlm@298: joint-palm-1]
rlm@298: ["("
rlm@298: "-size" "113x357" "xc:transparent"
rlm@298: (generate-top-finger
rlm@298: tip-flexor tip-extensor tip
rlm@298: joint-2-3
rlm@298: mid-flexor mid-extensor mid
rlm@298: joint-1-2) "-geometry" "+0+0" "-composite"
rlm@298: (prepare-muscle base-flexor) "-geometry" "+19+245" "-composite"
rlm@298: (prepare-muscle base-extensor) "-geometry" "+80+245" "-composite"
rlm@298: (prepare-touch base) "-geometry" "+39+247" "-composite"
rlm@298: joint-palm-1 "-geometry" "+32+307" "-composite"
rlm@298: ")"])
rlm@298:
rlm@298: (defn generate-thumb
rlm@298: [tip-flexor tip-extensor tip
rlm@298: joint-1-2
rlm@298: mid-flexor mid-extensor mid-flexor-2 mid-extensor-2 mid
rlm@298: joint-palm-1]
rlm@298: ["("
rlm@298: "-size" "113x357" "xc:transparent"
rlm@298: (generate-top-finger
rlm@298: tip-flexor tip-extensor tip
rlm@298: joint-1-2
rlm@298: mid-flexor mid-extensor mid
rlm@298: joint-palm-1) "-geometry" "+0+0" "-composite"
rlm@298: (prepare-muscle mid-flexor-2) "-geometry" "+2+131" "-composite"
rlm@298: (prepare-muscle mid-extensor-2) "-geometry" "+100+131" "-composite"
rlm@298: ")"])
rlm@298:
rlm@298: (defn generate-hand
rlm@298: [pinky-pieces
rlm@298: ring-pieces
rlm@298: middle-pieces
rlm@298: pointer-pieces
rlm@298: thumb-pieces]
rlm@298: ["("
rlm@298: "-size" "688x769" "xc:transparent"
rlm@298: (apply generate-finger pinky-pieces)
rlm@298: "-geometry" "+0+195" "-composite"
rlm@298: (apply generate-finger ring-pieces)
rlm@298: "-geometry" "+111+100" "-composite"
rlm@298: (apply generate-finger middle-pieces)
rlm@298: "-geometry" "+228+0" "-composite"
rlm@298: "(" (apply generate-thumb thumb-pieces) "-background" "#00000000"
rlm@298: "-rotate" "45" ")"
rlm@298: "-geometry" "+300+420" "-composite"
rlm@298: (apply generate-finger pointer-pieces)
rlm@298: "-geometry" "+350+96" "-composite"
rlm@298: ")"])
rlm@298:
rlm@298: (defn generate-vision
rlm@298: [all green blue red]
rlm@298: ["("
rlm@298: "-size" "204x192" "xc:transparent"
rlm@298: all "-geometry" "+0+0" "-composite"
rlm@298: green "-geometry" "+113+0" "-composite"
rlm@298: blue "-geometry" "+0+105" "-composite"
rlm@298: red "-geometry" "+113+105" "-composite"
rlm@298: ")"])
rlm@298:
rlm@298: (def test-muscle (File. base "muscle/0/0000000.png"))
rlm@298: (def test-proprio (File. base "proprio/0/0000000.png"))
rlm@298: (def test-tip (File. base "touch/2/0000000.png"))
rlm@298: (def test-mid (File. base "touch/0/0000000.png"))
rlm@298: (def test-vision (File. base "vision/0/0000000.png"))
rlm@298: (def test-hearing (File. base "hearing/0/0000000.png"))
rlm@298: (def test-main (File. base "main/0000000.png"))
rlm@298:
rlm@298: (def test-target (File. base "output.png"))
rlm@298:
rlm@298: (def background (File. base "background.png"))
rlm@298:
rlm@298: (use 'clojure.contrib.shell-out)
rlm@299:
rlm@299: (defn vision []
rlm@299: (file-groups
rlm@299: "vision/0"
rlm@299: "vision/1"
rlm@299: "vision/2"
rlm@299: "vision/3"))
rlm@299:
rlm@299: (defn hearing []
rlm@299: (file-names (File. base "hearing/0")))
rlm@299:
rlm@299: (defn main []
rlm@299: (file-names (File. base "main")))
rlm@299:
rlm@300: (defn targets [dest max]
rlm@299: (map
rlm@299: (comp #(.getCanonicalPath %)
rlm@300: #(File. (str base dest (format "%07d.png" %))))
rlm@300: (range max)))
rlm@299:
rlm@299:
rlm@299: (defn final-image [main [all red green blue] hearing
rlm@299: pinky ring middle pointer thumb target]
rlm@299: (println target)
rlm@299: (apply
rlm@298: sh
rlm@298: (flatten
rlm@298: ["convert"
rlm@298: (.getCanonicalPath background)
rlm@299:
rlm@299: (generate-hand pinky ring middle pointer thumb)
rlm@298: "-geometry" "+809+22" "-composite"
rlm@298:
rlm@299: (generate-vision all red green blue)
rlm@298: "-geometry" "+974+599" "-composite"
rlm@298:
rlm@298: hearing
rlm@298: "-geometry" "+784+819" "-composite"
rlm@298:
rlm@298: main
rlm@298: "-geometry" "+78+202" "-composite"
rlm@298:
rlm@299: target])))
rlm@298:
rlm@300: (defn combine-files []
rlm@299: (dorun
rlm@299: (pmap final-image
rlm@299: (main)
rlm@299: (vision)
rlm@299: (hearing)
rlm@299: (pinky)
rlm@299: (ring)
rlm@299: (middle)
rlm@299: (pointer)
rlm@299: (thumb)
rlm@300: (targets "/out/" (count (main))))))
rlm@300:
rlm@300: (defn subtitles []
rlm@300: (file-names (File. base "subs")))
rlm@300:
rlm@300: (defn outs []
rlm@300: (file-names (File. base "out")))
rlm@300:
rlm@300:
rlm@300: (defn mix-subtitles []
rlm@300: (let [subs (subtitles)
rlm@300: targets (targets "/out-subs/" (count subs))
rlm@300: overlay (.getCanonicalPath (File. base "output.png"))]
rlm@300: (dorun
rlm@300: (pmap
rlm@300: (fn [sub target]
rlm@300: (sh
rlm@300: "convert"
rlm@300: overlay
rlm@300: sub "-geometry" "+0+0" "-composite"
rlm@300: target))
rlm@300: subs targets))))
rlm@300:
rlm@300: (defn out-subtitles []
rlm@300: (file-names (File. base "out-subs")))
rlm@300:
rlm@300:
rlm@300: (defn insert-subtitles []
rlm@300: (let [subtitles (out-subtitles)
rlm@300: outs (outs)
rlm@300: targets (targets
rlm@300: "/final/"
rlm@300: (+ (count outs) (count subtitles)))]
rlm@300: (dorun
rlm@300: (pmap
rlm@300: #(sh "cp" %1 %2)
rlm@300: (concat subtitles outs) targets))))
rlm@300:
rlm@300: (defn generate-final []
rlm@300: (combine-files)
rlm@300: (mix-subtitles)
rlm@300: (insert-subtitles))
rlm@299: #+end_src
rlm@298:
rlm@300: #+begin_src sh :results silent
rlm@299: cd /home/r/proj/cortex/render/hand
rlm@298:
rlm@300: sox --ignore-length main.wav main-delayed.wav delay 24
rlm@300:
rlm@300: mogrify -resize 755x final/*
rlm@300:
rlm@300: ffmpeg -r 60 -i final/%07d.png -i main-delayed.wav -b:a 128k \
rlm@299: -b:v 9000k -c:a libvorbis -c:v libtheora hand.ogg
rlm@87: #+end_src
rlm@83:
rlm@301:
rlm@301: * Source Listing
rlm@301: - [[../src/cortex/test/integration.clj][cortex.test.integration]]
rlm@302: - [[../src/cortex/video/magick8.clj][cortex.video.magick8]]
rlm@301: - [[../assets/Models/subtitles/hand.blend][subtitles/hand.blend]]
rlm@301: #+html:
rlm@301: - [[http://hg.bortreb.com ][source-repository]]
rlm@301:
rlm@301:
rlm@78: * COMMENT purgatory
rlm@78: #+begin_src clojure
rlm@77: (defn bullet-trans* []
rlm@77: (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
rlm@77: :position (Vector3f. 5 0 0)
rlm@77: :mass 90)
rlm@77: obj-b (sphere 0.5 :color ColorRGBA/Blue
rlm@77: :position (Vector3f. -5 0 0)
rlm@77: :mass 0)
rlm@77: control-a (.getControl obj-a RigidBodyControl)
rlm@77: control-b (.getControl obj-b RigidBodyControl)
rlm@77: move-up? (atom nil)
rlm@77: move-down? (atom nil)
rlm@77: move-left? (atom nil)
rlm@77: move-right? (atom nil)
rlm@77: roll-left? (atom nil)
rlm@77: roll-right? (atom nil)
rlm@77: force 100
rlm@77: swivel
rlm@77: (.toRotationMatrix
rlm@77: (doto (Quaternion.)
rlm@77: (.fromAngleAxis (/ Math/PI 2)
rlm@77: Vector3f/UNIT_X)))
rlm@77: x-move
rlm@77: (doto (Matrix3f.)
rlm@77: (.fromStartEndVectors Vector3f/UNIT_X
rlm@77: (.normalize (Vector3f. 1 1 0))))
rlm@77:
rlm@77: timer (atom 0)]
rlm@77: (doto
rlm@77: (ConeJoint.
rlm@77: control-a control-b
rlm@77: (Vector3f. -8 0 0)
rlm@77: (Vector3f. 2 0 0)
rlm@77: ;;swivel swivel
rlm@77: ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
rlm@77: x-move Matrix3f/IDENTITY
rlm@77: )
rlm@77: (.setCollisionBetweenLinkedBodys false)
rlm@77: (.setLimit (* 1 (/ Math/PI 4)) ;; twist
rlm@77: (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
rlm@77: (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
rlm@77: (world (nodify
rlm@77: [obj-a obj-b])
rlm@77: (merge standard-debug-controls
rlm@77: {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
rlm@77: "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
rlm@77: "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
rlm@77: "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
rlm@77: "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
rlm@77: "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
rlm@77:
rlm@77: (fn [world]
rlm@77: (enable-debug world)
rlm@77: (set-gravity world Vector3f/ZERO)
rlm@77: )
rlm@77:
rlm@77: (fn [world _]
rlm@77:
rlm@77: (if @move-up?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. force 0 0)
rlm@77: (Vector3f. 0 0 0)))
rlm@77: (if @move-down?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. (- force) 0 0)
rlm@77: (Vector3f. 0 0 0)))
rlm@77: (if @move-left?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. 0 force 0)
rlm@77: (Vector3f. 0 0 0)))
rlm@77: (if @move-right?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. 0 (- force) 0)
rlm@77: (Vector3f. 0 0 0)))
rlm@77:
rlm@77: (if @roll-left?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. 0 0 force)
rlm@77: (Vector3f. 0 0 0)))
rlm@77: (if @roll-right?
rlm@77: (.applyForce control-a
rlm@77: (Vector3f. 0 0 (- force))
rlm@77: (Vector3f. 0 0 0)))
rlm@77:
rlm@77: (if (zero? (rem (swap! timer inc) 100))
rlm@77: (.attachChild
rlm@77: (.getRootNode world)
rlm@77: (sphere 0.05 :color ColorRGBA/Yellow
rlm@77: :physical? false :position
rlm@77: (.getWorldTranslation obj-a)))))
rlm@77: )
rlm@77: ))
rlm@77:
rlm@106: (defn test-joint [joint]
rlm@106: (let [[origin top bottom floor] (world-setup joint)
rlm@106: control (.getControl top RigidBodyControl)
rlm@106: move-up? (atom false)
rlm@106: move-down? (atom false)
rlm@106: move-left? (atom false)
rlm@106: move-right? (atom false)
rlm@106: roll-left? (atom false)
rlm@106: roll-right? (atom false)
rlm@106: timer (atom 0)]
rlm@106:
rlm@106: (world
rlm@106: (nodify [top bottom floor origin])
rlm@106: (merge standard-debug-controls
rlm@106: {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
rlm@106: "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
rlm@106: "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
rlm@106: "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
rlm@106: "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
rlm@106: "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
rlm@106:
rlm@106: (fn [world]
rlm@106: (light-up-everything world)
rlm@106: (enable-debug world)
rlm@106: (set-gravity world (Vector3f. 0 0 0))
rlm@106: )
rlm@106:
rlm@106: (fn [world _]
rlm@106: (if (zero? (rem (swap! timer inc) 100))
rlm@106: (do
rlm@106: ;; (println-repl @timer)
rlm@106: (.attachChild (.getRootNode world)
rlm@106: (sphere 0.05 :color ColorRGBA/Yellow
rlm@106: :position (.getWorldTranslation top)
rlm@106: :physical? false))
rlm@106: (.attachChild (.getRootNode world)
rlm@106: (sphere 0.05 :color ColorRGBA/LightGray
rlm@106: :position (.getWorldTranslation bottom)
rlm@106: :physical? false))))
rlm@106:
rlm@106: (if @move-up?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. 0 0 10))))
rlm@106: (if @move-down?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. 0 0 -10))))
rlm@106: (if @move-left?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. 0 10 0))))
rlm@106: (if @move-right?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. 0 -10 0))))
rlm@106: (if @roll-left?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. -1 0 0))))
rlm@106: (if @roll-right?
rlm@106: (.applyTorque control
rlm@106: (.mult (.getPhysicsRotation control)
rlm@106: (Vector3f. 1 0 0))))))))
rlm@99: #+end_src
rlm@192:
rlm@99:
rlm@306:
rlm@99: * COMMENT generate source
rlm@300: #+begin_src clojure :tangle ../src/cortex/test/integration.clj
rlm@192: <>
rlm@300: <>
rlm@300: #+end_src
rlm@300:
rlm@300: #+begin_src clojure :tangle ../src/cortex/video/magick8.clj
rlm@300: <>
rlm@99: #+end_src