Mercurial > cortex
view org/test-creature.org @ 88:3e929630a25f
multimethod dispatch works
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 07 Jan 2012 05:24:14 -0700 |
parents | af1bb43661f9 |
children | cd5151b5e7c3 |
line wrap: on
line source
1 #+title: First attempt at a creature!2 #+author: Robert McIntyre3 #+email: rlm@mit.edu4 #+description:5 #+keywords: simulation, jMonkeyEngine3, clojure6 #+SETUPFILE: ../../aurellem/org/setup.org7 #+INCLUDE: ../../aurellem/org/level-0.org9 * Intro10 So far, I've made the following senses --11 - Vision12 - Hearing13 - Touch14 - Proprioception16 And one effector:17 - Movement19 However, the code so far has only enabled these senses, but has not20 actually implemented them. For example, there is still a lot of work21 to be done for vision. I need to be able to create an /eyeball/ in22 simulation that can be moved around and see the world from different23 angles. I also need to determine weather to use log-polar or cartesian24 for the visual input, and I need to determine how/wether to25 disceritise the visual input.27 I also want to be able to visualize both the sensors and the28 effectors in pretty pictures. This semi-retarted creature will by my29 first attempt at bringing everything together.31 * The creature's body33 Still going to do an eve-like body in blender, but due to problems34 importing the joints, etc into jMonkeyEngine3, I',m going to do all35 the connecting here in clojure code, using the names of the individual36 components and trial and error. Later, I'll maybe make some sort of37 creature-building modifications to blender that support whatever38 discreitized senses I'm going to make.40 #+name: body-141 #+begin_src clojure42 (ns cortex.silly43 "let's play!"44 {:author "Robert McIntyre"})46 ;; TODO remove this!47 (require 'cortex.import)48 (cortex.import/mega-import-jme3)49 (use '(cortex world util body hearing touch vision))51 (rlm.rlm-commands/help)53 (declare joint-create)55 (defn load-bullet []56 (let [sim (world (Node.) {} no-op no-op)]57 (.enqueue58 sim59 (fn []60 (.stop sim)))61 (.start sim)))63 (defn load-blender-model64 "Load a .blend file using an asset folder relative path."65 [^String model]66 (.loadModel67 (doto (asset-manager)68 (.registerLoader BlenderModelLoader (into-array String ["blend"])))69 model))71 (defn meta-data [blender-node key]72 (if-let [data (.getUserData blender-node "properties")]73 (.findValue data key)74 nil))76 (defn blender-to-jme77 "Convert from Blender coordinates to JME coordinates"78 [#^Vector3f in]79 (Vector3f. (.getX in)80 (.getZ in)81 (- (.getY in))))83 (defn jme-to-blender84 "Convert from JME coordinates to Blender coordinates"85 [#^Vector3f in]86 (Vector3f. (.getX in)87 (- (.getZ in))88 (.getY in)))90 (defn joint-targets91 "Return the two closest two objects to the joint object, ordered92 from bottom to top according to the joint's rotation."93 [#^Node parts #^Node joint]94 ;;(println (meta-data joint "joint"))95 (.getWorldRotation joint)96 (loop [radius (float 0.01)]97 (let [results (CollisionResults.)]98 (.collideWith99 parts100 (BoundingBox. (.getWorldTranslation joint)101 radius radius radius)102 results)103 (let [targets104 (distinct105 (map #(.getGeometry %) results))]106 (if (>= (count targets) 2)107 (sort-by108 #(let [v109 (jme-to-blender110 (.mult111 (.inverse (.getWorldRotation joint))112 (.subtract (.getWorldTranslation %)113 (.getWorldTranslation joint))))]114 (println-repl (.getName %) ":" v)115 (.dot (Vector3f. 1 1 1)116 v))117 (take 2 targets))118 (recur (float (* radius 2))))))))120 (defn world-to-local121 "Convert the world coordinates into coordinates relative to the122 object (i.e. local coordinates), taking into account the rotation123 of object."124 [#^Spatial object world-coordinate]125 (let [out (Vector3f.)]126 (.worldToLocal object world-coordinate out) out))128 (defmulti joint-dispatch129 "Translate blender pseudo-joints into real JME joints."130 (fn [constraints & _]131 (:type constraints)))133 (defmethod joint-dispatch :point134 [constraints control-a control-b pivot-a pivot-b rotation]135 (println-repl "creating POINT2POINT joint")136 (Point2PointJoint.137 control-a138 control-b139 pivot-a140 pivot-b))142 (defmethod joint-dispatch :hinge143 [constraints control-a control-b pivot-a pivot-b rotation]144 (println-repl "creating HINGE joint")145 (let [axis146 (if-let147 [axis (:axis constraints)]148 axis149 Vector3f/UNIT_X)150 [limit-1 limit-2] (:limit constraints)151 hinge-axis152 (.mult153 rotation154 (blender-to-jme axis))]155 (doto156 (HingeJoint.157 control-a158 control-b159 pivot-a160 pivot-b161 hinge-axis162 hinge-axis)163 (.setLimit limit-1 limit-2))))166 (defmethod joint-dispatch :cone167 [constraints control-a control-b pivot-a pivot-b rotation]168 (let [limit-xz (:limit-xz constraints)169 limit-xy (:limit-xy constraints)170 twist (:twist constraints)]173 (println-repl "creating CONE joint")174 (println-repl rotation)175 (println-repl176 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))177 (println-repl178 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))179 (println-repl180 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))181 (doto182 (ConeJoint.183 control-a184 control-b185 pivot-a186 pivot-b187 rotation188 rotation)189 (.setLimit (float limit-xz)190 (float limit-xy)191 (float twist)))))195 (defn connect196 "here are some examples:197 {:type :point}198 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}199 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)201 {:type :cone :limit-xz 0]202 :limit-xy 0]203 :twist 0]} (use XZY rotation mode in blender!)"204 [#^Node obj-a #^Node obj-b #^Node joint]205 (let [control-a (.getControl obj-a RigidBodyControl)206 control-b (.getControl obj-b RigidBodyControl)207 joint-center (.getWorldTranslation joint)208 joint-rotation (.toRotationMatrix (.getWorldRotation joint))209 pivot-a (world-to-local obj-a joint-center)210 pivot-b (world-to-local obj-b joint-center)]211 ;; A side-effect of creating a joint registers212 ;; it with both physics objects which in turn213 ;; will register the joint with the physics system214 ;; when the simulation is started.215 (if-let [constraints216 (map-vals217 eval218 (read-string219 (meta-data joint "joint")))]220 (do221 (println-repl "creating joint between"222 (.getName obj-a) "and" (.getName obj-b))223 (joint-dispatch constraints224 control-a control-b225 pivot-a pivot-b226 joint-rotation))228 (println-repl "could not find joint meta-data!"))))230 (defn assemble-creature [#^Node pieces joints]231 (dorun232 (map233 (fn [geom]234 (let [physics-control235 (RigidBodyControl.236 (HullCollisionShape.237 (.getMesh geom))238 (if-let [mass (meta-data geom "mass")]239 (do240 (println-repl241 "setting" (.getName geom) "mass to" (float mass))242 (float mass))243 (float 1)))]245 (.addControl geom physics-control)))246 (filter #(isa? (class %) Geometry )247 (node-seq pieces))))249 (dorun250 (map251 (fn [joint]252 (let [[obj-a obj-b]253 (joint-targets pieces joint)]254 (connect obj-a obj-b joint)))255 joints))256 pieces)258 (defn blender-creature [blender-path]259 (let [model (load-blender-model blender-path)260 joints261 (if-let [joint-node (.getChild model "joints")]262 (seq (.getChildren joint-node))263 (do (println-repl "could not find joints node")264 []))]265 (assemble-creature model joints)))267 (def hand "Models/creature1/one.blend")269 (def worm "Models/creature1/try-again.blend")271 (defn x-ray [#^ColorRGBA color]272 (doto (Material. (asset-manager)273 "Common/MatDefs/Misc/Unshaded.j3md")274 (.setColor "Color" color)275 (-> (.getAdditionalRenderState)276 (.setDepthTest false))))278 (defn test-creature [thing]279 (let [x-axis280 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)281 y-axis282 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)283 z-axis284 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]285 (world286 (nodify [(blender-creature thing)287 (box 10 2 10 :position (Vector3f. 0 -9 0)288 :color ColorRGBA/Gray :mass 0)289 x-axis y-axis z-axis290 ])291 standard-debug-controls292 (comp light-up-everything enable-debug293 (fn [world]294 (.setTimer world (NanoTimer.))295 ;;(set-gravity world (Vector3f. 0 0 0))296 (speed-up world)297 world298 ))299 no-op)))301 (defn world-setup [joint]302 (let [304 joint-position (Vector3f. 0 0 0)305 joint-rotation306 (.toRotationMatrix307 (.mult308 (doto (Quaternion.)309 (.fromAngleAxis310 (* 1 (/ Math/PI 4))311 (Vector3f. -1 0 0)))312 (doto (Quaternion.)313 (.fromAngleAxis314 (* 1 (/ Math/PI 2))315 (Vector3f. 0 0 1)))))316 top-position (.mult joint-rotation (Vector3f. 8 0 0))318 origin (doto319 (sphere 0.1 :physical? false :color ColorRGBA/Cyan320 :position top-position))321 top (doto322 (sphere 0.1 :physical? false :color ColorRGBA/Yellow323 :position top-position)325 (.addControl326 (RigidBodyControl.327 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))328 bottom (doto329 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray330 :position (Vector3f. 0 0 0))331 (.addControl332 (RigidBodyControl.333 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))334 table (box 10 2 10 :position (Vector3f. 0 -20 0)335 :color ColorRGBA/Gray :mass 0)336 a (.getControl top RigidBodyControl)337 b (.getControl bottom RigidBodyControl)]339 (cond340 (= joint :cone)342 (doto (ConeJoint.343 a b344 (world-to-local top joint-position)345 (world-to-local bottom joint-position)346 joint-rotation347 joint-rotation348 )351 (.setLimit (* (/ 10) Math/PI)352 (* (/ 4) Math/PI)353 0)))354 [origin top bottom table]))358 (defn test-joint [joint]359 (let [[origin top bottom floor] (world-setup joint)360 control (.getControl top RigidBodyControl)361 move-up? (atom false)362 move-down? (atom false)363 move-left? (atom false)364 move-right? (atom false)365 roll-left? (atom false)366 roll-right? (atom false)367 timer (atom 0)]369 (world370 (nodify [top bottom floor origin])371 (merge standard-debug-controls372 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))373 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))374 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))375 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))376 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))377 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})379 (fn [world]380 (light-up-everything world)381 (enable-debug world)382 (set-gravity world (Vector3f. 0 0 0))383 )385 (fn [world _]386 (if (zero? (rem (swap! timer inc) 100))387 (do388 ;; (println-repl @timer)389 (.attachChild (.getRootNode world)390 (sphere 0.05 :color ColorRGBA/Yellow391 :position (.getWorldTranslation top)392 :physical? false))393 (.attachChild (.getRootNode world)394 (sphere 0.05 :color ColorRGBA/LightGray395 :position (.getWorldTranslation bottom)396 :physical? false))))398 (if @move-up?399 (.applyTorque control400 (.mult (.getPhysicsRotation control)401 (Vector3f. 0 0 10))))402 (if @move-down?403 (.applyTorque control404 (.mult (.getPhysicsRotation control)405 (Vector3f. 0 0 -10))))406 (if @move-left?407 (.applyTorque control408 (.mult (.getPhysicsRotation control)409 (Vector3f. 0 10 0))))410 (if @move-right?411 (.applyTorque control412 (.mult (.getPhysicsRotation control)413 (Vector3f. 0 -10 0))))414 (if @roll-left?415 (.applyTorque control416 (.mult (.getPhysicsRotation control)417 (Vector3f. -1 0 0))))418 (if @roll-right?419 (.applyTorque control420 (.mult (.getPhysicsRotation control)421 (Vector3f. 1 0 0))))))))425 #+end_src427 #+results: body-1428 : #'cortex.silly/test-joint431 * COMMENT purgatory432 #+begin_src clojure433 (defn bullet-trans []434 (let [obj-a (sphere 0.5 :color ColorRGBA/Red435 :position (Vector3f. -10 5 0))436 obj-b (sphere 0.5 :color ColorRGBA/Blue437 :position (Vector3f. -10 -5 0)438 :mass 0)439 control-a (.getControl obj-a RigidBodyControl)440 control-b (.getControl obj-b RigidBodyControl)441 swivel442 (.toRotationMatrix443 (doto (Quaternion.)444 (.fromAngleAxis (/ Math/PI 2)445 Vector3f/UNIT_X)))]446 (doto447 (ConeJoint.448 control-a control-b449 (Vector3f. 0 5 0)450 (Vector3f. 0 -5 0)451 swivel swivel)452 (.setLimit (* 0.6 (/ Math/PI 4))453 (/ Math/PI 4)454 (* Math/PI 0.8)))455 (world (nodify456 [obj-a obj-b])457 standard-debug-controls458 enable-debug459 no-op)))462 (defn bullet-trans* []463 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red464 :position (Vector3f. 5 0 0)465 :mass 90)466 obj-b (sphere 0.5 :color ColorRGBA/Blue467 :position (Vector3f. -5 0 0)468 :mass 0)469 control-a (.getControl obj-a RigidBodyControl)470 control-b (.getControl obj-b RigidBodyControl)471 move-up? (atom nil)472 move-down? (atom nil)473 move-left? (atom nil)474 move-right? (atom nil)475 roll-left? (atom nil)476 roll-right? (atom nil)477 force 100478 swivel479 (.toRotationMatrix480 (doto (Quaternion.)481 (.fromAngleAxis (/ Math/PI 2)482 Vector3f/UNIT_X)))483 x-move484 (doto (Matrix3f.)485 (.fromStartEndVectors Vector3f/UNIT_X486 (.normalize (Vector3f. 1 1 0))))488 timer (atom 0)]489 (doto490 (ConeJoint.491 control-a control-b492 (Vector3f. -8 0 0)493 (Vector3f. 2 0 0)494 ;;swivel swivel495 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY496 x-move Matrix3f/IDENTITY497 )498 (.setCollisionBetweenLinkedBodys false)499 (.setLimit (* 1 (/ Math/PI 4)) ;; twist500 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane501 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane502 (world (nodify503 [obj-a obj-b])504 (merge standard-debug-controls505 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))506 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))507 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))508 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))509 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))510 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})512 (fn [world]513 (enable-debug world)514 (set-gravity world Vector3f/ZERO)515 )517 (fn [world _]519 (if @move-up?520 (.applyForce control-a521 (Vector3f. force 0 0)522 (Vector3f. 0 0 0)))523 (if @move-down?524 (.applyForce control-a525 (Vector3f. (- force) 0 0)526 (Vector3f. 0 0 0)))527 (if @move-left?528 (.applyForce control-a529 (Vector3f. 0 force 0)530 (Vector3f. 0 0 0)))531 (if @move-right?532 (.applyForce control-a533 (Vector3f. 0 (- force) 0)534 (Vector3f. 0 0 0)))536 (if @roll-left?537 (.applyForce control-a538 (Vector3f. 0 0 force)539 (Vector3f. 0 0 0)))540 (if @roll-right?541 (.applyForce control-a542 (Vector3f. 0 0 (- force))543 (Vector3f. 0 0 0)))545 (if (zero? (rem (swap! timer inc) 100))546 (.attachChild547 (.getRootNode world)548 (sphere 0.05 :color ColorRGBA/Yellow549 :physical? false :position550 (.getWorldTranslation obj-a)))))551 )552 ))556 #+end_src559 * COMMENT generate source560 #+begin_src clojure :tangle ../src/cortex/silly.clj561 <<body-1>>562 #+end_src