Mercurial > cortex
changeset 60:e5e627f50a3a
finally got euler angle stuff working
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 28 Nov 2011 02:54:48 -0700 |
parents | 63951929fe44 |
children | 7b44348af538 |
files | assets/Models/property/test.blend org/body.org org/util.org |
diffstat | 3 files changed, 429 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
1.1 Binary file assets/Models/property/test.blend has changed
2.1 --- a/org/body.org Sat Nov 19 23:59:12 2011 -0700 2.2 +++ b/org/body.org Mon Nov 28 02:54:48 2011 -0700 2.3 @@ -143,6 +143,20 @@ 2.4 node)) 2.5 2.6 2.7 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.8 + 2.9 +;; this could be a good way to give objects special properties like 2.10 +;; being eyes and the like 2.11 + 2.12 +(.getUserData 2.13 + (.getChild 2.14 + (load-blender-model "Models/property/test.blend") 0) 2.15 + "properties") 2.16 + 2.17 +;; the properties are saved along with the blender file. 2.18 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.19 + 2.20 + 2.21 2.22 (defn init-debug-skel-node 2.23 [f debug-node skeleton] 2.24 @@ -312,32 +326,27 @@ 2.25 2.26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.27 2.28 +;;;;;;;;;;;; eve-style bodies ;;;;;;;; 2.29 2.30 2.31 - 2.32 - 2.33 - 2.34 -;;;;;;;;;;;; eve-style bodies ;;;;;;;; 2.35 -(defn joint-control 2.36 - [joint] 2.37 - (let [physics-space (ref nil)] 2.38 - (reify PhysicsControl 2.39 - (setPhysicsSpace [this space] 2.40 - (dosync 2.41 - (ref-set physics-space space)) 2.42 - (.addJoint space joint)) 2.43 - (update [this tpf]) 2.44 - (setSpatial [this spatial]) 2.45 - (render [this rm vp]) 2.46 - (getPhysicsSpace [this] (deref physics-space)) 2.47 - (isEnabled [this] true) 2.48 - (setEnabled [this state])))) 2.49 - 2.50 +(defrecord JointControl [joint physics-space] 2.51 + PhysicsControl 2.52 + (setPhysicsSpace [this space] 2.53 + (dosync 2.54 + (ref-set (:physics-space this) space)) 2.55 + (.addJoint space (:joint this))) 2.56 + (update [this tpf]) 2.57 + (setSpatial [this spatial]) 2.58 + (render [this rm vp]) 2.59 + (getPhysicsSpace [this] (deref (:physics-space this))) 2.60 + (isEnabled [this] true) 2.61 + (setEnabled [this state])) 2.62 + 2.63 (defn add-joint 2.64 "Add a joint to a particular object. When the object is added to the 2.65 PhysicsSpace of a simulation, the joint will also be added" 2.66 [object joint] 2.67 - (let [control (joint-control joint)] 2.68 + (let [control (JointControl. joint (ref nil))] 2.69 (.addControl object control)) 2.70 object) 2.71 2.72 @@ -371,7 +380,7 @@ 2.73 2.74 (defn nodify 2.75 "take a sequence of things that can be attached to a node and return 2.76 - a node with all of the attached" 2.77 + a node with all of them attached" 2.78 ([name children] 2.79 (let [node (Node. name)] 2.80 (dorun (map #(.attachChild node %) children)) 2.81 @@ -427,19 +436,408 @@ 2.82 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.83 2.84 2.85 +;;;;;;;;; Mortor Control ;;;;;;;;;;;;; 2.86 2.87 2.88 +;; surprisingly ehough, terristerial creatures only move by using 2.89 +;; torque applied to their joints. There's not a single straight line 2.90 +;; of force in the human body at all! (a straight line of force would 2.91 +;; correspond to some sort of jet or rocket propulseion) 2.92 2.93 +(defn node-seq 2.94 + "take a node and return a seq of all its children 2.95 + recursively. There will be no nodes left in the resulting 2.96 + structure" 2.97 + [#^Node node] 2.98 + (tree-seq #(isa? (class %) Node) #(.getChildren %) node)) 2.99 + 2.100 + 2.101 +(defn torque-controls [control] 2.102 + (let [torques 2.103 + (concat 2.104 + (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) 2.105 + (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) 2.106 + [Vector3f/UNIT_X])] 2.107 + (map (fn [torque-axis] 2.108 + (fn [torque] 2.109 + (.applyTorque 2.110 + control 2.111 + (.mult (.mult (.getPhysicsRotation control) 2.112 + torque-axis) 2.113 + (float 2.114 + (* (.getMass control) torque)))))) 2.115 + torques))) 2.116 2.117 +(defn motor-map 2.118 + "Take a creature and generate a function that will enable fine 2.119 + grained control over all the creature's limbs." 2.120 + [#^Node creature] 2.121 + (let [controls (keep #(.getControl % RigidBodyControl) 2.122 + (node-seq creature)) 2.123 + limb-controls (reduce concat (map torque-controls controls)) 2.124 + body-control (partial map #(%1 %2) limb-controls)] 2.125 + body-control)) 2.126 2.127 2.128 2.129 +(defn test-motor-map 2.130 + "see how torque works." 2.131 + [] 2.132 + (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) 2.133 + :mass 1 :color ColorRGBA/Green) 2.134 + motor-map (motor-map finger)] 2.135 + (world 2.136 + (nodify [finger 2.137 + (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 2.138 + :color ColorRGBA/Gray)]) 2.139 + standard-debug-controls 2.140 + (fn [world] 2.141 + (set-gravity world Vector3f/ZERO) 2.142 + (light-up-everything world) 2.143 + (.setTimer world (NanoTimer.))) 2.144 + (fn [_ _] 2.145 + (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) 2.146 + 2.147 + 2.148 + 2.149 +(defn test-torque 2.150 + "see how torque works." 2.151 + [] 2.152 + (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) 2.153 + :mass 1 :color ColorRGBA/Green) 2.154 + move-left? (atom false) 2.155 + move-right? (atom false) 2.156 + control (.getControl finger RigidBodyControl)] 2.157 + (world 2.158 + (nodify [finger 2.159 + (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 2.160 + :color ColorRGBA/Gray)]) 2.161 + (merge standard-debug-controls 2.162 + {"key-k" (fn [_ pressed?] (reset! move-left? pressed?)) 2.163 + "key-l" (fn [_ pressed?] (reset! move-right? pressed?))}) 2.164 + (fn [world] 2.165 + (set-gravity world Vector3f/ZERO) 2.166 + (light-up-everything world) 2.167 + (.setTimer world (NanoTimer.))) 2.168 + (fn [_ _] 2.169 + (if @move-left? 2.170 + (.applyTorque control 2.171 + (.mult (.getPhysicsRotation control) 2.172 + (Vector3f. -3 20 0)))) 2.173 + (if @move-right? 2.174 + (.applyTorque control (Vector3f. 0 0 1))))))) 2.175 + 2.176 + 2.177 +(defn worm-pattern [time] 2.178 + [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.179 + 2.180 + 0 0 0 0 0 0 0 0 0 0 0 2.181 + 2.182 + (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) 2.183 + 2.184 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.185 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.186 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.187 + 2.188 + ]) 2.189 + 2.190 + 2.191 +;; (defn copier-gen [] 2.192 +;; (let [count (atom 0)] 2.193 +;; (fn [in] 2.194 +;; (swap! count inc) 2.195 +;; (clojure.contrib.duck-streams/copy 2.196 +;; in (File. (str "/home/r/tmp/mao-test/clojure-images/" 2.197 +;; ;;/home/r/tmp/mao-test/clojure-images 2.198 +;; (format "%08d.png" @count))))))) 2.199 +;; (defn decrease-framerate [] 2.200 +;; (map 2.201 +;; (copier-gen) 2.202 +;; (sort 2.203 +;; (map first 2.204 +;; (partition 2.205 +;; 4 2.206 +;; (filter #(re-matches #".*.png$" (.getCanonicalPath %)) 2.207 +;; (file-seq 2.208 +;; (file-str 2.209 +;; "/home/r/media/anime/mao-temp/images")))))))) 2.210 + 2.211 + 2.212 + 2.213 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.214 + 2.215 + 2.216 + 2.217 + 2.218 +;;;;;;;;;;;;;;;;;; Proprioception ;;;;;;;;;;;;;;;;;;;;;;;; 2.219 + 2.220 + 2.221 +;; this is not used as just getting the rotation would be simpler. 2.222 +(defn proprioception-senses 2.223 + "given a control , create a sequence of thunks that will report the 2.224 + rotation of the control's object along the same axes as the motor-control map." 2.225 + [control] 2.226 + (let [torques 2.227 + (concat 2.228 + (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) 2.229 + (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) 2.230 + [Vector3f/UNIT_X])] 2.231 + (map (fn [torque-axis] 2.232 + (fn [] 2.233 + (.getPhysicsRotation control))) 2.234 + torques))) 2.235 + 2.236 +(defn orthogonal-vect 2.237 + "Return a vector orthogonal to the current one" 2.238 + [vector] 2.239 + (let [x (.getX vector) 2.240 + y (.getY vector) 2.241 + z (.getZ vector)] 2.242 + (cond 2.243 + (not= x (float 0)) (Vector3f. (- z) 0 x) 2.244 + (not= y (float 0)) (Vector3f. 0 (- z) y) 2.245 + (not= z (float 0)) (Vector3f. 0 (- z) y) 2.246 + true Vector3f/ZERO))) 2.247 + 2.248 +;; from 2.249 +;; http://stackoverflow.com/questions/3684269/ \\ 2.250 +;; component-of-a-quaternion-rotation-around-an-axis 2.251 +(defn rot-about-axis [#^Quaternion q #^Vector3f axis] 2.252 + (let [basis-1 (orthogonal-vect axis) 2.253 + basis-2 (.cross axis basis-1) 2.254 + rotated (.mult q basis-1) 2.255 + alpha (.dot basis-1 (.project rotated basis-1)) 2.256 + beta (.dot basis-2 (.project rotated basis-2))] 2.257 + (println-repl alpha) 2.258 + (println-repl beta) 2.259 + (Math/atan2 beta alpha))) 2.260 + 2.261 + 2.262 +(defn check-rot [a] 2.263 + (rot-about-axis 2.264 + (doto (Quaternion.) 2.265 + (.fromAngleAxis 2.266 + (float a) 2.267 + (Vector3f. 1 0 0))) (Vector3f. 1 0 0))) 2.268 + 2.269 +(defn relative-positions [joint] 2.270 + (let [object-a (.getUserObject (.getBodyA joint)) 2.271 + object-b (.getUserObject (.getBodyB joint)) 2.272 + arm-a 2.273 + (.normalize 2.274 + (.subtract 2.275 + (.localToWorld object-a (.getPivotA joint) nil) 2.276 + (.getWorldTranslation object-a))) 2.277 + rotate-a 2.278 + (doto (Matrix3f.) 2.279 + (.fromStartEndVectors arm-a Vector3f/UNIT_X)) 2.280 + arm-b 2.281 + (.mult 2.282 + rotate-a 2.283 + (.normalize 2.284 + (.subtract 2.285 + (.localToWorld object-b (.getPivotB joint) nil) 2.286 + (.getWorldTranslation object-b)))) 2.287 + rotate-b 2.288 + (doto (Matrix3f.) 2.289 + (.fromStartEndVectors arm-b Vector3f/UNIT_X)) 2.290 + 2.291 + pitch 2.292 + (.angleBetween 2.293 + (.normalize (Vector2f. (.getX arm-b) (.getY arm-b))) 2.294 + (Vector2f. 1 0)) 2.295 + yaw 2.296 + (.angleBetween 2.297 + (.normalize (Vector2f. (.getX arm-b) (.getZ arm-b))) 2.298 + (Vector2f. 1 0)) 2.299 + 2.300 + roll 2.301 + (.mult 2.302 + (.getLocalRotation object-b) 2.303 + (doto (Quaternion.) 2.304 + (.fromRotationMatrix rotate-a))) 2.305 + ] 2.306 + 2.307 + 2.308 + 2.309 + ;;(println-repl 2.310 + ;; "arm-b is " arm-b) 2.311 + ;;(println-repl 2.312 + ;; "pivot-b is " (.getPivotB joint)) 2.313 + ;;(println-repl 2.314 + ;; (format "pitch: %1.2f\nyaw: %1.2f\nroll: %1.2f\n" 2.315 + ;; pitch yaw roll)) 2.316 + [pitch yaw roll])) 2.317 + 2.318 + 2.319 + 2.320 + 2.321 + 2.322 +(defn proprioception 2.323 + "Create a proprioception map that reports the rotations of the 2.324 + various limbs of the creature's body" 2.325 + [creature] 2.326 + [#^Node creature] 2.327 + (let [ 2.328 + nodes (node-seq creature) 2.329 + joints 2.330 + (map 2.331 + :joint 2.332 + (filter 2.333 + #(isa? (class %) JointControl) 2.334 + (reduce 2.335 + concat 2.336 + (map (fn [node] 2.337 + (map (fn [num] (.getControl node num)) 2.338 + (range (.getNumControls node)))) 2.339 + nodes))))] 2.340 + (fn [] 2.341 + (reduce concat (map relative-positions (list (first joints))))))) 2.342 + 2.343 + 2.344 +(defn test-worm-control 2.345 + [] 2.346 + (let [worm (point-worm) 2.347 + time (atom 0) 2.348 + worm-motor-map (motor-map worm) 2.349 + body-map (proprioception worm) 2.350 + debug-segments 2.351 + (map 2.352 + #(doto 2.353 + (make-shape 2.354 + (assoc base-shape 2.355 + :name "debug-line" 2.356 + :physical? false 2.357 + :shape 2.358 + (com.jme3.scene.shape.Line. 2.359 + (.add (.getWorldTranslation %) 2.360 + (Vector3f. -0.2 0 0 )) 2.361 + (.add (.getWorldTranslation %) 2.362 + (Vector3f. 0.2 0 0))))) 2.363 + (.setMaterial (green-x-ray))) 2.364 + (drop 1 (node-seq worm)))] 2.365 + (world 2.366 + (nodify [worm 2.367 + (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 2.368 + :color ColorRGBA/Gray)]) 2.369 + standard-debug-controls 2.370 + (fn [world] 2.371 + (.attachChild (.getRootNode world) (nodify debug-segments)) 2.372 + (enable-debug world) 2.373 + (light-up-everything world) 2.374 + (com.aurellem.capture.Capture/captureVideo 2.375 + world 2.376 + (file-str "/home/r/proj/cortex/tmp/moving-worm"))) 2.377 + 2.378 + (fn [_ _] 2.379 + (dorun 2.380 + (map 2.381 + (fn [worm-segment 2.382 + debug-segment] 2.383 + (.rotate 2.384 + debug-segment 2.385 + (Quaternion. (float 0) (float 0.05) (float 0) (float 1)))) 2.386 + (drop 1 (node-seq worm)) 2.387 + debug-segments)) 2.388 + (swap! time inc) 2.389 + (println-repl (with-out-str (clojure.pprint/pprint (doall (body-map))))) 2.390 + (Thread/sleep 200) 2.391 + (dorun (worm-motor-map 2.392 + (worm-pattern @time))))))) 2.393 + 2.394 + 2.395 + 2.396 + 2.397 + 2.398 +(defn test-prop 2.399 + "see how torque works." 2.400 + [] 2.401 + (let [hand (box 1 0.2 0.2 :position (Vector3f. 0 2 0) 2.402 + :mass 0 :color ColorRGBA/Green) 2.403 + finger (box 1 0.2 0.2 :position (Vector3f. 2.4 2 0) 2.404 + :mass 1 :color (ColorRGBA. 0.20 0.40 0.99 1.0)) 2.405 + floor (box 10 0.5 10 :position (Vector3f. 0 -5 0) 2.406 + :mass 0 :color ColorRGBA/Gray) 2.407 + 2.408 + move-up? (atom false) 2.409 + move-down? (atom false) 2.410 + move-left? (atom false) 2.411 + move-right? (atom false) 2.412 + roll-left? (atom false) 2.413 + roll-right? (atom false) 2.414 + control (.getControl finger RigidBodyControl) 2.415 + joint 2.416 + (doto 2.417 + (Point2PointJoint. 2.418 + (.getControl hand RigidBodyControl) 2.419 + control 2.420 + (Vector3f. 1.2 0 0) 2.421 + (Vector3f. -1.2 0 0 )) 2.422 + (.setCollisionBetweenLinkedBodys false)) 2.423 + time (atom 0) 2.424 + ] 2.425 + (world 2.426 + (nodify [hand finger floor]) 2.427 + (merge standard-debug-controls 2.428 + {"key-r" (fn [_ pressed?] (reset! move-up? pressed?)) 2.429 + "key-t" (fn [_ pressed?] (reset! move-down? pressed?)) 2.430 + "key-f" (fn [_ pressed?] (reset! move-left? pressed?)) 2.431 + "key-g" (fn [_ pressed?] (reset! move-right? pressed?)) 2.432 + "key-v" (fn [_ pressed?] (reset! roll-left? pressed?)) 2.433 + "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))}) 2.434 + (fn [world] 2.435 + (set-gravity world Vector3f/ZERO) 2.436 + (.setMoveSpeed (.getFlyByCamera world) 50) 2.437 + (.setRotationSpeed (.getFlyByCamera world) 50) 2.438 + (light-up-everything world) 2.439 + (.setTimer world (NanoTimer.)) 2.440 + ) 2.441 + (fn [_ _] 2.442 + (if @move-up? 2.443 + (.applyTorque control 2.444 + (.mult (.getPhysicsRotation control) 2.445 + (Vector3f. 0 0 1)))) 2.446 + (if @move-down? 2.447 + (.applyTorque control 2.448 + (.mult (.getPhysicsRotation control) 2.449 + (Vector3f. 0 0 -1)))) 2.450 + (if @move-left? 2.451 + (.applyTorque control 2.452 + (.mult (.getPhysicsRotation control) 2.453 + (Vector3f. 0 1 0)))) 2.454 + (if @move-right? 2.455 + (.applyTorque control 2.456 + (.mult (.getPhysicsRotation control) 2.457 + (Vector3f. 0 -1 0)))) 2.458 + (if @roll-left? 2.459 + (.applyTorque control 2.460 + (.mult (.getPhysicsRotation control) 2.461 + (Vector3f. -0.1 0 0)))) 2.462 + (if @roll-right? 2.463 + (.applyTorque control 2.464 + (.mult (.getPhysicsRotation control) 2.465 + (Vector3f. 0.1 0 0)))) 2.466 + 2.467 + (if (= 0 (rem (swap! time inc) 2000)) 2.468 + (do 2.469 + ;;(println-repl (.getLocalRotation finger)) 2.470 + (println-repl (nth (relative-positions joint) 2)))) 2.471 + 2.472 + )))) 2.473 + 2.474 + 2.475 + 2.476 + 2.477 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2.478 2.479 2.480 2.481 2.482 #+end_src 2.483 2.484 +#+results: body-main 2.485 +: #'cortex.body/test-prop 2.486 + 2.487 2.488 2.489 2.490 @@ -452,3 +850,4 @@ 2.491 <<body-main>> 2.492 #+end_src 2.493 2.494 +
3.1 --- a/org/util.org Sat Nov 19 23:59:12 2011 -0700 3.2 +++ b/org/util.org Mon Nov 28 02:54:48 2011 -0700 3.3 @@ -280,6 +280,8 @@ 3.4 *** Debug Actions 3.5 #+srcname: debug-actions 3.6 #+begin_src clojure :results silent 3.7 +(in-ns 'cortex.util) 3.8 + 3.9 (defn basic-light-setup 3.10 "returns a sequence of lights appropiate for fully lighting a scene" 3.11 [] 3.12 @@ -333,6 +335,13 @@ 3.13 (add-element game cannon-ball (if node node (.getRootNode game))))))) 3.14 ([] 3.15 (fire-cannon-ball false))) 3.16 + 3.17 +(def standard-debug-controls 3.18 + {"key-space" (fire-cannon-ball)}) 3.19 + 3.20 + 3.21 + 3.22 + 3.23 #+end_src 3.24 3.25