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