comparison org/test-creature.org @ 97:2ff8c7c4e64d

have function for creating touch for a blender creature
author Robert McIntyre <rlm@mit.edu>
date Wed, 11 Jan 2012 00:06:33 -0700
parents 4a9096f31017
children 5b23961433e3
comparison
equal deleted inserted replaced
96:4a9096f31017 97:2ff8c7c4e64d
348 [#^Mesh mesh #^Triangle triangle] 348 [#^Mesh mesh #^Triangle triangle]
349 (map (partial uv-coord mesh) 349 (map (partial uv-coord mesh)
350 (triangle-indices mesh (.getIndex triangle)))) 350 (triangle-indices mesh (.getIndex triangle))))
351 351
352 (defn touch-receptor-image 352 (defn touch-receptor-image
353 "Return the touch-sensor distribution image in ImagePlus format." 353 "Return the touch-sensor distribution image in ImagePlus format, or
354 nil if it does not exist."
354 [#^Geometry obj] 355 [#^Geometry obj]
355 (let 356 (let [mat (.getMaterial obj)]
356 [mat (.getMaterial obj) 357 (if-let [texture-param
357 texture 358 (.getTextureParam
358 (.getTextureValue 359 mat
359 (.getTextureParam 360 MaterialHelper/TEXTURE_TYPE_DIFFUSE)]
360 mat 361 (let
361 MaterialHelper/TEXTURE_TYPE_DIFFUSE)) 362 [texture
362 im (.getImage texture)] 363 (.getTextureValue texture-param)
363 (ImagePlus. 364 im (.getImage texture)]
364 "UV-map" 365 (ImagePlus.
365 (ImageToAwt/convert im false false 0)))) 366 "UV-map"
367 (ImageToAwt/convert im false false 0))))))
368
366 369
367 370
368 (import ij.process.ImageProcessor) 371 (import ij.process.ImageProcessor)
369 (import java.awt.image.BufferedImage) 372 (import java.awt.image.BufferedImage)
370 373
531 (- (apply max (map first verts)) x) 534 (- (apply max (map first verts)) x)
532 (- (apply max (map second verts)) y) 535 (- (apply max (map second verts)) y)
533 ])) 536 ]))
534 537
535 538
536 (defn locate-tactile-sensors 539 (defn locate-feelers
537 "Search the geometry's tactile UV image for touch sensors, returning 540 "Search the geometry's tactile UV image for touch sensors, returning
538 their positions in geometry-relative coordinates." 541 their positions in geometry-relative coordinates."
539 [#^Geometry geo] 542 [#^Geometry geo]
540 (let [mesh (.getMesh geo) 543 (if-let [image (touch-receptor-image geo)]
544 (let [mesh (.getMesh geo)
545 tris (triangles geo)
546
547
548 width (.getWidth image)
549 height (.getHeight image)
550
551 ;; for each triangle
552 sensor-coords
553 (fn [tri]
554 ;; translate triangle to uv-pixel-space
555 (let [uv-tri
556 (pixel-triangle mesh tri width height)
557 bounds (vec (triangle-bounds uv-tri))]
558
559 ;; get that part of the picture
560
561 (apply #(.setRoi image %1 %2 %3 %4) bounds)
562 (let [cutout (.crop (.getProcessor image))
563 ;; extract white pixels inside triangle
564 cutout-tri
565 (map-triangle
566 (fn [_ v]
567 (.subtract
568 v
569 (Vector3f. (bounds 0) (bounds 1) (float 0))))
570 uv-tri)
571 whites (filter (partial inside-triangle? cutout-tri)
572 (map vector2f->vector3f
573 (white-coordinates cutout)))
574 ;; translate pixel coordinates to world-space
575 transform (triangle-transformation cutout-tri tri)]
576 (map #(.mult transform %) whites))))]
577 (vec (map sensor-coords tris)))
578 (repeat (count (triangles geo)) [])))
579
580 (defn enable-touch [#^Geometry geo]
581 (let [feeler-coords (locate-feelers geo)
541 tris (triangles geo) 582 tris (triangles geo)
542 583 limit 0.1]
543 image (touch-receptor-image geo) 584 (fn [node]
544 width (.getWidth image) 585 (let [sensor-origins
545 height (.getHeight image) 586 (map
546 587 #(map (partial local-to-world geo) %)
547 588 feeler-coords)
548 ;; for each triangle 589 triangle-normals
549 sensor-coords 590 (map (partial get-ray-direction geo)
550 (fn [tri] 591 tris)
551 ;; translate triangle to uv-pixel-space 592 rays
552 (let [uv-tri 593 (flatten
553 (pixel-triangle mesh tri width height) 594 (map (fn [origins norm]
554 bounds (vec (triangle-bounds uv-tri))] 595 (map #(doto (Ray. % norm)
555 596 (.setLimit limit)) origins))
556 ;; get that part of the picture 597 sensor-origins triangle-normals))]
557 598 (for [ray rays]
558 (apply #(.setRoi image %1 %2 %3 %4) bounds) 599 (do
559 (let [cutout (.crop (.getProcessor image)) 600 (let [results (CollisionResults.)]
560 ;; extract white pixels inside triangle 601 (.collideWith node ray results)
561 cutout-tri 602 (let [touch-objects
562 (map-triangle 603 (set
563 (fn [_ v] 604 (filter #(not (= geo %))
564 (.subtract 605 (map #(.getGeometry %) results)))]
565 v 606 (count touch-objects)))))))))
566 (Vector3f. (bounds 0) (bounds 1) (float 0)))) 607
567 uv-tri) 608 (defn touch [#^Node pieces]
568 whites (filter (partial inside-triangle? cutout-tri) 609 (let [touch-components
569 (map vector2f->vector3f 610 (map enable-touch
570 (white-coordinates cutout))) 611 (filter #(isa? (class %) Geometry)
571 ;; translate pixel coordinates to world-space 612 (node-seq pieces)))]
572 transform (triangle-transformation cutout-tri tri)] 613 (fn [node]
573 (map #(.mult transform %) whites))))] 614 (reduce into [] (map #(% node) touch-components)))))
574
575
576 615
577 (vec (map sensor-coords tris)))) 616
578
579 (defn locate-tactile-sensors*
580 "Search the geometry's tactile UV image for touch sensors, returning
581 their positions in geometry-relative coordinates."
582 [#^Geometry geo]
583 (let [uv-image (touch-receptor-image geo)
584 width (.getWidth uv-image)
585 height (.getHeight uv-image)
586
587 mesh (.getMesh geo)
588 mesh-tris (triangles geo)
589
590 ;; for each triangle
591 sensor-coords
592 (fn [tri]
593 ;; translate triangle to uv-pixel-space
594 (let [uv-tri
595 (rasterize mesh tri width height)
596 bounds (vec (triangle-bounds uv-tri))]
597
598 ;; get that part of the picture
599
600 (apply (partial (memfn setRoi) uv-image) bounds)
601 (let [cutout (.crop (.getProcessor uv-image))
602 ;; extract white pixels inside triangle
603 cutout-tri
604 (map-triangle
605 (fn [_ v]
606 (.subtract
607 v
608 (Vector3f. (bounds 0) (bounds 1) (float 0))))
609 uv-tri)
610 whites (filter (partial inside-triangle? cutout-tri)
611 (map vector2f->vector3f
612 (white-coordinates cutout)))
613 ;; translate pixel coordinates to world-space
614 transform (triangle-transformation cutout-tri tri)]
615 (map #(.mult transform %) whites))))]
616
617
618
619 (for [mesh-tri mesh-tris]
620
621 (let [uv-tri (rasterize mesh mesh-tri width height)
622 bounding-box (vec (triangle-bounds uv-tri))]
623 (apply (partial (memfn setRoi) uv-image) bounding-box)
624
625
626
627
628 ))
629 (vec (map sensor-coords mesh-tris))))
630
631
632
633 (defn measure-touchies [#^Geometry geo]
634 (let [tactile-sensor-coords (locate-tactile-sensors geo)
635 tris (triangles geo)]
636 (fn [world]
637 (let [sensor-origins (vec
638 (map
639 #(map (partial local-to-world geo) %)
640 tactile-sensor-coords))
641 triangle-normals (vec
642 (map (partial get-ray-direction geo)
643 tris))
644 rays (flatten
645 (map
646 (fn [origins normals]
647 (map
648 #(Ray. %1 %2)
649 origins
650 normals))
651 sensor-origins
652 (map repeat triangle-normals)))
653
654
655 ]
656 rays))))
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 ;; for each triangle in the mesh,
677 ;; get the normal to the triangle,
678 ;; look at the UV touch map, restricted to that triangle,
679 ;; get the positions of those touch sensors in geometry-relative
680 ;; coordinates.
681 (defn tactile-coords [#^Geometry obj]
682 (let [mesh (.getMesh obj)
683 num-triangles (.getTriangleCount mesh)
684 num-verticies (.getVertexCount mesh)
685 uv-coord (partial uv-coord mesh)
686 triangle-indices (partial triangle-indices mesh)
687 receptors (touch-receptor-image obj)
688 tris (triangles obj)
689 ]
690 (map
691 (fn [[tri-1 tri-2 tri-3]]
692 (let [width (.getWidth receptors)
693 height (.getHeight receptors)
694 uv-1 (uv-coord tri-1)
695 uv-2 (uv-coord tri-2)
696 uv-3 (uv-coord tri-3)
697 x-coords (map #(.getX %) [uv-1 uv-2 uv-3])
698 y-coords (map #(.getY %) [uv-1 uv-2 uv-3])
699 max-x (Math/ceil (* width (apply max x-coords)))
700 min-x (Math/floor (* width (apply min x-coords)))
701 max-y (Math/ceil (* height (apply max y-coords)))
702 min-y (Math/floor (* height (apply min y-coords)))
703
704 image-1 (Vector2f. (* width (.getX uv-1))
705 (* height (.getY uv-1)))
706 image-2 (Vector2f. (* width (.getX uv-2))
707 (* height (.getY uv-2)))
708 image-3 (Vector2f. (* width (.getX uv-3))
709 (* height (.getY uv-3)))
710 left-corner
711 (Vector2f. min-x min-y)
712 ]
713
714 (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y))
715 (let [processor (.crop (.getProcessor receptors))]
716 (map
717 #(.add left-corner %)
718
719 (filter
720 (partial
721 inside-triangle?
722 (.subtract image-1 left-corner)
723 (.subtract image-2 left-corner)
724 (.subtract image-3 left-corner))
725 (white-coordinates processor))))
726 )) (map triangle-indices (range num-triangles)))))
727
728
729
730 617
731 618
732 619
733 620
734 (defn all-names [] 621 (defn all-names []
872 (.applyTorque control 759 (.applyTorque control
873 (.mult (.getPhysicsRotation control) 760 (.mult (.getPhysicsRotation control)
874 (Vector3f. 1 0 0)))))))) 761 (Vector3f. 1 0 0))))))))
875 762
876 763
764 (defn locate-feelers*
765 "Search the geometry's tactile UV image for touch sensors, returning
766 their positions in geometry-relative coordinates."
767 [#^Geometry geo]
768 (let [uv-image (touch-receptor-image geo)
769 width (.getWidth uv-image)
770 height (.getHeight uv-image)
771
772 mesh (.getMesh geo)
773 mesh-tris (triangles geo)
774
775 ;; for each triangle
776 sensor-coords
777 (fn [tri]
778 ;; translate triangle to uv-pixel-space
779 (let [uv-tri
780 (rasterize mesh tri width height)
781 bounds (vec (triangle-bounds uv-tri))]
782
783 ;; get that part of the picture
784
785 (apply (partial (memfn setRoi) uv-image) bounds)
786 (let [cutout (.crop (.getProcessor uv-image))
787 ;; extract white pixels inside triangle
788 cutout-tri
789 (map-triangle
790 (fn [_ v]
791 (.subtract
792 v
793 (Vector3f. (bounds 0) (bounds 1) (float 0))))
794 uv-tri)
795 whites (filter (partial inside-triangle? cutout-tri)
796 (map vector2f->vector3f
797 (white-coordinates cutout)))
798 ;; translate pixel coordinates to world-space
799 transform (triangle-transformation cutout-tri tri)]
800 (map #(.mult transform %) whites))))]
801
802
803
804 (for [mesh-tri mesh-tris]
805
806 (let [uv-tri (rasterize mesh mesh-tri width height)
807 bounding-box (vec (triangle-bounds uv-tri))]
808 (apply (partial (memfn setRoi) uv-image) bounding-box)
809 ))
810 (vec (map sensor-coords mesh-tris))))
811
812
813 (defn tactile-coords [#^Geometry obj]
814 (let [mesh (.getMesh obj)
815 num-triangles (.getTriangleCount mesh)
816 num-verticies (.getVertexCount mesh)
817 uv-coord (partial uv-coord mesh)
818 triangle-indices (partial triangle-indices mesh)
819 receptors (touch-receptor-image obj)
820 tris (triangles obj)
821 ]
822 (map
823 (fn [[tri-1 tri-2 tri-3]]
824 (let [width (.getWidth receptors)
825 height (.getHeight receptors)
826 uv-1 (uv-coord tri-1)
827 uv-2 (uv-coord tri-2)
828 uv-3 (uv-coord tri-3)
829 x-coords (map #(.getX %) [uv-1 uv-2 uv-3])
830 y-coords (map #(.getY %) [uv-1 uv-2 uv-3])
831 max-x (Math/ceil (* width (apply max x-coords)))
832 min-x (Math/floor (* width (apply min x-coords)))
833 max-y (Math/ceil (* height (apply max y-coords)))
834 min-y (Math/floor (* height (apply min y-coords)))
835
836 image-1 (Vector2f. (* width (.getX uv-1))
837 (* height (.getY uv-1)))
838 image-2 (Vector2f. (* width (.getX uv-2))
839 (* height (.getY uv-2)))
840 image-3 (Vector2f. (* width (.getX uv-3))
841 (* height (.getY uv-3)))
842 left-corner
843 (Vector2f. min-x min-y)
844 ]
845
846 (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y))
847 (let [processor (.crop (.getProcessor receptors))]
848 (map
849 #(.add left-corner %)
850
851 (filter
852 (partial
853 inside-triangle?
854 (.subtract image-1 left-corner)
855 (.subtract image-2 left-corner)
856 (.subtract image-3 left-corner))
857 (white-coordinates processor))))
858 )) (map triangle-indices (range num-triangles)))))
877 859
878 #+end_src 860 #+end_src
879 861
880 #+results: body-1 862 #+results: body-1
881 : #'cortex.silly/test-joint 863 : #'cortex.silly/test-joint