# HG changeset patch # User Robert McIntyre # Date 1319485438 25200 # Node ID 0206878c28b4af2dc72d2d70d4a2e8e8a821129f # Parent 6372c108c5c676c4b6bcac02c8d16ef84d17e6af going to start on games.org diff -r 6372c108c5c6 -r 0206878c28b4 org/cortex.org --- a/org/cortex.org Mon Oct 24 12:35:15 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,789 +0,0 @@ -#+title: Simulated Senses -#+author: Robert McIntyre -#+email: rlm@mit.edu -#+description: Simulating senses for AI research using JMonkeyEngine3 -#+SETUPFILE: ../../aurellem/org/setup.org -#+INCLUDE: ../../aurellem/org/level-0.org -#+babel: :mkdirp yes :noweb yes :exports both - - -* Simulation Base - - -** Hello -Here are the jmonkeyengine "Hello" programs translated to clojure. -*** Hello Simple App -Here is the hello world example for jme3 in clojure. It's a more or -less direct translation from the java source [[http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication][here]]. - -Of note is the fact that since we don't have access to the -=AssetManager= via extendig =SimpleApplication=, we have to build one -ourselves. - -#+srcname: hello-simple-app -#+begin_src clojure :results silent -(ns hello.hello-simple-app) -(require 'cortex.import) -(use 'clojure.contrib.def) -(rlm.rlm-commands/help) -(cortex.import/mega-import-jme3) -(use 'cortex.world) - - -(def cube (Box. Vector3f/ZERO 1 1 1)) - -(def geom (Geometry. "Box" cube)) - -(def mat (Material. (asset-manager) "Common/MatDefs/Misc/Unshaded.j3md")) - -(.setColor mat "Color" ColorRGBA/Blue) - -(.setMaterial geom mat) - -(defn simple-app [] - (doto - (proxy [SimpleApplication] [] - (simpleInitApp - [] - ;; Don't take control of the mouse - (org.lwjgl.input.Mouse/setGrabbed false) - (.attachChild (.getRootNode this) geom))) - ;; don't show a menu to change options. - (.setShowSettings false) - (.setPauseOnLostFocus false) - (.setSettings *app-settings*))) -#+end_src - -Running this program will begin a new jMonkeyEngine game which -displays a single blue cube. - -#+begin_src clojure :exports code :results silent -(.start (hello.hello-simple-app/simple-app)) -#+end_src - -#+caption: the simplest JME game. -[[./images/simple-app.jpg]] - - - -*** Hello Physics -From http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics - -#+srcname: brick-wall-header -#+begin_src clojure :results silent -(ns hello.brick-wall) -(require 'cortex.import) -(use 'clojure.contrib.def) -(rlm.rlm-commands/help) -(cortex.import/mega-import-jme3) -(use '[pokemon [lpsolve :only [constant-map]]]) -(use 'cortex.world) -(use 'cortex.util) -#+end_src - -#+srcname: brick-wall-body -#+begin_src clojure :results silent -(in-ns 'hello.brick-wall) - -(defn floor - "make a sturdy, unmovable physical floor" - [] - (box 20 1 20 :mass 0 :color false :position (Vector3f. 0 -2 0))) - -(def brick-length 0.48) -(def brick-width 0.24) -(def brick-height 0.12) - - -(defn brick* [position] - (doto (box brick-length brick-height brick-width - :position position :name "brick" - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/Terrain/BrickWall/BrickWall.jpg" - :mass 36) - (-> - (.getMesh) - (.scaleTextureCoordinates (Vector2f. 1 0.5))) - ;;(.setShadowMode RenderQueue$ShadowMode/CastAndReceive) - ) - ) - -(defn inception-brick-wall - "construct a physical brick wall" - [] - (let [node (Node. "brick-wall")] - (dorun - (map (comp #(.attachChild node %) brick*) - (for - [x (range 15) - y (range 10) - z (range 1)] - (Vector3f. - (* brick-length x 1.03) - (* brick-width y y 10) - (* brick-height z))))) - node)) - -(defn gravity-toggle - [new-value] - (fn [game value] - (println-repl "set gravity to " new-value) - (if value - (set-gravity* game new-value) - (set-gravity* game gravity)))) - -(defn fire-cannon-ball - ([node] - (fn [game value] - (if (not value) - (let [camera (.getCamera game) - cannon-ball - (sphere 0.7 - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/PokeCopper.jpg" - :position - (.add (.getLocation camera) - (.mult (.getDirection camera) (float 1))) - :mass 3)] ;200 0.05 - (.setShadowMode cannon-ball RenderQueue$ShadowMode/CastAndReceive) - (.setLinearVelocity - (.getControl cannon-ball RigidBodyControl) - (.mult (.getDirection camera) (float 50))) ;50 - (add-element game cannon-ball (if node node (.getRootNode game))))))) - ([] - (fire-cannon-ball false))) - - -(defn floor* [] - (doto (box 10 0.1 5 :name "floor" ;10 0.1 5 ; 240 0.1 240 - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/Terrain/Pond/Pond.png" - :position (Vector3f. 0 -0.1 0 ) - :mass 0) - (-> - (.getMesh) - (.scaleTextureCoordinates (Vector2f. 3 6)));64 64 - (-> - (.getMaterial) - (.getTextureParam "ColorMap") - (.getTextureValue) - (.setWrap Texture$WrapMode/Repeat)) - (.setShadowMode RenderQueue$ShadowMode/Receive) - )) - -(defn brick-wall* [] - (let [node (Node. "brick-wall")] - (dorun - (map - (comp #(.attachChild node %) brick*) - (for [y (range 15) - x (range 4) - z (range 1)] - (Vector3f. - (+ (* 2 x brick-length) - (if (even? (+ y z)) - (/ brick-length 4) (/ brick-length -4))) - (+ (* brick-height (inc (* 2 y)))) - (* 2 z brick-width) )))) - (.setShadowMode node RenderQueue$ShadowMode/CastAndReceive) - node)) - -(defn brick-wall-game-run [] - (doto - (world - (doto (Node.) (.attachChild (floor*)) - (.attachChild (brick-wall*)) - ) - {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81)) - "key-m" (gravity-toggle (Vector3f. 0 0 9.81)) - "key-l" (gravity-toggle (Vector3f. 9.81 0 0)) - "key-j" (gravity-toggle (Vector3f. -9.81 0 0)) - "key-k" (gravity-toggle Vector3f/ZERO) - "key-u" (gravity-toggle (Vector3f. 0 9.81 0)) - "key-o" (gravity-toggle (Vector3f. 0 -9.81 0)) - "key-f" (fn[game value] - (if (not value) (add-element game (brick-wall*)))) - "key-return" (fire-cannon-ball)} - position-camera - (fn [& _])) - (.start))) -#+end_src - -#+begin_src clojure :results silent -(hello.brick-wall/brick-wall-game-run) -#+end_src - -#+caption: the brick wall standing -[[./images/brick-wall-standing.jpg]] - -#+caption: the brick wall after it has been knocked over by a "pok\eacute{}ball" -[[./images/brick-wall-knocked-down.jpg]] - -*** Other Brick Games -#+srcname: other-games -#+begin_src clojure :results silent -(ns cortex.other-games - {:author "Dylan Holmes"}) -(use 'cortex.world) -(use 'hello.brick-wall) -(use 'cortex.import) -(cortex.import/mega-import-jme3) - -(defn scad [position] - (doto (box 0.1 0.1 0.1 - :position position :name "brick" - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/Terrain/BrickWall/BrickWall.jpg" - :mass 20) - (-> - (.getMesh) - (.scaleTextureCoordinates (Vector2f. 1 0.5)) - ) - (-> (.getControl RigidBodyControl) - (.setLinearVelocity (Vector3f. 0 100 0)) - ) - - ;;(.setShadowMode RenderQueue$ShadowMode/Cast) - )) - - -(defn shrapnel [] - (let [node (Node. "explosion-day")] - (dorun - (map - (comp #(.attachChild node %) scad) - (for [y (range 15) - x (range 4) - z (range 1)] - (Vector3f. - (+ (* 2 x brick-height) - (if (even? (+ y z)) (/ brick-height 4) (/ brick-height -4))) - (+ (* brick-height (inc (* 2 y)))) - (* 2 z brick-height) )))) - node)) - - -(def domino-height 0.48) -(def domino-thickness 0.12) -(def domino-width 0.24) - -(def domino-thickness 0.05) -(def domino-width 0.5) -(def domino-height 1) - -(defn domino - ([position] - (domino position (Quaternion/IDENTITY))) - ([position rotation] - (doto (box domino-width domino-height domino-thickness - :position position :name "domino" - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/Terrain/BrickWall/BrickWall.jpg" - :mass 1 - :rotation rotation) - (.setShadowMode RenderQueue$ShadowMode/CastAndReceive) - ))) - - -(defn domino-row [] - (let [node (Node. "domino-row")] - (dorun - (map - (comp #(.attachChild node %) domino) - (for [ - z (range 10) - x (range 5) - ] - (Vector3f. - (+ (* z domino-width) (* x 5 domino-width)) - (/ domino-height 1) - (* -5.5 domino-thickness z) )))) - - node)) - -(defn domino-cycle [] - (let [node (Node. "domino-cycle")] - (dorun - (map - (comp #(.attachChild node %) (partial apply domino) ) - (for [n (range 720)] - (let [space (* domino-height 5.5) - r (fn[n] (* (+ n 3) domino-width 0.5)) - t (fn[n] (reduce - + - (map - (fn dt[n] (/ space (* 2 (Math/PI) (r n)))) - (range n)))) - t (t n) - r (r n) - ct (Math/cos t) - st (Math/sin t) - ] - (list - (Vector3f. - (* -1 r st) - (/ domino-height 1) - (* r ct)) - (.fromAngleAxis (Quaternion.) - (- (/ 3.1415926 2) t) (Vector3f. 0 1 0)) - ))) - )) - node)) - - -(defn domino-game-run [] - (doto - (world - (doto (Node.) (.attachChild (floor*)) - ) - {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81)) - "key-m" (gravity-toggle (Vector3f. 0 0 9.81)) - "key-l" (gravity-toggle (Vector3f. 9.81 0 0)) - "key-j" (gravity-toggle (Vector3f. -9.81 0 0)) - "key-k" (gravity-toggle (Vector3f. 0 9.81 0) ) - "key-u" (fn[g v] ((gravity-toggle (Vector3f. 0 -0 0)) g true)) - "key-o" (gravity-toggle (Vector3f. 0 -9.81 0)) - - "key-space" - (fn[game value] - - (if (not value) - (let [d (domino (Vector3f. 0 (/ domino-height 0.25) 0) - (.fromAngleAxis (Quaternion.) - (/ Math/PI 2) (Vector3f. 0 1 0)))] - (add-element game d)))) - "key-f" - (fn[game value](if (not value) (add-element game (domino-cycle)))) - "key-return" (fire-cannon-ball)} - position-camera - (fn [& _])) - (.start))) -#+end_src - -#+begin_src clojure :results silent -(cortex.other-games/domino-game-run) -#+end_src - -#+caption: floating dominos -[[./images/dominos.jpg]] - -*** Hello Loop -#+srcname: hello-loop -#+begin_src clojure :results silent -(ns hello.loop) -(use 'cortex.world) -(use 'cortex.import) -(cortex.import/mega-import-jme3) -(rlm.rlm-commands/help) - -(defn blue-cube [] - (box 1 1 1 - :color ColorRGBA/Blue - :texture false - :material "Common/MatDefs/Misc/Unshaded.j3md" - :name "blue-cube" - :physical? false)) - -(defn blue-cube-game [] - (let [cube (blue-cube) - root (doto (Node.) (.attachChild cube))] - (world root - {} - no-op - (fn [game tpf] - (.rotate cube 0.0 (* 2 tpf) 0.0))))) -#+end_src - -*** Hello Collision - -#+srcname: hello-collision -#+begin_src clojure :results silent -(ns hello.collision) -(use 'cortex.world) -(use 'cortex.import) -(use 'clojure.contrib.def) - - -(cortex.import/mega-import-jme3) -(rlm.rlm-commands/help) -(use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]]) - - -(defn environment [] - (let - [scene-model - (doto - (.loadModel - (doto (asset-manager) - (.registerLocator - "/home/r/cortex/assets/zips/town.zip" ZipLocator)) - "main.scene") - (.setLocalScale (float 2.0))) - collision-shape - (CollisionShapeFactory/createMeshShape #^Node scene-model) - landscape (RigidBodyControl. collision-shape 0)] - (.setShadowMode scene-model RenderQueue$ShadowMode/CastAndReceive) - (.addControl scene-model landscape) - scene-model)) - -(defn player-fn [] - (doto - (CharacterControl. - (CapsuleCollisionShape. (float 1.5) (float 6)(float 1)) - (float 0.05)) - (.setJumpSpeed 20) - (.setFallSpeed 30) - (.setGravity 30) ;30 - (.setPhysicsLocation (Vector3f. 0 10 0)))) - -(defn lights [] - [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 1 1 1) (float 1)))) - (doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 0.7 0 1) (float 1)))) - (doto (DirectionalLight.) - (.setColor (.mult ColorRGBA/White (float 0.9) )) - (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))]) - -(defn night-lights [] - [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 0.275 0.467 0.784 1) (float 0.3)))) - (doto (DirectionalLight.) - (.setColor (.mult ColorRGBA/White (float 0.2) )) - (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))]) - -(def player (atom (player-fn))) - -(defn setup-fn [game] - (dorun (map #(.addLight (.getRootNode game) %) (lights))) - ;; set the color of the sky - (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1)) - ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1) - (doto (.getFlyByCamera game) - (.setMoveSpeed (float 100)) - (.setRotationSpeed 3)) - (.add - (.getPhysicsSpace - (.getState (.getStateManager game) BulletAppState)) - @player) - - (doto (Node.) (.attachChild (.getRootNode game)) - (.attachChild (brick-wall*)) - ) - -) - - -(def walking-up? (atom false)) -(def walking-down? (atom false)) -(def walking-left? (atom false)) -(def walking-right? (atom false)) - -(defn set-walk [walk-atom game value] - ;;(println-repl "setting stuff to " value) - (reset! walk-atom value)) - -(defn responses [] - {"key-w" (partial set-walk walking-up?) - "key-d" (partial set-walk walking-right?) - "key-s" (partial set-walk walking-down?) - "key-a" (partial set-walk walking-left?) - "key-return" (fire-cannon-ball) - "key-space" (fn [game value] (.jump @player)) - }) - -(defn update-fn - [game tpf] - (let [camera (.getCamera game) - cam-dir (.multLocal - (.clone - (.getDirection camera)) (float 0.6)) - cam-left (.multLocal - (.clone - (.getLeft camera)) (float 0.4)) - walk-direction (Vector3f. 0 0 0)] - - (cond - @walking-up? (.addLocal walk-direction cam-dir) - @walking-right? (.addLocal walk-direction (.negate cam-left)) - @walking-down? (.addLocal walk-direction (.negate cam-dir)) - @walking-left? (.addLocal walk-direction cam-left)) - (.setWalkDirection @player walk-direction) - (.setLocation camera (.getPhysicsLocation @player)))) - -(defn run-game [] - (.start - (world (environment) - (responses) - setup-fn - update-fn))) -#+end_src - -*** Hello Terrain -#+srcname: hello-terrain -#+begin_src clojure :results silent -(ns hello.terrain) -(use 'cortex.world) -(use 'cortex.import) -(use 'clojure.contrib.def) -(import jme3tools.converters.ImageToAwt) - - -(cortex.import/mega-import-jme3) -(rlm.rlm-commands/help) -(use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]]) - - -(defn setup-fn [type game] - (.setMoveSpeed (.getFlyByCamera game) 50) - (.setFrustumFar (.getCamera game) 10000) - (let [env (environment type) - cameras [(.getCamera game)] - control (TerrainLodControl. env cameras)] - ;;(.addControl env control) - (.attachChild (.getRootNode game) env))) - -(defn environment [type] - (let - [mat_terrain - (Material. (asset-manager) "Common/MatDefs/Terrain/Terrain.j3md") - grass (.loadTexture (asset-manager) "Textures/Terrain/splat/grass.jpg") - dirt (.loadTexture (asset-manager) "Textures/Terrain/splat/dirt.jpg") - rock (.loadTexture (asset-manager) "Textures/Terrain/splat/road.jpg") - heightmap-image (.loadTexture (asset-manager) - ({:mountain "Textures/Terrain/splat/mountains512.png" - :fortress "Textures/Terrain/splat/fortress512.png" - }type)) - heightmap (ImageBasedHeightMap. - (ImageToAwt/convert (.getImage heightmap-image) false true 0)) - terrain (do (.load heightmap) - (TerrainQuad. "my terrain" 65 513 (.getHeightMap heightmap))) - ] - - (dorun (map #(.setWrap % Texture$WrapMode/Repeat) - [grass dirt rock])) - - (doto mat_terrain - (.setTexture "Tex1" grass) - (.setFloat "Tex1Scale" (float 64)) - - (.setTexture "Tex2" dirt) - (.setFloat "Tex2Scale" (float 32)) - - (.setTexture "Tex3" rock) - (.setFloat "Tex3Scale" (float 128)) - - (.setTexture "Alpha" - (.loadTexture - (asset-manager) - ({:mountain "Textures/Terrain/splat/alphamap.png" - :fortress "Textures/Terrain/splat/alphamap2.png"} type)))) - - (doto terrain - (.setMaterial mat_terrain) - (.setLocalTranslation 0 -100 0) - (.setLocalScale 2 1 2)))) - - - -(defn run-terrain-game [type] - (.start - (world - (Node.) - {} - (partial setup-fn type) - no-op))) -#+end_src - - - -#+srcname: hello-animation -#+begin_src clojure :results silent -(ns hello.animation) -(use 'cortex.world) -(use 'cortex.import) -(use 'clojure.contrib.def) -(cortex.import/mega-import-jme3) -(rlm.rlm-commands/help) -(use '[hello [collision :only [lights]]]) - -(defn stand - [channel] - (doto channel - (.setAnim "stand" (float 0.5)) - (.setLoopMode LoopMode/DontLoop) - (.setSpeed (float 1)))) - -(defn anim-listener [] - (proxy [AnimEventListener] [] - (onAnimChange - [control channel animation-name] - (println-repl "RLM --- onAnimChange")) - (onAnimCycleDone - [control channel animation-name] - (if (= animation-name "Walk") - (stand channel) - )))) - -(defn setup-fn [channel game] - (dorun (map #(.addLight (.getRootNode game) %) (lights))) - ;; set the color of the sky - (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1)) - ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1) - (.setAnim channel "stand") - (doto (.getFlyByCamera game) - (.setMoveSpeed (float 10)) - (.setRotationSpeed 1))) - -(defn walk [channel] - (println-repl "zzz") - (doto channel - (.setAnim "Walk" (float 0.5)) - (.setLoopMode LoopMode/Loop))) - - -(defn key-map [channel] - {"key-space" (fn [game value] - (if (not value) - (walk channel)))}) - -(defn player [] - (let [model (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml") - control (.getControl model AnimControl)] - (.setLocalScale model (float 0.5)) - (.clearListeners control) - (.addListener control (anim-control)) - model)) - - - -(defn run-anim-game [] - (let [ninja (player) - control (.getControl ninja AnimControl) - channel (.createChannel control)] - (.start - (world - ninja - (key-map channel) - (partial setup-fn channel) - no-op)))) -#+end_src - -*** Hello Materials -#+srcname: material -#+begin_src clojure :results silent -(ns hello.material) -(use 'cortex.world) -(use 'cortex.import) -(use 'clojure.contrib.def) -(cortex.import/mega-import-jme3) -(rlm.rlm-commands/help) - -(defn simple-cube [] - (box 1 1 1 - :position (Vector3f. -3 1.1 0) - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Interface/Logo/Monkey.jpg" - :physical? false)) - -(defn leaky-box [] - (box 1 1 1 - :position (Vector3f. 3 -1 0) - :material "Common/MatDefs/Misc/ColoredTextured.j3md" - :texture "Textures/ColoredTex/Monkey.png" - :color (ColorRGBA. 1 0 1 1) - :physical? false)) - -(defn transparent-box [] - (doto - (box 1 1 0.1 - :position Vector3f/ZERO - :name "window frame" - :material "Common/MatDefs/Misc/Unshaded.j3md" - :texture "Textures/ColoredTex/Monkey.png" - :physical? false) - (-> (.getMaterial) - (.getAdditionalRenderState) - (.setBlendMode RenderState$BlendMode/Alpha)) - (.setQueueBucket RenderQueue$Bucket/Transparent))) - -(defn bumpy-sphere [] - (doto - (sphere 2 - :position (Vector3f. 0 2 -2) - :name "Shiny rock" - :material "Common/MatDefs/Light/Lighting.j3md" - :texture false - :physical? false) - (-> (.getMesh) - (doto - (.setTextureMode Sphere$TextureMode/Projected) - (TangentBinormalGenerator/generate))) - (-> (.getMaterial) - (doto - (.setTexture "DiffuseMap" (.loadTexture (asset-manager) - "Textures/Terrain/Pond/Pond.png")) - (.setTexture "NormalMap" (.loadTexture (asset-manager) - "Textures/Terrain/Pond/Pond_normal.png")) - (.setFloat "Shininess" (float 5)))) - (.rotate (float 1.6) 0 0))) - - -(defn start-game [] - (.start - (world - (let [root (Node.)] - (dorun (map #(.attachChild root %) - [(simple-cube) (leaky-box) (transparent-box) (bumpy-sphere)])) - root) - {} - (fn [world] - (let [sun (doto (DirectionalLight.) - (.setDirection (.normalizeLocal (Vector3f. 1 0 -2))) - (.setColor ColorRGBA/White))] - (.addLight (.getRootNode world) sun))) - no-op - ))) -#+end_src - - - -* COMMENT code generation - -#+begin_src clojure :tangle ../src/hello/brick_wall.clj -<> -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/hello_simple_app.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/cortex/other_games.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/loop.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/collision.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/terrain.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/animation.clj -<> -#+end_src - -#+begin_src clojure :tangle ../src/hello/material.clj -<> -#+end_src - - - - - - - - diff -r 6372c108c5c6 -r 0206878c28b4 org/games.org --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org/games.org Mon Oct 24 12:43:58 2011 -0700 @@ -0,0 +1,789 @@ +#+title: Simulated Senses +#+author: Robert McIntyre +#+email: rlm@mit.edu +#+description: Simulating senses for AI research using JMonkeyEngine3 +#+SETUPFILE: ../../aurellem/org/setup.org +#+INCLUDE: ../../aurellem/org/level-0.org +#+babel: :mkdirp yes :noweb yes :exports both + + +* Simulation Base + + +** Hello +Here are the jmonkeyengine "Hello" programs translated to clojure. +*** Hello Simple App +Here is the hello world example for jme3 in clojure. It's a more or +less direct translation from the java source [[http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication][here]]. + +Of note is the fact that since we don't have access to the +=AssetManager= via extendig =SimpleApplication=, we have to build one +ourselves. + +#+srcname: hello-simple-app +#+begin_src clojure :results silent +(ns hello.hello-simple-app) +(require 'cortex.import) +(use 'clojure.contrib.def) +(rlm.rlm-commands/help) +(cortex.import/mega-import-jme3) +(use 'cortex.world) + + +(def cube (Box. Vector3f/ZERO 1 1 1)) + +(def geom (Geometry. "Box" cube)) + +(def mat (Material. (asset-manager) "Common/MatDefs/Misc/Unshaded.j3md")) + +(.setColor mat "Color" ColorRGBA/Blue) + +(.setMaterial geom mat) + +(defn simple-app [] + (doto + (proxy [SimpleApplication] [] + (simpleInitApp + [] + ;; Don't take control of the mouse + (org.lwjgl.input.Mouse/setGrabbed false) + (.attachChild (.getRootNode this) geom))) + ;; don't show a menu to change options. + (.setShowSettings false) + (.setPauseOnLostFocus false) + (.setSettings *app-settings*))) +#+end_src + +Running this program will begin a new jMonkeyEngine game which +displays a single blue cube. + +#+begin_src clojure :exports code :results silent +(.start (hello.hello-simple-app/simple-app)) +#+end_src + +#+caption: the simplest JME game. +[[./images/simple-app.jpg]] + + + +*** Hello Physics +From http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics + +#+srcname: brick-wall-header +#+begin_src clojure :results silent +(ns hello.brick-wall) +(require 'cortex.import) +(use 'clojure.contrib.def) +(rlm.rlm-commands/help) +(cortex.import/mega-import-jme3) +(use '[pokemon [lpsolve :only [constant-map]]]) +(use 'cortex.world) +(use 'cortex.util) +#+end_src + +#+srcname: brick-wall-body +#+begin_src clojure :results silent +(in-ns 'hello.brick-wall) + +(defn floor + "make a sturdy, unmovable physical floor" + [] + (box 20 1 20 :mass 0 :color false :position (Vector3f. 0 -2 0))) + +(def brick-length 0.48) +(def brick-width 0.24) +(def brick-height 0.12) + + +(defn brick* [position] + (doto (box brick-length brick-height brick-width + :position position :name "brick" + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/Terrain/BrickWall/BrickWall.jpg" + :mass 36) + (-> + (.getMesh) + (.scaleTextureCoordinates (Vector2f. 1 0.5))) + ;;(.setShadowMode RenderQueue$ShadowMode/CastAndReceive) + ) + ) + +(defn inception-brick-wall + "construct a physical brick wall" + [] + (let [node (Node. "brick-wall")] + (dorun + (map (comp #(.attachChild node %) brick*) + (for + [x (range 15) + y (range 10) + z (range 1)] + (Vector3f. + (* brick-length x 1.03) + (* brick-width y y 10) + (* brick-height z))))) + node)) + +(defn gravity-toggle + [new-value] + (fn [game value] + (println-repl "set gravity to " new-value) + (if value + (set-gravity* game new-value) + (set-gravity* game gravity)))) + +(defn fire-cannon-ball + ([node] + (fn [game value] + (if (not value) + (let [camera (.getCamera game) + cannon-ball + (sphere 0.7 + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/PokeCopper.jpg" + :position + (.add (.getLocation camera) + (.mult (.getDirection camera) (float 1))) + :mass 3)] ;200 0.05 + (.setShadowMode cannon-ball RenderQueue$ShadowMode/CastAndReceive) + (.setLinearVelocity + (.getControl cannon-ball RigidBodyControl) + (.mult (.getDirection camera) (float 50))) ;50 + (add-element game cannon-ball (if node node (.getRootNode game))))))) + ([] + (fire-cannon-ball false))) + + +(defn floor* [] + (doto (box 10 0.1 5 :name "floor" ;10 0.1 5 ; 240 0.1 240 + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/Terrain/Pond/Pond.png" + :position (Vector3f. 0 -0.1 0 ) + :mass 0) + (-> + (.getMesh) + (.scaleTextureCoordinates (Vector2f. 3 6)));64 64 + (-> + (.getMaterial) + (.getTextureParam "ColorMap") + (.getTextureValue) + (.setWrap Texture$WrapMode/Repeat)) + (.setShadowMode RenderQueue$ShadowMode/Receive) + )) + +(defn brick-wall* [] + (let [node (Node. "brick-wall")] + (dorun + (map + (comp #(.attachChild node %) brick*) + (for [y (range 15) + x (range 4) + z (range 1)] + (Vector3f. + (+ (* 2 x brick-length) + (if (even? (+ y z)) + (/ brick-length 4) (/ brick-length -4))) + (+ (* brick-height (inc (* 2 y)))) + (* 2 z brick-width) )))) + (.setShadowMode node RenderQueue$ShadowMode/CastAndReceive) + node)) + +(defn brick-wall-game-run [] + (doto + (world + (doto (Node.) (.attachChild (floor*)) + (.attachChild (brick-wall*)) + ) + {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81)) + "key-m" (gravity-toggle (Vector3f. 0 0 9.81)) + "key-l" (gravity-toggle (Vector3f. 9.81 0 0)) + "key-j" (gravity-toggle (Vector3f. -9.81 0 0)) + "key-k" (gravity-toggle Vector3f/ZERO) + "key-u" (gravity-toggle (Vector3f. 0 9.81 0)) + "key-o" (gravity-toggle (Vector3f. 0 -9.81 0)) + "key-f" (fn[game value] + (if (not value) (add-element game (brick-wall*)))) + "key-return" (fire-cannon-ball)} + position-camera + (fn [& _])) + (.start))) +#+end_src + +#+begin_src clojure :results silent +(hello.brick-wall/brick-wall-game-run) +#+end_src + +#+caption: the brick wall standing +[[./images/brick-wall-standing.jpg]] + +#+caption: the brick wall after it has been knocked over by a "pok\eacute{}ball" +[[./images/brick-wall-knocked-down.jpg]] + +*** Other Brick Games +#+srcname: other-games +#+begin_src clojure :results silent +(ns cortex.other-games + {:author "Dylan Holmes"}) +(use 'cortex.world) +(use 'hello.brick-wall) +(use 'cortex.import) +(cortex.import/mega-import-jme3) + +(defn scad [position] + (doto (box 0.1 0.1 0.1 + :position position :name "brick" + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/Terrain/BrickWall/BrickWall.jpg" + :mass 20) + (-> + (.getMesh) + (.scaleTextureCoordinates (Vector2f. 1 0.5)) + ) + (-> (.getControl RigidBodyControl) + (.setLinearVelocity (Vector3f. 0 100 0)) + ) + + ;;(.setShadowMode RenderQueue$ShadowMode/Cast) + )) + + +(defn shrapnel [] + (let [node (Node. "explosion-day")] + (dorun + (map + (comp #(.attachChild node %) scad) + (for [y (range 15) + x (range 4) + z (range 1)] + (Vector3f. + (+ (* 2 x brick-height) + (if (even? (+ y z)) (/ brick-height 4) (/ brick-height -4))) + (+ (* brick-height (inc (* 2 y)))) + (* 2 z brick-height) )))) + node)) + + +(def domino-height 0.48) +(def domino-thickness 0.12) +(def domino-width 0.24) + +(def domino-thickness 0.05) +(def domino-width 0.5) +(def domino-height 1) + +(defn domino + ([position] + (domino position (Quaternion/IDENTITY))) + ([position rotation] + (doto (box domino-width domino-height domino-thickness + :position position :name "domino" + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/Terrain/BrickWall/BrickWall.jpg" + :mass 1 + :rotation rotation) + (.setShadowMode RenderQueue$ShadowMode/CastAndReceive) + ))) + + +(defn domino-row [] + (let [node (Node. "domino-row")] + (dorun + (map + (comp #(.attachChild node %) domino) + (for [ + z (range 10) + x (range 5) + ] + (Vector3f. + (+ (* z domino-width) (* x 5 domino-width)) + (/ domino-height 1) + (* -5.5 domino-thickness z) )))) + + node)) + +(defn domino-cycle [] + (let [node (Node. "domino-cycle")] + (dorun + (map + (comp #(.attachChild node %) (partial apply domino) ) + (for [n (range 720)] + (let [space (* domino-height 5.5) + r (fn[n] (* (+ n 3) domino-width 0.5)) + t (fn[n] (reduce + + + (map + (fn dt[n] (/ space (* 2 (Math/PI) (r n)))) + (range n)))) + t (t n) + r (r n) + ct (Math/cos t) + st (Math/sin t) + ] + (list + (Vector3f. + (* -1 r st) + (/ domino-height 1) + (* r ct)) + (.fromAngleAxis (Quaternion.) + (- (/ 3.1415926 2) t) (Vector3f. 0 1 0)) + ))) + )) + node)) + + +(defn domino-game-run [] + (doto + (world + (doto (Node.) (.attachChild (floor*)) + ) + {"key-i" (gravity-toggle (Vector3f. 0 0 -9.81)) + "key-m" (gravity-toggle (Vector3f. 0 0 9.81)) + "key-l" (gravity-toggle (Vector3f. 9.81 0 0)) + "key-j" (gravity-toggle (Vector3f. -9.81 0 0)) + "key-k" (gravity-toggle (Vector3f. 0 9.81 0) ) + "key-u" (fn[g v] ((gravity-toggle (Vector3f. 0 -0 0)) g true)) + "key-o" (gravity-toggle (Vector3f. 0 -9.81 0)) + + "key-space" + (fn[game value] + + (if (not value) + (let [d (domino (Vector3f. 0 (/ domino-height 0.25) 0) + (.fromAngleAxis (Quaternion.) + (/ Math/PI 2) (Vector3f. 0 1 0)))] + (add-element game d)))) + "key-f" + (fn[game value](if (not value) (add-element game (domino-cycle)))) + "key-return" (fire-cannon-ball)} + position-camera + (fn [& _])) + (.start))) +#+end_src + +#+begin_src clojure :results silent +(cortex.other-games/domino-game-run) +#+end_src + +#+caption: floating dominos +[[./images/dominos.jpg]] + +*** Hello Loop +#+srcname: hello-loop +#+begin_src clojure :results silent +(ns hello.loop) +(use 'cortex.world) +(use 'cortex.import) +(cortex.import/mega-import-jme3) +(rlm.rlm-commands/help) + +(defn blue-cube [] + (box 1 1 1 + :color ColorRGBA/Blue + :texture false + :material "Common/MatDefs/Misc/Unshaded.j3md" + :name "blue-cube" + :physical? false)) + +(defn blue-cube-game [] + (let [cube (blue-cube) + root (doto (Node.) (.attachChild cube))] + (world root + {} + no-op + (fn [game tpf] + (.rotate cube 0.0 (* 2 tpf) 0.0))))) +#+end_src + +*** Hello Collision + +#+srcname: hello-collision +#+begin_src clojure :results silent +(ns hello.collision) +(use 'cortex.world) +(use 'cortex.import) +(use 'clojure.contrib.def) + + +(cortex.import/mega-import-jme3) +(rlm.rlm-commands/help) +(use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]]) + + +(defn environment [] + (let + [scene-model + (doto + (.loadModel + (doto (asset-manager) + (.registerLocator + "/home/r/cortex/assets/zips/town.zip" ZipLocator)) + "main.scene") + (.setLocalScale (float 2.0))) + collision-shape + (CollisionShapeFactory/createMeshShape #^Node scene-model) + landscape (RigidBodyControl. collision-shape 0)] + (.setShadowMode scene-model RenderQueue$ShadowMode/CastAndReceive) + (.addControl scene-model landscape) + scene-model)) + +(defn player-fn [] + (doto + (CharacterControl. + (CapsuleCollisionShape. (float 1.5) (float 6)(float 1)) + (float 0.05)) + (.setJumpSpeed 20) + (.setFallSpeed 30) + (.setGravity 30) ;30 + (.setPhysicsLocation (Vector3f. 0 10 0)))) + +(defn lights [] + [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 1 1 1) (float 1)))) + (doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 1 0.7 0 1) (float 1)))) + (doto (DirectionalLight.) + (.setColor (.mult ColorRGBA/White (float 0.9) )) + (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))]) + +(defn night-lights [] + [(doto (AmbientLight.) (.setColor (.mult (ColorRGBA. 0.275 0.467 0.784 1) (float 0.3)))) + (doto (DirectionalLight.) + (.setColor (.mult ColorRGBA/White (float 0.2) )) + (.setDirection (.normalizeLocal (Vector3f. 2.8 -28 2.8))))]) + +(def player (atom (player-fn))) + +(defn setup-fn [game] + (dorun (map #(.addLight (.getRootNode game) %) (lights))) + ;; set the color of the sky + (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1)) + ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1) + (doto (.getFlyByCamera game) + (.setMoveSpeed (float 100)) + (.setRotationSpeed 3)) + (.add + (.getPhysicsSpace + (.getState (.getStateManager game) BulletAppState)) + @player) + + (doto (Node.) (.attachChild (.getRootNode game)) + (.attachChild (brick-wall*)) + ) + +) + + +(def walking-up? (atom false)) +(def walking-down? (atom false)) +(def walking-left? (atom false)) +(def walking-right? (atom false)) + +(defn set-walk [walk-atom game value] + ;;(println-repl "setting stuff to " value) + (reset! walk-atom value)) + +(defn responses [] + {"key-w" (partial set-walk walking-up?) + "key-d" (partial set-walk walking-right?) + "key-s" (partial set-walk walking-down?) + "key-a" (partial set-walk walking-left?) + "key-return" (fire-cannon-ball) + "key-space" (fn [game value] (.jump @player)) + }) + +(defn update-fn + [game tpf] + (let [camera (.getCamera game) + cam-dir (.multLocal + (.clone + (.getDirection camera)) (float 0.6)) + cam-left (.multLocal + (.clone + (.getLeft camera)) (float 0.4)) + walk-direction (Vector3f. 0 0 0)] + + (cond + @walking-up? (.addLocal walk-direction cam-dir) + @walking-right? (.addLocal walk-direction (.negate cam-left)) + @walking-down? (.addLocal walk-direction (.negate cam-dir)) + @walking-left? (.addLocal walk-direction cam-left)) + (.setWalkDirection @player walk-direction) + (.setLocation camera (.getPhysicsLocation @player)))) + +(defn run-game [] + (.start + (world (environment) + (responses) + setup-fn + update-fn))) +#+end_src + +*** Hello Terrain +#+srcname: hello-terrain +#+begin_src clojure :results silent +(ns hello.terrain) +(use 'cortex.world) +(use 'cortex.import) +(use 'clojure.contrib.def) +(import jme3tools.converters.ImageToAwt) + + +(cortex.import/mega-import-jme3) +(rlm.rlm-commands/help) +(use '[hello [brick-wall :only [fire-cannon-ball brick-wall*]]]) + + +(defn setup-fn [type game] + (.setMoveSpeed (.getFlyByCamera game) 50) + (.setFrustumFar (.getCamera game) 10000) + (let [env (environment type) + cameras [(.getCamera game)] + control (TerrainLodControl. env cameras)] + ;;(.addControl env control) + (.attachChild (.getRootNode game) env))) + +(defn environment [type] + (let + [mat_terrain + (Material. (asset-manager) "Common/MatDefs/Terrain/Terrain.j3md") + grass (.loadTexture (asset-manager) "Textures/Terrain/splat/grass.jpg") + dirt (.loadTexture (asset-manager) "Textures/Terrain/splat/dirt.jpg") + rock (.loadTexture (asset-manager) "Textures/Terrain/splat/road.jpg") + heightmap-image (.loadTexture (asset-manager) + ({:mountain "Textures/Terrain/splat/mountains512.png" + :fortress "Textures/Terrain/splat/fortress512.png" + }type)) + heightmap (ImageBasedHeightMap. + (ImageToAwt/convert (.getImage heightmap-image) false true 0)) + terrain (do (.load heightmap) + (TerrainQuad. "my terrain" 65 513 (.getHeightMap heightmap))) + ] + + (dorun (map #(.setWrap % Texture$WrapMode/Repeat) + [grass dirt rock])) + + (doto mat_terrain + (.setTexture "Tex1" grass) + (.setFloat "Tex1Scale" (float 64)) + + (.setTexture "Tex2" dirt) + (.setFloat "Tex2Scale" (float 32)) + + (.setTexture "Tex3" rock) + (.setFloat "Tex3Scale" (float 128)) + + (.setTexture "Alpha" + (.loadTexture + (asset-manager) + ({:mountain "Textures/Terrain/splat/alphamap.png" + :fortress "Textures/Terrain/splat/alphamap2.png"} type)))) + + (doto terrain + (.setMaterial mat_terrain) + (.setLocalTranslation 0 -100 0) + (.setLocalScale 2 1 2)))) + + + +(defn run-terrain-game [type] + (.start + (world + (Node.) + {} + (partial setup-fn type) + no-op))) +#+end_src + + + +#+srcname: hello-animation +#+begin_src clojure :results silent +(ns hello.animation) +(use 'cortex.world) +(use 'cortex.import) +(use 'clojure.contrib.def) +(cortex.import/mega-import-jme3) +(rlm.rlm-commands/help) +(use '[hello [collision :only [lights]]]) + +(defn stand + [channel] + (doto channel + (.setAnim "stand" (float 0.5)) + (.setLoopMode LoopMode/DontLoop) + (.setSpeed (float 1)))) + +(defn anim-listener [] + (proxy [AnimEventListener] [] + (onAnimChange + [control channel animation-name] + (println-repl "RLM --- onAnimChange")) + (onAnimCycleDone + [control channel animation-name] + (if (= animation-name "Walk") + (stand channel) + )))) + +(defn setup-fn [channel game] + (dorun (map #(.addLight (.getRootNode game) %) (lights))) + ;; set the color of the sky + (.setBackgroundColor (.getViewPort game) (ColorRGBA. 0.3 0.4 0.9 1)) + ;(.setBackgroundColor (.getViewPort game) (ColorRGBA. 0 0 0 1) + (.setAnim channel "stand") + (doto (.getFlyByCamera game) + (.setMoveSpeed (float 10)) + (.setRotationSpeed 1))) + +(defn walk [channel] + (println-repl "zzz") + (doto channel + (.setAnim "Walk" (float 0.5)) + (.setLoopMode LoopMode/Loop))) + + +(defn key-map [channel] + {"key-space" (fn [game value] + (if (not value) + (walk channel)))}) + +(defn player [] + (let [model (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml") + control (.getControl model AnimControl)] + (.setLocalScale model (float 0.5)) + (.clearListeners control) + (.addListener control (anim-control)) + model)) + + + +(defn run-anim-game [] + (let [ninja (player) + control (.getControl ninja AnimControl) + channel (.createChannel control)] + (.start + (world + ninja + (key-map channel) + (partial setup-fn channel) + no-op)))) +#+end_src + +*** Hello Materials +#+srcname: material +#+begin_src clojure :results silent +(ns hello.material) +(use 'cortex.world) +(use 'cortex.import) +(use 'clojure.contrib.def) +(cortex.import/mega-import-jme3) +(rlm.rlm-commands/help) + +(defn simple-cube [] + (box 1 1 1 + :position (Vector3f. -3 1.1 0) + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Interface/Logo/Monkey.jpg" + :physical? false)) + +(defn leaky-box [] + (box 1 1 1 + :position (Vector3f. 3 -1 0) + :material "Common/MatDefs/Misc/ColoredTextured.j3md" + :texture "Textures/ColoredTex/Monkey.png" + :color (ColorRGBA. 1 0 1 1) + :physical? false)) + +(defn transparent-box [] + (doto + (box 1 1 0.1 + :position Vector3f/ZERO + :name "window frame" + :material "Common/MatDefs/Misc/Unshaded.j3md" + :texture "Textures/ColoredTex/Monkey.png" + :physical? false) + (-> (.getMaterial) + (.getAdditionalRenderState) + (.setBlendMode RenderState$BlendMode/Alpha)) + (.setQueueBucket RenderQueue$Bucket/Transparent))) + +(defn bumpy-sphere [] + (doto + (sphere 2 + :position (Vector3f. 0 2 -2) + :name "Shiny rock" + :material "Common/MatDefs/Light/Lighting.j3md" + :texture false + :physical? false) + (-> (.getMesh) + (doto + (.setTextureMode Sphere$TextureMode/Projected) + (TangentBinormalGenerator/generate))) + (-> (.getMaterial) + (doto + (.setTexture "DiffuseMap" (.loadTexture (asset-manager) + "Textures/Terrain/Pond/Pond.png")) + (.setTexture "NormalMap" (.loadTexture (asset-manager) + "Textures/Terrain/Pond/Pond_normal.png")) + (.setFloat "Shininess" (float 5)))) + (.rotate (float 1.6) 0 0))) + + +(defn start-game [] + (.start + (world + (let [root (Node.)] + (dorun (map #(.attachChild root %) + [(simple-cube) (leaky-box) (transparent-box) (bumpy-sphere)])) + root) + {} + (fn [world] + (let [sun (doto (DirectionalLight.) + (.setDirection (.normalizeLocal (Vector3f. 1 0 -2))) + (.setColor ColorRGBA/White))] + (.addLight (.getRootNode world) sun))) + no-op + ))) +#+end_src + + + +* COMMENT code generation + +#+begin_src clojure :tangle ../src/hello/brick_wall.clj +<> +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/hello_simple_app.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/cortex/other_games.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/loop.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/collision.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/terrain.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/animation.clj +<> +#+end_src + +#+begin_src clojure :tangle ../src/hello/material.clj +<> +#+end_src + + + + + + + + diff -r 6372c108c5c6 -r 0206878c28b4 org/util.org --- a/org/util.org Mon Oct 24 12:35:15 2011 -0700 +++ b/org/util.org Mon Oct 24 12:43:58 2011 -0700 @@ -291,8 +291,6 @@ #+end_src - - * COMMENT code generation #+begin_src clojure :tangle ../src/cortex/import.clj <>