annotate org/util.org @ 28:122f12f81dc1

going to work on util.org now
author Robert McIntyre <rlm@mit.edu>
date Mon, 24 Oct 2011 07:36:04 -0700
parents bbffa41a12a9
children 6372c108c5c6
rev   line source
rlm@23 1 #+title: Helper Utilities
rlm@23 2 #+author: Robert McIntyre
rlm@23 3 #+email: rlm@mit.edu
rlm@23 4 #+description: Simulating senses for AI research using JMonkeyEngine3
rlm@23 5 #+SETUPFILE: ../../aurellem/org/setup.org
rlm@23 6 #+INCLUDE: ../../aurellem/org/level-0.org
rlm@23 7 #+babel: :mkdirp yes :noweb yes :exports both
rlm@23 8
rlm@23 9 ** Imports
rlm@28 10
rlm@23 11 jMonkeyEngine has a plethora of classes which can be overwhelming at
rlm@23 12 first. So that I one can get right to coding, it's good to take the
rlm@23 13 time right now and make a "import all" function which brings in all of
rlm@23 14 the important jme3 classes. Once I'm happy with the general structure
rlm@23 15 of a namespace I can deal with importing only the classes it actually
rlm@23 16 needs.
rlm@23 17
rlm@23 18 #+srcname: import
rlm@23 19 #+begin_src clojure :results silent
rlm@23 20 (ns cortex.import
rlm@23 21 (:require swank.util.class-browse))
rlm@23 22
rlm@23 23 (defn permissive-import
rlm@23 24 [classname]
rlm@23 25 (eval `(try (import '~classname)
rlm@23 26 (catch java.lang.Exception e#
rlm@23 27 (println "couldn't import " '~classname))))
rlm@23 28 classname)
rlm@23 29
rlm@23 30 (defn jme-class? [classname]
rlm@23 31 (and
rlm@23 32 (.startsWith classname "com.jme3.")
rlm@23 33 ;; Don't import the Lwjgl stuff since it can throw exceptions
rlm@23 34 ;; upon being loaded.
rlm@23 35 (not (re-matches #".*Lwjgl.*" classname))))
rlm@23 36
rlm@23 37 (defn jme-classes
rlm@23 38 "returns a list of all jme3 classes"
rlm@23 39 []
rlm@23 40 (filter
rlm@23 41 jme-class?
rlm@23 42 (map :name
rlm@23 43 swank.util.class-browse/available-classes)))
rlm@23 44
rlm@23 45 (defn mega-import-jme3
rlm@23 46 "Import ALL the jme classes. For REPL use."
rlm@23 47 []
rlm@23 48 (doall
rlm@23 49 (map (comp permissive-import symbol) (jme-classes))))
rlm@23 50 #+end_src
rlm@23 51
rlm@23 52 The =mega-import-jme3= is quite usefull for debugging purposes since
rlm@23 53 it allows completion for almost all of JME's classes.
rlm@23 54
rlm@23 55 Out of curiousity, let's see just how many classes =mega-import-jme3=
rlm@23 56 imports:
rlm@23 57
rlm@23 58 #+begin_src clojure :exports both
rlm@23 59 (clojure.core/count (cortex.import/jme-classes))
rlm@23 60 #+end_src
rlm@23 61
rlm@23 62 #+results:
rlm@23 63 : 955
rlm@23 64
rlm@25 65
rlm@23 66 #+srcname: world-view
rlm@23 67 #+begin_src clojure :results silent
rlm@25 68 (ns cortex.util)
rlm@25 69 (require 'cortex.import)
rlm@25 70 (cortex.import/mega-import-jme3)
rlm@25 71 (use 'cortex.world)
rlm@23 72 (defprotocol Viewable
rlm@23 73 (view [something]))
rlm@23 74
rlm@23 75 (extend-type com.jme3.scene.Geometry
rlm@23 76 Viewable
rlm@23 77 (view [geo]
rlm@23 78 (view (doto (Node.)(.attachChild geo)))))
rlm@23 79
rlm@23 80 (extend-type com.jme3.scene.Node
rlm@23 81 Viewable
rlm@23 82 (view [node]
rlm@23 83 (.start
rlm@23 84 (world node
rlm@23 85 {}
rlm@23 86 (fn [world]
rlm@23 87 (.enableDebug
rlm@23 88 (.getPhysicsSpace
rlm@23 89 (.getState
rlm@23 90 (.getStateManager world)
rlm@23 91 BulletAppState))
rlm@23 92 (asset-manager))
rlm@23 93 (set-gravity* world Vector3f/ZERO)
rlm@23 94 ;; (set-gravity* world (Vector3f. 0 (float -0.4) 0))
rlm@23 95 (let [sun (doto (DirectionalLight.)
rlm@23 96 (.setDirection (.normalizeLocal (Vector3f. 1 0 -2)))
rlm@23 97 (.setColor ColorRGBA/White))]
rlm@23 98 (.addLight (.getRootNode world) sun)))
rlm@23 99 no-op))))
rlm@23 100 #+end_src
rlm@23 101
rlm@23 102 Here I make the =Viewable= protocol and extend it to JME's types. Now
rlm@23 103 hello-world can be written as easily as:
rlm@23 104
rlm@23 105 #+begin_src clojure :results silent
rlm@23 106 (cortex.world/view (cortex.world/box))
rlm@23 107 #+end_src
rlm@24 108
rlm@24 109
rlm@25 110 #+srcname: util
rlm@25 111 #+begin_src clojure
rlm@25 112 (in-ns 'cortex.util)
rlm@25 113
rlm@25 114 (def println-repl (bound-fn [& args] (apply println args)))
rlm@25 115
rlm@25 116 (defn position-camera [game]
rlm@25 117 (doto (.getCamera game)
rlm@25 118 (.setLocation (Vector3f. 0 6 6))
rlm@25 119 (.lookAt Vector3f/ZERO (Vector3f. 0 1 0))))
rlm@25 120
rlm@25 121 (defn set-gravity*
rlm@25 122 [game gravity]
rlm@25 123 (traverse
rlm@25 124 (fn [geom]
rlm@25 125 (if-let
rlm@25 126 [control (.getControl geom RigidBodyControl)]
rlm@25 127 (do
rlm@25 128 (.setGravity control gravity)
rlm@25 129 (.applyImpulse control Vector3f/ZERO Vector3f/ZERO)
rlm@25 130 )))
rlm@25 131 (.getRootNode game)))
rlm@25 132 #+end_src
rlm@25 133
rlm@25 134
rlm@25 135 #+srcname: shapes
rlm@25 136 #+begin_src clojure :results silent
rlm@25 137 (in-ns 'cortex.util)
rlm@25 138 (defrecord shape-description
rlm@25 139 [name
rlm@25 140 color
rlm@25 141 mass
rlm@25 142 friction
rlm@25 143 texture
rlm@25 144 material
rlm@25 145 position
rlm@25 146 rotation
rlm@25 147 shape
rlm@25 148 physical?])
rlm@25 149
rlm@25 150 (def base-shape
rlm@25 151 (shape-description.
rlm@25 152 "default-shape"
rlm@25 153 false
rlm@25 154 ;;ColorRGBA/Blue
rlm@25 155 1.0 ;; mass
rlm@25 156 1.0 ;; friction
rlm@25 157 ;; texture
rlm@25 158 "Textures/Terrain/BrickWall/BrickWall.jpg"
rlm@25 159 ;; material
rlm@25 160 "Common/MatDefs/Misc/Unshaded.j3md"
rlm@25 161 Vector3f/ZERO
rlm@25 162 Quaternion/IDENTITY
rlm@25 163 (Box. Vector3f/ZERO 0.5 0.5 0.5)
rlm@25 164 true))
rlm@25 165
rlm@25 166 (defn make-shape
rlm@25 167 [#^shape-description d]
rlm@25 168 (let [asset-manager (if (:asset-manager d) (:asset-manager d) (asset-manager))
rlm@25 169 mat (Material. asset-manager (:material d))
rlm@25 170 geom (Geometry. (:name d) (:shape d))]
rlm@25 171 (if (:texture d)
rlm@25 172 (let [key (TextureKey. (:texture d))]
rlm@25 173 (.setGenerateMips key true)
rlm@25 174 (.setTexture mat "ColorMap" (.loadTexture asset-manager key))))
rlm@25 175 (if (:color d) (.setColor mat "Color" (:color d)))
rlm@25 176 (.setMaterial geom mat)
rlm@25 177 (if-let [rotation (:rotation d)] (.rotate geom rotation))
rlm@25 178 (.setLocalTranslation geom (:position d))
rlm@25 179 (if (:physical? d)
rlm@25 180 (let [impact-shape (doto (GImpactCollisionShape.
rlm@25 181 (.getMesh geom)) (.setMargin 0))
rlm@25 182 physics-control (RigidBodyControl.
rlm@25 183 ;;impact-shape ;; comment to disable
rlm@25 184 (float (:mass d)))]
rlm@25 185 (.createJmeMesh impact-shape)
rlm@25 186 (.addControl geom physics-control)
rlm@25 187 ;;(.setSleepingThresholds physics-control (float 0) (float 0))
rlm@25 188 (.setFriction physics-control (:friction d))))
rlm@25 189 ;;the default is to keep this node in the physics engine forever.
rlm@25 190 ;;these commands must come after the control is added to the geometry.
rlm@25 191 ;;
rlm@25 192 geom))
rlm@25 193
rlm@25 194 (defn box
rlm@25 195 ([l w h & {:as options}]
rlm@25 196 (let [options (merge base-shape options)]
rlm@25 197 (make-shape (assoc options
rlm@25 198 :shape (Box. l w h)))))
rlm@25 199 ([] (box 0.5 0.5 0.5)))
rlm@25 200
rlm@25 201 (defn sphere
rlm@25 202 ([r & {:as options}]
rlm@25 203 (let [options (merge base-shape options)]
rlm@25 204 (make-shape (assoc options
rlm@25 205 :shape (Sphere. 32 32 (float r))))))
rlm@25 206 ([] (sphere 0.5)))
rlm@25 207
rlm@25 208 (defn add-element
rlm@25 209 ([game element node]
rlm@25 210 (.addAll
rlm@25 211 (.getPhysicsSpace
rlm@25 212 (.getState
rlm@25 213 (.getStateManager game)
rlm@25 214 BulletAppState))
rlm@25 215 element)
rlm@25 216 (.attachChild node element))
rlm@25 217 ([game element]
rlm@25 218 (add-element game element (.getRootNode game))))
rlm@25 219
rlm@25 220
rlm@26 221 (defn apply-map
rlm@26 222 "Like apply, but works for maps and functions that expect an
rlm@26 223 implicit map and nothing else as in (fn [& {}]).
rlm@26 224 ------- Example -------
rlm@26 225 (defn demo [& {:keys [www] :or {www \"oh yeah\"} :as env}]
rlm@26 226 (println www))
rlm@26 227 (apply-map demo {:www \"hello!\"})
rlm@26 228 -->\"hello\""
rlm@26 229 [fn m]
rlm@26 230 (apply fn (reduce #(into %1 %2) [] m)))
rlm@25 231
rlm@25 232 #+end_src
rlm@25 233
rlm@25 234
rlm@24 235
rlm@24 236 * COMMENT code generation
rlm@24 237 #+begin_src clojure :tangle ../src/cortex/import.clj
rlm@24 238 <<import>>
rlm@24 239 #+end_src
rlm@25 240
rlm@25 241
rlm@25 242 #+begin_src clojure :tangle ../src/cortex/util.clj
rlm@25 243 <<world-view>>
rlm@25 244 <<util>>
rlm@25 245 <<shapes>>
rlm@25 246 #+end_src
rlm@25 247