Mercurial > cortex
view org/sense-util.org @ 171:15bde60217aa
updated docstring for vision-fn
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 04 Feb 2012 05:02:25 -0700 |
parents | 9e6a30b8c99a |
children | 0f1c7921d967 |
line wrap: on
line source
1 #+title: General sense/effector utilities2 #+author: Robert McIntyre3 #+email: rlm@mit.edu4 #+description: sensory utilities5 #+keywords: simulation, jMonkeyEngine3, clojure, simulated senses6 #+SETUPFILE: ../../aurellem/org/setup.org7 #+INCLUDE: ../../aurellem/org/level-0.org10 #+name: sense-util11 #+begin_src clojure12 (ns cortex.sense)13 (cortex.import/mega-import-jme3)14 (import ij.process.ImageProcessor)15 (import java.awt.image.BufferedImage)16 (use 'cortex.util)17 (import jme3tools.converters.ImageToAwt)19 (defn meta-data [blender-node key]20 (if-let [data (.getUserData blender-node "properties")]21 (.findValue data key)22 nil))24 (defn closest-node25 "Return the object in creature which is closest to the given node."26 ;;dylan"The closest object in creature to the given node."27 [#^Node creature #^Node eye]28 (loop [radius (float 0.01)]29 (let [results (CollisionResults.)]30 (.collideWith31 creature32 (BoundingBox. (.getWorldTranslation eye)33 radius radius radius)34 results)35 (if-let [target (first results)]36 (.getGeometry target)37 (recur (float (* 2 radius)))))))39 (defn bind-sense40 "Bind the sense to the Spatial such that it will maintain its41 current position relative to the Spatial no matter how the spatial42 moves. 'sense can be either a Camera or Listener object."43 [#^Spatial obj sense]44 (let [sense-offset (.subtract (.getLocation sense)45 (.getWorldTranslation obj))46 initial-sense-rotation (Quaternion. (.getRotation sense))47 base-anti-rotation (.inverse (.getWorldRotation obj))]48 (.addControl49 obj50 (proxy [AbstractControl] []51 (controlUpdate [tpf]52 (let [total-rotation53 (.mult base-anti-rotation (.getWorldRotation obj))]54 (.setLocation sense55 (.add56 (.mult total-rotation sense-offset)57 (.getWorldTranslation obj)))58 (.setRotation sense59 (.mult total-rotation initial-sense-rotation))))60 (controlRender [_ _])))))62 (def white -1)64 (defn filter-pixels65 "List the coordinates of all pixels matching pred, within the bounds66 provided. Bounds -> [x0 y0 width height]"67 {:author "Dylan Holmes"}68 ([pred #^BufferedImage image]69 (filter-pixels pred image [0 0 (.getWidth image) (.getHeight image)]))70 ([pred #^BufferedImage image [x0 y0 width height]]71 ((fn accumulate [x y matches]72 (cond73 (>= y (+ height y0)) matches74 (>= x (+ width x0)) (recur 0 (inc y) matches)75 (pred (.getRGB image x y))76 (recur (inc x) y (conj matches [x y]))77 :else (recur (inc x) y matches)))78 x0 y0 [])))80 (defn white-coordinates81 "Coordinates of all the white pixels in a subset of the image."82 ([#^BufferedImage image bounds]83 (filter-pixels #(= % white) image bounds))84 ([#^BufferedImage image]85 (filter-pixels #(= % white) image)))87 (defn points->image88 "Take a sparse collection of points and visuliaze it as a89 BufferedImage."91 ;; TODO maybe parallelize this since it's easy93 [points]94 (if (empty? points)95 (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY)96 (let [xs (vec (map first points))97 ys (vec (map second points))98 x0 (apply min xs)99 y0 (apply min ys)100 width (- (apply max xs) x0)101 height (- (apply max ys) y0)102 image (BufferedImage. (inc width) (inc height)103 BufferedImage/TYPE_INT_RGB)]104 (dorun105 (for [x (range (.getWidth image))106 y (range (.getHeight image))]107 (.setRGB image x y 0xFF0000)))108 (dorun109 (for [index (range (count points))]110 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1)))112 image)))114 (defn average [coll]115 (/ (reduce + coll) (count coll)))117 (defn collapse-1d118 "One dimensional analogue of collapse"119 [center line]120 (let [length (count line)121 num-above (count (filter (partial < center) line))122 num-below (- length num-above)]123 (range (- center num-below)124 (+ center num-above))))126 (defn collapse127 "Take a set of pairs of integers and collapse them into a128 contigous bitmap."129 [points]130 (if (empty? points) []131 (let132 [num-points (count points)133 center (vector134 (int (average (map first points)))135 (int (average (map first points))))136 flattened137 (reduce138 concat139 (map140 (fn [column]141 (map vector142 (map first column)143 (collapse-1d (second center)144 (map second column))))145 (partition-by first (sort-by first points))))146 squeezed147 (reduce148 concat149 (map150 (fn [row]151 (map vector152 (collapse-1d (first center)153 (map first row))154 (map second row)))155 (partition-by second (sort-by second flattened))))156 relocate157 (let [min-x (apply min (map first squeezed))158 min-y (apply min (map second squeezed))]159 (map (fn [[x y]]160 [(- x min-x)161 (- y min-y)])162 squeezed))]163 relocate)))165 (defn world-to-local166 "Convert the world coordinates into coordinates relative to the167 object (i.e. local coordinates), taking into account the rotation168 of object."169 [#^Spatial object world-coordinate]170 (.worldToLocal object world-coordinate nil))172 (defn local-to-world173 "Convert the local coordinates into coordinates into world relative174 coordinates"175 [#^Spatial object local-coordinate]176 (.localToWorld object local-coordinate nil))179 (defn sense-nodes [parent-name]180 (fn [#^Node creature]181 (if-let [sense-node (.getChild creature parent-name)]182 (seq (.getChildren sense-node))183 (do (println-repl "could not find" parent-name "node") []))))185 (defn load-image186 "Load an image as a BufferedImage using the asset-manager system."187 [asset-relative-path]188 (ImageToAwt/convert189 (.getImage (.loadTexture (asset-manager) asset-relative-path))190 false false 0))193 #+end_src195 #+results: sense-util196 : #'cortex.sense/meta-data200 * COMMENT generate source201 #+begin_src clojure :tangle ../src/cortex/sense.clj202 <<sense-util>>203 #+end_src