Mercurial > cortex
comparison org/body.org @ 60:e5e627f50a3a
finally got euler angle stuff working
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 28 Nov 2011 02:54:48 -0700 |
parents | 25142dad240a |
children | 7b44348af538 |
comparison
equal
deleted
inserted
replaced
59:63951929fe44 | 60:e5e627f50a3a |
---|---|
141 (.setMaterial (green-x-ray)))] | 141 (.setMaterial (green-x-ray)))] |
142 (.attachChild node sd) | 142 (.attachChild node sd) |
143 node)) | 143 node)) |
144 | 144 |
145 | 145 |
146 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
147 | |
148 ;; this could be a good way to give objects special properties like | |
149 ;; being eyes and the like | |
150 | |
151 (.getUserData | |
152 (.getChild | |
153 (load-blender-model "Models/property/test.blend") 0) | |
154 "properties") | |
155 | |
156 ;; the properties are saved along with the blender file. | |
157 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
158 | |
159 | |
146 | 160 |
147 (defn init-debug-skel-node | 161 (defn init-debug-skel-node |
148 [f debug-node skeleton] | 162 [f debug-node skeleton] |
149 (let [bones | 163 (let [bones |
150 (map #(.getBone skeleton %) | 164 (map #(.getBone skeleton %) |
310 (range 60)))) | 324 (range 60)))) |
311 (view points))) | 325 (view points))) |
312 | 326 |
313 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 327 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
314 | 328 |
315 | |
316 | |
317 | |
318 | |
319 | |
320 ;;;;;;;;;;;; eve-style bodies ;;;;;;;; | 329 ;;;;;;;;;;;; eve-style bodies ;;;;;;;; |
321 (defn joint-control | 330 |
322 [joint] | 331 |
323 (let [physics-space (ref nil)] | 332 (defrecord JointControl [joint physics-space] |
324 (reify PhysicsControl | 333 PhysicsControl |
325 (setPhysicsSpace [this space] | 334 (setPhysicsSpace [this space] |
326 (dosync | 335 (dosync |
327 (ref-set physics-space space)) | 336 (ref-set (:physics-space this) space)) |
328 (.addJoint space joint)) | 337 (.addJoint space (:joint this))) |
329 (update [this tpf]) | 338 (update [this tpf]) |
330 (setSpatial [this spatial]) | 339 (setSpatial [this spatial]) |
331 (render [this rm vp]) | 340 (render [this rm vp]) |
332 (getPhysicsSpace [this] (deref physics-space)) | 341 (getPhysicsSpace [this] (deref (:physics-space this))) |
333 (isEnabled [this] true) | 342 (isEnabled [this] true) |
334 (setEnabled [this state])))) | 343 (setEnabled [this state])) |
335 | 344 |
336 (defn add-joint | 345 (defn add-joint |
337 "Add a joint to a particular object. When the object is added to the | 346 "Add a joint to a particular object. When the object is added to the |
338 PhysicsSpace of a simulation, the joint will also be added" | 347 PhysicsSpace of a simulation, the joint will also be added" |
339 [object joint] | 348 [object joint] |
340 (let [control (joint-control joint)] | 349 (let [control (JointControl. joint (ref nil))] |
341 (.addControl object control)) | 350 (.addControl object control)) |
342 object) | 351 object) |
343 | 352 |
344 (defn hinge-world | 353 (defn hinge-world |
345 [] | 354 [] |
369 :color (ColorRGBA/randomColor)))] | 378 :color (ColorRGBA/randomColor)))] |
370 (map nth-segment (range num-segments)))) | 379 (map nth-segment (range num-segments)))) |
371 | 380 |
372 (defn nodify | 381 (defn nodify |
373 "take a sequence of things that can be attached to a node and return | 382 "take a sequence of things that can be attached to a node and return |
374 a node with all of the attached" | 383 a node with all of them attached" |
375 ([name children] | 384 ([name children] |
376 (let [node (Node. name)] | 385 (let [node (Node. name)] |
377 (dorun (map #(.attachChild node %) children)) | 386 (dorun (map #(.attachChild node %) children)) |
378 node)) | 387 node)) |
379 ([children] (nodify "" children))) | 388 ([children] (nodify "" children))) |
425 no-op))) | 434 no-op))) |
426 | 435 |
427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 436 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
428 | 437 |
429 | 438 |
430 | 439 ;;;;;;;;; Mortor Control ;;;;;;;;;;;;; |
431 | 440 |
432 | 441 |
433 | 442 ;; surprisingly ehough, terristerial creatures only move by using |
434 | 443 ;; torque applied to their joints. There's not a single straight line |
435 | 444 ;; of force in the human body at all! (a straight line of force would |
436 | 445 ;; correspond to some sort of jet or rocket propulseion) |
446 | |
447 (defn node-seq | |
448 "take a node and return a seq of all its children | |
449 recursively. There will be no nodes left in the resulting | |
450 structure" | |
451 [#^Node node] | |
452 (tree-seq #(isa? (class %) Node) #(.getChildren %) node)) | |
453 | |
454 | |
455 (defn torque-controls [control] | |
456 (let [torques | |
457 (concat | |
458 (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) | |
459 (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) | |
460 [Vector3f/UNIT_X])] | |
461 (map (fn [torque-axis] | |
462 (fn [torque] | |
463 (.applyTorque | |
464 control | |
465 (.mult (.mult (.getPhysicsRotation control) | |
466 torque-axis) | |
467 (float | |
468 (* (.getMass control) torque)))))) | |
469 torques))) | |
470 | |
471 (defn motor-map | |
472 "Take a creature and generate a function that will enable fine | |
473 grained control over all the creature's limbs." | |
474 [#^Node creature] | |
475 (let [controls (keep #(.getControl % RigidBodyControl) | |
476 (node-seq creature)) | |
477 limb-controls (reduce concat (map torque-controls controls)) | |
478 body-control (partial map #(%1 %2) limb-controls)] | |
479 body-control)) | |
480 | |
481 | |
482 | |
483 (defn test-motor-map | |
484 "see how torque works." | |
485 [] | |
486 (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) | |
487 :mass 1 :color ColorRGBA/Green) | |
488 motor-map (motor-map finger)] | |
489 (world | |
490 (nodify [finger | |
491 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
492 :color ColorRGBA/Gray)]) | |
493 standard-debug-controls | |
494 (fn [world] | |
495 (set-gravity world Vector3f/ZERO) | |
496 (light-up-everything world) | |
497 (.setTimer world (NanoTimer.))) | |
498 (fn [_ _] | |
499 (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) | |
500 | |
501 | |
502 | |
503 (defn test-torque | |
504 "see how torque works." | |
505 [] | |
506 (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) | |
507 :mass 1 :color ColorRGBA/Green) | |
508 move-left? (atom false) | |
509 move-right? (atom false) | |
510 control (.getControl finger RigidBodyControl)] | |
511 (world | |
512 (nodify [finger | |
513 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
514 :color ColorRGBA/Gray)]) | |
515 (merge standard-debug-controls | |
516 {"key-k" (fn [_ pressed?] (reset! move-left? pressed?)) | |
517 "key-l" (fn [_ pressed?] (reset! move-right? pressed?))}) | |
518 (fn [world] | |
519 (set-gravity world Vector3f/ZERO) | |
520 (light-up-everything world) | |
521 (.setTimer world (NanoTimer.))) | |
522 (fn [_ _] | |
523 (if @move-left? | |
524 (.applyTorque control | |
525 (.mult (.getPhysicsRotation control) | |
526 (Vector3f. -3 20 0)))) | |
527 (if @move-right? | |
528 (.applyTorque control (Vector3f. 0 0 1))))))) | |
529 | |
530 | |
531 (defn worm-pattern [time] | |
532 [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
533 | |
534 0 0 0 0 0 0 0 0 0 0 0 | |
535 | |
536 (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) | |
537 | |
538 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
539 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 | |
540 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | |
541 | |
542 ]) | |
543 | |
544 | |
545 ;; (defn copier-gen [] | |
546 ;; (let [count (atom 0)] | |
547 ;; (fn [in] | |
548 ;; (swap! count inc) | |
549 ;; (clojure.contrib.duck-streams/copy | |
550 ;; in (File. (str "/home/r/tmp/mao-test/clojure-images/" | |
551 ;; ;;/home/r/tmp/mao-test/clojure-images | |
552 ;; (format "%08d.png" @count))))))) | |
553 ;; (defn decrease-framerate [] | |
554 ;; (map | |
555 ;; (copier-gen) | |
556 ;; (sort | |
557 ;; (map first | |
558 ;; (partition | |
559 ;; 4 | |
560 ;; (filter #(re-matches #".*.png$" (.getCanonicalPath %)) | |
561 ;; (file-seq | |
562 ;; (file-str | |
563 ;; "/home/r/media/anime/mao-temp/images")))))))) | |
564 | |
565 | |
566 | |
567 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
568 | |
569 | |
570 | |
571 | |
572 ;;;;;;;;;;;;;;;;;; Proprioception ;;;;;;;;;;;;;;;;;;;;;;;; | |
573 | |
574 | |
575 ;; this is not used as just getting the rotation would be simpler. | |
576 (defn proprioception-senses | |
577 "given a control , create a sequence of thunks that will report the | |
578 rotation of the control's object along the same axes as the motor-control map." | |
579 [control] | |
580 (let [torques | |
581 (concat | |
582 (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) | |
583 (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) | |
584 [Vector3f/UNIT_X])] | |
585 (map (fn [torque-axis] | |
586 (fn [] | |
587 (.getPhysicsRotation control))) | |
588 torques))) | |
589 | |
590 (defn orthogonal-vect | |
591 "Return a vector orthogonal to the current one" | |
592 [vector] | |
593 (let [x (.getX vector) | |
594 y (.getY vector) | |
595 z (.getZ vector)] | |
596 (cond | |
597 (not= x (float 0)) (Vector3f. (- z) 0 x) | |
598 (not= y (float 0)) (Vector3f. 0 (- z) y) | |
599 (not= z (float 0)) (Vector3f. 0 (- z) y) | |
600 true Vector3f/ZERO))) | |
601 | |
602 ;; from | |
603 ;; http://stackoverflow.com/questions/3684269/ \\ | |
604 ;; component-of-a-quaternion-rotation-around-an-axis | |
605 (defn rot-about-axis [#^Quaternion q #^Vector3f axis] | |
606 (let [basis-1 (orthogonal-vect axis) | |
607 basis-2 (.cross axis basis-1) | |
608 rotated (.mult q basis-1) | |
609 alpha (.dot basis-1 (.project rotated basis-1)) | |
610 beta (.dot basis-2 (.project rotated basis-2))] | |
611 (println-repl alpha) | |
612 (println-repl beta) | |
613 (Math/atan2 beta alpha))) | |
614 | |
615 | |
616 (defn check-rot [a] | |
617 (rot-about-axis | |
618 (doto (Quaternion.) | |
619 (.fromAngleAxis | |
620 (float a) | |
621 (Vector3f. 1 0 0))) (Vector3f. 1 0 0))) | |
622 | |
623 (defn relative-positions [joint] | |
624 (let [object-a (.getUserObject (.getBodyA joint)) | |
625 object-b (.getUserObject (.getBodyB joint)) | |
626 arm-a | |
627 (.normalize | |
628 (.subtract | |
629 (.localToWorld object-a (.getPivotA joint) nil) | |
630 (.getWorldTranslation object-a))) | |
631 rotate-a | |
632 (doto (Matrix3f.) | |
633 (.fromStartEndVectors arm-a Vector3f/UNIT_X)) | |
634 arm-b | |
635 (.mult | |
636 rotate-a | |
637 (.normalize | |
638 (.subtract | |
639 (.localToWorld object-b (.getPivotB joint) nil) | |
640 (.getWorldTranslation object-b)))) | |
641 rotate-b | |
642 (doto (Matrix3f.) | |
643 (.fromStartEndVectors arm-b Vector3f/UNIT_X)) | |
644 | |
645 pitch | |
646 (.angleBetween | |
647 (.normalize (Vector2f. (.getX arm-b) (.getY arm-b))) | |
648 (Vector2f. 1 0)) | |
649 yaw | |
650 (.angleBetween | |
651 (.normalize (Vector2f. (.getX arm-b) (.getZ arm-b))) | |
652 (Vector2f. 1 0)) | |
653 | |
654 roll | |
655 (.mult | |
656 (.getLocalRotation object-b) | |
657 (doto (Quaternion.) | |
658 (.fromRotationMatrix rotate-a))) | |
659 ] | |
660 | |
661 | |
662 | |
663 ;;(println-repl | |
664 ;; "arm-b is " arm-b) | |
665 ;;(println-repl | |
666 ;; "pivot-b is " (.getPivotB joint)) | |
667 ;;(println-repl | |
668 ;; (format "pitch: %1.2f\nyaw: %1.2f\nroll: %1.2f\n" | |
669 ;; pitch yaw roll)) | |
670 [pitch yaw roll])) | |
671 | |
672 | |
673 | |
674 | |
675 | |
676 (defn proprioception | |
677 "Create a proprioception map that reports the rotations of the | |
678 various limbs of the creature's body" | |
679 [creature] | |
680 [#^Node creature] | |
681 (let [ | |
682 nodes (node-seq creature) | |
683 joints | |
684 (map | |
685 :joint | |
686 (filter | |
687 #(isa? (class %) JointControl) | |
688 (reduce | |
689 concat | |
690 (map (fn [node] | |
691 (map (fn [num] (.getControl node num)) | |
692 (range (.getNumControls node)))) | |
693 nodes))))] | |
694 (fn [] | |
695 (reduce concat (map relative-positions (list (first joints))))))) | |
696 | |
697 | |
698 (defn test-worm-control | |
699 [] | |
700 (let [worm (point-worm) | |
701 time (atom 0) | |
702 worm-motor-map (motor-map worm) | |
703 body-map (proprioception worm) | |
704 debug-segments | |
705 (map | |
706 #(doto | |
707 (make-shape | |
708 (assoc base-shape | |
709 :name "debug-line" | |
710 :physical? false | |
711 :shape | |
712 (com.jme3.scene.shape.Line. | |
713 (.add (.getWorldTranslation %) | |
714 (Vector3f. -0.2 0 0 )) | |
715 (.add (.getWorldTranslation %) | |
716 (Vector3f. 0.2 0 0))))) | |
717 (.setMaterial (green-x-ray))) | |
718 (drop 1 (node-seq worm)))] | |
719 (world | |
720 (nodify [worm | |
721 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 | |
722 :color ColorRGBA/Gray)]) | |
723 standard-debug-controls | |
724 (fn [world] | |
725 (.attachChild (.getRootNode world) (nodify debug-segments)) | |
726 (enable-debug world) | |
727 (light-up-everything world) | |
728 (com.aurellem.capture.Capture/captureVideo | |
729 world | |
730 (file-str "/home/r/proj/cortex/tmp/moving-worm"))) | |
731 | |
732 (fn [_ _] | |
733 (dorun | |
734 (map | |
735 (fn [worm-segment | |
736 debug-segment] | |
737 (.rotate | |
738 debug-segment | |
739 (Quaternion. (float 0) (float 0.05) (float 0) (float 1)))) | |
740 (drop 1 (node-seq worm)) | |
741 debug-segments)) | |
742 (swap! time inc) | |
743 (println-repl (with-out-str (clojure.pprint/pprint (doall (body-map))))) | |
744 (Thread/sleep 200) | |
745 (dorun (worm-motor-map | |
746 (worm-pattern @time))))))) | |
747 | |
748 | |
749 | |
750 | |
751 | |
752 (defn test-prop | |
753 "see how torque works." | |
754 [] | |
755 (let [hand (box 1 0.2 0.2 :position (Vector3f. 0 2 0) | |
756 :mass 0 :color ColorRGBA/Green) | |
757 finger (box 1 0.2 0.2 :position (Vector3f. 2.4 2 0) | |
758 :mass 1 :color (ColorRGBA. 0.20 0.40 0.99 1.0)) | |
759 floor (box 10 0.5 10 :position (Vector3f. 0 -5 0) | |
760 :mass 0 :color ColorRGBA/Gray) | |
761 | |
762 move-up? (atom false) | |
763 move-down? (atom false) | |
764 move-left? (atom false) | |
765 move-right? (atom false) | |
766 roll-left? (atom false) | |
767 roll-right? (atom false) | |
768 control (.getControl finger RigidBodyControl) | |
769 joint | |
770 (doto | |
771 (Point2PointJoint. | |
772 (.getControl hand RigidBodyControl) | |
773 control | |
774 (Vector3f. 1.2 0 0) | |
775 (Vector3f. -1.2 0 0 )) | |
776 (.setCollisionBetweenLinkedBodys false)) | |
777 time (atom 0) | |
778 ] | |
779 (world | |
780 (nodify [hand finger floor]) | |
781 (merge standard-debug-controls | |
782 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?)) | |
783 "key-t" (fn [_ pressed?] (reset! move-down? pressed?)) | |
784 "key-f" (fn [_ pressed?] (reset! move-left? pressed?)) | |
785 "key-g" (fn [_ pressed?] (reset! move-right? pressed?)) | |
786 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?)) | |
787 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))}) | |
788 (fn [world] | |
789 (set-gravity world Vector3f/ZERO) | |
790 (.setMoveSpeed (.getFlyByCamera world) 50) | |
791 (.setRotationSpeed (.getFlyByCamera world) 50) | |
792 (light-up-everything world) | |
793 (.setTimer world (NanoTimer.)) | |
794 ) | |
795 (fn [_ _] | |
796 (if @move-up? | |
797 (.applyTorque control | |
798 (.mult (.getPhysicsRotation control) | |
799 (Vector3f. 0 0 1)))) | |
800 (if @move-down? | |
801 (.applyTorque control | |
802 (.mult (.getPhysicsRotation control) | |
803 (Vector3f. 0 0 -1)))) | |
804 (if @move-left? | |
805 (.applyTorque control | |
806 (.mult (.getPhysicsRotation control) | |
807 (Vector3f. 0 1 0)))) | |
808 (if @move-right? | |
809 (.applyTorque control | |
810 (.mult (.getPhysicsRotation control) | |
811 (Vector3f. 0 -1 0)))) | |
812 (if @roll-left? | |
813 (.applyTorque control | |
814 (.mult (.getPhysicsRotation control) | |
815 (Vector3f. -0.1 0 0)))) | |
816 (if @roll-right? | |
817 (.applyTorque control | |
818 (.mult (.getPhysicsRotation control) | |
819 (Vector3f. 0.1 0 0)))) | |
820 | |
821 (if (= 0 (rem (swap! time inc) 2000)) | |
822 (do | |
823 ;;(println-repl (.getLocalRotation finger)) | |
824 (println-repl (nth (relative-positions joint) 2)))) | |
825 | |
826 )))) | |
827 | |
828 | |
829 | |
830 | |
831 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
437 | 832 |
438 | 833 |
439 | 834 |
440 | 835 |
441 #+end_src | 836 #+end_src |
837 | |
838 #+results: body-main | |
839 : #'cortex.body/test-prop | |
442 | 840 |
443 | 841 |
444 | 842 |
445 | 843 |
446 | 844 |
450 * COMMENT generate Source. | 848 * COMMENT generate Source. |
451 #+begin_src clojure :tangle ../src/cortex/body.clj | 849 #+begin_src clojure :tangle ../src/cortex/body.clj |
452 <<body-main>> | 850 <<body-main>> |
453 #+end_src | 851 #+end_src |
454 | 852 |
853 |