Mercurial > cortex
view org/cortex.org @ 24:e965675ec4d0
moving things around
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 24 Oct 2011 01:19:15 -0700 |
parents | cab2da252494 |
children | 775d97247dd0 |
line wrap: on
line source
1 #+title: Simulated Senses2 #+author: Robert McIntyre3 #+email: rlm@mit.edu4 #+description: Simulating senses for AI research using JMonkeyEngine35 #+SETUPFILE: ../../aurellem/org/setup.org6 #+INCLUDE: ../../aurellem/org/level-0.org7 #+babel: :mkdirp yes :noweb yes :exports both10 * Simulation Base13 ** Hello14 Here are the jmonkeyengine "Hello" programs translated to clojure.15 *** Hello Simple App16 Here is the hello world example for jme3 in clojure. It's a more or17 less direct translation from the java source [[http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication][here]].19 Of note is the fact that since we don't have access to the20 =AssetManager= via extendig =SimpleApplication=, we have to build one21 ourselves.23 #+srcname: hello-simple-app24 #+begin_src clojure :results silent25 (ns hello.hello-simple-app)26 (require 'cortex.import)27 (use 'clojure.contrib.def)28 (rlm.rlm-commands/help)29 (cortex.import/mega-import-jme3)30 (use 'cortex.world)33 (def cube (Box. Vector3f/ZERO 1 1 1))35 (def geom (Geometry. "Box" cube))37 (def mat (Material. (asset-manager) "Common/MatDefs/Misc/Unshaded.j3md"))39 (.setColor mat "Color" ColorRGBA/Blue)41 (.setMaterial geom mat)43 (defn simple-app []44 (doto45 (proxy [SimpleApplication] []46 (simpleInitApp47 []48 ;; Don't take control of the mouse49 (org.lwjgl.input.Mouse/setGrabbed false)50 (.attachChild (.getRootNode this) geom)))51 ;; don't show a menu to change options.52 (.setShowSettings false)53 (.setPauseOnLostFocus false)54 (.setSettings *app-settings*)))55 #+end_src57 Running this program will begin a new jMonkeyEngine game which58 displays a single blue cube.60 #+begin_src clojure :exports code :results silent61 (.start (hello.hello-simple-app/simple-app))62 #+end_src64 #+caption: the simplest JME game.65 [[./images/simple-app.jpg]]69 *** Hello Physics70 From http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics72 #+srcname: brick-wall-header73 #+begin_src clojure :results silent74 (ns hello.brick-wall)75 (require 'cortex.import)76 (use 'clojure.contrib.def)77 (rlm.rlm-commands/help)78 (cortex.import/mega-import-jme3)79 (use '[pokemon [lpsolve :only [constant-map]]])80 (use 'cortex.world)81 #+end_src83 #+srcname: brick-wall-body84 #+begin_src clojure :results silent85 (in-ns 'hello.brick-wall)87 (defn floor88 "make a sturdy, unmovable physical floor"89 []90 (box 20 1 20 :mass 0 :color false :position (Vector3f. 0 -2 0)))92 (def brick-length 0.48)93 (def brick-width 0.24)94 (def brick-height 0.12)97 (defn brick* [position]98 (doto (box brick-length brick-height brick-width99 :position position :name "brick"100 :material "Common/MatDefs/Misc/Unshaded.j3md"101 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"102 :mass 36)103 (->104 (.getMesh)105 (.scaleTextureCoordinates (Vector2f. 1 0.5)))106 ;;(.setShadowMode RenderQueue$ShadowMode/CastAndReceive)107 )108 )110 (defn inception-brick-wall111 "construct a physical brick wall"112 []113 (let [node (Node. "brick-wall")]114 (dorun115 (map (comp #(.attachChild node %) brick*)116 (for117 [x (range 15)118 y (range 10)119 z (range 1)]120 (Vector3f.121 (* brick-length x 1.03)122 (* brick-width y y 10)123 (* brick-height z)))))124 node))126 (defn gravity-toggle127 [new-value]128 (fn [game value]129 (println-repl "set gravity to " new-value)130 (if value131 (set-gravity* game new-value)132 (set-gravity* game gravity))))134 (defn fire-cannon-ball135 ([node]136 (fn [game value]137 (if (not value)138 (let [camera (.getCamera game)139 cannon-ball140 (sphere 0.7141 :material "Common/MatDefs/Misc/Unshaded.j3md"142 :texture "Textures/PokeCopper.jpg"143 :position144 (.add (.getLocation camera)145 (.mult (.getDirection camera) (float 1)))146 :mass 3)] ;200 0.05147 (.setShadowMode cannon-ball RenderQueue$ShadowMode/CastAndReceive)148 (.setLinearVelocity149 (.getControl cannon-ball RigidBodyControl)150 (.mult (.getDirection camera) (float 50))) ;50151 (add-element game cannon-ball (if node node (.getRootNode game)))))))152 ([]153 (fire-cannon-ball false)))156 (defn floor* []157 (doto (box 10 0.1 5 :name "floor" ;10 0.1 5 ; 240 0.1 240158 :material "Common/MatDefs/Misc/Unshaded.j3md"159 :texture "Textures/Terrain/Pond/Pond.png"160 :position (Vector3f. 0 -0.1 0 )161 :mass 0)162 (->163 (.getMesh)164 (.scaleTextureCoordinates (Vector2f. 3 6)));64 64165 (->166 (.getMaterial)167 (.getTextureParam "ColorMap")168 (.getTextureValue)169 (.setWrap Texture$WrapMode/Repeat))170 (.setShadowMode RenderQueue$ShadowMode/Receive)171 ))173 (defn brick-wall* []174 (let [node (Node. "brick-wall")]175 (dorun176 (map177 (comp #(.attachChild node %) brick*)178 (for [y (range 15)179 x (range 4)180 z (range 1)]181 (Vector3f.182 (+ (* 2 x brick-length)183 (if (even? (+ y z))184 (/ brick-length 4) (/ brick-length -4)))185 (+ (* brick-height (inc (* 2 y))))186 (* 2 z brick-width) ))))187 (.setShadowMode node RenderQueue$ShadowMode/CastAndReceive)188 node))190 (defn brick-wall-game-run []191 (doto192 (world193 (doto (Node.) (.attachChild (floor*))194 (.attachChild (brick-wall*))195 )196 {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81))197 "key-m" (gravity-toggle (Vector3f. 0 0 9.81))198 "key-l" (gravity-toggle (Vector3f. 9.81 0 0))199 "key-j" (gravity-toggle (Vector3f. -9.81 0 0))200 "key-k" (gravity-toggle Vector3f/ZERO)201 "key-u" (gravity-toggle (Vector3f. 0 9.81 0))202 "key-o" (gravity-toggle (Vector3f. 0 -9.81 0))203 "key-f" (fn[game value]204 (if (not value) (add-element game (brick-wall*))))205 "key-return" (fire-cannon-ball)}206 position-camera207 (fn [& _]))208 (.start)))209 #+end_src211 #+begin_src clojure :results silent212 (hello.brick-wall/brick-wall-game-run)213 #+end_src215 #+caption: the brick wall standing216 [[./images/brick-wall-standing.jpg]]218 #+caption: the brick wall after it has been knocked over by a "pok\eacute{}ball"219 [[./images/brick-wall-knocked-down.jpg]]221 *** Other Brick Games222 #+srcname: other-games223 #+begin_src clojure :results silent224 (ns cortex.other-games225 {:author "Dylan Holmes"})226 (use 'cortex.world)227 (use 'hello.brick-wall)228 (use 'cortex.import)229 (cortex.import/mega-import-jme3)231 (defn scad [position]232 (doto (box 0.1 0.1 0.1233 :position position :name "brick"234 :material "Common/MatDefs/Misc/Unshaded.j3md"235 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"236 :mass 20)237 (->238 (.getMesh)239 (.scaleTextureCoordinates (Vector2f. 1 0.5))240 )241 (-> (.getControl RigidBodyControl)242 (.setLinearVelocity (Vector3f. 0 100 0))243 )245 ;;(.setShadowMode RenderQueue$ShadowMode/Cast)246 ))249 (defn shrapnel []250 (let [node (Node. "explosion-day")]251 (dorun252 (map253 (comp #(.attachChild node %) scad)254 (for [y (range 15)255 x (range 4)256 z (range 1)]257 (Vector3f.258 (+ (* 2 x brick-height)259 (if (even? (+ y z)) (/ brick-height 4) (/ brick-height -4)))260 (+ (* brick-height (inc (* 2 y))))261 (* 2 z brick-height) ))))262 node))265 (def domino-height 0.48)266 (def domino-thickness 0.12)267 (def domino-width 0.24)269 (def domino-thickness 0.05)270 (def domino-width 0.5)271 (def domino-height 1)273 (defn domino274 ([position]275 (domino position (Quaternion/IDENTITY)))276 ([position rotation]277 (doto (box domino-width domino-height domino-thickness278 :position position :name "domino"279 :material "Common/MatDefs/Misc/Unshaded.j3md"280 :texture "Textures/Terrain/BrickWall/BrickWall.jpg"281 :mass 1282 :rotation rotation)283 (.setShadowMode RenderQueue$ShadowMode/CastAndReceive)284 )))287 (defn domino-row []288 (let [node (Node. "domino-row")]289 (dorun290 (map291 (comp #(.attachChild node %) domino)292 (for [293 z (range 10)294 x (range 5)295 ]296 (Vector3f.297 (+ (* z domino-width) (* x 5 domino-width))298 (/ domino-height 1)299 (* -5.5 domino-thickness z) ))))301 node))303 (defn domino-cycle []304 (let [node (Node. "domino-cycle")]305 (dorun306 (map307 (comp #(.attachChild node %) (partial apply domino) )308 (for [n (range 720)]309 (let [space (* domino-height 5.5)310 r (fn[n] (* (+ n 3) domino-width 0.5))311 t (fn[n] (reduce312 +313 (map314 (fn dt[n] (/ space (* 2 (Math/PI) (r n))))315 (range n))))316 t (t n)317 r (r n)318 ct (Math/cos t)319 st (Math/sin t)320 ]321 (list322 (Vector3f.323 (* -1 r st)324 (/ domino-height 1)325 (* r ct))326 (.fromAngleAxis (Quaternion.)327 (- (/ 3.1415926 2) t) (Vector3f. 0 1 0))328 )))329 ))330 node))333 (defn domino-game-run []334 (doto335 (world336 (doto (Node.) (.attachChild (floor*))337 )338 {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81))339 "key-m" (gravity-toggle (Vector3f. 0 0 9.81))340 "key-l" (gravity-toggle (Vector3f. 9.81 0 0))341 "key-j" (gravity-toggle (Vector3f. -9.81 0 0))342 "key-k" (gravity-toggle (Vector3f. 0 9.81 0) )343 "key-u" (fn[g v] ((gravity-toggle (Vector3f. 0 -0 0)) g true))344 "key-o" (gravity-toggle (Vector3f. 0 -9.81 0))346 "key-space"347 (fn[game value]349 (if (not value)350 (let [d (domino (Vector3f. 0 (/ domino-height 0.25) 0)351 (.fromAngleAxis (Quaternion.)352 (/ Math/PI 2) (Vector3f. 0 1 0)))]353 (add-element game d))))354 "key-f"355 (fn[game value](if (not value) (add-element game (domino-cycle))))356 "key-return" (fire-cannon-ball)}357 position-camera358 (fn [& _]))359 (.start)))360 #+end_src362 #+begin_src clojure :results silent363 (cortex.other-games/domino-game-run)364 #+end_src366 #+caption: floating dominos367 [[./images/dominos.jpg]]369 *** Hello Loop370 #+srcname: hello-loop371 #+begin_src clojure :results silent372 (ns hello.loop)373 (use 'cortex.world)374 (use 'cortex.import)375 (cortex.import/mega-import-jme3)376 (rlm.rlm-commands/help)378 (defn blue-cube []379 (box 1 1 1380 :color ColorRGBA/Blue381 :texture false382 :material "Common/MatDefs/Misc/Unshaded.j3md"383 :name "blue-cube"384 :physical? false))386 (defn blue-cube-game []387 (let [cube (blue-cube)388 root (doto (Node.) (.attachChild cube))]389 (world root390 {}391 no-op392 (fn [game tpf]393 (.rotate cube 0.0 (* 2 tpf) 0.0)))))394 #+end_src396 *** Hello Collision398 #+srcname: hello-collision399 #+begin_src clojure :results silent400 (ns hello.collision)401 (use 'cortex.world)402 (use 'cortex.import)403 (use 'clojure.contrib.def)406 (cortex.import/mega-import-jme3)407 (rlm.rlm-commands/help)408 (use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]])411 (defn environment []412 (let413 [scene-model414 (doto415 (.loadModel416 (doto (asset-manager)417 (.registerLocator418 "/home/r/cortex/assets/zips/town.zip" ZipLocator))419 "main.scene")420 (.setLocalScale (float 2.0)))421 collision-shape422 (CollisionShapeFactory/createMeshShape #^Node scene-model)423 landscape (RigidBodyControl. collision-shape 0)]424 (.setShadowMode scene-model RenderQueue$ShadowMode/CastAndReceive)425 (.addControl scene-model landscape)426 scene-model))428 (defn player-fn []429 (doto430 (CharacterControl.431 (CapsuleCollisionShape. (float 1.5) (float 6)(float 1))432 (float 0.05))433 (.setJumpSpeed 20)434 (.setFallSpeed 30)435 (.setGravity 30) ;30436 (.setPhysicsLocation (Vector3f. 0 10 0))))438 (defn lights []439 [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 1 1 1) (float 1))))440 (doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 0.7 0 1) (float 1))))441 (doto (DirectionalLight.)442 (.setColor (.mult ColorRGBA/White (float 0.9) ))443 (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))])445 (defn night-lights []446 [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 0.275 0.467 0.784 1) (float 0.3))))447 (doto (DirectionalLight.)448 (.setColor (.mult ColorRGBA/White (float 0.2) ))449 (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))])451 (def player (atom (player-fn)))453 (defn setup-fn [game]454 (dorun (map #(.addLight (.getRootNode game) %) (lights)))455 ;; set the color of the sky456 (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1))457 ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1)458 (doto (.getFlyByCamera game)459 (.setMoveSpeed (float 100))460 (.setRotationSpeed 3))461 (.add462 (.getPhysicsSpace463 (.getState (.getStateManager game) BulletAppState))464 @player)466 (doto (Node.) (.attachChild (.getRootNode game))467 (.attachChild (brick-wall*))468 )470 )473 (def walking-up? (atom false))474 (def walking-down? (atom false))475 (def walking-left? (atom false))476 (def walking-right? (atom false))478 (defn set-walk [walk-atom game value]479 ;;(println-repl "setting stuff to " value)480 (reset! walk-atom value))482 (defn responses []483 {"key-w" (partial set-walk walking-up?)484 "key-d" (partial set-walk walking-right?)485 "key-s" (partial set-walk walking-down?)486 "key-a" (partial set-walk walking-left?)487 "key-return" (fire-cannon-ball)488 "key-space" (fn [game value] (.jump @player))489 })491 (defn update-fn492 [game tpf]493 (let [camera (.getCamera game)494 cam-dir (.multLocal495 (.clone496 (.getDirection camera)) (float 0.6))497 cam-left (.multLocal498 (.clone499 (.getLeft camera)) (float 0.4))500 walk-direction (Vector3f. 0 0 0)]502 (cond503 @walking-up? (.addLocal walk-direction cam-dir)504 @walking-right? (.addLocal walk-direction (.negate cam-left))505 @walking-down? (.addLocal walk-direction (.negate cam-dir))506 @walking-left? (.addLocal walk-direction cam-left))507 (.setWalkDirection @player walk-direction)508 (.setLocation camera (.getPhysicsLocation @player))))510 (defn run-game []511 (.start512 (world (environment)513 (responses)514 setup-fn515 update-fn)))516 #+end_src518 *** Hello Terrain519 #+srcname: hello-terrain520 #+begin_src clojure :results silent521 (ns hello.terrain)522 (use 'cortex.world)523 (use 'cortex.import)524 (use 'clojure.contrib.def)525 (import jme3tools.converters.ImageToAwt)528 (cortex.import/mega-import-jme3)529 (rlm.rlm-commands/help)530 (use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]])533 (defn setup-fn [type game]534 (.setMoveSpeed (.getFlyByCamera game) 50)535 (.setFrustumFar (.getCamera game) 10000)536 (let [env (environment type)537 cameras [(.getCamera game)]538 control (TerrainLodControl. env cameras)]539 ;;(.addControl env control)540 (.attachChild (.getRootNode game) env)))542 (defn environment [type]543 (let544 [mat_terrain545 (Material. (asset-manager) "Common/MatDefs/Terrain/Terrain.j3md")546 grass (.loadTexture (asset-manager) "Textures/Terrain/splat/grass.jpg")547 dirt (.loadTexture (asset-manager) "Textures/Terrain/splat/dirt.jpg")548 rock (.loadTexture (asset-manager) "Textures/Terrain/splat/road.jpg")549 heightmap-image (.loadTexture (asset-manager)550 ({:mountain "Textures/Terrain/splat/mountains512.png"551 :fortress "Textures/Terrain/splat/fortress512.png"552 }type))553 heightmap (ImageBasedHeightMap.554 (ImageToAwt/convert (.getImage heightmap-image) false true 0))555 terrain (do (.load heightmap)556 (TerrainQuad. "my terrain" 65 513 (.getHeightMap heightmap)))557 ]559 (dorun (map #(.setWrap % Texture$WrapMode/Repeat)560 [grass dirt rock]))562 (doto mat_terrain563 (.setTexture "Tex1" grass)564 (.setFloat "Tex1Scale" (float 64))566 (.setTexture "Tex2" dirt)567 (.setFloat "Tex2Scale" (float 32))569 (.setTexture "Tex3" rock)570 (.setFloat "Tex3Scale" (float 128))572 (.setTexture "Alpha"573 (.loadTexture574 (asset-manager)575 ({:mountain "Textures/Terrain/splat/alphamap.png"576 :fortress "Textures/Terrain/splat/alphamap2.png"} type))))578 (doto terrain579 (.setMaterial mat_terrain)580 (.setLocalTranslation 0 -100 0)581 (.setLocalScale 2 1 2))))585 (defn run-terrain-game [type]586 (.start587 (world588 (Node.)589 {}590 (partial setup-fn type)591 no-op)))592 #+end_src596 #+srcname: hello-animation597 #+begin_src clojure :results silent598 (ns hello.animation)599 (use 'cortex.world)600 (use 'cortex.import)601 (use 'clojure.contrib.def)602 (cortex.import/mega-import-jme3)603 (rlm.rlm-commands/help)604 (use '[hello [collision :only [lights]]])606 (defn stand607 [channel]608 (doto channel609 (.setAnim "stand" (float 0.5))610 (.setLoopMode LoopMode/DontLoop)611 (.setSpeed (float 1))))613 (defn anim-listener []614 (proxy [AnimEventListener] []615 (onAnimChange616 [control channel animation-name]617 (println-repl "RLM --- onAnimChange"))618 (onAnimCycleDone619 [control channel animation-name]620 (if (= animation-name "Walk")621 (stand channel)622 ))))624 (defn setup-fn [channel game]625 (dorun (map #(.addLight (.getRootNode game) %) (lights)))626 ;; set the color of the sky627 (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1))628 ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1)629 (.setAnim channel "stand")630 (doto (.getFlyByCamera game)631 (.setMoveSpeed (float 10))632 (.setRotationSpeed 1)))634 (defn walk [channel]635 (println-repl "zzz")636 (doto channel637 (.setAnim "Walk" (float 0.5))638 (.setLoopMode LoopMode/Loop)))641 (defn key-map [channel]642 {"key-space" (fn [game value]643 (if (not value)644 (walk channel)))})646 (defn player []647 (let [model (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml")648 control (.getControl model AnimControl)]649 (.setLocalScale model (float 0.5))650 (.clearListeners control)651 (.addListener control (anim-control))652 model))656 (defn run-anim-game []657 (let [ninja (player)658 control (.getControl ninja AnimControl)659 channel (.createChannel control)]660 (.start661 (world662 ninja663 (key-map channel)664 (partial setup-fn channel)665 no-op))))666 #+end_src668 *** Hello Materials669 #+srcname: material670 #+begin_src clojure :results silent671 (ns hello.material)672 (use 'cortex.world)673 (use 'cortex.import)674 (use 'clojure.contrib.def)675 (cortex.import/mega-import-jme3)676 (rlm.rlm-commands/help)678 (defn simple-cube []679 (box 1 1 1680 :position (Vector3f. -3 1.1 0)681 :material "Common/MatDefs/Misc/Unshaded.j3md"682 :texture "Interface/Logo/Monkey.jpg"683 :physical? false))685 (defn leaky-box []686 (box 1 1 1687 :position (Vector3f. 3 -1 0)688 :material "Common/MatDefs/Misc/ColoredTextured.j3md"689 :texture "Textures/ColoredTex/Monkey.png"690 :color (ColorRGBA. 1 0 1 1)691 :physical? false))693 (defn transparent-box []694 (doto695 (box 1 1 0.1696 :position Vector3f/ZERO697 :name "window frame"698 :material "Common/MatDefs/Misc/Unshaded.j3md"699 :texture "Textures/ColoredTex/Monkey.png"700 :physical? false)701 (-> (.getMaterial)702 (.getAdditionalRenderState)703 (.setBlendMode RenderState$BlendMode/Alpha))704 (.setQueueBucket RenderQueue$Bucket/Transparent)))706 (defn bumpy-sphere []707 (doto708 (sphere 2709 :position (Vector3f. 0 2 -2)710 :name "Shiny rock"711 :material "Common/MatDefs/Light/Lighting.j3md"712 :texture false713 :physical? false)714 (-> (.getMesh)715 (doto716 (.setTextureMode Sphere$TextureMode/Projected)717 (TangentBinormalGenerator/generate)))718 (-> (.getMaterial)719 (doto720 (.setTexture "DiffuseMap" (.loadTexture (asset-manager)721 "Textures/Terrain/Pond/Pond.png"))722 (.setTexture "NormalMap" (.loadTexture (asset-manager)723 "Textures/Terrain/Pond/Pond_normal.png"))724 (.setFloat "Shininess" (float 5))))725 (.rotate (float 1.6) 0 0)))728 (defn start-game []729 (.start730 (world731 (let [root (Node.)]732 (dorun (map #(.attachChild root %)733 [(simple-cube) (leaky-box) (transparent-box) (bumpy-sphere)]))734 root)735 {}736 (fn [world]737 (let [sun (doto (DirectionalLight.)738 (.setDirection (.normalizeLocal (Vector3f. 1 0 -2)))739 (.setColor ColorRGBA/White))]740 (.addLight (.getRootNode world) sun)))741 no-op742 )))743 #+end_src747 * The Body748 ** Eyes750 Ultimately I want to make creatures with eyes. Each eye can be751 independely moved and should see its own version of the world752 depending on where it is.753 #+srcname: eyes754 #+begin_src clojure755 (ns body.eye)756 (use 'cortex.world)757 (use 'cortex.import)758 (use 'clojure.contrib.def)759 (cortex.import/mega-import-jme3)760 (rlm.rlm-commands/help)761 (import java.nio.ByteBuffer)762 (import java.awt.image.BufferedImage)763 (import java.awt.Color)764 (import java.awt.Dimension)765 (import java.awt.Graphics)766 (import java.awt.Graphics2D)767 (import java.awt.event.WindowAdapter)768 (import java.awt.event.WindowEvent)769 (import java.awt.image.BufferedImage)770 (import java.nio.ByteBuffer)771 (import javax.swing.JFrame)772 (import javax.swing.JPanel)773 (import javax.swing.SwingUtilities)774 (import javax.swing.ImageIcon)775 (import javax.swing.JOptionPane)776 (import java.awt.image.ImageObserver)780 (defn scene-processor781 "deals with converting FrameBuffers to BufferedImages so782 that the continuation function can be defined only in terms783 of what it does with BufferedImages"784 [continuation]785 (let [byte-buffer (atom nil)786 renderer (atom nil)787 image (atom nil)]788 (proxy [SceneProcessor] []789 (initialize790 [renderManager viewPort]791 (let [cam (.getCamera viewPort)792 width (.getWidth cam)793 height (.getHeight cam)]794 (reset! renderer (.getRenderer renderManager))795 (reset! byte-buffer796 (BufferUtils/createByteBuffer797 (* width height 4)))798 (reset! image (BufferedImage. width height799 BufferedImage/TYPE_4BYTE_ABGR))))800 (isInitialized [] (not (nil? @byte-buffer)))801 (reshape [_ _ _])802 (preFrame [_])803 (postQueue [_])804 (postFrame805 [#^FrameBuffer fb]806 (.clear @byte-buffer)807 (.readFrameBuffer @renderer fb @byte-buffer)808 (Screenshots/convertScreenShot @byte-buffer @image)809 (continuation @image))810 (cleanup []))))812 (defn add-eye813 "Add an eye to the world, and call continuation on814 every frame produced"815 [world camera continuation]816 (let [width (.getWidth camera)817 height (.getHeight camera)818 render-manager (.getRenderManager world)819 viewport (.createMainView render-manager "eye-view" camera)]820 (doto viewport821 (.setBackgroundColor ColorRGBA/Black)822 (.setClearFlags true true true)823 (.addProcessor (scene-processor continuation))824 (.attachScene (.getRootNode world)))))826 (defn make-display-frame [display width height]827 (SwingUtilities/invokeLater828 (fn []829 (.setPreferredSize display (Dimension. width height))830 (doto (JFrame. "Eye Camera!")831 (-> (.getContentPane) (.add display))832 (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)833 (.pack)834 (.setLocationRelativeTo nil)835 (.setResizable false)836 (.setVisible true)))))838 (defn image-monitor [#^BufferedImage image]839 (proxy [JPanel] []840 (paintComponent841 [g]842 (proxy-super paintComponent g)843 (locking image844 (.drawImage g image 0 0845 (proxy [ImageObserver]846 []847 (imageUpdate848 []849 (proxy-super imageUpdate))))))))851 (defn movie-image []852 (let [setup853 (runonce854 (fn [#^BufferedImage image]855 (let [width (.getWidth image)856 height (.getHeight image)857 display (image-monitor image)858 frame (make-display-frame display width height)]859 display)))]860 (fn [#^BufferedImage image]861 (.repaint (setup image)))))864 (defn observer865 "place thy eye!"866 [world camera]867 (let [eye camera868 width (.getWidth eye)869 height (.getHeight eye)]870 (no-exceptions871 (add-eye872 world873 eye874 (movie-image)))))875 #+end_src877 #+srcname: test-vision878 #+begin_src clojure880 (ns test.vision)881 (use 'cortex.world)882 (use 'cortex.import)883 (use 'clojure.contrib.def)884 (use 'body.eye)885 (cortex.import/mega-import-jme3)886 (rlm.rlm-commands/help)887 (import java.nio.ByteBuffer)888 (import java.awt.image.BufferedImage)889 (import java.awt.Color)890 (import java.awt.Dimension)891 (import java.awt.Graphics)892 (import java.awt.Graphics2D)893 (import java.awt.event.WindowAdapter)894 (import java.awt.event.WindowEvent)895 (import java.awt.image.BufferedImage)896 (import java.nio.ByteBuffer)897 (import javax.swing.JFrame)898 (import javax.swing.JPanel)899 (import javax.swing.SwingUtilities)900 (import javax.swing.ImageIcon)901 (import javax.swing.JOptionPane)902 (import java.awt.image.ImageObserver)905 (def width 200)906 (def height 200)908 (defn camera []909 (doto (Camera. width height)910 (.setFrustumPerspective 45 1 1 1000)911 (.setLocation (Vector3f. -3 0 -5))912 (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))914 (defn camera2 []915 (doto (Camera. width height)916 (.setFrustumPerspective 45 1 1 1000)917 (.setLocation (Vector3f. 3 0 -5))918 (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))920 (defn setup-fn [world]921 (let [eye (camera)922 width (.getWidth eye)923 height (.getHeight eye)]924 (no-exceptions925 (add-eye926 world927 eye928 (runonce visual))929 (add-eye930 world931 (camera2)932 (runonce visual)))))934 (defn spider-eye [position]935 (doto (Camera. 200 200 )936 (.setFrustumPerspective 45 1 1 1000)937 (.setLocation position)938 (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)))940 (defn setup-fn* [world]941 (let [eye (camera)942 width (.getWidth eye)943 height (.getHeight eye)]944 ;;(.setClearFlags (.getViewPort world) true true true)945 (observer world (.getCamera world))946 (observer world (spider-eye (Vector3f. 3 0 -5)))947 ;;(observer world (spider-eye (Vector3f. 0 0 -5)))948 ;; (observer world (spider-eye (Vector3f. -3 0 -5)))949 ;; (observer world (spider-eye (Vector3f. 0 3 -5)))950 ;; (observer world (spider-eye (Vector3f. 0 -3 -5)))951 ;; (observer world (spider-eye (Vector3f. 3 3 -5)))952 ;; (observer world (spider-eye (Vector3f. -3 3 -5)))953 ;; (observer world (spider-eye (Vector3f. 3 -3 -5)))954 ;; (observer world (spider-eye (Vector3f. -3 -3 -5)))956 )957 world)959 (defn test-world []960 (let [thing (box 1 1 1 :physical? false)]961 (world962 (doto (Node.)963 (.attachChild thing))964 {}965 setup-fn966 (fn [world tpf]967 (.rotate thing (* tpf 0.2) 0 0)968 ))))971 #+end_src974 #+results: eyes975 : #'body.eye/test-world977 Note the use of continuation passing style for connecting the eye to a978 function to process the output. The example code will create two979 videos of the same rotating cube from different angles, sutiable for980 stereoscopic vision.987 * COMMENT code generation988 #+begin_src clojure :tangle ../src/cortex/import.clj989 <<import>>990 #+end_src992 #+begin_src clojure :tangle ../src/hello/brick_wall.clj993 <<brick-wall-header>>994 <<brick-wall-body>>995 #+end_src997 #+begin_src clojure :tangle ../src/hello/hello_simple_app.clj998 <<hello-simple-app>>999 #+end_src1001 #+begin_src clojure :tangle ../src/cortex/world.clj1002 <<world-inputs>>1003 <<world>>1004 <<world-shapes>>1005 <<world-view>>1006 #+end_src1008 #+begin_src clojure :tangle ../src/cortex/other_games.clj1009 <<other-games>>1010 #+end_src1012 #+begin_src clojure :tangle ../src/hello/loop.clj1013 <<hello-loop>>1014 #+end_src1016 #+begin_src clojure :tangle ../src/hello/collision.clj1017 <<hello-collision>>1018 #+end_src1020 #+begin_src clojure :tangle ../src/hello/terrain.clj1021 <<hello-terrain>>1022 #+end_src1024 #+begin_src clojure :tangle ../src/hello/animation.clj1025 <<hello-animation>>1026 #+end_src1028 #+begin_src clojure :tangle ../src/hello/material.clj1029 <<material>>1030 #+end_src1032 #+begin_src clojure :tangle ../src/body/eye.clj1033 <<eyes>>1034 #+end_src1036 #+begin_src clojure :tangle ../src/test/vision.clj1037 <<test-vision>>1038 #+end_src