Mercurial > cortex
view org/test-creature.org @ 77:1f84f425e05d
first draft of automatic constraints from blender
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 04 Jan 2012 08:36:42 -0700 |
parents | f4c77512808e |
children | 77b506ac64f3 |
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 (use '[clojure.contrib [seq :only [find-first]]])54 (rlm.rlm-commands/help)56 (defn load-blender-model57 "Load a .blend file using an asset folder relative path."58 [^String model]59 (.loadModel60 (doto (asset-manager)61 (.registerLoader BlenderModelLoader (into-array String ["blend"])))62 model))64 (defn meta-data [blender-node key]65 (if-let [data (.getUserData blender-node "properties")]66 (.findValue data key)67 nil))70 (defn hand []71 (load-blender-model "Models/creature1/one.blend"))75 (def hand-names76 #{77 "middle-1"78 "middle-2"79 "middle-3"80 "palm"81 "pinky-1"82 "pinky-2"83 "pinky-3"84 "pointer-1"85 "pointer-2"86 "pointer-3"87 "ring-1"88 "ring-2"89 "ring-3"90 "thumb-1"91 "thumb-2"})93 (defn hand-pieces []94 (filter95 (comp hand-names #(apply str (drop-last (.getName %)))) (node-seq (hand))))97 (defn hand-joints []98 (map #(.getWorldTranslation %)99 (filter #(re-matches #"joint\.\d\d\d" (.getName %))100 (node-seq (hand)))))101 (defn worm []102 (load-blender-model "Models/creature1/try-again.blend"))105 (defn worm-pieces []106 (filter107 (comp #{"worm-2" "worm-1"}108 #(apply str (drop-last (.getName %))))109 (node-seq (worm))))111 (defn worm-joints []112 (filter #(re-matches #"joint\.\d\d\d" (.getName %))113 (node-seq (worm))))115 (defn bullet-trans []116 (let [obj-a (sphere 0.5 :color ColorRGBA/Red117 :position (Vector3f. -10 5 0))118 obj-b (sphere 0.5 :color ColorRGBA/Blue119 :position (Vector3f. -10 -5 0)120 :mass 0)121 control-a (.getControl obj-a RigidBodyControl)122 control-b (.getControl obj-b RigidBodyControl)123 swivel124 (.toRotationMatrix125 (doto (Quaternion.)126 (.fromAngleAxis (/ Math/PI 2)127 Vector3f/UNIT_X)))]128 (doto129 (ConeJoint.130 control-a control-b131 (Vector3f. 0 5 0)132 (Vector3f. 0 -5 0)133 swivel swivel)134 (.setLimit (* 0.6 (/ Math/PI 4))135 (/ Math/PI 4)136 (* Math/PI 0.8)))137 (world (nodify138 [obj-a obj-b])139 standard-debug-controls140 enable-debug141 no-op)))144 (defn bullet-trans* []145 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red146 :position (Vector3f. 5 0 0)147 :mass 90)148 obj-b (sphere 0.5 :color ColorRGBA/Blue149 :position (Vector3f. -5 0 0)150 :mass 0)151 control-a (.getControl obj-a RigidBodyControl)152 control-b (.getControl obj-b RigidBodyControl)153 move-up? (atom nil)154 move-down? (atom nil)155 move-left? (atom nil)156 move-right? (atom nil)157 roll-left? (atom nil)158 roll-right? (atom nil)159 force 100160 swivel161 (.toRotationMatrix162 (doto (Quaternion.)163 (.fromAngleAxis (/ Math/PI 2)164 Vector3f/UNIT_X)))165 x-move166 (doto (Matrix3f.)167 (.fromStartEndVectors Vector3f/UNIT_X168 (.normalize (Vector3f. 1 1 0))))170 timer (atom 0)]171 (doto172 (ConeJoint.173 control-a control-b174 (Vector3f. -8 0 0)175 (Vector3f. 2 0 0)176 ;;swivel swivel177 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY178 x-move Matrix3f/IDENTITY179 )180 (.setCollisionBetweenLinkedBodys false)181 (.setLimit (* 1 (/ Math/PI 4)) ;; twist182 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane183 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane184 (world (nodify185 [obj-a obj-b])186 (merge standard-debug-controls187 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))188 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))189 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))190 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))191 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))192 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})194 (fn [world]195 (enable-debug world)196 (set-gravity world Vector3f/ZERO)197 )199 (fn [world _]201 (if @move-up?202 (.applyForce control-a203 (Vector3f. force 0 0)204 (Vector3f. 0 0 0)))205 (if @move-down?206 (.applyForce control-a207 (Vector3f. (- force) 0 0)208 (Vector3f. 0 0 0)))209 (if @move-left?210 (.applyForce control-a211 (Vector3f. 0 force 0)212 (Vector3f. 0 0 0)))213 (if @move-right?214 (.applyForce control-a215 (Vector3f. 0 (- force) 0)216 (Vector3f. 0 0 0)))218 (if @roll-left?219 (.applyForce control-a220 (Vector3f. 0 0 force)221 (Vector3f. 0 0 0)))222 (if @roll-right?223 (.applyForce control-a224 (Vector3f. 0 0 (- force))225 (Vector3f. 0 0 0)))227 (if (zero? (rem (swap! timer inc) 100))228 (.attachChild229 (.getRootNode world)230 (sphere 0.05 :color ColorRGBA/Yellow231 :physical? false :position232 (.getWorldTranslation obj-a)))))233 )234 ))246 (defn world-setup [joint]247 (let [top (doto248 (sphere 0.1 :physical? false :color ColorRGBA/Yellow249 :position (Vector3f. 0 7 0))250 (.addControl251 (RigidBodyControl.252 (CapsuleCollisionShape. 0.5 1.5 1) (float 15))))253 bottom (doto254 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray255 :position (Vector3f. 0 -1 0))256 (.addControl257 (RigidBodyControl.258 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))259 table (box 10 2 10 :position (Vector3f. 0 -6 0)260 :color ColorRGBA/Gray :mass 0)261 a (.getControl top RigidBodyControl)262 b (.getControl bottom RigidBodyControl)]263 (cond264 (= joint :point)265 (doto266 (Point2PointJoint. a b267 (Vector3f. 0 -2 0)268 (Vector3f. 0 2 0))269 (.setCollisionBetweenLinkedBodys false))270 (= joint :hinge)271 (doto272 (HingeJoint.273 a b274 (Vector3f. 0 -2 0)275 (Vector3f. 0 2 0)276 (Vector3f. 0 0 1)277 (Vector3f. 0 0 1)279 )280 (.setCollisionBetweenLinkedBodys false)281 ;;(.setLimit (- Math/PI) Math/PI)282 )283 (= joint :cone)284 ;; note to self -- jbullet does NOT implement cone joints285 ;; correctly. You must use plain ol' bullet for this to work.286 ;; It's faster anyway, so whatever.288 (doto (ConeJoint.289 a b290 (Vector3f. 0 -5 0)291 (Vector3f. 0 2 0)293 (doto (Matrix3f.)294 (.fromStartEndVectors Vector3f/UNIT_X295 Vector3f/UNIT_Y))296 (doto (Matrix3f.)297 (.fromStartEndVectors Vector3f/UNIT_X298 Vector3f/UNIT_Y))299 )300 ;;(.setAngularOnly true)302 (.setCollisionBetweenLinkedBodys false)303 (.setLimit (* 1 (/ Math/PI 4))304 (* 1 (/ Math/PI 4))305 (* 0 (/ Math/PI 4)))307 )308 (= joint :six)309 (doto310 (SixDofJoint.311 a b312 (Vector3f. 0 -2 0)313 (Vector3f. 0 2 0)314 ;;(doto (Matrix3f.)315 ;; (.fromStartEndVectors Vector3f/UNIT_X316 ;; Vector3f/UNIT_Y))317 ;;(doto (Matrix3f.)318 ;; (.fromStartEndVectors Vector3f/UNIT_X319 ;; Vector3f/UNIT_Y))320 true)321 (.setCollisionBetweenLinkedBodys false)322 (.setAngularLowerLimit (Vector3f. 0323 (- (/ Math/PI 2))324 0))326 (.setAngularUpperLimit (Vector3f. 0327 (/ Math/PI 2)328 0))329 (.setLinearLowerLimit (Vector3f. 0 0 0))330 (.setLinearUpperLimit (Vector3f. 0 0 0))332 )338 )340 [top bottom table]))342 (defn speed-up [world]343 (.setMoveSpeed (.getFlyByCamera world)344 (float 100))345 (.setRotationSpeed (.getFlyByCamera world)346 (float 20))347 world)350 (defn test-joint [joint]351 (let [[top bottom floor] (world-setup joint)352 control (.getControl top RigidBodyControl)353 move-up? (atom false)354 move-down? (atom false)355 move-left? (atom false)356 move-right? (atom false)357 roll-left? (atom false)358 roll-right? (atom false)359 timer (atom 0)]361 (world362 (nodify [top bottom floor])363 (merge standard-debug-controls364 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))365 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))366 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))367 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))368 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))369 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})371 (fn [world]372 (light-up-everything world)373 (enable-debug world)374 (set-gravity world (Vector3f. 0 0 0))375 )377 (fn [world _]378 (if (zero? (rem (swap! timer inc) 100))379 (do380 ;; (println-repl @timer)381 (.attachChild (.getRootNode world)382 (sphere 0.05 :color ColorRGBA/Yellow383 :position (.getWorldTranslation top)384 :physical? false))))385 (if @move-up?386 (.applyTorque control387 (.mult (.getPhysicsRotation control)388 (Vector3f. 0 0 10))))389 (if @move-down?390 (.applyTorque control391 (.mult (.getPhysicsRotation control)392 (Vector3f. 0 0 -10))))393 (if @move-left?394 (.applyTorque control395 (.mult (.getPhysicsRotation control)396 (Vector3f. 0 10 0))))397 (if @move-right?398 (.applyTorque control399 (.mult (.getPhysicsRotation control)400 (Vector3f. 0 -10 0))))401 (if @roll-left?402 (.applyTorque control403 (.mult (.getPhysicsRotation control)404 (Vector3f. -1 0 0))))405 (if @roll-right?406 (.applyTorque control407 (.mult (.getPhysicsRotation control)408 (Vector3f. 1 0 0))))))))412 (defn run [joint] (.start (test-joint joint)))413 (defn look [joint] (view (nodify (world-setup joint))))415 (defn blender-to-jme416 "Convert from Blender coordinates to JME coordinates"417 [#^Vector3f in]418 (Vector3f. (.getX in)419 (.getZ in)420 (- (.getY in))))423 (defn joint-targets424 "Return the two closest two objects to the joint object, ordered425 from bottom to top according to the joint's rotation."426 [#^Node parts #^Node joint]427 ;;(println (meta-data joint "joint"))428 (.getWorldRotation joint)429 (loop [radius (float 0.01)]430 (let [results (CollisionResults.)]431 (.collideWith432 parts433 (BoundingBox. (.getWorldTranslation joint)434 radius radius radius)435 results)436 (let [targets437 (distinct438 (map #(.getGeometry %) results))]439 (if (>= (count targets) 2)440 (sort-by441 #(.getY442 (.mult443 (.inverse (.getWorldRotation joint))444 (.subtract (.getWorldTranslation %)445 (.getWorldTranslation joint))))446 (take 2 targets))447 (recur (float (* radius 2))))))))449 (defn connect450 "here are some examples:451 {:type :point}452 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}453 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)455 {:type :cone :limit-xz 0]456 :limit-yz 0]457 :twist 0]}458 "459 ([#^Node obj-a #^Node obj-b #^Node joint]460 (let [center-a (.getWorldTranslation obj-a)461 center-b (.getWorldTranslation obj-b)462 joint-center (.getWorldTranslation joint)463 pivot-a (.subtract joint-center center-a)464 pivot-b (.subtract joint-center center-b)465 control-a (.getControl obj-a RigidBodyControl)466 control-b (.getControl obj-b RigidBodyControl)]467 ;; A side-effect of creating a joint registers468 ;; it with both physics objects which in turn469 ;; will register the joint with the physics system470 ;; when the simulation is started.471 (if-let [constraints472 (map-vals473 eval474 (read-string475 (meta-data (first (worm-joints)) "joint")))]477 (let [joint-type (:type constraints)]478 (cond (= :point joint-type)479 (do480 (println-repl "creating POINT joint")481 (Point2PointJoint.482 control-a483 control-b484 pivot-a485 pivot-b))486 (= :hinge joint-type)487 (do488 (println-repl "creating HINGE joint")489 (let [axis (if-let490 [axis (:axis constraints)]491 axis492 Vector3f/UNIT_X)493 [limit-1 limit-2] (:limit constraints)494 hinge-axis495 (.mult496 (.getWorldRotation joint)497 (blender-to-jme axis))]498 (doto499 (HingeJoint.500 control-a501 control-b502 pivot-a503 pivot-b504 hinge-axis505 hinge-axis)506 (.setLimit limit-1 limit-2))))507 (= :cone joint-type)508 (do509 (let [limit-xy (:limit-xz constraints)510 limit-yz (:limit-yz constraints)511 twist (:twist constraints)]513 (println-repl "creating CONE joint")514 (doto515 (ConeJoint.516 control-a517 control-b518 pivot-a519 pivot-b520 (doto (Matrix3f.)521 (.fromStartEndVectors522 Vector3f/UNIT_X523 (.normalize524 (.subtract (.getWorldTranslation joint)525 (.getWorldTranslation obj-a)))))526 (doto (Matrix3f.)527 (.fromStartEndVectors528 Vector3f/UNIT_X529 (.normalize530 (.subtract531 (.getWorldTranslation obj-b)532 (.getWorldTranslation joint))))))533 (.setLimit (float limit-xy)534 (float limit-yz)535 (float twist)))))536 true537 (println-repl538 "joint-type " joint-type " not recognized")))540 (println-repl "could not find joint meta-data!")))))544 (defn physical-worm [#^Node pieces joints]545 (dorun546 (map547 (fn [geom]548 (let [physics-control549 (RigidBodyControl.550 (HullCollisionShape.551 (.getMesh geom))552 (if-let [mass (meta-data geom "mass")]553 (do554 (println-repl555 "setting mass to " (float mass))556 (float mass))557 (float 1)))]559 (.addControl geom physics-control)))560 (filter #(isa? (class %) Geometry )561 (node-seq pieces))))563 (dorun564 (map565 (fn [joint]566 (let [[obj-a obj-b]567 (joint-targets pieces joint)]568 (connect obj-a obj-b joint)))569 joints))570 pieces)572 (defn the-worm []573 (physical-worm (worm) (worm-joints)))575 (defn test-worm []576 (world577 (nodify [(the-worm)578 (box 10 2 10 :position (Vector3f. 0 -5 0)579 :color ColorRGBA/Gray :mass 0)])580 standard-debug-controls581 (comp light-up-everything enable-debug582 (fn [world]583 (.setTimer world (NanoTimer.))584 (speed-up world)585 ;;(set-gravity world (Vector3f. 0 0 0))586 world587 ))588 no-op))590 #+end_src592 #+results: body-1593 : #'cortex.silly/test-try-again597 * COMMENT generate source598 #+begin_src clojure :tangle ../src/cortex/silly.clj599 <<body-1>>600 #+end_src