# HG changeset patch # User Robert McIntyre # Date 1326265593 25200 # Node ID 2ff8c7c4e64de00c75c8029bc0a56ae8f909559a # Parent 4a9096f31017c45079f5fdbf140840b5bbc2fdd2 have function for creating touch for a blender creature diff -r 4a9096f31017 -r 2ff8c7c4e64d assets/Models/creature1/tip.png Binary file assets/Models/creature1/tip.png has changed diff -r 4a9096f31017 -r 2ff8c7c4e64d org/test-creature.org --- a/org/test-creature.org Tue Jan 10 21:26:41 2012 -0700 +++ b/org/test-creature.org Wed Jan 11 00:06:33 2012 -0700 @@ -350,19 +350,22 @@ (triangle-indices mesh (.getIndex triangle)))) (defn touch-receptor-image - "Return the touch-sensor distribution image in ImagePlus format." + "Return the touch-sensor distribution image in ImagePlus format, or + nil if it does not exist." [#^Geometry obj] - (let - [mat (.getMaterial obj) - texture - (.getTextureValue - (.getTextureParam - mat - MaterialHelper/TEXTURE_TYPE_DIFFUSE)) - im (.getImage texture)] - (ImagePlus. - "UV-map" - (ImageToAwt/convert im false false 0)))) + (let [mat (.getMaterial obj)] + (if-let [texture-param + (.getTextureParam + mat + MaterialHelper/TEXTURE_TYPE_DIFFUSE)] + (let + [texture + (.getTextureValue texture-param) + im (.getImage texture)] + (ImagePlus. + "UV-map" + (ImageToAwt/convert im false false 0)))))) + (import ij.process.ImageProcessor) @@ -533,200 +536,84 @@ ])) -(defn locate-tactile-sensors +(defn locate-feelers "Search the geometry's tactile UV image for touch sensors, returning their positions in geometry-relative coordinates." [#^Geometry geo] - (let [mesh (.getMesh geo) + (if-let [image (touch-receptor-image geo)] + (let [mesh (.getMesh geo) + tris (triangles geo) + + + width (.getWidth image) + height (.getHeight image) + + ;; for each triangle + sensor-coords + (fn [tri] + ;; translate triangle to uv-pixel-space + (let [uv-tri + (pixel-triangle mesh tri width height) + bounds (vec (triangle-bounds uv-tri))] + + ;; get that part of the picture + + (apply #(.setRoi image %1 %2 %3 %4) bounds) + (let [cutout (.crop (.getProcessor image)) + ;; extract white pixels inside triangle + cutout-tri + (map-triangle + (fn [_ v] + (.subtract + v + (Vector3f. (bounds 0) (bounds 1) (float 0)))) + uv-tri) + whites (filter (partial inside-triangle? cutout-tri) + (map vector2f->vector3f + (white-coordinates cutout))) + ;; translate pixel coordinates to world-space + transform (triangle-transformation cutout-tri tri)] + (map #(.mult transform %) whites))))] + (vec (map sensor-coords tris))) + (repeat (count (triangles geo)) []))) + +(defn enable-touch [#^Geometry geo] + (let [feeler-coords (locate-feelers geo) tris (triangles geo) - - image (touch-receptor-image geo) - width (.getWidth image) - height (.getHeight image) - + limit 0.1] + (fn [node] + (let [sensor-origins + (map + #(map (partial local-to-world geo) %) + feeler-coords) + triangle-normals + (map (partial get-ray-direction geo) + tris) + rays + (flatten + (map (fn [origins norm] + (map #(doto (Ray. % norm) + (.setLimit limit)) origins)) + sensor-origins triangle-normals))] + (for [ray rays] + (do + (let [results (CollisionResults.)] + (.collideWith node ray results) + (let [touch-objects + (set + (filter #(not (= geo %)) + (map #(.getGeometry %) results)))] + (count touch-objects))))))))) - ;; for each triangle - sensor-coords - (fn [tri] - ;; translate triangle to uv-pixel-space - (let [uv-tri - (pixel-triangle mesh tri width height) - bounds (vec (triangle-bounds uv-tri))] - - ;; get that part of the picture - - (apply #(.setRoi image %1 %2 %3 %4) bounds) - (let [cutout (.crop (.getProcessor image)) - ;; extract white pixels inside triangle - cutout-tri - (map-triangle - (fn [_ v] - (.subtract - v - (Vector3f. (bounds 0) (bounds 1) (float 0)))) - uv-tri) - whites (filter (partial inside-triangle? cutout-tri) - (map vector2f->vector3f - (white-coordinates cutout))) - ;; translate pixel coordinates to world-space - transform (triangle-transformation cutout-tri tri)] - (map #(.mult transform %) whites))))] - - +(defn touch [#^Node pieces] + (let [touch-components + (map enable-touch + (filter #(isa? (class %) Geometry) + (node-seq pieces)))] + (fn [node] + (reduce into [] (map #(% node) touch-components))))) - (vec (map sensor-coords tris)))) - -(defn locate-tactile-sensors* - "Search the geometry's tactile UV image for touch sensors, returning - their positions in geometry-relative coordinates." - [#^Geometry geo] - (let [uv-image (touch-receptor-image geo) - width (.getWidth uv-image) - height (.getHeight uv-image) - - mesh (.getMesh geo) - mesh-tris (triangles geo) - - ;; for each triangle - sensor-coords - (fn [tri] - ;; translate triangle to uv-pixel-space - (let [uv-tri - (rasterize mesh tri width height) - bounds (vec (triangle-bounds uv-tri))] - - ;; get that part of the picture - - (apply (partial (memfn setRoi) uv-image) bounds) - (let [cutout (.crop (.getProcessor uv-image)) - ;; extract white pixels inside triangle - cutout-tri - (map-triangle - (fn [_ v] - (.subtract - v - (Vector3f. (bounds 0) (bounds 1) (float 0)))) - uv-tri) - whites (filter (partial inside-triangle? cutout-tri) - (map vector2f->vector3f - (white-coordinates cutout))) - ;; translate pixel coordinates to world-space - transform (triangle-transformation cutout-tri tri)] - (map #(.mult transform %) whites))))] - - - - (for [mesh-tri mesh-tris] - - (let [uv-tri (rasterize mesh mesh-tri width height) - bounding-box (vec (triangle-bounds uv-tri))] - (apply (partial (memfn setRoi) uv-image) bounding-box) - - - - - )) - (vec (map sensor-coords mesh-tris)))) - - - -(defn measure-touchies [#^Geometry geo] - (let [tactile-sensor-coords (locate-tactile-sensors geo) - tris (triangles geo)] - (fn [world] - (let [sensor-origins (vec - (map - #(map (partial local-to-world geo) %) - tactile-sensor-coords)) - triangle-normals (vec - (map (partial get-ray-direction geo) - tris)) - rays (flatten - (map - (fn [origins normals] - (map - #(Ray. %1 %2) - origins - normals)) - sensor-origins - (map repeat triangle-normals))) - - - ] - rays)))) - - - - - - - - - - - - - - - - - - - -;; for each triangle in the mesh, -;; get the normal to the triangle, -;; look at the UV touch map, restricted to that triangle, -;; get the positions of those touch sensors in geometry-relative -;; coordinates. -(defn tactile-coords [#^Geometry obj] - (let [mesh (.getMesh obj) - num-triangles (.getTriangleCount mesh) - num-verticies (.getVertexCount mesh) - uv-coord (partial uv-coord mesh) - triangle-indices (partial triangle-indices mesh) - receptors (touch-receptor-image obj) - tris (triangles obj) - ] - (map - (fn [[tri-1 tri-2 tri-3]] - (let [width (.getWidth receptors) - height (.getHeight receptors) - uv-1 (uv-coord tri-1) - uv-2 (uv-coord tri-2) - uv-3 (uv-coord tri-3) - x-coords (map #(.getX %) [uv-1 uv-2 uv-3]) - y-coords (map #(.getY %) [uv-1 uv-2 uv-3]) - max-x (Math/ceil (* width (apply max x-coords))) - min-x (Math/floor (* width (apply min x-coords))) - max-y (Math/ceil (* height (apply max y-coords))) - min-y (Math/floor (* height (apply min y-coords))) - - image-1 (Vector2f. (* width (.getX uv-1)) - (* height (.getY uv-1))) - image-2 (Vector2f. (* width (.getX uv-2)) - (* height (.getY uv-2))) - image-3 (Vector2f. (* width (.getX uv-3)) - (* height (.getY uv-3))) - left-corner - (Vector2f. min-x min-y) - ] - - (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y)) - (let [processor (.crop (.getProcessor receptors))] - (map - #(.add left-corner %) - - (filter - (partial - inside-triangle? - (.subtract image-1 left-corner) - (.subtract image-2 left-corner) - (.subtract image-3 left-corner)) - (white-coordinates processor)))) - )) (map triangle-indices (range num-triangles))))) - - - + @@ -874,6 +761,101 @@ (Vector3f. 1 0 0)))))))) +(defn locate-feelers* + "Search the geometry's tactile UV image for touch sensors, returning + their positions in geometry-relative coordinates." + [#^Geometry geo] + (let [uv-image (touch-receptor-image geo) + width (.getWidth uv-image) + height (.getHeight uv-image) + + mesh (.getMesh geo) + mesh-tris (triangles geo) + + ;; for each triangle + sensor-coords + (fn [tri] + ;; translate triangle to uv-pixel-space + (let [uv-tri + (rasterize mesh tri width height) + bounds (vec (triangle-bounds uv-tri))] + + ;; get that part of the picture + + (apply (partial (memfn setRoi) uv-image) bounds) + (let [cutout (.crop (.getProcessor uv-image)) + ;; extract white pixels inside triangle + cutout-tri + (map-triangle + (fn [_ v] + (.subtract + v + (Vector3f. (bounds 0) (bounds 1) (float 0)))) + uv-tri) + whites (filter (partial inside-triangle? cutout-tri) + (map vector2f->vector3f + (white-coordinates cutout))) + ;; translate pixel coordinates to world-space + transform (triangle-transformation cutout-tri tri)] + (map #(.mult transform %) whites))))] + + + + (for [mesh-tri mesh-tris] + + (let [uv-tri (rasterize mesh mesh-tri width height) + bounding-box (vec (triangle-bounds uv-tri))] + (apply (partial (memfn setRoi) uv-image) bounding-box) + )) + (vec (map sensor-coords mesh-tris)))) + + +(defn tactile-coords [#^Geometry obj] + (let [mesh (.getMesh obj) + num-triangles (.getTriangleCount mesh) + num-verticies (.getVertexCount mesh) + uv-coord (partial uv-coord mesh) + triangle-indices (partial triangle-indices mesh) + receptors (touch-receptor-image obj) + tris (triangles obj) + ] + (map + (fn [[tri-1 tri-2 tri-3]] + (let [width (.getWidth receptors) + height (.getHeight receptors) + uv-1 (uv-coord tri-1) + uv-2 (uv-coord tri-2) + uv-3 (uv-coord tri-3) + x-coords (map #(.getX %) [uv-1 uv-2 uv-3]) + y-coords (map #(.getY %) [uv-1 uv-2 uv-3]) + max-x (Math/ceil (* width (apply max x-coords))) + min-x (Math/floor (* width (apply min x-coords))) + max-y (Math/ceil (* height (apply max y-coords))) + min-y (Math/floor (* height (apply min y-coords))) + + image-1 (Vector2f. (* width (.getX uv-1)) + (* height (.getY uv-1))) + image-2 (Vector2f. (* width (.getX uv-2)) + (* height (.getY uv-2))) + image-3 (Vector2f. (* width (.getX uv-3)) + (* height (.getY uv-3))) + left-corner + (Vector2f. min-x min-y) + ] + + (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y)) + (let [processor (.crop (.getProcessor receptors))] + (map + #(.add left-corner %) + + (filter + (partial + inside-triangle? + (.subtract image-1 left-corner) + (.subtract image-2 left-corner) + (.subtract image-3 left-corner)) + (white-coordinates processor)))) + )) (map triangle-indices (range num-triangles))))) #+end_src