Mercurial > cortex
view org/test-creature.org @ 84:4f5e2c629e45
going to try to fix cone-joint generating code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 07 Jan 2012 01:10:14 -0700 |
parents | 14b604e955ed |
children | 00ab1f10266f |
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 get-subjective-position)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 connect121 "here are some examples:122 {:type :point}123 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}124 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)126 {:type :cone :limit-xz 0]127 :limit-xy 0]128 :twist 0]} (use XZY rotation mode in blender!)"129 [#^Node obj-a #^Node obj-b #^Node joint]130 (let [center-a (.getWorldTranslation obj-a)131 center-b (.getWorldTranslation obj-b)132 joint-center (.getWorldTranslation joint)133 pivot-a (.subtract joint-center center-a)134 pivot-b (.subtract joint-center center-b)135 control-a (.getControl obj-a RigidBodyControl)136 control-b (.getControl obj-b RigidBodyControl)]137 ;; A side-effect of creating a joint registers138 ;; it with both physics objects which in turn139 ;; will register the joint with the physics system140 ;; when the simulation is started.141 (if-let [constraints142 (map-vals143 eval144 (read-string145 (meta-data joint "joint")))]147 (let [joint-type (:type constraints)]148 (println-repl "creating joint between"149 (.getName obj-a) "and" (.getName obj-b))150 (cond (= :point joint-type)151 (do152 (println-repl "creating POINT joint")153 (Point2PointJoint.154 control-a155 control-b156 pivot-a157 pivot-b))158 (= :hinge joint-type)159 (do160 (println-repl "creating HINGE joint")161 (let [axis (if-let162 [axis (:axis constraints)]163 axis164 Vector3f/UNIT_X)165 [limit-1 limit-2] (:limit constraints)166 hinge-axis167 (.mult168 (.getWorldRotation joint)169 (blender-to-jme axis))]170 (doto171 (HingeJoint.172 control-a173 control-b174 pivot-a175 pivot-b176 hinge-axis177 hinge-axis)178 (.setLimit limit-1 limit-2))))179 (= :cone joint-type)180 (do181 (let [limit-xz (:limit-xz constraints)182 limit-xy (:limit-xy constraints)183 twist (:twist constraints)]185 (println-repl "creating CONE joint")186 (let [frame-a187 (.toRotationMatrix188 (doto (Quaternion.)189 (.fromAngleAxis190 (float191 (.angleBetween192 (.normalize pivot-a) Vector3f/UNIT_X))193 (.normalize194 (.cross pivot-a195 Vector3f/UNIT_X)))))196 ]197 (println-repl "pivot-a" pivot-a)198 (println-repl199 "angle between pivot-a and UNIT_X is"200 (.angleBetween Vector3f/UNIT_X (.normalize pivot-a)))201 (println-repl "frame-a:" frame-a)202 (println-repl203 "frame-a moves Vector3f/UNIT_X to"204 (.mult frame-a Vector3f/UNIT_X ))207 (doto208 (ConeJoint.209 control-a210 control-b211 pivot-a212 pivot-b215 ;; frame-in-A216 ;;frame-a217 ;;frame-a219 (.toRotationMatrix220 (doto (Quaternion.)221 (.fromAngles222 0 0 (* -0.5 (/ Math/PI 2)))))225 ;; frame-in-B226 (.toRotationMatrix227 (doto (Quaternion.)228 (.fromAngles229 0 0 (* -0.5 (/ Math/PI 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!"))))243 (defn assemble-creature [#^Node pieces joints]244 (dorun245 (map246 (fn [geom]247 (let [physics-control248 (RigidBodyControl.249 (HullCollisionShape.250 (.getMesh geom))251 (if-let [mass (meta-data geom "mass")]252 (do253 (println-repl254 "setting" (.getName geom) "mass to" (float mass))255 (float mass))256 (float 1)))]258 (.addControl geom physics-control)))259 (filter #(isa? (class %) Geometry )260 (node-seq pieces))))262 (dorun263 (map264 (fn [joint]265 (let [[obj-a obj-b]266 (joint-targets pieces joint)]267 (connect obj-a obj-b joint)))268 joints))269 pieces)271 (defn blender-creature [blender-path]272 (let [model (load-blender-model blender-path)273 joints274 (if-let [joint-node (.getChild model "joints")]275 (seq (.getChildren joint-node))276 (do (println-repl "could not find joints node")277 []))]278 (assemble-creature model joints)))280 (def hand "Models/creature1/one.blend")282 (def worm "Models/creature1/try-again.blend")284 (defn x-ray [#^ColorRGBA color]285 (doto (Material. (asset-manager)286 "Common/MatDefs/Misc/Unshaded.j3md")287 (.setColor "Color" color)288 (-> (.getAdditionalRenderState)289 (.setDepthTest false))))291 (defn test-creature [thing]292 (let [x-axis293 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)294 y-axis295 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)296 z-axis297 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]298 (world299 (nodify [(blender-creature thing)300 (box 10 2 10 :position (Vector3f. 0 -9 0)301 :color ColorRGBA/Gray :mass 0)302 x-axis y-axis z-axis303 ])304 standard-debug-controls305 (comp light-up-everything enable-debug306 (fn [world]307 (.setTimer world (NanoTimer.))308 (set-gravity world (Vector3f. 0 0 0))309 (speed-up world)310 world311 ))312 no-op)))314 (defn world-setup [joint]315 (let [317 joint-position (Vector3f. 0 0 0)318 joint-rotation319 (.toRotationMatrix320 (.mult321 (doto (Quaternion.)322 (.fromAngleAxis323 (* 1 (/ Math/PI 4))324 (Vector3f. 0 0 1)))325 (.mult326 (doto (Quaternion.)327 (.fromAngleAxis328 (* 2 (/ Math/PI 4))329 (Vector3f. 0 1 0)))330 (doto (Quaternion.)331 (.fromAngleAxis332 (* 1 (/ Math/PI 2))333 (Vector3f. 0 0 1))))))334 top-position (.mult joint-rotation (Vector3f. 8 0 0))336 origin (doto337 (sphere 0.1 :physical? false :color ColorRGBA/Cyan338 :position top-position))339 top (doto340 (sphere 0.1 :physical? false :color ColorRGBA/Yellow341 :position top-position)343 (.addControl344 (RigidBodyControl.345 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))346 bottom (doto347 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray348 :position (Vector3f. 0 0 0))349 (.addControl350 (RigidBodyControl.351 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))352 table (box 10 2 10 :position (Vector3f. 0 -20 0)353 :color ColorRGBA/Gray :mass 0)354 a (.getControl top RigidBodyControl)355 b (.getControl bottom RigidBodyControl)]357 (cond358 (= joint :cone)360 (doto (ConeJoint.361 a b362 (get-subjective-position joint-position top)363 (get-subjective-position joint-position bottom)364 joint-rotation365 joint-rotation366 )369 (.setLimit (* (/ 10) Math/PI)370 (* (/ 4) Math/PI)371 0)))372 [origin top bottom table]))376 (defn test-joint [joint]377 (let [[origin top bottom floor] (world-setup joint)378 control (.getControl top RigidBodyControl)379 move-up? (atom false)380 move-down? (atom false)381 move-left? (atom false)382 move-right? (atom false)383 roll-left? (atom false)384 roll-right? (atom false)385 timer (atom 0)]387 (world388 (nodify [top bottom floor origin])389 (merge standard-debug-controls390 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))391 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))392 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))393 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))394 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))395 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})397 (fn [world]398 (light-up-everything world)399 (enable-debug world)400 (set-gravity world (Vector3f. 0 0 0))401 )403 (fn [world _]404 (if (zero? (rem (swap! timer inc) 100))405 (do406 ;; (println-repl @timer)407 (.attachChild (.getRootNode world)408 (sphere 0.05 :color ColorRGBA/Yellow409 :position (.getWorldTranslation top)410 :physical? false))411 (.attachChild (.getRootNode world)412 (sphere 0.05 :color ColorRGBA/LightGray413 :position (.getWorldTranslation bottom)414 :physical? false))))416 (if @move-up?417 (.applyTorque control418 (.mult (.getPhysicsRotation control)419 (Vector3f. 0 0 10))))420 (if @move-down?421 (.applyTorque control422 (.mult (.getPhysicsRotation control)423 (Vector3f. 0 0 -10))))424 (if @move-left?425 (.applyTorque control426 (.mult (.getPhysicsRotation control)427 (Vector3f. 0 10 0))))428 (if @move-right?429 (.applyTorque control430 (.mult (.getPhysicsRotation control)431 (Vector3f. 0 -10 0))))432 (if @roll-left?433 (.applyTorque control434 (.mult (.getPhysicsRotation control)435 (Vector3f. -1 0 0))))436 (if @roll-right?437 (.applyTorque control438 (.mult (.getPhysicsRotation control)439 (Vector3f. 1 0 0))))))))453 ;; please validate these.455 (defn get-subjective-position456 "Convert the world coordinates into coordinates relative to457 object (i.e. local coordinates), taking into account the rotation458 of object."459 [#^Vector3f world-coordinates object]460 ;; I don't know if it's important to take into account the rotation461 ;; of the object. If it isn't, then remove the multiplication-by-inverse.462 (.mult (.inverse (.getWorldRotation object))463 (.subtract world-coordinates (.getWorldTranslation object))))466 (defn get-subjective-rotation467 "cf get-subjective-position. Converts a rotation specified relative468 to the world's axes into a rotation specified in terms of the object's469 coordinate system."470 [#^Quaternion world-rotation object]471 (.mult (.inverse (.getWorldRotation object)) world-rotation))476 (defn joint-create "Connect objects 1 and 2 using a joint constraint. If477 only position is specified, creates a point-to-point joint at the478 given location479 in world coordinates. etc. etc. for other joints.480 To ensure consistency, I may alter this function481 so that it moves obj-1 to be at the apex of the cone.483 NOTE:484 In the usual construction method, you create a joint and, if your485 contraints are consistent, all the objects snap into position and486 orientation around it, otherwise the systen explodes.488 This construction method assumes that you have in mind a position and489 rotation for the joint, and that you have already put your objects490 at the required distances from that joint so that no snapping needs491 to occur. The radial distances ('pivot lengths') are therefore just set to be492 the pre-existing distances between the objects and the joint."493 [#^Node obj-1494 #^Node obj-2495 #^Vector3f joint-position496 #^Quaternion joint-rotation497 span-1498 span-2499 twist500 ]502 (let503 [body-1 (.getControl obj-1 RigidBodyControl)504 body-2 (.getControl obj-2 RigidBodyControl)505 ]506 (doto (ConeJoint.507 body-1508 body-2509 (get-subjective-position joint-position body-1)510 (get-subjective-position joint-position body-2)511 ;; ALIGN X-AXIS OF OBJECT-1 WITH THE CENTRAL AXIS OF THE CONE TO512 ;;LOWER THE RISK OF INCONSISTENCY513 ;;(Matrix3f/IDENTITY)514 (.toRotationMatrix (get-subjective-rotation joint-rotation body-1))515 (.toRotationMatrix (get-subjective-rotation joint-rotation body-2))516 )517 (.setLimit518 span-1519 span-2520 twist))))527 #+end_src530 * COMMENT purgatory531 #+begin_src clojure532 (defn bullet-trans []533 (let [obj-a (sphere 0.5 :color ColorRGBA/Red534 :position (Vector3f. -10 5 0))535 obj-b (sphere 0.5 :color ColorRGBA/Blue536 :position (Vector3f. -10 -5 0)537 :mass 0)538 control-a (.getControl obj-a RigidBodyControl)539 control-b (.getControl obj-b RigidBodyControl)540 swivel541 (.toRotationMatrix542 (doto (Quaternion.)543 (.fromAngleAxis (/ Math/PI 2)544 Vector3f/UNIT_X)))]545 (doto546 (ConeJoint.547 control-a control-b548 (Vector3f. 0 5 0)549 (Vector3f. 0 -5 0)550 swivel swivel)551 (.setLimit (* 0.6 (/ Math/PI 4))552 (/ Math/PI 4)553 (* Math/PI 0.8)))554 (world (nodify555 [obj-a obj-b])556 standard-debug-controls557 enable-debug558 no-op)))561 (defn bullet-trans* []562 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red563 :position (Vector3f. 5 0 0)564 :mass 90)565 obj-b (sphere 0.5 :color ColorRGBA/Blue566 :position (Vector3f. -5 0 0)567 :mass 0)568 control-a (.getControl obj-a RigidBodyControl)569 control-b (.getControl obj-b RigidBodyControl)570 move-up? (atom nil)571 move-down? (atom nil)572 move-left? (atom nil)573 move-right? (atom nil)574 roll-left? (atom nil)575 roll-right? (atom nil)576 force 100577 swivel578 (.toRotationMatrix579 (doto (Quaternion.)580 (.fromAngleAxis (/ Math/PI 2)581 Vector3f/UNIT_X)))582 x-move583 (doto (Matrix3f.)584 (.fromStartEndVectors Vector3f/UNIT_X585 (.normalize (Vector3f. 1 1 0))))587 timer (atom 0)]588 (doto589 (ConeJoint.590 control-a control-b591 (Vector3f. -8 0 0)592 (Vector3f. 2 0 0)593 ;;swivel swivel594 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY595 x-move Matrix3f/IDENTITY596 )597 (.setCollisionBetweenLinkedBodys false)598 (.setLimit (* 1 (/ Math/PI 4)) ;; twist599 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane600 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane601 (world (nodify602 [obj-a obj-b])603 (merge standard-debug-controls604 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))605 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))606 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))607 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))608 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))609 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})611 (fn [world]612 (enable-debug world)613 (set-gravity world Vector3f/ZERO)614 )616 (fn [world _]618 (if @move-up?619 (.applyForce control-a620 (Vector3f. force 0 0)621 (Vector3f. 0 0 0)))622 (if @move-down?623 (.applyForce control-a624 (Vector3f. (- force) 0 0)625 (Vector3f. 0 0 0)))626 (if @move-left?627 (.applyForce control-a628 (Vector3f. 0 force 0)629 (Vector3f. 0 0 0)))630 (if @move-right?631 (.applyForce control-a632 (Vector3f. 0 (- force) 0)633 (Vector3f. 0 0 0)))635 (if @roll-left?636 (.applyForce control-a637 (Vector3f. 0 0 force)638 (Vector3f. 0 0 0)))639 (if @roll-right?640 (.applyForce control-a641 (Vector3f. 0 0 (- force))642 (Vector3f. 0 0 0)))644 (if (zero? (rem (swap! timer inc) 100))645 (.attachChild646 (.getRootNode world)647 (sphere 0.05 :color ColorRGBA/Yellow648 :physical? false :position649 (.getWorldTranslation obj-a)))))650 )651 ))655 #+end_src658 * COMMENT generate source659 #+begin_src clojure :tangle ../src/cortex/silly.clj660 <<body-1>>661 #+end_src