Mercurial > cortex
view org/util.org @ 25:775d97247dd0
cleaning up world.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 24 Oct 2011 05:25:01 -0700 |
parents | e965675ec4d0 |
children | bbffa41a12a9 |
line wrap: on
line source
1 #+title: Helper Utilities2 #+author: Robert McIntyre3 #+email: rlm@mit.edu4 #+description: Simulating senses for AI research using JMonkeyEngine35 #+SETUPFILE: ../../aurellem/org/setup.org6 #+INCLUDE: ../../aurellem/org/level-0.org7 #+babel: :mkdirp yes :noweb yes :exports both9 ** Imports10 jMonkeyEngine has a plethora of classes which can be overwhelming at11 first. So that I one can get right to coding, it's good to take the12 time right now and make a "import all" function which brings in all of13 the important jme3 classes. Once I'm happy with the general structure14 of a namespace I can deal with importing only the classes it actually15 needs.17 #+srcname: import18 #+begin_src clojure :results silent19 (ns cortex.import20 (:require swank.util.class-browse))22 (defn permissive-import23 [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 (and31 (.startsWith classname "com.jme3.")32 ;; Don't import the Lwjgl stuff since it can throw exceptions33 ;; upon being loaded.34 (not (re-matches #".*Lwjgl.*" classname))))36 (defn jme-classes37 "returns a list of all jme3 classes"38 []39 (filter40 jme-class?41 (map :name42 swank.util.class-browse/available-classes)))44 (defn mega-import-jme345 "Import ALL the jme classes. For REPL use."46 []47 (doall48 (map (comp permissive-import symbol) (jme-classes))))49 #+end_src51 The =mega-import-jme3= is quite usefull for debugging purposes since52 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 both58 (clojure.core/count (cortex.import/jme-classes))59 #+end_src61 #+results:62 : 95565 #+srcname: world-view66 #+begin_src clojure :results silent67 (ns cortex.util)68 (require 'cortex.import)69 (cortex.import/mega-import-jme3)70 (use 'cortex.world)71 (defprotocol Viewable72 (view [something]))74 (extend-type com.jme3.scene.Geometry75 Viewable76 (view [geo]77 (view (doto (Node.)(.attachChild geo)))))79 (extend-type com.jme3.scene.Node80 Viewable81 (view [node]82 (.start83 (world node84 {}85 (fn [world]86 (.enableDebug87 (.getPhysicsSpace88 (.getState89 (.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_src101 Here I make the =Viewable= protocol and extend it to JME's types. Now102 hello-world can be written as easily as:104 #+begin_src clojure :results silent105 (cortex.world/view (cortex.world/box))106 #+end_src109 #+srcname: util110 #+begin_src clojure111 (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 (traverse123 (fn [geom]124 (if-let125 [control (.getControl geom RigidBodyControl)]126 (do127 (.setGravity control gravity)128 (.applyImpulse control Vector3f/ZERO Vector3f/ZERO)129 )))130 (.getRootNode game)))131 #+end_src134 #+srcname: shapes135 #+begin_src clojure :results silent136 (in-ns 'cortex.util)137 (defrecord shape-description138 [name139 color140 mass141 friction142 texture143 material144 position145 rotation146 shape147 physical?])149 (def base-shape150 (shape-description.151 "default-shape"152 false153 ;;ColorRGBA/Blue154 1.0 ;; mass155 1.0 ;; friction156 ;; texture157 "Textures/Terrain/BrickWall/BrickWall.jpg"158 ;; material159 "Common/MatDefs/Misc/Unshaded.j3md"160 Vector3f/ZERO161 Quaternion/IDENTITY162 (Box. Vector3f/ZERO 0.5 0.5 0.5)163 true))165 (defn make-shape166 [#^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 disable183 (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 box194 ([l w h & {:as options}]195 (let [options (merge base-shape options)]196 (make-shape (assoc options197 :shape (Box. l w h)))))198 ([] (box 0.5 0.5 0.5)))200 (defn sphere201 ([r & {:as options}]202 (let [options (merge base-shape options)]203 (make-shape (assoc options204 :shape (Sphere. 32 32 (float r))))))205 ([] (sphere 0.5)))207 (defn add-element208 ([game element node]209 (.addAll210 (.getPhysicsSpace211 (.getState212 (.getStateManager game)213 BulletAppState))214 element)215 (.attachChild node element))216 ([game element]217 (add-element game element (.getRootNode game))))221 #+end_src225 * COMMENT code generation226 #+begin_src clojure :tangle ../src/cortex/import.clj227 <<import>>228 #+end_src231 #+begin_src clojure :tangle ../src/cortex/util.clj232 <<world-view>>233 <<util>>234 <<shapes>>235 #+end_src