changeset 29:6372c108c5c6

cleaned up util.org
author Robert McIntyre <rlm@mit.edu>
date Mon, 24 Oct 2011 12:35:15 -0700
parents 122f12f81dc1
children 0206878c28b4
files org/cortex.org org/intro.org org/skin.org org/util.org org/world.org
diffstat 5 files changed, 210 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/org/cortex.org	Mon Oct 24 07:36:04 2011 -0700
     1.2 +++ b/org/cortex.org	Mon Oct 24 12:35:15 2011 -0700
     1.3 @@ -783,3 +783,7 @@
     1.4  
     1.5    
     1.6  
     1.7 +
     1.8 +
     1.9 +
    1.10 +
     2.1 --- a/org/intro.org	Mon Oct 24 07:36:04 2011 -0700
     2.2 +++ b/org/intro.org	Mon Oct 24 12:35:15 2011 -0700
     2.3 @@ -173,3 +173,34 @@
     2.4  because it had the most features out of all the open projects I looked
     2.5  at, and because I could then write my code in Clojure, an
     2.6  implementation of LISP that runs on the JVM...
     2.7 +
     2.8 +
     2.9 +
    2.10 +
    2.11 +
    2.12 +
    2.13 +
    2.14 +
    2.15 +
    2.16 +
    2.17 +
    2.18 +
    2.19 +
    2.20 +
    2.21 +
    2.22 +
    2.23 +
    2.24 +
    2.25 +
    2.26 +
    2.27 +
    2.28 +
    2.29 +
    2.30 +
    2.31 +
    2.32 +
    2.33 +
    2.34 +
    2.35 +
    2.36 +
    2.37 +
     3.1 --- a/org/skin.org	Mon Oct 24 07:36:04 2011 -0700
     3.2 +++ b/org/skin.org	Mon Oct 24 12:35:15 2011 -0700
     3.3 @@ -148,14 +148,6 @@
     3.4                 ;;(dorun (map #(println-repl (.getName %)) touch-objects))
     3.5               (count touch-objects))))))))
     3.6  
     3.7 -(defn enable-debug [world]
     3.8 -  (.enableDebug 
     3.9 -   (.getPhysicsSpace
    3.10 -    (.getState
    3.11 -     (.getStateManager world)
    3.12 -     BulletAppState))
    3.13 -   (asset-manager)))
    3.14 -
    3.15  (defn no-logging []
    3.16    (.setLevel (Logger/getLogger "com.jme3") Level/OFF))
    3.17  
     4.1 --- a/org/util.org	Mon Oct 24 07:36:04 2011 -0700
     4.2 +++ b/org/util.org	Mon Oct 24 12:35:15 2011 -0700
     4.3 @@ -1,20 +1,18 @@
     4.4 -#+title: Helper Utilities
     4.5 +#+title: Clojure Utilities for jMonkeyEngine3
     4.6  #+author: Robert McIntyre
     4.7  #+email: rlm@mit.edu
     4.8 -#+description: Simulating senses for AI research using JMonkeyEngine3
     4.9 +#+description: 
    4.10 +#+keywords: JME3, clojure, import, utilities
    4.11  #+SETUPFILE: ../../aurellem/org/setup.org
    4.12  #+INCLUDE: ../../aurellem/org/level-0.org
    4.13 -#+babel: :mkdirp yes :noweb yes :exports both
    4.14 +
    4.15 +* Utilities
    4.16 +
    4.17 +These are a collection of functions to make programming jMonkeyEngine
    4.18 +in clojure easier.
    4.19  
    4.20  ** Imports
    4.21  
    4.22 -jMonkeyEngine has a plethora of classes which can be overwhelming at
    4.23 -first. So that I one can get right to coding, it's good to take the
    4.24 -time right now and make a "import all" function which brings in all of
    4.25 -the important jme3 classes. Once I'm happy with the general structure
    4.26 -of a namespace I can deal with importing only the classes it actually
    4.27 -needs.
    4.28 -
    4.29  #+srcname: import
    4.30  #+begin_src clojure :results silent
    4.31  (ns cortex.import
    4.32 @@ -49,92 +47,131 @@
    4.33     (map (comp permissive-import symbol) (jme-classes))))
    4.34  #+end_src  
    4.35  
    4.36 +jMonkeyEngine3 has a plethora of classes which can be overwhelming to
    4.37 +manage. This code uses reflection to import all of them. Once I'm
    4.38 +happy with the general structure of a namespace I can deal with
    4.39 +importing only the classes it actually needs.
    4.40 +
    4.41  The =mega-import-jme3= is quite usefull for debugging purposes since
    4.42  it allows completion for almost all of JME's classes.
    4.43  
    4.44  Out of curiousity, let's see just how many classes =mega-import-jme3=
    4.45  imports:
    4.46  
    4.47 -#+begin_src clojure :exports both
    4.48 -(clojure.core/count (cortex.import/jme-classes))
    4.49 +#+begin_src clojure :exports both :results output
    4.50 +(println (clojure.core/count (cortex.import/jme-classes)) "classes")
    4.51  #+end_src
    4.52  
    4.53  #+results:
    4.54 -: 955
    4.55 +: 955 classes
    4.56  
    4.57  
    4.58 -#+srcname: world-view
    4.59 -#+begin_src clojure :results silent
    4.60 -(ns cortex.util)
    4.61 -(require 'cortex.import)
    4.62 -(cortex.import/mega-import-jme3)
    4.63 -(use 'cortex.world)
    4.64 -(defprotocol Viewable
    4.65 -  (view [something]))
    4.66 +** Utilities
    4.67  
    4.68 -(extend-type com.jme3.scene.Geometry
    4.69 -  Viewable
    4.70 -  (view [geo]
    4.71 -	(view (doto (Node.)(.attachChild geo)))))
    4.72 +The utilities here come in three main groups:
    4.73 + - Changing settings in a running =Application=
    4.74 + - Creating objects
    4.75 + - Visualizing objects
    4.76  
    4.77 -(extend-type com.jme3.scene.Node
    4.78 -  Viewable
    4.79 -  (view [node]
    4.80 -	(.start
    4.81 -	 (world node
    4.82 -		{}
    4.83 -		(fn [world]
    4.84 -		  (.enableDebug 
    4.85 -		   (.getPhysicsSpace
    4.86 -		    (.getState
    4.87 -		     (.getStateManager world)
    4.88 -		     BulletAppState))
    4.89 -		   (asset-manager))
    4.90 -		  (set-gravity* world Vector3f/ZERO)
    4.91 -;;		  (set-gravity* world (Vector3f. 0 (float -0.4) 0))
    4.92 -		  (let [sun (doto (DirectionalLight.)
    4.93 -			      (.setDirection (.normalizeLocal (Vector3f. 1 0 -2)))
    4.94 -			      (.setColor ColorRGBA/White))]
    4.95 -		    (.addLight (.getRootNode world) sun)))
    4.96 -		no-op))))
    4.97 -#+end_src
    4.98  
    4.99 -Here I make the =Viewable= protocol and extend it to JME's types.  Now
   4.100 -hello-world can be written as easily as:
   4.101 -
   4.102 -#+begin_src clojure :results silent
   4.103 -(cortex.world/view (cortex.world/box))
   4.104 -#+end_src
   4.105 -
   4.106 +*** Changing Settings
   4.107  
   4.108  #+srcname: util
   4.109  #+begin_src clojure 
   4.110 -(in-ns 'cortex.util)
   4.111 +(ns cortex.util
   4.112 +  "Utility functions for making jMonkeyEngine easier to program from
   4.113 +   clojure"
   4.114 +  {:author "Robert McIntyre"}
   4.115 +  (:use cortex.world)
   4.116 +  (:use clojure.contrib.def)
   4.117 +  (:import com.jme3.math.Vector3f)
   4.118 +  (:import com.jme3.math.Quaternion)
   4.119 +  (:import com.jme3.asset.TextureKey)
   4.120 +  (:import com.jme3.bullet.control.RigidBodyControl)
   4.121 +  (:import com.jme3.bullet.collision.shapes.GImpactCollisionShape)
   4.122 +  (:import com.jme3.scene.shape.Box)
   4.123 +  (:import com.jme3.scene.Node)
   4.124 +  (:import com.jme3.scene.shape.Sphere)
   4.125 +  (:import com.jme3.light.DirectionalLight)
   4.126 +  (:import com.jme3.math.ColorRGBA)
   4.127 +  (:import com.jme3.bullet.BulletAppState)
   4.128 +  (:import com.jme3.material.Material)
   4.129 +  (:import com.jme3.scene.Geometry))
   4.130  
   4.131 -(def println-repl (bound-fn [& args] (apply println args)))
   4.132 +(defvar println-repl
   4.133 +  (bound-fn [& args] (apply println args))
   4.134 +  "println called from the LWJGL thread will not go to the REPL, but
   4.135 +  instead to whatever terminal started the JVM process. This function
   4.136 +  will always output to the REPL")
   4.137  
   4.138 -(defn position-camera [game]
   4.139 -  (doto (.getCamera game)
   4.140 -    (.setLocation (Vector3f. 0 6 6))
   4.141 -    (.lookAt Vector3f/ZERO (Vector3f. 0 1 0))))
   4.142 +(defn position-camera
   4.143 +  ([game position direction up]
   4.144 +     (doto (.getCamera game)
   4.145 +       (.setLocation )
   4.146 +       (.lookAt direction up)))
   4.147 +  ([game position direction]
   4.148 +     (position-camera
   4.149 +      game position direction Vector3f/UNIT_Y)))
   4.150  
   4.151 -(defn set-gravity*
   4.152 +(defn enable-debug 
   4.153 +  "Turn on the debug wireframes for every object in this simulation"
   4.154 +  [world]
   4.155 +  (.enableDebug 
   4.156 +   (.getPhysicsSpace
   4.157 +    (.getState
   4.158 +     (.getStateManager world)
   4.159 +     BulletAppState))
   4.160 +   (asset-manager)))
   4.161 +
   4.162 +(defn set-gravity
   4.163 +  "In order to change the gravity of a scene, it is not only necessary
   4.164 +   to set the gravity variable, but to \"tap\" every physics object in
   4.165 +   the scene to reactivate physics calculations."
   4.166    [game gravity]
   4.167    (traverse
   4.168     (fn [geom]
   4.169       (if-let
   4.170 +         ;; only set gravity for physical objects.
   4.171  	 [control (.getControl geom RigidBodyControl)]
   4.172         (do
   4.173  	 (.setGravity control gravity)
   4.174 -	 (.applyImpulse control Vector3f/ZERO Vector3f/ZERO)
   4.175 -	 )))
   4.176 +         ;; tappsies!
   4.177 +	 (.applyImpulse control Vector3f/ZERO Vector3f/ZERO))))
   4.178     (.getRootNode game)))
   4.179 +
   4.180 +(defn add-element
   4.181 +  "Add the Spatial to the game's environment"
   4.182 +  ([game element node]
   4.183 +  (.addAll
   4.184 +   (.getPhysicsSpace
   4.185 +    (.getState
   4.186 +     (.getStateManager game)
   4.187 +     BulletAppState))
   4.188 +    element)
   4.189 +  (.attachChild node element))
   4.190 +  ([game element]
   4.191 +     (add-element game element (.getRootNode game))))
   4.192 +
   4.193 +(defn apply-map
   4.194 +  "Like apply, but works for maps and functions that expect an
   4.195 +   implicit map and nothing else as in (fn [& {}]).
   4.196 +   ------- Example -------
   4.197 +   (defn demo [& {:keys [www] :or {www \"oh yeah\"} :as env}] 
   4.198 +     (println www))
   4.199 +   (apply-map demo {:www \"hello!\"})
   4.200 +   -->\"hello\""
   4.201 +  [fn m]
   4.202 +  (apply fn (reduce #(into %1 %2) [] m)))
   4.203 +
   4.204  #+end_src
   4.205  
   4.206  
   4.207 +*** Creating Basic Shapes
   4.208 +
   4.209  #+srcname: shapes
   4.210  #+begin_src clojure :results silent
   4.211  (in-ns 'cortex.util)
   4.212 +
   4.213  (defrecord shape-description
   4.214    [name
   4.215     color
   4.216 @@ -145,7 +182,9 @@
   4.217     position
   4.218     rotation
   4.219     shape
   4.220 -   physical?])
   4.221 +   physical?
   4.222 +   GImpact?
   4.223 +   ])
   4.224  
   4.225  (def base-shape
   4.226       (shape-description.
   4.227 @@ -161,11 +200,12 @@
   4.228        Vector3f/ZERO
   4.229        Quaternion/IDENTITY
   4.230        (Box. Vector3f/ZERO 0.5 0.5 0.5)
   4.231 -      true))
   4.232 +      true
   4.233 +      false))
   4.234  
   4.235  (defn make-shape
   4.236    [#^shape-description d]
   4.237 -  (let [asset-manager (if (:asset-manager d) (:asset-manager d) (asset-manager))
   4.238 +  (let [asset-manager (asset-manager)
   4.239          mat (Material. asset-manager (:material d))
   4.240  	geom (Geometry. (:name d) (:shape d))]
   4.241      (if (:texture d)
   4.242 @@ -177,18 +217,20 @@
   4.243      (if-let [rotation (:rotation d)] (.rotate geom rotation))
   4.244      (.setLocalTranslation geom (:position d))
   4.245      (if (:physical? d)
   4.246 -      (let [impact-shape (doto (GImpactCollisionShape. 
   4.247 -                                (.getMesh geom)) (.setMargin 0))
   4.248 -	    physics-control (RigidBodyControl.
   4.249 -			     ;;impact-shape ;; comment to disable 
   4.250 -			     (float (:mass d)))]
   4.251 -	(.createJmeMesh impact-shape)
   4.252 +      (let [physics-control
   4.253 +            (if (:GImpact d)
   4.254 +              ;; Create an accurate mesh collision shape if desired. 
   4.255 +              (RigidBodyControl.
   4.256 +               (doto (GImpactCollisionShape. 
   4.257 +                      (.getMesh geom))
   4.258 +                 (.createJmeMesh)
   4.259 +                 (.setMargin 0))
   4.260 +               (float (:mass d)))
   4.261 +              ;; otherwise use jme3's default
   4.262 +              (RigidBodyControl. (float (:mass d))))]
   4.263  	(.addControl geom physics-control)
   4.264  	;;(.setSleepingThresholds physics-control (float 0) (float 0))
   4.265  	(.setFriction physics-control (:friction d))))
   4.266 -    ;;the default is to keep this node in the physics engine forever.
   4.267 -    ;;these commands must come after the control is added to the geometry.
   4.268 -    ;;
   4.269      geom))
   4.270    
   4.271  (defn box
   4.272 @@ -204,33 +246,51 @@
   4.273         (make-shape (assoc options
   4.274  		     :shape (Sphere. 32 32 (float r)))))) 
   4.275    ([] (sphere 0.5)))
   4.276 +#+end_src
   4.277  
   4.278 -(defn add-element
   4.279 -  ([game element node]
   4.280 -  (.addAll
   4.281 -   (.getPhysicsSpace
   4.282 -    (.getState
   4.283 -     (.getStateManager game)
   4.284 -     BulletAppState))
   4.285 -    element)
   4.286 -  (.attachChild node element))
   4.287 -  ([game element]
   4.288 -     (add-element game element (.getRootNode game))))
   4.289  
   4.290 +*** Viewing Objects
   4.291  
   4.292 -(defn apply-map
   4.293 -  "Like apply, but works for maps and functions that expect an
   4.294 -   implicit map and nothing else as in (fn [& {}]).
   4.295 -   ------- Example -------
   4.296 -   (defn demo [& {:keys [www] :or {www \"oh yeah\"} :as env}] 
   4.297 -     (println www))
   4.298 -   (apply-map demo {:www \"hello!\"})
   4.299 -   -->\"hello\""
   4.300 -  [fn m]
   4.301 -  (apply fn (reduce #(into %1 %2) [] m)))
   4.302 +#+srcname: world-view
   4.303 +#+begin_src clojure :results silent
   4.304 +(in-ns 'cortex.util)
   4.305  
   4.306 +(defprotocol Viewable
   4.307 +  (view [something]))
   4.308 +
   4.309 +(extend-type com.jme3.scene.Geometry
   4.310 +  Viewable
   4.311 +  (view [geo]
   4.312 +	(view (doto (Node.)(.attachChild geo)))))
   4.313 +
   4.314 +(extend-type com.jme3.scene.Node
   4.315 +  Viewable
   4.316 +  (view 
   4.317 +    [node]
   4.318 +    (.start
   4.319 +     (world
   4.320 +      node
   4.321 +      {}
   4.322 +      (fn [world]
   4.323 +        (enable-debug world)
   4.324 +        (set-gravity world Vector3f/ZERO)
   4.325 +        (let [sun 
   4.326 +              (doto (DirectionalLight.)
   4.327 +                (.setDirection
   4.328 +                 (.normalizeLocal (Vector3f. 1 0 -2)))
   4.329 +                (.setColor ColorRGBA/White))]
   4.330 +          (.addLight (.getRootNode world) sun)))
   4.331 +      no-op))))
   4.332  #+end_src
   4.333  
   4.334 +Here I make the =Viewable= protocol and extend it to JME's types.  Now
   4.335 +hello-world can be written as easily as:
   4.336 +
   4.337 +#+begin_src clojure :results silent
   4.338 +(cortex.util/view (cortex.util/box))
   4.339 +#+end_src
   4.340 +
   4.341 +
   4.342  
   4.343  
   4.344  * COMMENT code generation
   4.345 @@ -239,9 +299,25 @@
   4.346  #+end_src
   4.347  
   4.348  
   4.349 -#+begin_src clojure :tangle ../src/cortex/util.clj
   4.350 -<<world-view>>
   4.351 +#+begin_src clojure :tangle ../src/cortex/util.clj :noweb yes
   4.352  <<util>>
   4.353  <<shapes>>
   4.354 +<<world-view>>
   4.355  #+end_src
   4.356  
   4.357 +
   4.358 +
   4.359 +
   4.360 +
   4.361 +
   4.362 +
   4.363 +
   4.364 +
   4.365 +
   4.366 +
   4.367 +
   4.368 +
   4.369 +
   4.370 +
   4.371 +
   4.372 + 
     5.1 --- a/org/world.org	Mon Oct 24 07:36:04 2011 -0700
     5.2 +++ b/org/world.org	Mon Oct 24 12:35:15 2011 -0700
     5.3 @@ -5,7 +5,7 @@
     5.4  #+keywords: JME3, clojure, virtual world, exception handling
     5.5  #+SETUPFILE: ../../aurellem/org/setup.org
     5.6  #+INCLUDE: ../../aurellem/org/level-0.org
     5.7 -#+babel: :mkdirp yes :noweb yes :exports both
     5.8 +#+BABEL: :mkdirp yes :noweb yes :exports both
     5.9  
    5.10  * The  World
    5.11  
    5.12 @@ -344,7 +344,7 @@
    5.13  
    5.14  
    5.15  * COMMENT code generation
    5.16 -#+begin_src clojure :tangle ../src/cortex/world.clj
    5.17 +#+begin_src clojure :tangle ../src/cortex/world.clj :noweb yes
    5.18  <<header>>
    5.19  <<settings>>
    5.20  <<exceptions>>