view org/util.org @ 26:bbffa41a12a9

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