Mercurial > cortex
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 |