Mercurial > cortex
view org/test-creature.org @ 81:10f495560c59
correcting problem with joints
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 05 Jan 2012 21:31:34 -0700 |
parents | 7af5ef686539 |
children | 6b4ca076285e |
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 (defn load-blender-model54 "Load a .blend file using an asset folder relative path."55 [^String model]56 (.loadModel57 (doto (asset-manager)58 (.registerLoader BlenderModelLoader (into-array String ["blend"])))59 model))61 (defn meta-data [blender-node key]62 (if-let [data (.getUserData blender-node "properties")]63 (.findValue data key)64 nil))66 (defn blender-to-jme67 "Convert from Blender coordinates to JME coordinates"68 [#^Vector3f in]69 (Vector3f. (.getX in)70 (.getZ in)71 (- (.getY in))))73 (defn jme-to-blender74 "Convert from JME coordinates to Blender coordinates"75 [#^Vector3f in]76 (Vector3f. (.getX in)77 (- (.getZ in))78 (.getY in)))80 (defn joint-targets81 "Return the two closest two objects to the joint object, ordered82 from bottom to top according to the joint's rotation."83 [#^Node parts #^Node joint]84 ;;(println (meta-data joint "joint"))85 (.getWorldRotation joint)86 (loop [radius (float 0.01)]87 (let [results (CollisionResults.)]88 (.collideWith89 parts90 (BoundingBox. (.getWorldTranslation joint)91 radius radius radius)92 results)93 (let [targets94 (distinct95 (map #(.getGeometry %) results))]96 (if (>= (count targets) 2)97 (sort-by98 #(let [v99 (jme-to-blender100 (.mult101 (.inverse (.getWorldRotation joint))102 (.subtract (.getWorldTranslation %)103 (.getWorldTranslation joint))))]104 (println-repl (.getName %) ":" v)105 (.dot (Vector3f. 1 1 1)106 v))107 (take 2 targets))108 (recur (float (* radius 2))))))))110 (defn connect111 "here are some examples:112 {:type :point}113 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}114 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)116 {:type :cone :limit-xz 0]117 :limit-xy 0]118 :twist 0]} (use XZY rotation mode in blender!)"119 [#^Node obj-a #^Node obj-b #^Node joint]120 (let [center-a (.getWorldTranslation obj-a)121 center-b (.getWorldTranslation obj-b)122 joint-center (.getWorldTranslation joint)123 pivot-a (.subtract joint-center center-a)124 pivot-b (.subtract joint-center center-b)125 control-a (.getControl obj-a RigidBodyControl)126 control-b (.getControl obj-b RigidBodyControl)]127 ;; A side-effect of creating a joint registers128 ;; it with both physics objects which in turn129 ;; will register the joint with the physics system130 ;; when the simulation is started.131 (if-let [constraints132 (map-vals133 eval134 (read-string135 (meta-data joint "joint")))]137 (let [joint-type (:type constraints)]138 (println-repl "creating joint between"139 (.getName obj-a) "and" (.getName obj-b))140 (cond (= :point joint-type)141 (do142 (println-repl "creating POINT joint")143 (Point2PointJoint.144 control-a145 control-b146 pivot-a147 pivot-b))148 (= :hinge joint-type)149 (do150 (println-repl "creating HINGE joint")151 (let [axis (if-let152 [axis (:axis constraints)]153 axis154 Vector3f/UNIT_X)155 [limit-1 limit-2] (:limit constraints)156 hinge-axis157 (.mult158 (.getWorldRotation joint)159 (blender-to-jme axis))]160 (doto161 (HingeJoint.162 control-a163 control-b164 pivot-a165 pivot-b166 hinge-axis167 hinge-axis)168 (.setLimit limit-1 limit-2))))169 (= :cone joint-type)170 (do171 (let [limit-xz (:limit-xz constraints)172 limit-xy (:limit-xy constraints)173 twist (:twist constraints)]175 (println-repl "creating CONE joint")176 (let [vector-1177 (.mult (.getWorldRotation joint)178 Vector3f/UNIT_X)179 vector-2180 (.normalize181 (.subtract182 (.getWorldTranslation joint)183 (.getWorldTranslation obj-a)))184 ]185 (println-repl186 "vector-1 :" vector-1)187 (println-repl188 "vector-2 :" vector-2)192 (doto193 (ConeJoint.194 control-a195 control-b196 pivot-a197 pivot-b199 ;;(doto (Matrix3f.)200 ;; (.fromStartEndVectors201 ;; Vector3f/UNIT_X202 ;; (.normalize203 ;; (.subtract204 ;; (.getWorldTranslation joint)205 ;; (.getWorldTranslation obj-a)))))208 (.toRotationMatrix209 (.getWorldRotation joint))213 (.toRotationMatrix214 (.fromAngleAxis215 (Quaternion.)216 (.angleBetween Vector3f/UNIT_X pivot-a)217 (.cross Vector3f/UNIT_X pivot-a)))222 ;; (doto (Matrix3f.)223 ;; (.fromStartEndVectors224 ;; Vector3f/UNIT_X225 ;; (.normalize226 ;; vector-1)))228 ;; (doto (Matrix3f.)229 ;; (.fromStartEndVectors230 ;; Vector3f/UNIT_X231 ;; vector-2))232 )233 (.setLimit (float limit-xz)234 (float limit-xy)235 (float twist))))))236 true237 (println-repl238 "joint-type" joint-type "not recognized")))240 (println-repl "could not find joint meta-data!"))))242 (defn assemble-creature [#^Node pieces joints]243 (dorun244 (map245 (fn [geom]246 (let [physics-control247 (RigidBodyControl.248 (HullCollisionShape.249 (.getMesh geom))250 (if-let [mass (meta-data geom "mass")]251 (do252 (println-repl253 "setting" (.getName geom) "mass to" (float mass))254 (float mass))255 (float 1)))]257 (.addControl geom physics-control)))258 (filter #(isa? (class %) Geometry )259 (node-seq pieces))))261 (dorun262 (map263 (fn [joint]264 (let [[obj-a obj-b]265 (joint-targets pieces joint)]266 (connect obj-a obj-b joint)))267 joints))268 pieces)270 (defn blender-creature [blender-path]271 (let [model (load-blender-model blender-path)272 joints273 (if-let [joint-node (.getChild model "joints")]274 (seq (.getChildren joint-node))275 (do (println-repl "could not find joints node")276 []))]277 (assemble-creature model joints)))279 (def hand "Models/creature1/one.blend")281 (def worm "Models/creature1/try-again.blend")283 (defn x-ray [#^ColorRGBA color]284 (doto (Material. (asset-manager)285 "Common/MatDefs/Misc/Unshaded.j3md")286 (.setColor "Color" color)287 (-> (.getAdditionalRenderState)288 (.setDepthTest false))))290 (defn test-creature [thing]291 (let [x-axis292 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)293 y-axis294 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)295 z-axis296 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]297 (world298 (nodify [(blender-creature thing)299 (box 10 2 10 :position (Vector3f. 0 -9 0)300 :color ColorRGBA/Gray :mass 0)301 x-axis y-axis z-axis302 ])303 standard-debug-controls304 (comp light-up-everything enable-debug305 (fn [world]306 (.setTimer world (NanoTimer.))307 (set-gravity world (Vector3f. 0 0 0))308 (speed-up world)309 world310 ))311 no-op)))313 (defn world-setup [joint]314 (let [top (doto315 (sphere 0.1 :physical? false :color ColorRGBA/Yellow316 :position (Vector3f. 0 7 0))317 (.addControl318 (RigidBodyControl.319 (CapsuleCollisionShape. 0.5 1.5 1) (float 15))))320 bottom (doto321 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray322 :position (Vector3f. 0 -1 0))323 (.addControl324 (RigidBodyControl.325 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))326 table (box 10 2 10 :position (Vector3f. 0 -6 0)327 :color ColorRGBA/Gray :mass 0)328 a (.getControl top RigidBodyControl)329 b (.getControl bottom RigidBodyControl)]330 (cond331 (= joint :point)332 (doto333 (Point2PointJoint. a b334 (Vector3f. 0 -2 0)335 (Vector3f. 0 2 0))336 (.setCollisionBetweenLinkedBodys false))337 (= joint :hinge)338 (doto339 (HingeJoint.340 a b341 (Vector3f. 0 -2 0)342 (Vector3f. 0 2 0)343 (Vector3f. 0 0 1)344 (Vector3f. 0 0 1)346 )347 (.setCollisionBetweenLinkedBodys false)348 ;;(.setLimit (- Math/PI) Math/PI)349 )350 (= joint :cone)351 ;; note to self -- jbullet does NOT implement cone joints352 ;; correctly. You must use plain ol' bullet for this to work.353 ;; It's faster anyway, so whatever.355 (doto (ConeJoint.356 a b357 (Vector3f. 0 -5 0)358 (Vector3f. 0 2 0)360 (doto (Matrix3f.)361 (.fromStartEndVectors Vector3f/UNIT_X362 Vector3f/UNIT_Y))363 (doto (Matrix3f.)364 (.fromStartEndVectors Vector3f/UNIT_X365 (.normalize366 (Vector3f. 0 0 -1))))367 )368 ;;(.setAngularOnly true)370 (.setCollisionBetweenLinkedBodys false)371 (.setLimit (* 1 (/ Math/PI 4))372 (* 1 (/ Math/PI 2))373 (* 0 (/ Math/PI 4)))375 )376 (= joint :six)377 (doto378 (SixDofJoint.379 a b380 (Vector3f. 0 -2 0)381 (Vector3f. 0 2 0)382 ;;(doto (Matrix3f.)383 ;; (.fromStartEndVectors Vector3f/UNIT_X384 ;; Vector3f/UNIT_Y))385 ;;(doto (Matrix3f.)386 ;; (.fromStartEndVectors Vector3f/UNIT_X387 ;; Vector3f/UNIT_Y))388 true)389 (.setCollisionBetweenLinkedBodys false)390 (.setAngularLowerLimit (Vector3f. 0391 (- (/ Math/PI 2))392 0))394 (.setAngularUpperLimit (Vector3f. 0395 (/ Math/PI 2)396 0))397 (.setLinearLowerLimit (Vector3f. 0 0 0))398 (.setLinearUpperLimit (Vector3f. 0 0 0))400 )406 )408 [top bottom table]))411 (defn test-joint [joint]412 (let [[top bottom floor] (world-setup joint)413 control (.getControl top RigidBodyControl)414 move-up? (atom false)415 move-down? (atom false)416 move-left? (atom false)417 move-right? (atom false)418 roll-left? (atom false)419 roll-right? (atom false)420 timer (atom 0)]422 (world423 (nodify [top bottom floor])424 (merge standard-debug-controls425 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))426 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))427 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))428 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))429 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))430 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})432 (fn [world]433 (light-up-everything world)434 (enable-debug world)435 (set-gravity world (Vector3f. 0 0 0))436 )438 (fn [world _]439 (if (zero? (rem (swap! timer inc) 100))440 (do441 ;; (println-repl @timer)442 (.attachChild (.getRootNode world)443 (sphere 0.05 :color ColorRGBA/Yellow444 :position (.getWorldTranslation top)445 :physical? false))))446 (if @move-up?447 (.applyTorque control448 (.mult (.getPhysicsRotation control)449 (Vector3f. 0 0 10))))450 (if @move-down?451 (.applyTorque control452 (.mult (.getPhysicsRotation control)453 (Vector3f. 0 0 -10))))454 (if @move-left?455 (.applyTorque control456 (.mult (.getPhysicsRotation control)457 (Vector3f. 0 10 0))))458 (if @move-right?459 (.applyTorque control460 (.mult (.getPhysicsRotation control)461 (Vector3f. 0 -10 0))))462 (if @roll-left?463 (.applyTorque control464 (.mult (.getPhysicsRotation control)465 (Vector3f. -1 0 0))))466 (if @roll-right?467 (.applyTorque control468 (.mult (.getPhysicsRotation control)469 (Vector3f. 1 0 0))))))))470 #+end_src473 * COMMENT purgatory474 #+begin_src clojure475 (defn bullet-trans []476 (let [obj-a (sphere 0.5 :color ColorRGBA/Red477 :position (Vector3f. -10 5 0))478 obj-b (sphere 0.5 :color ColorRGBA/Blue479 :position (Vector3f. -10 -5 0)480 :mass 0)481 control-a (.getControl obj-a RigidBodyControl)482 control-b (.getControl obj-b RigidBodyControl)483 swivel484 (.toRotationMatrix485 (doto (Quaternion.)486 (.fromAngleAxis (/ Math/PI 2)487 Vector3f/UNIT_X)))]488 (doto489 (ConeJoint.490 control-a control-b491 (Vector3f. 0 5 0)492 (Vector3f. 0 -5 0)493 swivel swivel)494 (.setLimit (* 0.6 (/ Math/PI 4))495 (/ Math/PI 4)496 (* Math/PI 0.8)))497 (world (nodify498 [obj-a obj-b])499 standard-debug-controls500 enable-debug501 no-op)))504 (defn bullet-trans* []505 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red506 :position (Vector3f. 5 0 0)507 :mass 90)508 obj-b (sphere 0.5 :color ColorRGBA/Blue509 :position (Vector3f. -5 0 0)510 :mass 0)511 control-a (.getControl obj-a RigidBodyControl)512 control-b (.getControl obj-b RigidBodyControl)513 move-up? (atom nil)514 move-down? (atom nil)515 move-left? (atom nil)516 move-right? (atom nil)517 roll-left? (atom nil)518 roll-right? (atom nil)519 force 100520 swivel521 (.toRotationMatrix522 (doto (Quaternion.)523 (.fromAngleAxis (/ Math/PI 2)524 Vector3f/UNIT_X)))525 x-move526 (doto (Matrix3f.)527 (.fromStartEndVectors Vector3f/UNIT_X528 (.normalize (Vector3f. 1 1 0))))530 timer (atom 0)]531 (doto532 (ConeJoint.533 control-a control-b534 (Vector3f. -8 0 0)535 (Vector3f. 2 0 0)536 ;;swivel swivel537 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY538 x-move Matrix3f/IDENTITY539 )540 (.setCollisionBetweenLinkedBodys false)541 (.setLimit (* 1 (/ Math/PI 4)) ;; twist542 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane543 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane544 (world (nodify545 [obj-a obj-b])546 (merge standard-debug-controls547 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))548 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))549 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))550 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))551 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))552 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})554 (fn [world]555 (enable-debug world)556 (set-gravity world Vector3f/ZERO)557 )559 (fn [world _]561 (if @move-up?562 (.applyForce control-a563 (Vector3f. force 0 0)564 (Vector3f. 0 0 0)))565 (if @move-down?566 (.applyForce control-a567 (Vector3f. (- force) 0 0)568 (Vector3f. 0 0 0)))569 (if @move-left?570 (.applyForce control-a571 (Vector3f. 0 force 0)572 (Vector3f. 0 0 0)))573 (if @move-right?574 (.applyForce control-a575 (Vector3f. 0 (- force) 0)576 (Vector3f. 0 0 0)))578 (if @roll-left?579 (.applyForce control-a580 (Vector3f. 0 0 force)581 (Vector3f. 0 0 0)))582 (if @roll-right?583 (.applyForce control-a584 (Vector3f. 0 0 (- force))585 (Vector3f. 0 0 0)))587 (if (zero? (rem (swap! timer inc) 100))588 (.attachChild589 (.getRootNode world)590 (sphere 0.05 :color ColorRGBA/Yellow591 :physical? false :position592 (.getWorldTranslation obj-a)))))593 )594 ))598 #+end_src601 * COMMENT generate source602 #+begin_src clojure :tangle ../src/cortex/silly.clj603 <<body-1>>604 #+end_src