Mercurial > cortex
view org/test-creature.org @ 87:af1bb43661f9
working on multimethod joint creation
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 07 Jan 2012 05:06:58 -0700 |
parents | 00ab1f10266f |
children | 3e929630a25f |
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 zz129 (fn [a b _ _ _ _ _]131 (:type a)))132 (defmethod zz :p [a b] (println "hi"))135 (defmulti joint-dispatch136 "Translate blender pseudo-joints into real JME joints."137 (fn [constraints _ _ _ _ _]138 (:type constraints)))140 (defmethod joint-dispatch :point141 [constraints control-a control-b pivot-a pivot-b rotation]142 (println-repl "creating POINT2POINT joint")143 (Point2PointJoint.144 control-a145 control-b146 pivot-a147 pivot-b))149 (defmethod joint-dispatch :hinge150 [constraints control-a control-b pivot-a pivot-b rotation]151 (println-repl "creating HINGE joint")152 (let [axis153 (if-let154 [axis (:axis constraints)]155 axis156 Vector3f/UNIT_X)157 [limit-1 limit-2] (:limit constraints)158 hinge-axis159 (.mult160 rotation161 (blender-to-jme axis))]162 (doto163 (HingeJoint.164 control-a165 control-b166 pivot-a167 pivot-b168 hinge-axis169 hinge-axis)170 (.setLimit limit-1 limit-2))))173 (defmethod joint-dispatch :cone174 [constraints control-a control-b pivot-a pivot-b rotation]175 (let [limit-xz (:limit-xz constraints)176 limit-xy (:limit-xy constraints)177 twist (:twist constraints)]180 (println-repl "creating CONE joint")181 (println-repl rotation)182 (println-repl183 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))184 (println-repl185 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))186 (println-repl187 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))188 (doto189 (ConeJoint.190 control-a191 control-b192 pivot-a193 pivot-b194 rotation195 rotation)196 (.setLimit (float limit-xz)197 (float limit-xy)198 (float twist)))))202 (defn connect*203 "here are some examples:204 {:type :point}205 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}206 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)208 {:type :cone :limit-xz 0]209 :limit-xy 0]210 :twist 0]} (use XZY rotation mode in blender!)"211 [#^Node obj-a #^Node obj-b #^Node joint]212 (let [control-a (.getControl obj-a RigidBodyControl)213 control-b (.getControl obj-b RigidBodyControl)214 joint-center (.getWorldTranslation joint)215 joint-rotation (.toRotationMatrix (.getWorldRotation joint))216 pivot-a (world-to-local obj-a joint-center)217 pivot-b (world-to-local obj-b joint-center)]218 ;; A side-effect of creating a joint registers219 ;; it with both physics objects which in turn220 ;; will register the joint with the physics system221 ;; when the simulation is started.222 (if-let [constraints223 (map-vals224 eval225 (read-string226 (meta-data joint "joint")))]227 (do228 (println-repl "creating joint between"229 (.getName obj-a) "and" (.getName obj-b))230 (joint-dispatch constraints231 control-a control-b232 pivot-a pivot-b233 joint-rotation))235 (println-repl "could not find joint meta-data!"))))240 (defn connect241 "here are some examples:242 {:type :point}243 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}244 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)246 {:type :cone :limit-xz 0]247 :limit-xy 0]248 :twist 0]} (use XZY rotation mode in blender!)"249 [#^Node obj-a #^Node obj-b #^Node joint]250 (let [control-a (.getControl obj-a RigidBodyControl)251 control-b (.getControl obj-b RigidBodyControl)252 joint-center (.getWorldTranslation joint)253 joint-rotation (.toRotationMatrix (.getWorldRotation joint))254 pivot-a (world-to-local obj-a joint-center)255 pivot-b (world-to-local obj-b joint-center)]256 ;; A side-effect of creating a joint registers257 ;; it with both physics objects which in turn258 ;; will register the joint with the physics system259 ;; when the simulation is started.260 (if-let [constraints261 (map-vals262 eval263 (read-string264 (meta-data joint "joint")))]266 (let [joint-type (:type constraints)]267 (println-repl "creating joint between"268 (.getName obj-a) "and" (.getName obj-b))269 (cond (= :point joint-type)270 (do271 (println-repl "creating POINT joint")272 (Point2PointJoint.273 control-a274 control-b275 pivot-a276 pivot-b))277 (= :hinge joint-type)278 (do279 (println-repl "creating HINGE joint")280 (let [axis (if-let281 [axis (:axis constraints)]282 axis283 Vector3f/UNIT_X)284 [limit-1 limit-2] (:limit constraints)285 hinge-axis286 (.mult287 (.getWorldRotation joint)288 (blender-to-jme axis))]289 (doto290 (HingeJoint.291 control-a292 control-b293 pivot-a294 pivot-b295 hinge-axis296 hinge-axis)297 (.setLimit limit-1 limit-2))))298 (= :cone joint-type)299 (do300 (let [limit-xz (:limit-xz constraints)301 limit-xy (:limit-xy constraints)302 twist (:twist constraints)]305 (println-repl "creating CONE joint")306 (println-repl joint-rotation)307 (println-repl308 "UNIT_X --> " (.mult joint-rotation (Vector3f. 1 0 0)))309 (println-repl310 "UNIT_Y --> " (.mult joint-rotation (Vector3f. 0 1 0)))311 (println-repl312 "UNIT_Z --> " (.mult joint-rotation (Vector3f. 0 0 1)))313 (doto314 (ConeJoint.315 control-a316 control-b317 pivot-a318 pivot-b319 joint-rotation320 joint-rotation321 )322 (.setLimit (float limit-xz)323 (float limit-xy)324 (float twist)))))325 true326 (println-repl327 "joint-type" joint-type "not recognized")))329 (println-repl "could not find joint meta-data!"))))332 (defn assemble-creature [#^Node pieces joints]333 (dorun334 (map335 (fn [geom]336 (let [physics-control337 (RigidBodyControl.338 (HullCollisionShape.339 (.getMesh geom))340 (if-let [mass (meta-data geom "mass")]341 (do342 (println-repl343 "setting" (.getName geom) "mass to" (float mass))344 (float mass))345 (float 1)))]347 (.addControl geom physics-control)))348 (filter #(isa? (class %) Geometry )349 (node-seq pieces))))351 (dorun352 (map353 (fn [joint]354 (let [[obj-a obj-b]355 (joint-targets pieces joint)]356 (connect* obj-a obj-b joint)))357 joints))358 pieces)360 (defn blender-creature [blender-path]361 (let [model (load-blender-model blender-path)362 joints363 (if-let [joint-node (.getChild model "joints")]364 (seq (.getChildren joint-node))365 (do (println-repl "could not find joints node")366 []))]367 (assemble-creature model joints)))369 (def hand "Models/creature1/one.blend")371 (def worm "Models/creature1/try-again.blend")373 (defn x-ray [#^ColorRGBA color]374 (doto (Material. (asset-manager)375 "Common/MatDefs/Misc/Unshaded.j3md")376 (.setColor "Color" color)377 (-> (.getAdditionalRenderState)378 (.setDepthTest false))))380 (defn test-creature [thing]381 (let [x-axis382 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)383 y-axis384 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)385 z-axis386 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]387 (world388 (nodify [(blender-creature thing)389 (box 10 2 10 :position (Vector3f. 0 -9 0)390 :color ColorRGBA/Gray :mass 0)391 x-axis y-axis z-axis392 ])393 standard-debug-controls394 (comp light-up-everything enable-debug395 (fn [world]396 (.setTimer world (NanoTimer.))397 ;;(set-gravity world (Vector3f. 0 0 0))398 (speed-up world)399 world400 ))401 no-op)))403 (defn world-setup [joint]404 (let [406 joint-position (Vector3f. 0 0 0)407 joint-rotation408 (.toRotationMatrix409 (.mult410 (doto (Quaternion.)411 (.fromAngleAxis412 (* 1 (/ Math/PI 4))413 (Vector3f. -1 0 0)))414 (doto (Quaternion.)415 (.fromAngleAxis416 (* 1 (/ Math/PI 2))417 (Vector3f. 0 0 1)))))418 top-position (.mult joint-rotation (Vector3f. 8 0 0))420 origin (doto421 (sphere 0.1 :physical? false :color ColorRGBA/Cyan422 :position top-position))423 top (doto424 (sphere 0.1 :physical? false :color ColorRGBA/Yellow425 :position top-position)427 (.addControl428 (RigidBodyControl.429 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))430 bottom (doto431 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray432 :position (Vector3f. 0 0 0))433 (.addControl434 (RigidBodyControl.435 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))436 table (box 10 2 10 :position (Vector3f. 0 -20 0)437 :color ColorRGBA/Gray :mass 0)438 a (.getControl top RigidBodyControl)439 b (.getControl bottom RigidBodyControl)]441 (cond442 (= joint :cone)444 (doto (ConeJoint.445 a b446 (world-to-local top joint-position)447 (world-to-local bottom joint-position)448 joint-rotation449 joint-rotation450 )453 (.setLimit (* (/ 10) Math/PI)454 (* (/ 4) Math/PI)455 0)))456 [origin top bottom table]))460 (defn test-joint [joint]461 (let [[origin top bottom floor] (world-setup joint)462 control (.getControl top RigidBodyControl)463 move-up? (atom false)464 move-down? (atom false)465 move-left? (atom false)466 move-right? (atom false)467 roll-left? (atom false)468 roll-right? (atom false)469 timer (atom 0)]471 (world472 (nodify [top bottom floor origin])473 (merge standard-debug-controls474 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))475 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))476 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))477 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))478 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))479 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})481 (fn [world]482 (light-up-everything world)483 (enable-debug world)484 (set-gravity world (Vector3f. 0 0 0))485 )487 (fn [world _]488 (if (zero? (rem (swap! timer inc) 100))489 (do490 ;; (println-repl @timer)491 (.attachChild (.getRootNode world)492 (sphere 0.05 :color ColorRGBA/Yellow493 :position (.getWorldTranslation top)494 :physical? false))495 (.attachChild (.getRootNode world)496 (sphere 0.05 :color ColorRGBA/LightGray497 :position (.getWorldTranslation bottom)498 :physical? false))))500 (if @move-up?501 (.applyTorque control502 (.mult (.getPhysicsRotation control)503 (Vector3f. 0 0 10))))504 (if @move-down?505 (.applyTorque control506 (.mult (.getPhysicsRotation control)507 (Vector3f. 0 0 -10))))508 (if @move-left?509 (.applyTorque control510 (.mult (.getPhysicsRotation control)511 (Vector3f. 0 10 0))))512 (if @move-right?513 (.applyTorque control514 (.mult (.getPhysicsRotation control)515 (Vector3f. 0 -10 0))))516 (if @roll-left?517 (.applyTorque control518 (.mult (.getPhysicsRotation control)519 (Vector3f. -1 0 0))))520 (if @roll-right?521 (.applyTorque control522 (.mult (.getPhysicsRotation control)523 (Vector3f. 1 0 0))))))))527 #+end_src529 #+results: body-1530 : #'cortex.silly/test-joint533 * COMMENT purgatory534 #+begin_src clojure535 (defn bullet-trans []536 (let [obj-a (sphere 0.5 :color ColorRGBA/Red537 :position (Vector3f. -10 5 0))538 obj-b (sphere 0.5 :color ColorRGBA/Blue539 :position (Vector3f. -10 -5 0)540 :mass 0)541 control-a (.getControl obj-a RigidBodyControl)542 control-b (.getControl obj-b RigidBodyControl)543 swivel544 (.toRotationMatrix545 (doto (Quaternion.)546 (.fromAngleAxis (/ Math/PI 2)547 Vector3f/UNIT_X)))]548 (doto549 (ConeJoint.550 control-a control-b551 (Vector3f. 0 5 0)552 (Vector3f. 0 -5 0)553 swivel swivel)554 (.setLimit (* 0.6 (/ Math/PI 4))555 (/ Math/PI 4)556 (* Math/PI 0.8)))557 (world (nodify558 [obj-a obj-b])559 standard-debug-controls560 enable-debug561 no-op)))564 (defn bullet-trans* []565 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red566 :position (Vector3f. 5 0 0)567 :mass 90)568 obj-b (sphere 0.5 :color ColorRGBA/Blue569 :position (Vector3f. -5 0 0)570 :mass 0)571 control-a (.getControl obj-a RigidBodyControl)572 control-b (.getControl obj-b RigidBodyControl)573 move-up? (atom nil)574 move-down? (atom nil)575 move-left? (atom nil)576 move-right? (atom nil)577 roll-left? (atom nil)578 roll-right? (atom nil)579 force 100580 swivel581 (.toRotationMatrix582 (doto (Quaternion.)583 (.fromAngleAxis (/ Math/PI 2)584 Vector3f/UNIT_X)))585 x-move586 (doto (Matrix3f.)587 (.fromStartEndVectors Vector3f/UNIT_X588 (.normalize (Vector3f. 1 1 0))))590 timer (atom 0)]591 (doto592 (ConeJoint.593 control-a control-b594 (Vector3f. -8 0 0)595 (Vector3f. 2 0 0)596 ;;swivel swivel597 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY598 x-move Matrix3f/IDENTITY599 )600 (.setCollisionBetweenLinkedBodys false)601 (.setLimit (* 1 (/ Math/PI 4)) ;; twist602 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane603 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane604 (world (nodify605 [obj-a obj-b])606 (merge standard-debug-controls607 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))608 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))609 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))610 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))611 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))612 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})614 (fn [world]615 (enable-debug world)616 (set-gravity world Vector3f/ZERO)617 )619 (fn [world _]621 (if @move-up?622 (.applyForce control-a623 (Vector3f. force 0 0)624 (Vector3f. 0 0 0)))625 (if @move-down?626 (.applyForce control-a627 (Vector3f. (- force) 0 0)628 (Vector3f. 0 0 0)))629 (if @move-left?630 (.applyForce control-a631 (Vector3f. 0 force 0)632 (Vector3f. 0 0 0)))633 (if @move-right?634 (.applyForce control-a635 (Vector3f. 0 (- force) 0)636 (Vector3f. 0 0 0)))638 (if @roll-left?639 (.applyForce control-a640 (Vector3f. 0 0 force)641 (Vector3f. 0 0 0)))642 (if @roll-right?643 (.applyForce control-a644 (Vector3f. 0 0 (- force))645 (Vector3f. 0 0 0)))647 (if (zero? (rem (swap! timer inc) 100))648 (.attachChild649 (.getRootNode world)650 (sphere 0.05 :color ColorRGBA/Yellow651 :physical? false :position652 (.getWorldTranslation obj-a)))))653 )654 ))658 #+end_src661 * COMMENT generate source662 #+begin_src clojure :tangle ../src/cortex/silly.clj663 <<body-1>>664 #+end_src