rlm@23: #+title: Helper Utilities rlm@23: #+author: Robert McIntyre rlm@23: #+email: rlm@mit.edu rlm@23: #+description: Simulating senses for AI research using JMonkeyEngine3 rlm@23: #+SETUPFILE: ../../aurellem/org/setup.org rlm@23: #+INCLUDE: ../../aurellem/org/level-0.org rlm@23: #+babel: :mkdirp yes :noweb yes :exports both rlm@23: rlm@23: ** Imports rlm@23: jMonkeyEngine has a plethora of classes which can be overwhelming at rlm@23: first. So that I one can get right to coding, it's good to take the rlm@23: time right now and make a "import all" function which brings in all of rlm@23: the important jme3 classes. Once I'm happy with the general structure rlm@23: of a namespace I can deal with importing only the classes it actually rlm@23: needs. rlm@23: rlm@23: #+srcname: import rlm@23: #+begin_src clojure :results silent rlm@23: (ns cortex.import rlm@23: (:require swank.util.class-browse)) rlm@23: rlm@23: (defn permissive-import rlm@23: [classname] rlm@23: (eval `(try (import '~classname) rlm@23: (catch java.lang.Exception e# rlm@23: (println "couldn't import " '~classname)))) rlm@23: classname) rlm@23: rlm@23: (defn jme-class? [classname] rlm@23: (and rlm@23: (.startsWith classname "com.jme3.") rlm@23: ;; Don't import the Lwjgl stuff since it can throw exceptions rlm@23: ;; upon being loaded. rlm@23: (not (re-matches #".*Lwjgl.*" classname)))) rlm@23: rlm@23: (defn jme-classes rlm@23: "returns a list of all jme3 classes" rlm@23: [] rlm@23: (filter rlm@23: jme-class? rlm@23: (map :name rlm@23: swank.util.class-browse/available-classes))) rlm@23: rlm@23: (defn mega-import-jme3 rlm@23: "Import ALL the jme classes. For REPL use." rlm@23: [] rlm@23: (doall rlm@23: (map (comp permissive-import symbol) (jme-classes)))) rlm@23: #+end_src rlm@23: rlm@23: The =mega-import-jme3= is quite usefull for debugging purposes since rlm@23: it allows completion for almost all of JME's classes. rlm@23: rlm@23: Out of curiousity, let's see just how many classes =mega-import-jme3= rlm@23: imports: rlm@23: rlm@23: #+begin_src clojure :exports both rlm@23: (clojure.core/count (cortex.import/jme-classes)) rlm@23: #+end_src rlm@23: rlm@23: #+results: rlm@23: : 955 rlm@23: rlm@23: ** Simplification rlm@23: #+srcname: world-view rlm@23: #+begin_src clojure :results silent rlm@23: (in-ns 'cortex.world) rlm@23: rlm@23: (defprotocol Viewable rlm@23: (view [something])) rlm@23: rlm@23: (extend-type com.jme3.scene.Geometry rlm@23: Viewable rlm@23: (view [geo] rlm@23: (view (doto (Node.)(.attachChild geo))))) rlm@23: rlm@23: (extend-type com.jme3.scene.Node rlm@23: Viewable rlm@23: (view [node] rlm@23: (.start rlm@23: (world node rlm@23: {} rlm@23: (fn [world] rlm@23: (.enableDebug rlm@23: (.getPhysicsSpace rlm@23: (.getState rlm@23: (.getStateManager world) rlm@23: BulletAppState)) rlm@23: (asset-manager)) rlm@23: (set-gravity* world Vector3f/ZERO) rlm@23: ;; (set-gravity* world (Vector3f. 0 (float -0.4) 0)) rlm@23: (let [sun (doto (DirectionalLight.) rlm@23: (.setDirection (.normalizeLocal (Vector3f. 1 0 -2))) rlm@23: (.setColor ColorRGBA/White))] rlm@23: (.addLight (.getRootNode world) sun))) rlm@23: no-op)))) rlm@23: rlm@23: (defn position-camera [game] rlm@23: (doto (.getCamera game) rlm@23: (.setLocation (Vector3f. 0 6 6)) rlm@23: (.lookAt Vector3f/ZERO (Vector3f. 0 1 0)))) rlm@23: rlm@23: #+end_src rlm@23: rlm@23: Here I make the =Viewable= protocol and extend it to JME's types. Now rlm@23: hello-world can be written as easily as: rlm@23: rlm@23: #+begin_src clojure :results silent rlm@23: (cortex.world/view (cortex.world/box)) rlm@23: #+end_src