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@23
|
10 jMonkeyEngine has a plethora of classes which can be overwhelming at
|
rlm@23
|
11 first. So that I one can get right to coding, it's good to take the
|
rlm@23
|
12 time right now and make a "import all" function which brings in all of
|
rlm@23
|
13 the important jme3 classes. Once I'm happy with the general structure
|
rlm@23
|
14 of a namespace I can deal with importing only the classes it actually
|
rlm@23
|
15 needs.
|
rlm@23
|
16
|
rlm@23
|
17 #+srcname: import
|
rlm@23
|
18 #+begin_src clojure :results silent
|
rlm@23
|
19 (ns cortex.import
|
rlm@23
|
20 (:require swank.util.class-browse))
|
rlm@23
|
21
|
rlm@23
|
22 (defn permissive-import
|
rlm@23
|
23 [classname]
|
rlm@23
|
24 (eval `(try (import '~classname)
|
rlm@23
|
25 (catch java.lang.Exception e#
|
rlm@23
|
26 (println "couldn't import " '~classname))))
|
rlm@23
|
27 classname)
|
rlm@23
|
28
|
rlm@23
|
29 (defn jme-class? [classname]
|
rlm@23
|
30 (and
|
rlm@23
|
31 (.startsWith classname "com.jme3.")
|
rlm@23
|
32 ;; Don't import the Lwjgl stuff since it can throw exceptions
|
rlm@23
|
33 ;; upon being loaded.
|
rlm@23
|
34 (not (re-matches #".*Lwjgl.*" classname))))
|
rlm@23
|
35
|
rlm@23
|
36 (defn jme-classes
|
rlm@23
|
37 "returns a list of all jme3 classes"
|
rlm@23
|
38 []
|
rlm@23
|
39 (filter
|
rlm@23
|
40 jme-class?
|
rlm@23
|
41 (map :name
|
rlm@23
|
42 swank.util.class-browse/available-classes)))
|
rlm@23
|
43
|
rlm@23
|
44 (defn mega-import-jme3
|
rlm@23
|
45 "Import ALL the jme classes. For REPL use."
|
rlm@23
|
46 []
|
rlm@23
|
47 (doall
|
rlm@23
|
48 (map (comp permissive-import symbol) (jme-classes))))
|
rlm@23
|
49 #+end_src
|
rlm@23
|
50
|
rlm@23
|
51 The =mega-import-jme3= is quite usefull for debugging purposes since
|
rlm@23
|
52 it allows completion for almost all of JME's classes.
|
rlm@23
|
53
|
rlm@23
|
54 Out of curiousity, let's see just how many classes =mega-import-jme3=
|
rlm@23
|
55 imports:
|
rlm@23
|
56
|
rlm@23
|
57 #+begin_src clojure :exports both
|
rlm@23
|
58 (clojure.core/count (cortex.import/jme-classes))
|
rlm@23
|
59 #+end_src
|
rlm@23
|
60
|
rlm@23
|
61 #+results:
|
rlm@23
|
62 : 955
|
rlm@23
|
63
|
rlm@23
|
64 ** Simplification
|
rlm@23
|
65 #+srcname: world-view
|
rlm@23
|
66 #+begin_src clojure :results silent
|
rlm@23
|
67 (in-ns 'cortex.world)
|
rlm@23
|
68
|
rlm@23
|
69 (defprotocol Viewable
|
rlm@23
|
70 (view [something]))
|
rlm@23
|
71
|
rlm@23
|
72 (extend-type com.jme3.scene.Geometry
|
rlm@23
|
73 Viewable
|
rlm@23
|
74 (view [geo]
|
rlm@23
|
75 (view (doto (Node.)(.attachChild geo)))))
|
rlm@23
|
76
|
rlm@23
|
77 (extend-type com.jme3.scene.Node
|
rlm@23
|
78 Viewable
|
rlm@23
|
79 (view [node]
|
rlm@23
|
80 (.start
|
rlm@23
|
81 (world node
|
rlm@23
|
82 {}
|
rlm@23
|
83 (fn [world]
|
rlm@23
|
84 (.enableDebug
|
rlm@23
|
85 (.getPhysicsSpace
|
rlm@23
|
86 (.getState
|
rlm@23
|
87 (.getStateManager world)
|
rlm@23
|
88 BulletAppState))
|
rlm@23
|
89 (asset-manager))
|
rlm@23
|
90 (set-gravity* world Vector3f/ZERO)
|
rlm@23
|
91 ;; (set-gravity* world (Vector3f. 0 (float -0.4) 0))
|
rlm@23
|
92 (let [sun (doto (DirectionalLight.)
|
rlm@23
|
93 (.setDirection (.normalizeLocal (Vector3f. 1 0 -2)))
|
rlm@23
|
94 (.setColor ColorRGBA/White))]
|
rlm@23
|
95 (.addLight (.getRootNode world) sun)))
|
rlm@23
|
96 no-op))))
|
rlm@23
|
97
|
rlm@23
|
98 (defn position-camera [game]
|
rlm@23
|
99 (doto (.getCamera game)
|
rlm@23
|
100 (.setLocation (Vector3f. 0 6 6))
|
rlm@23
|
101 (.lookAt Vector3f/ZERO (Vector3f. 0 1 0))))
|
rlm@23
|
102
|
rlm@23
|
103 #+end_src
|
rlm@23
|
104
|
rlm@23
|
105 Here I make the =Viewable= protocol and extend it to JME's types. Now
|
rlm@23
|
106 hello-world can be written as easily as:
|
rlm@23
|
107
|
rlm@23
|
108 #+begin_src clojure :results silent
|
rlm@23
|
109 (cortex.world/view (cortex.world/box))
|
rlm@23
|
110 #+end_src
|