changeset 78:77b506ac64f3

trying to make offset cone joints
author Robert McIntyre <rlm@mit.edu>
date Wed, 04 Jan 2012 20:34:00 -0700
parents 1f84f425e05d
children 01dbdb0d5500
files assets/Models/creature1/one.blend assets/Models/creature1/try-again.blend org/test-creature.org org/util.org
diffstat 4 files changed, 346 insertions(+), 396 deletions(-) [+]
line wrap: on
line diff
     1.1 Binary file assets/Models/creature1/one.blend has changed
     2.1 Binary file assets/Models/creature1/try-again.blend has changed
     3.1 --- a/org/test-creature.org	Wed Jan 04 08:36:42 2012 -0700
     3.2 +++ b/org/test-creature.org	Wed Jan 04 20:34:00 2012 -0700
     3.3 @@ -48,9 +48,6 @@
     3.4  (cortex.import/mega-import-jme3)
     3.5  (use '(cortex world util body hearing touch vision))
     3.6  
     3.7 -(use '[clojure.contrib [seq :only [find-first]]])
     3.8 -
     3.9 -
    3.10  (rlm.rlm-commands/help)
    3.11  
    3.12  (defn load-blender-model
    3.13 @@ -66,52 +63,351 @@
    3.14      (.findValue data key)
    3.15      nil))
    3.16  
    3.17 +(defn blender-to-jme
    3.18 +  "Convert from Blender coordinates to JME coordinates"
    3.19 +  [#^Vector3f in]
    3.20 +  (Vector3f. (.getX in)
    3.21 +             (.getZ in)
    3.22 +             (- (.getY in))))
    3.23  
    3.24 -(defn hand []
    3.25 -  (load-blender-model "Models/creature1/one.blend"))
    3.26 +(defn joint-targets
    3.27 +  "Return the two closest two objects to the joint object, ordered
    3.28 +  from bottom to top according to the joint's rotation."
    3.29 +  [#^Node parts #^Node joint]
    3.30 +  ;;(println (meta-data joint "joint"))
    3.31 +  (.getWorldRotation joint)
    3.32 +  (loop [radius (float 0.01)]
    3.33 +    (let [results (CollisionResults.)]
    3.34 +      (.collideWith
    3.35 +       parts
    3.36 +       (BoundingBox. (.getWorldTranslation joint)
    3.37 +                     radius radius radius)
    3.38 +       results)
    3.39 +      (let [targets
    3.40 +            (distinct
    3.41 +             (map  #(.getGeometry %) results))]
    3.42 +        (if (>= (count targets) 2)
    3.43 +          (sort-by
    3.44 +           #(.getY
    3.45 +             (.mult
    3.46 +              (.inverse (.getWorldRotation joint))
    3.47 +              (.subtract (.getWorldTranslation %)
    3.48 +                         (.getWorldTranslation joint))))
    3.49 +           (take 2 targets))
    3.50 +          (recur (float (* radius 2))))))))
    3.51  
    3.52 +(defn connect
    3.53 +  "here are some examples:
    3.54 +   {:type :point}
    3.55 +   {:type :hinge  :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
    3.56 +   (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
    3.57  
    3.58 -  
    3.59 -(def hand-names
    3.60 -  #{
    3.61 -    "middle-1"
    3.62 -    "middle-2"
    3.63 -    "middle-3"
    3.64 -    "palm"
    3.65 -    "pinky-1"
    3.66 -    "pinky-2"
    3.67 -    "pinky-3"
    3.68 -    "pointer-1"
    3.69 -    "pointer-2"
    3.70 -    "pointer-3"
    3.71 -    "ring-1"
    3.72 -    "ring-2"
    3.73 -    "ring-3"
    3.74 -    "thumb-1"
    3.75 -    "thumb-2"})
    3.76 +   {:type :cone   :limit-xz 0]
    3.77 +                  :limit-yz 0]
    3.78 +                  :twist 0]}"
    3.79 +  ([#^Node obj-a #^Node obj-b #^Node joint]
    3.80 +     (let [center-a (.getWorldTranslation obj-a)
    3.81 +           center-b (.getWorldTranslation obj-b)
    3.82 +           joint-center (.getWorldTranslation joint)
    3.83 +           pivot-a (.subtract joint-center center-a)
    3.84 +           pivot-b (.subtract joint-center center-b)
    3.85 +           control-a (.getControl obj-a RigidBodyControl)
    3.86 +           control-b (.getControl obj-b RigidBodyControl)]
    3.87 +           ;; A side-effect of creating a joint registers
    3.88 +           ;; it with both physics objects which in turn
    3.89 +           ;; will register the joint with the physics system
    3.90 +           ;; when the simulation is started.
    3.91 +       (if-let [constraints
    3.92 +                (map-vals
    3.93 +                 eval
    3.94 +                 (read-string
    3.95 +                  (meta-data joint "joint")))]
    3.96  
    3.97 -(defn hand-pieces []
    3.98 -  (filter
    3.99 -   (comp hand-names #(apply str (drop-last (.getName %)))) (node-seq (hand))))
   3.100 +         (let [joint-type (:type constraints)]
   3.101 +           (println-repl "creating joint between"
   3.102 +                         (.getName obj-a) "and" (.getName obj-b))
   3.103 +           (cond (= :point joint-type)
   3.104 +                 (do
   3.105 +                   (println-repl "creating POINT joint")
   3.106 +                   (Point2PointJoint.
   3.107 +                    control-a
   3.108 +                    control-b
   3.109 +                    pivot-a
   3.110 +                    pivot-b))
   3.111 +                 (= :hinge joint-type)
   3.112 +                 (do
   3.113 +                   (println-repl "creating HINGE joint")
   3.114 +                   (let [axis (if-let
   3.115 +                                  [axis (:axis constraints)]
   3.116 +                                axis
   3.117 +                                Vector3f/UNIT_X)
   3.118 +                         [limit-1 limit-2] (:limit constraints)
   3.119 +                         hinge-axis
   3.120 +                         (.mult
   3.121 +                          (.getWorldRotation joint)
   3.122 +                          (blender-to-jme axis))]
   3.123 +                     (doto
   3.124 +                         (HingeJoint.
   3.125 +                          control-a
   3.126 +                          control-b
   3.127 +                          pivot-a
   3.128 +                          pivot-b
   3.129 +                          hinge-axis
   3.130 +                          hinge-axis)
   3.131 +                       (.setLimit limit-1 limit-2))))
   3.132 +                 (= :cone joint-type)
   3.133 +                 (do
   3.134 +                   (let [limit-xy (:limit-xz constraints)
   3.135 +                         limit-yz (:limit-yz constraints)
   3.136 +                         twist    (:twist constraints)]
   3.137 +                     
   3.138 +                     (println-repl "creating CONE joint")
   3.139 +                     (doto
   3.140 +                         (ConeJoint.
   3.141 +                          control-a
   3.142 +                          control-b
   3.143 +                          pivot-a
   3.144 +                          pivot-b
   3.145 +                          (doto (Matrix3f.)
   3.146 +                            (.fromStartEndVectors
   3.147 +                             Vector3f/UNIT_X
   3.148 +                             (.normalize
   3.149 +                              (.subtract (.getWorldTranslation joint)
   3.150 +                                         (.getWorldTranslation obj-a)))))
   3.151 +                          (doto (Matrix3f.)
   3.152 +                            (.fromStartEndVectors
   3.153 +                             Vector3f/UNIT_X
   3.154 +                             (.normalize
   3.155 +                              (.subtract
   3.156 +                               (.getWorldTranslation obj-b)
   3.157 +                               (.getWorldTranslation joint))))))
   3.158 +                       (.setLimit (float limit-xy)
   3.159 +                                  (float limit-yz)
   3.160 +                                  (float twist)))))
   3.161 +                 true
   3.162 +                 (println-repl
   3.163 +                  "joint-type" joint-type "not recognized")))
   3.164 +                 
   3.165 +           (println-repl "could not find joint meta-data!")))))
   3.166  
   3.167 -(defn hand-joints []
   3.168 -  (map #(.getWorldTranslation %)
   3.169 -       (filter #(re-matches #"joint\.\d\d\d" (.getName %))
   3.170 -               (node-seq (hand)))))
   3.171 -(defn worm []
   3.172 -  (load-blender-model "Models/creature1/try-again.blend"))
   3.173 +(defn assemble-creature [#^Node pieces joints]
   3.174 +  (dorun
   3.175 +   (map
   3.176 +    (fn [geom]
   3.177 +      (let [physics-control
   3.178 +            (RigidBodyControl.
   3.179 +             (HullCollisionShape.
   3.180 +              (.getMesh geom))
   3.181 +             (if-let [mass (meta-data geom "mass")]
   3.182 +               (do
   3.183 +                 (println-repl
   3.184 +                  "setting" (.getName geom) "mass to" (float mass))
   3.185 +                 (float mass))
   3.186 +               (float 1)))]
   3.187 +               
   3.188 +        (.addControl geom physics-control)))
   3.189 +    (filter #(isa? (class %) Geometry )
   3.190 +            (node-seq pieces))))
   3.191  
   3.192 +  (dorun
   3.193 +   (map
   3.194 +    (fn [joint]
   3.195 +      (let [[obj-a obj-b]
   3.196 +            (joint-targets pieces joint)]
   3.197 +        (connect obj-a obj-b joint)))
   3.198 +    joints))
   3.199 +  pieces)
   3.200  
   3.201 -(defn worm-pieces []
   3.202 -  (filter
   3.203 -   (comp #{"worm-2" "worm-1"}
   3.204 -         #(apply str (drop-last (.getName %))))
   3.205 -   (node-seq (worm))))
   3.206 +(defn blender-creature [blender-path]
   3.207 +  (let [model (load-blender-model blender-path)
   3.208 +        joints
   3.209 +        (if-let [joint-node (.getChild model "joints")]
   3.210 +          (seq (.getChildren joint-node))
   3.211 +          (do (println-repl "could not find joints node")
   3.212 +              []))]
   3.213 +  (assemble-creature model joints)))
   3.214  
   3.215 -(defn worm-joints []
   3.216 -  (filter #(re-matches #"joint\.\d\d\d" (.getName %))
   3.217 -          (node-seq (worm))))
   3.218 +(def hand "Models/creature1/one.blend")
   3.219  
   3.220 +(def worm "Models/creature1/try-again.blend")
   3.221 +
   3.222 +(defn test-creature [thing]
   3.223 +  (world
   3.224 +   (nodify [(blender-creature thing)
   3.225 +            (box 10 2 10 :position (Vector3f. 0 -5.5 0)
   3.226 +                 :color ColorRGBA/Gray :mass 0)])
   3.227 +   standard-debug-controls
   3.228 +   (comp light-up-everything enable-debug
   3.229 +         (fn [world]
   3.230 +           (.setTimer world (NanoTimer.))
   3.231 +           ;;(set-gravity world (Vector3f. 0 0 0))
   3.232 +           (speed-up world)
   3.233 +           world
   3.234 +           ))
   3.235 +   no-op))
   3.236 +
   3.237 +(defn world-setup [joint]
   3.238 +  (let [top (doto
   3.239 +                (sphere 0.1 :physical? false :color ColorRGBA/Yellow
   3.240 +                        :position (Vector3f. 0 7 0))
   3.241 +              (.addControl
   3.242 +               (RigidBodyControl.
   3.243 +                (CapsuleCollisionShape. 0.5 1.5 1) (float 15))))
   3.244 +        bottom (doto
   3.245 +                   (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
   3.246 +                           :position (Vector3f. 0 -1 0))
   3.247 +              (.addControl
   3.248 +               (RigidBodyControl.
   3.249 +                (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
   3.250 +        table (box 10 2 10 :position (Vector3f. 0 -6 0)
   3.251 +                   :color ColorRGBA/Gray :mass 0)
   3.252 +        a (.getControl top RigidBodyControl)
   3.253 +        b (.getControl bottom RigidBodyControl)]
   3.254 +    (cond
   3.255 +     (= joint :point)
   3.256 +     (doto
   3.257 +         (Point2PointJoint. a b
   3.258 +                            (Vector3f. 0 -2 0)
   3.259 +                            (Vector3f. 0  2 0))
   3.260 +       (.setCollisionBetweenLinkedBodys false))
   3.261 +     (= joint :hinge)
   3.262 +     (doto
   3.263 +         (HingeJoint.
   3.264 +          a b
   3.265 +          (Vector3f. 0 -2 0)
   3.266 +          (Vector3f. 0 2 0)
   3.267 +          (Vector3f. 0 0 1)
   3.268 +          (Vector3f. 0 0 1)
   3.269 +
   3.270 +          )
   3.271 +       (.setCollisionBetweenLinkedBodys false)
   3.272 +       ;;(.setLimit (- Math/PI) Math/PI)
   3.273 +       )
   3.274 +     (= joint :cone)
   3.275 +     ;; note to self -- jbullet does NOT implement cone joints
   3.276 +     ;; correctly. You must use plain ol' bullet for this to work.
   3.277 +     ;; It's faster anyway, so whatever.
   3.278 +     
   3.279 +     (doto (ConeJoint.
   3.280 +            a b
   3.281 +            (Vector3f. 0 -5 0)
   3.282 +            (Vector3f. 0 2 0)
   3.283 +
   3.284 +            (doto (Matrix3f.)
   3.285 +              (.fromStartEndVectors Vector3f/UNIT_X
   3.286 +                                    Vector3f/UNIT_Y))
   3.287 +            (doto (Matrix3f.)
   3.288 +              (.fromStartEndVectors Vector3f/UNIT_X
   3.289 +                                    (.normalize
   3.290 +                                     (Vector3f. 5 5 0))))
   3.291 +            )
   3.292 +       ;;(.setAngularOnly true)
   3.293 +       
   3.294 +       (.setCollisionBetweenLinkedBodys false)
   3.295 +       (.setLimit (* 1 (/ Math/PI 4))
   3.296 +                  (* 1 (/ Math/PI 2))
   3.297 +                  (* 0 (/ Math/PI 4)))
   3.298 +        
   3.299 +       )
   3.300 +     (= joint :six)
   3.301 +     (doto
   3.302 +         (SixDofJoint.
   3.303 +          a b
   3.304 +          (Vector3f. 0 -2 0)
   3.305 +          (Vector3f. 0 2 0)
   3.306 +          ;;(doto (Matrix3f.)
   3.307 +          ;;    (.fromStartEndVectors Vector3f/UNIT_X
   3.308 +          ;;                          Vector3f/UNIT_Y))
   3.309 +          ;;(doto (Matrix3f.)
   3.310 +          ;;  (.fromStartEndVectors Vector3f/UNIT_X
   3.311 +          ;;                        Vector3f/UNIT_Y))
   3.312 +          true)
   3.313 +       (.setCollisionBetweenLinkedBodys false)
   3.314 +       (.setAngularLowerLimit (Vector3f. 0
   3.315 +                                         (- (/ Math/PI 2))
   3.316 +                                         0))
   3.317 +                                         
   3.318 +       (.setAngularUpperLimit (Vector3f. 0
   3.319 +                                         (/ Math/PI 2)
   3.320 +                                         0))
   3.321 +       (.setLinearLowerLimit  (Vector3f. 0 0 0))
   3.322 +       (.setLinearUpperLimit  (Vector3f. 0 0 0))
   3.323 +
   3.324 +       )
   3.325 +          
   3.326 +            
   3.327 +            
   3.328 +          
   3.329 +     
   3.330 +    )
   3.331 +      
   3.332 +    [top bottom table]))
   3.333 +
   3.334 +
   3.335 +(defn test-joint [joint]
   3.336 +  (let [[top bottom floor] (world-setup joint)
   3.337 +        control (.getControl top RigidBodyControl)
   3.338 +        move-up? (atom false)
   3.339 +        move-down? (atom false)
   3.340 +        move-left? (atom false)
   3.341 +        move-right? (atom false)
   3.342 +        roll-left? (atom false)
   3.343 +        roll-right? (atom false)
   3.344 +        timer (atom 0)]
   3.345 +
   3.346 +    (world
   3.347 +     (nodify [top bottom floor])
   3.348 +     (merge standard-debug-controls
   3.349 +            {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
   3.350 +             "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
   3.351 +             "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
   3.352 +             "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
   3.353 +             "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
   3.354 +             "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})     
   3.355 +     
   3.356 +     (fn [world]
   3.357 +       (light-up-everything world)
   3.358 +       (enable-debug world)
   3.359 +       (set-gravity world (Vector3f. 0 0 0))
   3.360 +       )
   3.361 +     
   3.362 +     (fn [world _]
   3.363 +       (if (zero? (rem (swap! timer inc) 100))
   3.364 +         (do
   3.365 +         ;;  (println-repl @timer)
   3.366 +           (.attachChild (.getRootNode world)
   3.367 +                       (sphere 0.05 :color ColorRGBA/Yellow
   3.368 +                               :position (.getWorldTranslation top)
   3.369 +                               :physical? false))))
   3.370 +       (if @move-up?
   3.371 +         (.applyTorque control
   3.372 +                       (.mult (.getPhysicsRotation control)
   3.373 +                              (Vector3f. 0 0 10))))
   3.374 +       (if @move-down?
   3.375 +         (.applyTorque control
   3.376 +                       (.mult (.getPhysicsRotation control)
   3.377 +                              (Vector3f. 0 0 -10))))
   3.378 +       (if @move-left?
   3.379 +         (.applyTorque control
   3.380 +                       (.mult (.getPhysicsRotation control)
   3.381 +                              (Vector3f. 0 10 0))))
   3.382 +       (if @move-right?
   3.383 +         (.applyTorque control
   3.384 +                       (.mult (.getPhysicsRotation control)
   3.385 +                              (Vector3f. 0 -10 0))))
   3.386 +       (if @roll-left?
   3.387 +         (.applyTorque control
   3.388 +                       (.mult (.getPhysicsRotation control)
   3.389 +                              (Vector3f. -1 0 0))))
   3.390 +       (if @roll-right?
   3.391 +         (.applyTorque control
   3.392 +                       (.mult (.getPhysicsRotation control)
   3.393 +                              (Vector3f. 1 0 0))))))))
   3.394 +#+end_src
   3.395 +
   3.396 +
   3.397 +* COMMENT purgatory
   3.398 +#+begin_src clojure
   3.399  (defn bullet-trans []
   3.400    (let [obj-a (sphere 0.5 :color ColorRGBA/Red
   3.401                        :position (Vector3f. -10 5 0))
   3.402 @@ -233,366 +529,10 @@
   3.403             )
   3.404      ))
   3.405  
   3.406 -        
   3.407 -                          
   3.408 -    
   3.409 -        
   3.410 -    
   3.411  
   3.412  
   3.413 -
   3.414 -
   3.415 -
   3.416 -(defn world-setup [joint]
   3.417 -  (let [top (doto
   3.418 -                (sphere 0.1 :physical? false :color ColorRGBA/Yellow
   3.419 -                        :position (Vector3f. 0 7 0))
   3.420 -              (.addControl
   3.421 -               (RigidBodyControl.
   3.422 -                (CapsuleCollisionShape. 0.5 1.5 1) (float 15))))
   3.423 -        bottom (doto
   3.424 -                   (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
   3.425 -                           :position (Vector3f. 0 -1 0))
   3.426 -              (.addControl
   3.427 -               (RigidBodyControl.
   3.428 -                (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
   3.429 -        table (box 10 2 10 :position (Vector3f. 0 -6 0)
   3.430 -                   :color ColorRGBA/Gray :mass 0)
   3.431 -        a (.getControl top RigidBodyControl)
   3.432 -        b (.getControl bottom RigidBodyControl)]
   3.433 -    (cond
   3.434 -     (= joint :point)
   3.435 -     (doto
   3.436 -         (Point2PointJoint. a b
   3.437 -                            (Vector3f. 0 -2 0)
   3.438 -                            (Vector3f. 0  2 0))
   3.439 -       (.setCollisionBetweenLinkedBodys false))
   3.440 -     (= joint :hinge)
   3.441 -     (doto
   3.442 -         (HingeJoint.
   3.443 -          a b
   3.444 -          (Vector3f. 0 -2 0)
   3.445 -          (Vector3f. 0 2 0)
   3.446 -          (Vector3f. 0 0 1)
   3.447 -          (Vector3f. 0 0 1)
   3.448 -
   3.449 -          )
   3.450 -       (.setCollisionBetweenLinkedBodys false)
   3.451 -       ;;(.setLimit (- Math/PI) Math/PI)
   3.452 -       )
   3.453 -     (= joint :cone)
   3.454 -     ;; note to self -- jbullet does NOT implement cone joints
   3.455 -     ;; correctly. You must use plain ol' bullet for this to work.
   3.456 -     ;; It's faster anyway, so whatever.
   3.457 -     
   3.458 -     (doto (ConeJoint.
   3.459 -            a b
   3.460 -            (Vector3f. 0 -5 0)
   3.461 -            (Vector3f. 0 2 0)
   3.462 -
   3.463 -            (doto (Matrix3f.)
   3.464 -              (.fromStartEndVectors Vector3f/UNIT_X
   3.465 -                                    Vector3f/UNIT_Y))
   3.466 -            (doto (Matrix3f.)
   3.467 -              (.fromStartEndVectors Vector3f/UNIT_X
   3.468 -                                    Vector3f/UNIT_Y))
   3.469 -            )
   3.470 -       ;;(.setAngularOnly true)
   3.471 -       
   3.472 -       (.setCollisionBetweenLinkedBodys false)
   3.473 -       (.setLimit (* 1 (/ Math/PI 4))
   3.474 -                  (* 1 (/ Math/PI 4))
   3.475 -                  (* 0 (/ Math/PI 4)))
   3.476 -        
   3.477 -       )
   3.478 -     (= joint :six)
   3.479 -     (doto
   3.480 -         (SixDofJoint.
   3.481 -          a b
   3.482 -          (Vector3f. 0 -2 0)
   3.483 -          (Vector3f. 0 2 0)
   3.484 -          ;;(doto (Matrix3f.)
   3.485 -          ;;    (.fromStartEndVectors Vector3f/UNIT_X
   3.486 -          ;;                          Vector3f/UNIT_Y))
   3.487 -          ;;(doto (Matrix3f.)
   3.488 -          ;;  (.fromStartEndVectors Vector3f/UNIT_X
   3.489 -          ;;                        Vector3f/UNIT_Y))
   3.490 -          true)
   3.491 -       (.setCollisionBetweenLinkedBodys false)
   3.492 -       (.setAngularLowerLimit (Vector3f. 0
   3.493 -                                         (- (/ Math/PI 2))
   3.494 -                                         0))
   3.495 -                                         
   3.496 -       (.setAngularUpperLimit (Vector3f. 0
   3.497 -                                         (/ Math/PI 2)
   3.498 -                                         0))
   3.499 -       (.setLinearLowerLimit  (Vector3f. 0 0 0))
   3.500 -       (.setLinearUpperLimit  (Vector3f. 0 0 0))
   3.501 -
   3.502 -       )
   3.503 -          
   3.504 -            
   3.505 -            
   3.506 -          
   3.507 -     
   3.508 -    )
   3.509 -      
   3.510 -    [top bottom table]))
   3.511 -
   3.512 -(defn speed-up [world]
   3.513 -  (.setMoveSpeed (.getFlyByCamera world)
   3.514 -                 (float 100))
   3.515 -  (.setRotationSpeed (.getFlyByCamera world)
   3.516 -                     (float 20))
   3.517 -  world)
   3.518 -
   3.519 -
   3.520 -(defn test-joint [joint]
   3.521 -  (let [[top bottom floor] (world-setup joint)
   3.522 -        control (.getControl top RigidBodyControl)
   3.523 -        move-up? (atom false)
   3.524 -        move-down? (atom false)
   3.525 -        move-left? (atom false)
   3.526 -        move-right? (atom false)
   3.527 -        roll-left? (atom false)
   3.528 -        roll-right? (atom false)
   3.529 -        timer (atom 0)]
   3.530 -
   3.531 -    (world
   3.532 -     (nodify [top bottom floor])
   3.533 -     (merge standard-debug-controls
   3.534 -            {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
   3.535 -             "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
   3.536 -             "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
   3.537 -             "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
   3.538 -             "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
   3.539 -             "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})     
   3.540 -     
   3.541 -     (fn [world]
   3.542 -       (light-up-everything world)
   3.543 -       (enable-debug world)
   3.544 -       (set-gravity world (Vector3f. 0 0 0))
   3.545 -       )
   3.546 -     
   3.547 -     (fn [world _]
   3.548 -       (if (zero? (rem (swap! timer inc) 100))
   3.549 -         (do
   3.550 -         ;;  (println-repl @timer)
   3.551 -           (.attachChild (.getRootNode world)
   3.552 -                       (sphere 0.05 :color ColorRGBA/Yellow
   3.553 -                               :position (.getWorldTranslation top)
   3.554 -                               :physical? false))))
   3.555 -       (if @move-up?
   3.556 -         (.applyTorque control
   3.557 -                       (.mult (.getPhysicsRotation control)
   3.558 -                              (Vector3f. 0 0 10))))
   3.559 -       (if @move-down?
   3.560 -         (.applyTorque control
   3.561 -                       (.mult (.getPhysicsRotation control)
   3.562 -                              (Vector3f. 0 0 -10))))
   3.563 -       (if @move-left?
   3.564 -         (.applyTorque control
   3.565 -                       (.mult (.getPhysicsRotation control)
   3.566 -                              (Vector3f. 0 10 0))))
   3.567 -       (if @move-right?
   3.568 -         (.applyTorque control
   3.569 -                       (.mult (.getPhysicsRotation control)
   3.570 -                              (Vector3f. 0 -10 0))))
   3.571 -       (if @roll-left?
   3.572 -         (.applyTorque control
   3.573 -                       (.mult (.getPhysicsRotation control)
   3.574 -                              (Vector3f. -1 0 0))))
   3.575 -       (if @roll-right?
   3.576 -         (.applyTorque control
   3.577 -                       (.mult (.getPhysicsRotation control)
   3.578 -                              (Vector3f. 1 0 0))))))))
   3.579 -
   3.580 -                  
   3.581 -
   3.582 -(defn run [joint] (.start (test-joint joint)))
   3.583 -(defn look [joint] (view (nodify (world-setup joint))))
   3.584 -
   3.585 -(defn blender-to-jme
   3.586 -  "Convert from Blender coordinates to JME coordinates"
   3.587 -  [#^Vector3f in]
   3.588 -  (Vector3f. (.getX in)
   3.589 -             (.getZ in)
   3.590 -             (- (.getY in))))
   3.591 -
   3.592 -
   3.593 -(defn joint-targets
   3.594 -  "Return the two closest two objects to the joint object, ordered
   3.595 -  from bottom to top according to the joint's rotation."
   3.596 -  [#^Node parts #^Node joint]
   3.597 -  ;;(println (meta-data joint "joint"))
   3.598 -  (.getWorldRotation joint)
   3.599 -  (loop [radius (float 0.01)]
   3.600 -    (let [results (CollisionResults.)]
   3.601 -      (.collideWith
   3.602 -       parts
   3.603 -       (BoundingBox. (.getWorldTranslation joint)
   3.604 -                     radius radius radius)
   3.605 -       results)
   3.606 -      (let [targets
   3.607 -            (distinct
   3.608 -             (map  #(.getGeometry %) results))]
   3.609 -        (if (>= (count targets) 2)
   3.610 -          (sort-by
   3.611 -           #(.getY
   3.612 -             (.mult
   3.613 -              (.inverse (.getWorldRotation joint))
   3.614 -              (.subtract (.getWorldTranslation %)
   3.615 -                         (.getWorldTranslation joint))))
   3.616 -           (take 2 targets))
   3.617 -          (recur (float (* radius 2))))))))
   3.618 -
   3.619 -(defn connect
   3.620 -  "here are some examples:
   3.621 -   {:type :point}
   3.622 -   {:type :hinge  :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
   3.623 -   (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
   3.624 -
   3.625 -   {:type :cone   :limit-xz 0]
   3.626 -                  :limit-yz 0]
   3.627 -                  :twist 0]}
   3.628 -"
   3.629 -  ([#^Node obj-a #^Node obj-b #^Node joint]
   3.630 -     (let [center-a (.getWorldTranslation obj-a)
   3.631 -           center-b (.getWorldTranslation obj-b)
   3.632 -           joint-center (.getWorldTranslation joint)
   3.633 -           pivot-a (.subtract joint-center center-a)
   3.634 -           pivot-b (.subtract joint-center center-b)
   3.635 -           control-a (.getControl obj-a RigidBodyControl)
   3.636 -           control-b (.getControl obj-b RigidBodyControl)]
   3.637 -           ;; A side-effect of creating a joint registers
   3.638 -           ;; it with both physics objects which in turn
   3.639 -           ;; will register the joint with the physics system
   3.640 -           ;; when the simulation is started.
   3.641 -       (if-let [constraints
   3.642 -                (map-vals
   3.643 -                 eval
   3.644 -                 (read-string
   3.645 -                  (meta-data (first (worm-joints)) "joint")))]
   3.646 -
   3.647 -         (let [joint-type (:type constraints)]
   3.648 -           (cond (= :point joint-type)
   3.649 -                 (do
   3.650 -                   (println-repl "creating POINT joint")
   3.651 -                   (Point2PointJoint.
   3.652 -                    control-a
   3.653 -                    control-b
   3.654 -                    pivot-a
   3.655 -                    pivot-b))
   3.656 -                 (= :hinge joint-type)
   3.657 -                 (do
   3.658 -                   (println-repl "creating HINGE joint")
   3.659 -                   (let [axis (if-let
   3.660 -                                  [axis (:axis constraints)]
   3.661 -                                axis
   3.662 -                                Vector3f/UNIT_X)
   3.663 -                         [limit-1 limit-2] (:limit constraints)
   3.664 -                         hinge-axis
   3.665 -                         (.mult
   3.666 -                          (.getWorldRotation joint)
   3.667 -                          (blender-to-jme axis))]
   3.668 -                     (doto
   3.669 -                         (HingeJoint.
   3.670 -                          control-a
   3.671 -                          control-b
   3.672 -                          pivot-a
   3.673 -                          pivot-b
   3.674 -                          hinge-axis
   3.675 -                          hinge-axis)
   3.676 -                       (.setLimit limit-1 limit-2))))
   3.677 -                 (= :cone joint-type)
   3.678 -                 (do
   3.679 -                   (let [limit-xy (:limit-xz constraints)
   3.680 -                         limit-yz (:limit-yz constraints)
   3.681 -                         twist    (:twist constraints)]
   3.682 -                     
   3.683 -                     (println-repl "creating CONE joint")
   3.684 -                     (doto
   3.685 -                         (ConeJoint.
   3.686 -                          control-a
   3.687 -                          control-b
   3.688 -                          pivot-a
   3.689 -                          pivot-b
   3.690 -                          (doto (Matrix3f.)
   3.691 -                            (.fromStartEndVectors
   3.692 -                             Vector3f/UNIT_X
   3.693 -                             (.normalize
   3.694 -                              (.subtract (.getWorldTranslation joint)
   3.695 -                                         (.getWorldTranslation obj-a)))))
   3.696 -                          (doto (Matrix3f.)
   3.697 -                            (.fromStartEndVectors
   3.698 -                             Vector3f/UNIT_X
   3.699 -                             (.normalize
   3.700 -                              (.subtract
   3.701 -                               (.getWorldTranslation obj-b)
   3.702 -                               (.getWorldTranslation joint))))))
   3.703 -                       (.setLimit (float limit-xy)
   3.704 -                                  (float limit-yz)
   3.705 -                                  (float twist)))))
   3.706 -                 true
   3.707 -                 (println-repl
   3.708 -                  "joint-type " joint-type " not recognized")))
   3.709 -                 
   3.710 -           (println-repl "could not find joint meta-data!")))))
   3.711 -           
   3.712 -
   3.713 -
   3.714 -(defn physical-worm [#^Node pieces joints]
   3.715 -  (dorun
   3.716 -   (map
   3.717 -    (fn [geom]
   3.718 -      (let [physics-control
   3.719 -            (RigidBodyControl.
   3.720 -             (HullCollisionShape.
   3.721 -              (.getMesh geom))
   3.722 -             (if-let [mass (meta-data geom "mass")]
   3.723 -               (do
   3.724 -                 (println-repl
   3.725 -                  "setting mass to " (float mass))
   3.726 -                 (float mass))
   3.727 -               (float 1)))]
   3.728 -               
   3.729 -        (.addControl geom physics-control)))
   3.730 -    (filter #(isa? (class %) Geometry )
   3.731 -            (node-seq pieces))))
   3.732 -
   3.733 -  (dorun
   3.734 -   (map
   3.735 -    (fn [joint]
   3.736 -      (let [[obj-a obj-b]
   3.737 -            (joint-targets pieces joint)]
   3.738 -        (connect obj-a obj-b joint)))
   3.739 -    joints))
   3.740 -  pieces)
   3.741 -
   3.742 -(defn the-worm []
   3.743 -  (physical-worm (worm) (worm-joints)))
   3.744 -
   3.745 -(defn test-worm []
   3.746 -  (world
   3.747 -   (nodify [(the-worm)
   3.748 -            (box 10 2 10 :position (Vector3f. 0 -5 0)
   3.749 -                 :color ColorRGBA/Gray :mass 0)])
   3.750 -   standard-debug-controls
   3.751 -   (comp light-up-everything enable-debug
   3.752 -         (fn [world]
   3.753 -           (.setTimer world (NanoTimer.))
   3.754 -           (speed-up world)
   3.755 -           ;;(set-gravity world (Vector3f. 0 0 0))
   3.756 -           world
   3.757 -           ))
   3.758 -   no-op))
   3.759 -
   3.760  #+end_src
   3.761  
   3.762 -#+results: body-1
   3.763 -: #'cortex.silly/test-try-again
   3.764 -
   3.765 -
   3.766  
   3.767  * COMMENT generate source
   3.768  #+begin_src clojure :tangle ../src/cortex/silly.clj
     4.1 --- a/org/util.org	Wed Jan 04 08:36:42 2012 -0700
     4.2 +++ b/org/util.org	Wed Jan 04 20:34:00 2012 -0700
     4.3 @@ -128,6 +128,16 @@
     4.4       BulletAppState))
     4.5     (asset-manager)))
     4.6  
     4.7 +(defn speed-up 
     4.8 +  "Increase the dismally slow speed of the world's camera."
     4.9 +  [world]
    4.10 +  (.setMoveSpeed (.getFlyByCamera world)
    4.11 +                 (float 100))
    4.12 +  (.setRotationSpeed (.getFlyByCamera world)
    4.13 +                     (float 20))
    4.14 +  world)
    4.15 +
    4.16 +
    4.17  (defn no-logging 
    4.18    "Disable all of jMonkeyEngine's logging."
    4.19    []